blob: d7f920de25f7932e19c25545e07dcea90c805f3b [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,
Malcolm Priestleyab01fed2013-08-07 21:31:48 +0100109 u32 uDMAIdx, int bNeedAck, u8 byFBOption);
Forest Bond92b96792009-06-13 07:38:31 -0400110
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000111static void s_vGenerateMACHeader(struct vnt_private *pDevice,
Andres Moreceb8c5d2013-03-18 20:33:49 -0500112 u8 *pbyBufferAddr, u16 wDuration, struct ethhdr *psEthHeader,
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000113 int bNeedEncrypt, u16 wFragType, u32 uDMAIdx, u32 uFragIdx);
Forest Bond92b96792009-06-13 07:38:31 -0400114
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000115static void s_vFillTxKey(struct vnt_private *pDevice, u8 *pbyBuf,
116 u8 *pbyIVHead, PSKeyItem pTransmitKey, u8 *pbyHdrBuf, u16 wPayloadLen,
117 u8 *pMICHDR);
Forest Bond92b96792009-06-13 07:38:31 -0400118
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000119static void s_vSWencryption(struct vnt_private *pDevice,
120 PSKeyItem pTransmitKey, u8 *pbyPayloadHead, u16 wPayloadSize);
Forest Bond92b96792009-06-13 07:38:31 -0400121
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000122static unsigned int s_uGetTxRsvTime(struct vnt_private *pDevice, u8 byPktType,
123 u32 cbFrameLength, u16 wRate, int bNeedAck);
Forest Bond92b96792009-06-13 07:38:31 -0400124
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000125static u32 s_uGetRTSCTSRsvTime(struct vnt_private *pDevice, u8 byRTSRsvType,
126 u8 byPktType, u32 cbFrameLength, u16 wCurrentRate);
Forest Bond92b96792009-06-13 07:38:31 -0400127
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000128static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
129 u8 byPktType, void *pvCTS, u32 cbFrameLength, int bNeedAck,
130 int bDisCRC, u16 wCurrentRate, u8 byFBOption);
Forest Bond92b96792009-06-13 07:38:31 -0400131
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000132static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
133 void *pvRTS, u32 cbFrameLength, int bNeedAck, int bDisCRC,
Andres Moreceb8c5d2013-03-18 20:33:49 -0500134 struct ethhdr *psEthHeader, u16 wCurrentRate, u8 byFBOption);
Forest Bond92b96792009-06-13 07:38:31 -0400135
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000136static u32 s_uGetDataDuration(struct vnt_private *pDevice, u8 byDurType,
Malcolm Priestley3ed210e2013-08-07 21:28:45 +0100137 u8 byPktType, int bNeedAck);
Forest Bond92b96792009-06-13 07:38:31 -0400138
Malcolm Priestleye34f9db2013-08-13 20:17:11 +0100139static u16 s_uGetRTSCTSDuration(struct vnt_private *pDevice,
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000140 u8 byDurType, u32 cbFrameLength, u8 byPktType, u16 wRate,
141 int bNeedAck, u8 byFBOption);
Forest Bond92b96792009-06-13 07:38:31 -0400142
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000143static void *s_vGetFreeContext(struct vnt_private *pDevice)
Forest Bond92b96792009-06-13 07:38:31 -0400144{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000145 PUSB_SEND_CONTEXT pContext = NULL;
146 PUSB_SEND_CONTEXT pReturnContext = NULL;
147 int ii;
Forest Bond92b96792009-06-13 07:38:31 -0400148
149 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GetFreeContext()\n");
150
151 for (ii = 0; ii < pDevice->cbTD; ii++) {
152 pContext = pDevice->apTD[ii];
Andres Moree269fc22013-02-12 20:36:29 -0500153 if (pContext->bBoolInUse == false) {
Andres More4e9b5e22013-02-12 20:36:30 -0500154 pContext->bBoolInUse = true;
Malcolm Priestleyc0de17e2013-08-05 21:09:14 +0100155 memset(pContext->Data, 0, MAX_TOTAL_SIZE_WITH_ALL_HEADERS);
Forest Bond92b96792009-06-13 07:38:31 -0400156 pReturnContext = pContext;
157 break;
158 }
159 }
160 if ( ii == pDevice->cbTD ) {
161 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No Free Tx Context\n");
162 }
Andres More8611a292010-05-01 14:25:00 -0300163 return (void *) pReturnContext;
Forest Bond92b96792009-06-13 07:38:31 -0400164}
165
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000166static void s_vSaveTxPktInfo(struct vnt_private *pDevice, u8 byPktNum,
167 u8 *pbyDestAddr, u16 wPktLength, u16 wFIFOCtl)
Forest Bond92b96792009-06-13 07:38:31 -0400168{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000169 PSStatCounter pStatistic = &pDevice->scStatistic;
Forest Bond92b96792009-06-13 07:38:31 -0400170
Andres More4b50fb42010-06-22 21:57:42 -0300171 if (is_broadcast_ether_addr(pbyDestAddr))
Forest Bond92b96792009-06-13 07:38:31 -0400172 pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni = TX_PKT_BROAD;
Andres More4b50fb42010-06-22 21:57:42 -0300173 else if (is_multicast_ether_addr(pbyDestAddr))
Forest Bond92b96792009-06-13 07:38:31 -0400174 pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni = TX_PKT_MULTI;
175 else
176 pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni = TX_PKT_UNI;
177
178 pStatistic->abyTxPktInfo[byPktNum].wLength = wPktLength;
179 pStatistic->abyTxPktInfo[byPktNum].wFIFOCtl = wFIFOCtl;
Andres More9a0e7562010-04-13 21:54:48 -0300180 memcpy(pStatistic->abyTxPktInfo[byPktNum].abyDestAddr,
181 pbyDestAddr,
182 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400183}
184
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000185static void s_vFillTxKey(struct vnt_private *pDevice, u8 *pbyBuf,
186 u8 *pbyIVHead, PSKeyItem pTransmitKey, u8 *pbyHdrBuf,
187 u16 wPayloadLen, u8 *pMICHDR)
Forest Bond92b96792009-06-13 07:38:31 -0400188{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000189 u32 *pdwIV = (u32 *)pbyIVHead;
190 u32 *pdwExtIV = (u32 *)((u8 *)pbyIVHead + 4);
191 u16 wValue;
Andres More1cac4a42013-03-18 20:33:50 -0500192 struct ieee80211_hdr *pMACHeader = (struct ieee80211_hdr *)pbyHdrBuf;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000193 u32 dwRevIVCounter;
Forest Bond92b96792009-06-13 07:38:31 -0400194
Forest Bond92b96792009-06-13 07:38:31 -0400195 //Fill TXKEY
196 if (pTransmitKey == NULL)
197 return;
198
199 dwRevIVCounter = cpu_to_le32(pDevice->dwIVCounter);
200 *pdwIV = pDevice->dwIVCounter;
201 pDevice->byKeyIndex = pTransmitKey->dwKeyIndex & 0xf;
202
203 if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
204 if (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN ){
Andres Moreb902fbf2013-02-25 20:32:51 -0500205 memcpy(pDevice->abyPRNG, (u8 *)&(dwRevIVCounter), 3);
Jim Lieb3e362592009-08-12 14:54:11 -0700206 memcpy(pDevice->abyPRNG+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
Forest Bond92b96792009-06-13 07:38:31 -0400207 } else {
Andres Moreb902fbf2013-02-25 20:32:51 -0500208 memcpy(pbyBuf, (u8 *)&(dwRevIVCounter), 3);
Jim Lieb3e362592009-08-12 14:54:11 -0700209 memcpy(pbyBuf+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
Forest Bond92b96792009-06-13 07:38:31 -0400210 if(pTransmitKey->uKeyLength == WLAN_WEP40_KEYLEN) {
Andres Moreb902fbf2013-02-25 20:32:51 -0500211 memcpy(pbyBuf+8, (u8 *)&(dwRevIVCounter), 3);
Jim Lieb3e362592009-08-12 14:54:11 -0700212 memcpy(pbyBuf+11, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
Forest Bond92b96792009-06-13 07:38:31 -0400213 }
Jim Lieb3e362592009-08-12 14:54:11 -0700214 memcpy(pDevice->abyPRNG, pbyBuf, 16);
Forest Bond92b96792009-06-13 07:38:31 -0400215 }
216 // Append IV after Mac Header
217 *pdwIV &= WEP_IV_MASK;//00000000 11111111 11111111 11111111
Malcolm Priestleyd5bbef72012-11-11 15:53:14 +0000218 *pdwIV |= (u32)pDevice->byKeyIndex << 30;
Forest Bond92b96792009-06-13 07:38:31 -0400219 *pdwIV = cpu_to_le32(*pdwIV);
220 pDevice->dwIVCounter++;
221 if (pDevice->dwIVCounter > WEP_IV_MASK) {
222 pDevice->dwIVCounter = 0;
223 }
224 } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
225 pTransmitKey->wTSC15_0++;
226 if (pTransmitKey->wTSC15_0 == 0) {
227 pTransmitKey->dwTSC47_16++;
228 }
229 TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr,
230 pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG);
Jim Lieb3e362592009-08-12 14:54:11 -0700231 memcpy(pbyBuf, pDevice->abyPRNG, 16);
Forest Bond92b96792009-06-13 07:38:31 -0400232 // Make IV
Jim Lieb3e362592009-08-12 14:54:11 -0700233 memcpy(pdwIV, pDevice->abyPRNG, 3);
Forest Bond92b96792009-06-13 07:38:31 -0400234
Andres Moreb902fbf2013-02-25 20:32:51 -0500235 *(pbyIVHead+3) = (u8)(((pDevice->byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV
Forest Bond92b96792009-06-13 07:38:31 -0400236 // Append IV&ExtIV after Mac Header
237 *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16);
Malcolm Priestleyb4dc03a2012-11-11 15:45:52 +0000238 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vFillTxKey()---- pdwExtIV: %x\n",
239 *pdwExtIV);
Forest Bond92b96792009-06-13 07:38:31 -0400240
241 } else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) {
242 pTransmitKey->wTSC15_0++;
243 if (pTransmitKey->wTSC15_0 == 0) {
244 pTransmitKey->dwTSC47_16++;
245 }
Jim Lieb3e362592009-08-12 14:54:11 -0700246 memcpy(pbyBuf, pTransmitKey->abyKey, 16);
Forest Bond92b96792009-06-13 07:38:31 -0400247
248 // Make IV
249 *pdwIV = 0;
Andres Moreb902fbf2013-02-25 20:32:51 -0500250 *(pbyIVHead+3) = (u8)(((pDevice->byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV
Andres More3eaca0d2013-02-25 20:32:52 -0500251 *pdwIV |= cpu_to_le16((u16)(pTransmitKey->wTSC15_0));
Forest Bond92b96792009-06-13 07:38:31 -0400252 //Append IV&ExtIV after Mac Header
253 *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16);
254
255 //Fill MICHDR0
256 *pMICHDR = 0x59;
Andres Moreb902fbf2013-02-25 20:32:51 -0500257 *((u8 *)(pMICHDR+1)) = 0; // TxPriority
Andres More1cac4a42013-03-18 20:33:50 -0500258 memcpy(pMICHDR+2, &(pMACHeader->addr2[0]), 6);
Andres Moreb902fbf2013-02-25 20:32:51 -0500259 *((u8 *)(pMICHDR+8)) = HIBYTE(HIWORD(pTransmitKey->dwTSC47_16));
260 *((u8 *)(pMICHDR+9)) = LOBYTE(HIWORD(pTransmitKey->dwTSC47_16));
261 *((u8 *)(pMICHDR+10)) = HIBYTE(LOWORD(pTransmitKey->dwTSC47_16));
262 *((u8 *)(pMICHDR+11)) = LOBYTE(LOWORD(pTransmitKey->dwTSC47_16));
263 *((u8 *)(pMICHDR+12)) = HIBYTE(pTransmitKey->wTSC15_0);
264 *((u8 *)(pMICHDR+13)) = LOBYTE(pTransmitKey->wTSC15_0);
265 *((u8 *)(pMICHDR+14)) = HIBYTE(wPayloadLen);
266 *((u8 *)(pMICHDR+15)) = LOBYTE(wPayloadLen);
Forest Bond92b96792009-06-13 07:38:31 -0400267
268 //Fill MICHDR1
Andres Moreb902fbf2013-02-25 20:32:51 -0500269 *((u8 *)(pMICHDR+16)) = 0; // HLEN[15:8]
Forest Bond92b96792009-06-13 07:38:31 -0400270 if (pDevice->bLongHeader) {
Andres Moreb902fbf2013-02-25 20:32:51 -0500271 *((u8 *)(pMICHDR+17)) = 28; // HLEN[7:0]
Forest Bond92b96792009-06-13 07:38:31 -0400272 } else {
Andres Moreb902fbf2013-02-25 20:32:51 -0500273 *((u8 *)(pMICHDR+17)) = 22; // HLEN[7:0]
Forest Bond92b96792009-06-13 07:38:31 -0400274 }
Andres More1cac4a42013-03-18 20:33:50 -0500275 wValue = cpu_to_le16(pMACHeader->frame_control & 0xC78F);
Andres Moreb902fbf2013-02-25 20:32:51 -0500276 memcpy(pMICHDR+18, (u8 *)&wValue, 2); // MSKFRACTL
Andres More1cac4a42013-03-18 20:33:50 -0500277 memcpy(pMICHDR+20, &(pMACHeader->addr1[0]), 6);
278 memcpy(pMICHDR+26, &(pMACHeader->addr2[0]), 6);
Forest Bond92b96792009-06-13 07:38:31 -0400279
280 //Fill MICHDR2
Andres More1cac4a42013-03-18 20:33:50 -0500281 memcpy(pMICHDR+32, &(pMACHeader->addr3[0]), 6);
282 wValue = pMACHeader->seq_ctrl;
Forest Bond92b96792009-06-13 07:38:31 -0400283 wValue &= 0x000F;
284 wValue = cpu_to_le16(wValue);
Andres Moreb902fbf2013-02-25 20:32:51 -0500285 memcpy(pMICHDR+38, (u8 *)&wValue, 2); // MSKSEQCTL
Forest Bond92b96792009-06-13 07:38:31 -0400286 if (pDevice->bLongHeader) {
Andres More1cac4a42013-03-18 20:33:50 -0500287 memcpy(pMICHDR+40, &(pMACHeader->addr4[0]), 6);
Forest Bond92b96792009-06-13 07:38:31 -0400288 }
289 }
290}
291
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000292static void s_vSWencryption(struct vnt_private *pDevice,
293 PSKeyItem pTransmitKey, u8 *pbyPayloadHead, u16 wPayloadSize)
Forest Bond92b96792009-06-13 07:38:31 -0400294{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000295 u32 cbICVlen = 4;
296 u32 dwICV = 0xffffffff;
297 u32 *pdwICV;
Forest Bond92b96792009-06-13 07:38:31 -0400298
299 if (pTransmitKey == NULL)
300 return;
301
302 if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
303 //=======================================================================
304 // Append ICV after payload
305 dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload)
Andres More52a7e642013-02-25 20:32:53 -0500306 pdwICV = (u32 *)(pbyPayloadHead + wPayloadSize);
Forest Bond92b96792009-06-13 07:38:31 -0400307 // finally, we must invert dwCRC to get the correct answer
308 *pdwICV = cpu_to_le32(~dwICV);
309 // RC4 encryption
310 rc4_init(&pDevice->SBox, pDevice->abyPRNG, pTransmitKey->uKeyLength + 3);
311 rc4_encrypt(&pDevice->SBox, pbyPayloadHead, pbyPayloadHead, wPayloadSize+cbICVlen);
312 //=======================================================================
313 } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
314 //=======================================================================
315 //Append ICV after payload
316 dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload)
Andres More52a7e642013-02-25 20:32:53 -0500317 pdwICV = (u32 *)(pbyPayloadHead + wPayloadSize);
Forest Bond92b96792009-06-13 07:38:31 -0400318 // finally, we must invert dwCRC to get the correct answer
319 *pdwICV = cpu_to_le32(~dwICV);
320 // RC4 encryption
321 rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN);
322 rc4_encrypt(&pDevice->SBox, pbyPayloadHead, pbyPayloadHead, wPayloadSize+cbICVlen);
323 //=======================================================================
324 }
325}
326
Forest Bond92b96792009-06-13 07:38:31 -0400327/*byPktType : PK_TYPE_11A 0
328 PK_TYPE_11B 1
329 PK_TYPE_11GB 2
330 PK_TYPE_11GA 3
331*/
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000332static u32 s_uGetTxRsvTime(struct vnt_private *pDevice, u8 byPktType,
333 u32 cbFrameLength, u16 wRate, int bNeedAck)
Forest Bond92b96792009-06-13 07:38:31 -0400334{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000335 u32 uDataTime, uAckTime;
Forest Bond92b96792009-06-13 07:38:31 -0400336
337 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wRate);
338 if (byPktType == PK_TYPE_11B) {//llb,CCK mode
Andres More3eaca0d2013-02-25 20:32:52 -0500339 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (u16)pDevice->byTopCCKBasicRate);
Forest Bond92b96792009-06-13 07:38:31 -0400340 } else {//11g 2.4G OFDM mode & 11a 5G OFDM mode
Andres More3eaca0d2013-02-25 20:32:52 -0500341 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (u16)pDevice->byTopOFDMBasicRate);
Forest Bond92b96792009-06-13 07:38:31 -0400342 }
343
344 if (bNeedAck) {
345 return (uDataTime + pDevice->uSIFS + uAckTime);
346 }
347 else {
348 return uDataTime;
349 }
350}
351
352//byFreqType: 0=>5GHZ 1=>2.4GHZ
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000353static u32 s_uGetRTSCTSRsvTime(struct vnt_private *pDevice,
354 u8 byRTSRsvType, u8 byPktType, u32 cbFrameLength, u16 wCurrentRate)
Forest Bond92b96792009-06-13 07:38:31 -0400355{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000356 u32 uRrvTime, uRTSTime, uCTSTime, uAckTime, uDataTime;
Forest Bond92b96792009-06-13 07:38:31 -0400357
358 uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0;
359
Forest Bond92b96792009-06-13 07:38:31 -0400360 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wCurrentRate);
361 if (byRTSRsvType == 0) { //RTSTxRrvTime_bb
362 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
363 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
364 }
365 else if (byRTSRsvType == 1){ //RTSTxRrvTime_ba, only in 2.4GHZ
366 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
367 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
368 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
369 }
370 else if (byRTSRsvType == 2) { //RTSTxRrvTime_aa
371 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopOFDMBasicRate);
372 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
373 }
374 else if (byRTSRsvType == 3) { //CTSTxRrvTime_ba, only in 2.4GHZ
375 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
376 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
377 uRrvTime = uCTSTime + uAckTime + uDataTime + 2*pDevice->uSIFS;
378 return uRrvTime;
379 }
380
381 //RTSRrvTime
382 uRrvTime = uRTSTime + uCTSTime + uAckTime + uDataTime + 3*pDevice->uSIFS;
383 return uRrvTime;
384}
385
386//byFreqType 0: 5GHz, 1:2.4Ghz
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000387static u32 s_uGetDataDuration(struct vnt_private *pDevice, u8 byDurType,
Malcolm Priestley3ed210e2013-08-07 21:28:45 +0100388 u8 byPktType, int bNeedAck)
Forest Bond92b96792009-06-13 07:38:31 -0400389{
Malcolm Priestley0005cb02013-08-07 21:26:12 +0100390 u32 uAckTime = 0;
Forest Bond92b96792009-06-13 07:38:31 -0400391
Malcolm Priestleyb02ccd52013-08-13 19:59:31 +0100392 if (bNeedAck) {
393 if (byDurType == DATADUR_B)
394 uAckTime = BBuGetFrameTime(pDevice->byPreambleType,
395 byPktType, 14, pDevice->byTopCCKBasicRate);
396 else
397 uAckTime = BBuGetFrameTime(pDevice->byPreambleType,
398 byPktType, 14, pDevice->byTopOFDMBasicRate);
399 return pDevice->uSIFS + uAckTime;
400 }
Forest Bond92b96792009-06-13 07:38:31 -0400401
Forest Bond92b96792009-06-13 07:38:31 -0400402 return 0;
403}
404
Forest Bond92b96792009-06-13 07:38:31 -0400405//byFreqType: 0=>5GHZ 1=>2.4GHZ
Malcolm Priestleye34f9db2013-08-13 20:17:11 +0100406static u16 s_uGetRTSCTSDuration(struct vnt_private *pDevice, u8 byDurType,
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000407 u32 cbFrameLength, u8 byPktType, u16 wRate, int bNeedAck,
408 u8 byFBOption)
Forest Bond92b96792009-06-13 07:38:31 -0400409{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000410 u32 uCTSTime = 0, uDurTime = 0;
Forest Bond92b96792009-06-13 07:38:31 -0400411
Forest Bond92b96792009-06-13 07:38:31 -0400412 switch (byDurType) {
413
414 case RTSDUR_BB: //RTSDuration_bb
415 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
416 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
417 break;
418
419 case RTSDUR_BA: //RTSDuration_ba
420 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
421 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
422 break;
423
424 case RTSDUR_AA: //RTSDuration_aa
425 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
426 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
427 break;
428
429 case CTSDUR_BA: //CTSDuration_ba
430 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
431 break;
432
433 case RTSDUR_BA_F0: //RTSDuration_ba_f0
434 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
435 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
436 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
437 } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
438 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
439 }
440 break;
441
442 case RTSDUR_AA_F0: //RTSDuration_aa_f0
443 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
444 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
445 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
446 } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
447 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
448 }
449 break;
450
451 case RTSDUR_BA_F1: //RTSDuration_ba_f1
452 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
453 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
454 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
455 } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
456 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
457 }
458 break;
459
460 case RTSDUR_AA_F1: //RTSDuration_aa_f1
461 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
462 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
463 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
464 } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
465 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
466 }
467 break;
468
469 case CTSDUR_BA_F0: //CTSDuration_ba_f0
470 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
471 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
472 } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
473 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
474 }
475 break;
476
477 case CTSDUR_BA_F1: //CTSDuration_ba_f1
478 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
479 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
480 } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
481 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
482 }
483 break;
484
485 default:
486 break;
487 }
488
Malcolm Priestleye34f9db2013-08-13 20:17:11 +0100489 return cpu_to_le16((u16)uDurTime);
Forest Bond92b96792009-06-13 07:38:31 -0400490}
491
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000492static u32 s_uFillDataHead(struct vnt_private *pDevice,
493 u8 byPktType, u16 wCurrentRate, void *pTxDataHead, u32 cbFrameLength,
Malcolm Priestleyab01fed2013-08-07 21:31:48 +0100494 u32 uDMAIdx, int bNeedAck, u8 byFBOption)
Forest Bond92b96792009-06-13 07:38:31 -0400495{
496
497 if (pTxDataHead == NULL) {
498 return 0;
499 }
500
501 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
Andres Morebd2bc4c2010-08-02 23:35:57 -0300502 if ((uDMAIdx == TYPE_ATIMDMA) || (uDMAIdx == TYPE_BEACONDMA)) {
Malcolm Priestley558becf2013-08-16 23:50:32 +0100503 struct vnt_tx_datahead_ab *pBuf =
504 (struct vnt_tx_datahead_ab *)pTxDataHead;
Forest Bond92b96792009-06-13 07:38:31 -0400505 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700506 BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
Andres More3eaca0d2013-02-25 20:32:52 -0500507 (u16 *)&(pBuf->wTransmitLength), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField)
Forest Bond92b96792009-06-13 07:38:31 -0400508 );
509 //Get Duration and TimeStampOff
Malcolm Priestley3ed210e2013-08-07 21:28:45 +0100510 pBuf->wDuration = (u16)s_uGetDataDuration(pDevice, DATADUR_A,
511 byPktType, bNeedAck);
Forest Bond92b96792009-06-13 07:38:31 -0400512 if(uDMAIdx!=TYPE_ATIMDMA) {
513 pBuf->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
514 }
515 return (pBuf->wDuration);
516 }
517 else { // DATA & MANAGE Frame
518 if (byFBOption == AUTO_FB_NONE) {
Malcolm Priestley7e60a3de2013-08-16 23:48:03 +0100519 struct vnt_tx_datahead_g *pBuf =
520 (struct vnt_tx_datahead_g *)pTxDataHead;
Forest Bond92b96792009-06-13 07:38:31 -0400521 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700522 BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
Andres More3eaca0d2013-02-25 20:32:52 -0500523 (u16 *)&(pBuf->wTransmitLength_a), (u8 *)&(pBuf->byServiceField_a), (u8 *)&(pBuf->bySignalField_a)
Forest Bond92b96792009-06-13 07:38:31 -0400524 );
Justin P. Mattockbda79782012-08-26 08:16:44 -0700525 BBvCalculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
Andres More3eaca0d2013-02-25 20:32:52 -0500526 (u16 *)&(pBuf->wTransmitLength_b), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b)
Forest Bond92b96792009-06-13 07:38:31 -0400527 );
528 //Get Duration and TimeStamp
Malcolm Priestley3ed210e2013-08-07 21:28:45 +0100529 pBuf->wDuration_a = (u16)s_uGetDataDuration(pDevice, DATADUR_A,
530 byPktType, bNeedAck);
531 pBuf->wDuration_b = (u16)s_uGetDataDuration(pDevice, DATADUR_B,
532 PK_TYPE_11B, bNeedAck);
Forest Bond92b96792009-06-13 07:38:31 -0400533
534 pBuf->wTimeStampOff_a = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
535 pBuf->wTimeStampOff_b = wTimeStampOff[pDevice->byPreambleType%2][pDevice->byTopCCKBasicRate%MAX_RATE];
536 return (pBuf->wDuration_a);
537 } else {
538 // Auto Fallback
Malcolm Priestley7c05c542013-08-16 23:49:15 +0100539 struct vnt_tx_datahead_g_fb *pBuf =
540 (struct vnt_tx_datahead_g_fb *)pTxDataHead;
Forest Bond92b96792009-06-13 07:38:31 -0400541 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700542 BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
Andres More3eaca0d2013-02-25 20:32:52 -0500543 (u16 *)&(pBuf->wTransmitLength_a), (u8 *)&(pBuf->byServiceField_a), (u8 *)&(pBuf->bySignalField_a)
Forest Bond92b96792009-06-13 07:38:31 -0400544 );
Justin P. Mattockbda79782012-08-26 08:16:44 -0700545 BBvCalculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
Andres More3eaca0d2013-02-25 20:32:52 -0500546 (u16 *)&(pBuf->wTransmitLength_b), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b)
Forest Bond92b96792009-06-13 07:38:31 -0400547 );
548 //Get Duration and TimeStamp
Malcolm Priestley3ed210e2013-08-07 21:28:45 +0100549 pBuf->wDuration_a = (u16)s_uGetDataDuration(pDevice, DATADUR_A,
550 byPktType, bNeedAck);
551 pBuf->wDuration_b = (u16)s_uGetDataDuration(pDevice, DATADUR_B,
552 PK_TYPE_11B, bNeedAck);
553 pBuf->wDuration_a_f0 = (u16)s_uGetDataDuration(pDevice,
554 DATADUR_A_F0, byPktType, bNeedAck);
555 pBuf->wDuration_a_f1 = (u16)s_uGetDataDuration(pDevice,
556 DATADUR_A_F1, byPktType, bNeedAck);
Forest Bond92b96792009-06-13 07:38:31 -0400557 pBuf->wTimeStampOff_a = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
558 pBuf->wTimeStampOff_b = wTimeStampOff[pDevice->byPreambleType%2][pDevice->byTopCCKBasicRate%MAX_RATE];
559 return (pBuf->wDuration_a);
560 } //if (byFBOption == AUTO_FB_NONE)
561 }
562 }
563 else if (byPktType == PK_TYPE_11A) {
564 if ((byFBOption != AUTO_FB_NONE) && (uDMAIdx != TYPE_ATIMDMA) && (uDMAIdx != TYPE_BEACONDMA)) {
565 // Auto Fallback
Malcolm Priestley1da4ee22013-08-16 23:51:38 +0100566 struct vnt_tx_datahead_a_fb *pBuf =
567 (struct vnt_tx_datahead_a_fb *)pTxDataHead;
Forest Bond92b96792009-06-13 07:38:31 -0400568 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700569 BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
Andres More3eaca0d2013-02-25 20:32:52 -0500570 (u16 *)&(pBuf->wTransmitLength), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField)
Forest Bond92b96792009-06-13 07:38:31 -0400571 );
572 //Get Duration and TimeStampOff
Malcolm Priestley3ed210e2013-08-07 21:28:45 +0100573 pBuf->wDuration = (u16)s_uGetDataDuration(pDevice, DATADUR_A,
574 byPktType, bNeedAck);
575 pBuf->wDuration_f0 = (u16)s_uGetDataDuration(pDevice,
576 DATADUR_A_F0, byPktType, bNeedAck);
577 pBuf->wDuration_f1 = (u16)s_uGetDataDuration(pDevice,
578 DATADUR_A_F1, byPktType, bNeedAck);
Forest Bond92b96792009-06-13 07:38:31 -0400579 if(uDMAIdx!=TYPE_ATIMDMA) {
580 pBuf->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
581 }
582 return (pBuf->wDuration);
583 } else {
Malcolm Priestley558becf2013-08-16 23:50:32 +0100584 struct vnt_tx_datahead_ab *pBuf =
585 (struct vnt_tx_datahead_ab *)pTxDataHead;
Forest Bond92b96792009-06-13 07:38:31 -0400586 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700587 BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
Andres More3eaca0d2013-02-25 20:32:52 -0500588 (u16 *)&(pBuf->wTransmitLength), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField)
Forest Bond92b96792009-06-13 07:38:31 -0400589 );
590 //Get Duration and TimeStampOff
Malcolm Priestley3ed210e2013-08-07 21:28:45 +0100591 pBuf->wDuration = (u16)s_uGetDataDuration(pDevice, DATADUR_A,
592 byPktType, bNeedAck);
Forest Bond92b96792009-06-13 07:38:31 -0400593
594 if(uDMAIdx!=TYPE_ATIMDMA) {
595 pBuf->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
596 }
597 return (pBuf->wDuration);
598 }
599 }
600 else if (byPktType == PK_TYPE_11B) {
Malcolm Priestley558becf2013-08-16 23:50:32 +0100601 struct vnt_tx_datahead_ab *pBuf =
602 (struct vnt_tx_datahead_ab *)pTxDataHead;
Forest Bond92b96792009-06-13 07:38:31 -0400603 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700604 BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
Andres More3eaca0d2013-02-25 20:32:52 -0500605 (u16 *)&(pBuf->wTransmitLength), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField)
Forest Bond92b96792009-06-13 07:38:31 -0400606 );
607 //Get Duration and TimeStampOff
Malcolm Priestley3ed210e2013-08-07 21:28:45 +0100608 pBuf->wDuration = (u16)s_uGetDataDuration(pDevice, DATADUR_B,
609 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 }
615 return 0;
616}
617
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000618static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
619 void *pvRTS, u32 cbFrameLength, int bNeedAck, int bDisCRC,
Andres Moreceb8c5d2013-03-18 20:33:49 -0500620 struct ethhdr *psEthHeader, u16 wCurrentRate, u8 byFBOption)
Forest Bond92b96792009-06-13 07:38:31 -0400621{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000622 u32 uRTSFrameLen = 20;
623 u16 wLen = 0;
Forest Bond92b96792009-06-13 07:38:31 -0400624
Forest Bond92b96792009-06-13 07:38:31 -0400625 if (pvRTS == NULL)
626 return;
627
628 if (bDisCRC) {
629 // When CRCDIS bit is on, H/W forgot to generate FCS for RTS frame,
630 // in this case we need to decrease its length by 4.
631 uRTSFrameLen -= 4;
632 }
633
Masanari Iida93184692012-08-13 21:21:50 +0900634 // 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 -0400635 // Otherwise, we need to modified codes for them.
636 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
637 if (byFBOption == AUTO_FB_NONE) {
Malcolm Priestleyc521cb52013-08-15 21:23:25 +0100638 struct vnt_rts_g *pBuf = (struct vnt_rts_g *)pvRTS;
Forest Bond92b96792009-06-13 07:38:31 -0400639 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700640 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
Andres More3eaca0d2013-02-25 20:32:52 -0500641 (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b)
Forest Bond92b96792009-06-13 07:38:31 -0400642 );
643 pBuf->wTransmitLength_b = cpu_to_le16(wLen);
Justin P. Mattockbda79782012-08-26 08:16:44 -0700644 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
Andres More3eaca0d2013-02-25 20:32:52 -0500645 (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField_a), (u8 *)&(pBuf->bySignalField_a)
Forest Bond92b96792009-06-13 07:38:31 -0400646 );
647 pBuf->wTransmitLength_a = cpu_to_le16(wLen);
648 //Get Duration
Malcolm Priestleye34f9db2013-08-13 20:17:11 +0100649 pBuf->wDuration_bb = s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
650 cbFrameLength, PK_TYPE_11B,
651 pDevice->byTopCCKBasicRate, bNeedAck, byFBOption);
652 pBuf->wDuration_aa = s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
653 cbFrameLength, byPktType,
654 wCurrentRate, bNeedAck, byFBOption);
655 pBuf->wDuration_ba = s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
656 cbFrameLength, byPktType,
657 wCurrentRate, bNeedAck, byFBOption);
Malcolm Priestley07738932013-08-05 22:08:05 +0100658 pBuf->data.duration = pBuf->wDuration_aa;
659 /*Get RTS Frame body */
660 pBuf->data.frame_control = TYPE_CTL_RTS;
Forest Bond92b96792009-06-13 07:38:31 -0400661
Malcolm Priestley07738932013-08-05 22:08:05 +0100662 if (pDevice->eOPMode == OP_MODE_ADHOC ||
663 pDevice->eOPMode == OP_MODE_AP)
664 memcpy(pBuf->data.ra, psEthHeader->h_dest, ETH_ALEN);
665 else
666 memcpy(pBuf->data.ra, pDevice->abyBSSID, ETH_ALEN);
Andres More9a0e7562010-04-13 21:54:48 -0300667
Malcolm Priestley07738932013-08-05 22:08:05 +0100668 if (pDevice->eOPMode == OP_MODE_AP)
669 memcpy(pBuf->data.ta, pDevice->abyBSSID, ETH_ALEN);
670 else
671 memcpy(pBuf->data.ta, psEthHeader->h_source, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400672 }
673 else {
Malcolm Priestleyc521cb52013-08-15 21:23:25 +0100674 struct vnt_rts_g_fb *pBuf = (struct vnt_rts_g_fb *)pvRTS;
Forest Bond92b96792009-06-13 07:38:31 -0400675 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700676 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
Andres More3eaca0d2013-02-25 20:32:52 -0500677 (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b)
Forest Bond92b96792009-06-13 07:38:31 -0400678 );
679 pBuf->wTransmitLength_b = cpu_to_le16(wLen);
Justin P. Mattockbda79782012-08-26 08:16:44 -0700680 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
Andres More3eaca0d2013-02-25 20:32:52 -0500681 (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField_a), (u8 *)&(pBuf->bySignalField_a)
Forest Bond92b96792009-06-13 07:38:31 -0400682 );
683 pBuf->wTransmitLength_a = cpu_to_le16(wLen);
684 //Get Duration
Malcolm Priestleye34f9db2013-08-13 20:17:11 +0100685 pBuf->wDuration_bb = s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
686 cbFrameLength, PK_TYPE_11B,
687 pDevice->byTopCCKBasicRate, bNeedAck, byFBOption);
688 pBuf->wDuration_aa = s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
689 cbFrameLength, byPktType,
690 wCurrentRate, bNeedAck, byFBOption);
691 pBuf->wDuration_ba = s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
692 cbFrameLength, byPktType,
693 wCurrentRate, bNeedAck, byFBOption);
694 pBuf->wRTSDuration_ba_f0 = s_uGetRTSCTSDuration(pDevice,
695 RTSDUR_BA_F0, cbFrameLength, byPktType, wCurrentRate,
696 bNeedAck, byFBOption);
697 pBuf->wRTSDuration_aa_f0 = s_uGetRTSCTSDuration(pDevice,
698 RTSDUR_AA_F0, cbFrameLength, byPktType,
699 wCurrentRate, bNeedAck, byFBOption);
700 pBuf->wRTSDuration_ba_f1 = s_uGetRTSCTSDuration(pDevice,
701 RTSDUR_BA_F1, cbFrameLength, byPktType, wCurrentRate,
702 bNeedAck, byFBOption);
703 pBuf->wRTSDuration_aa_f1 = s_uGetRTSCTSDuration(pDevice,
704 RTSDUR_AA_F1, cbFrameLength, byPktType, wCurrentRate,
705 bNeedAck, byFBOption);
Malcolm Priestley07738932013-08-05 22:08:05 +0100706 pBuf->data.duration = pBuf->wDuration_aa;
707 /*Get RTS Frame body*/
708 pBuf->data.frame_control = TYPE_CTL_RTS;
Forest Bond92b96792009-06-13 07:38:31 -0400709
Malcolm Priestley07738932013-08-05 22:08:05 +0100710 if (pDevice->eOPMode == OP_MODE_ADHOC ||
711 pDevice->eOPMode == OP_MODE_AP)
712 memcpy(pBuf->data.ra, psEthHeader->h_dest, ETH_ALEN);
713 else
714 memcpy(pBuf->data.ra, pDevice->abyBSSID, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400715
Malcolm Priestley07738932013-08-05 22:08:05 +0100716 if (pDevice->eOPMode == OP_MODE_AP)
717 memcpy(pBuf->data.ta, pDevice->abyBSSID, ETH_ALEN);
718 else
719 memcpy(pBuf->data.ta, psEthHeader->h_source, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400720 } // if (byFBOption == AUTO_FB_NONE)
721 }
722 else if (byPktType == PK_TYPE_11A) {
723 if (byFBOption == AUTO_FB_NONE) {
Malcolm Priestleyc521cb52013-08-15 21:23:25 +0100724 struct vnt_rts_ab *pBuf = (struct vnt_rts_ab *)pvRTS;
Forest Bond92b96792009-06-13 07:38:31 -0400725 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700726 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
Andres More3eaca0d2013-02-25 20:32:52 -0500727 (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField)
Forest Bond92b96792009-06-13 07:38:31 -0400728 );
729 pBuf->wTransmitLength = cpu_to_le16(wLen);
730 //Get Duration
Malcolm Priestleye34f9db2013-08-13 20:17:11 +0100731 pBuf->wDuration = s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
732 cbFrameLength, byPktType, wCurrentRate,
733 bNeedAck, byFBOption);
Malcolm Priestley07738932013-08-05 22:08:05 +0100734 pBuf->data.duration = pBuf->wDuration;
735 /* Get RTS Frame body */
736 pBuf->data.frame_control = TYPE_CTL_RTS;
Forest Bond92b96792009-06-13 07:38:31 -0400737
Malcolm Priestley07738932013-08-05 22:08:05 +0100738 if (pDevice->eOPMode == OP_MODE_ADHOC ||
739 pDevice->eOPMode == OP_MODE_AP)
740 memcpy(pBuf->data.ra, psEthHeader->h_dest, ETH_ALEN);
741 else
742 memcpy(pBuf->data.ra, pDevice->abyBSSID, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400743
Malcolm Priestley07738932013-08-05 22:08:05 +0100744 if (pDevice->eOPMode == OP_MODE_AP)
745 memcpy(pBuf->data.ta, pDevice->abyBSSID, ETH_ALEN);
746 else
747 memcpy(pBuf->data.ta, psEthHeader->h_source, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400748 }
749 else {
Malcolm Priestleyc521cb52013-08-15 21:23:25 +0100750 struct vnt_rts_a_fb *pBuf = (struct vnt_rts_a_fb *)pvRTS;
Forest Bond92b96792009-06-13 07:38:31 -0400751 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700752 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
Andres More3eaca0d2013-02-25 20:32:52 -0500753 (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField)
Forest Bond92b96792009-06-13 07:38:31 -0400754 );
755 pBuf->wTransmitLength = cpu_to_le16(wLen);
756 //Get Duration
Malcolm Priestleye34f9db2013-08-13 20:17:11 +0100757 pBuf->wDuration = s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
758 cbFrameLength, byPktType, wCurrentRate,
759 bNeedAck, byFBOption);
760 pBuf->wRTSDuration_f0 = s_uGetRTSCTSDuration(pDevice,
761 RTSDUR_AA_F0, cbFrameLength, byPktType,
762 wCurrentRate, bNeedAck, byFBOption);
763 pBuf->wRTSDuration_f1 = s_uGetRTSCTSDuration(pDevice,
764 RTSDUR_AA_F1, cbFrameLength, byPktType,
765 wCurrentRate, bNeedAck, byFBOption);
Malcolm Priestley07738932013-08-05 22:08:05 +0100766 pBuf->data.duration = pBuf->wDuration;
767 /* Get RTS Frame body */
768 pBuf->data.frame_control = TYPE_CTL_RTS;
Forest Bond92b96792009-06-13 07:38:31 -0400769
Malcolm Priestley07738932013-08-05 22:08:05 +0100770 if (pDevice->eOPMode == OP_MODE_ADHOC ||
771 pDevice->eOPMode == OP_MODE_AP)
772 memcpy(pBuf->data.ra, psEthHeader->h_dest, ETH_ALEN);
773 else
774 memcpy(pBuf->data.ra, pDevice->abyBSSID, ETH_ALEN);
775
776 if (pDevice->eOPMode == OP_MODE_AP)
777 memcpy(pBuf->data.ta, pDevice->abyBSSID, ETH_ALEN);
778 else
779 memcpy(pBuf->data.ta, psEthHeader->h_source, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400780 }
781 }
782 else if (byPktType == PK_TYPE_11B) {
Malcolm Priestleyc521cb52013-08-15 21:23:25 +0100783 struct vnt_rts_ab *pBuf = (struct vnt_rts_ab *)pvRTS;
Forest Bond92b96792009-06-13 07:38:31 -0400784 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700785 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
Andres More3eaca0d2013-02-25 20:32:52 -0500786 (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField)
Forest Bond92b96792009-06-13 07:38:31 -0400787 );
788 pBuf->wTransmitLength = cpu_to_le16(wLen);
789 //Get Duration
Malcolm Priestleye34f9db2013-08-13 20:17:11 +0100790 pBuf->wDuration = s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
791 cbFrameLength, byPktType, wCurrentRate,
792 bNeedAck, byFBOption);
Forest Bond92b96792009-06-13 07:38:31 -0400793
Malcolm Priestley07738932013-08-05 22:08:05 +0100794 pBuf->data.duration = pBuf->wDuration;
795 /* Get RTS Frame body */
796 pBuf->data.frame_control = TYPE_CTL_RTS;
Forest Bond92b96792009-06-13 07:38:31 -0400797
Malcolm Priestley07738932013-08-05 22:08:05 +0100798 if (pDevice->eOPMode == OP_MODE_ADHOC ||
799 pDevice->eOPMode == OP_MODE_AP)
800 memcpy(pBuf->data.ra, psEthHeader->h_dest, ETH_ALEN);
801 else
802 memcpy(pBuf->data.ra, pDevice->abyBSSID, ETH_ALEN);
803
804 if (pDevice->eOPMode == OP_MODE_AP)
805 memcpy(pBuf->data.ta, pDevice->abyBSSID, ETH_ALEN);
806 else
807 memcpy(pBuf->data.ta, psEthHeader->h_source, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400808 }
809}
810
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000811static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
812 u8 byPktType, void *pvCTS, u32 cbFrameLength, int bNeedAck,
813 int bDisCRC, u16 wCurrentRate, u8 byFBOption)
Forest Bond92b96792009-06-13 07:38:31 -0400814{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000815 u32 uCTSFrameLen = 14;
816 u16 wLen = 0;
Forest Bond92b96792009-06-13 07:38:31 -0400817
818 if (pvCTS == NULL) {
819 return;
820 }
821
822 if (bDisCRC) {
823 // When CRCDIS bit is on, H/W forgot to generate FCS for CTS frame,
824 // in this case we need to decrease its length by 4.
825 uCTSFrameLen -= 4;
826 }
827
828 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
829 if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) {
830 // Auto Fall back
Malcolm Priestleyf0c5ba22013-08-15 21:27:22 +0100831 struct vnt_cts_fb *pBuf = (struct vnt_cts_fb *)pvCTS;
Forest Bond92b96792009-06-13 07:38:31 -0400832 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700833 BBvCalculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
Andres More3eaca0d2013-02-25 20:32:52 -0500834 (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b)
Forest Bond92b96792009-06-13 07:38:31 -0400835 );
836 pBuf->wTransmitLength_b = cpu_to_le16(wLen);
Malcolm Priestleye34f9db2013-08-13 20:17:11 +0100837 pBuf->wDuration_ba = s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
838 cbFrameLength, byPktType,
839 wCurrentRate, bNeedAck, byFBOption);
840 /* Get CTSDuration_ba_f0 */
841 pBuf->wCTSDuration_ba_f0 = s_uGetRTSCTSDuration(pDevice,
842 CTSDUR_BA_F0, cbFrameLength, byPktType, wCurrentRate,
843 bNeedAck, byFBOption);
844 /* Get CTSDuration_ba_f1 */
845 pBuf->wCTSDuration_ba_f1 = s_uGetRTSCTSDuration(pDevice,
846 CTSDUR_BA_F1, cbFrameLength, byPktType, wCurrentRate,
847 bNeedAck, byFBOption);
Malcolm Priestley14840cd2013-08-05 22:12:42 +0100848 /* Get CTS Frame body */
849 pBuf->data.duration = pBuf->wDuration_ba;
850 pBuf->data.frame_control = TYPE_CTL_CTS;
851 memcpy(pBuf->data.ra, pDevice->abyCurrentNetAddr, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400852 } else { //if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA)
Malcolm Priestleyf0c5ba22013-08-15 21:27:22 +0100853 struct vnt_cts *pBuf = (struct vnt_cts *)pvCTS;
Forest Bond92b96792009-06-13 07:38:31 -0400854 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700855 BBvCalculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
Andres More3eaca0d2013-02-25 20:32:52 -0500856 (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b)
Forest Bond92b96792009-06-13 07:38:31 -0400857 );
858 pBuf->wTransmitLength_b = cpu_to_le16(wLen);
Malcolm Priestleye34f9db2013-08-13 20:17:11 +0100859 /* Get CTSDuration_ba */
860 pBuf->wDuration_ba = s_uGetRTSCTSDuration(pDevice,
861 CTSDUR_BA, cbFrameLength, byPktType,
862 wCurrentRate, bNeedAck, byFBOption);
Malcolm Priestley14840cd2013-08-05 22:12:42 +0100863 /*Get CTS Frame body*/
864 pBuf->data.duration = pBuf->wDuration_ba;
865 pBuf->data.frame_control = TYPE_CTL_CTS;
866 memcpy(pBuf->data.ra, pDevice->abyCurrentNetAddr, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400867 }
868 }
869}
870
Forest Bond92b96792009-06-13 07:38:31 -0400871/*+
872 *
873 * Description:
874 * Generate FIFO control for MAC & Baseband controller
875 *
876 * Parameters:
877 * In:
878 * pDevice - Pointer to adpater
879 * pTxDataHead - Transmit Data Buffer
880 * pTxBufHead - pTxBufHead
881 * pvRrvTime - pvRrvTime
882 * pvRTS - RTS Buffer
883 * pCTS - CTS Buffer
884 * cbFrameSize - Transmit Data Length (Hdr+Payload+FCS)
885 * bNeedACK - If need ACK
886 * uDMAIdx - DMA Index
887 * Out:
888 * none
889 *
890 * Return Value: none
891 *
892-*/
Andres Morecc856e62010-05-17 21:34:01 -0300893
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000894static void s_vGenerateTxParameter(struct vnt_private *pDevice,
895 u8 byPktType, u16 wCurrentRate, void *pTxBufHead, void *pvRrvTime,
896 void *pvRTS, void *pvCTS, u32 cbFrameSize, int bNeedACK, u32 uDMAIdx,
Andres Moreceb8c5d2013-03-18 20:33:49 -0500897 struct ethhdr *psEthHeader)
Forest Bond92b96792009-06-13 07:38:31 -0400898{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000899 u32 cbMACHdLen = WLAN_HDR_ADDR3_LEN; /* 24 */
900 u16 wFifoCtl;
Andres Moree269fc22013-02-12 20:36:29 -0500901 int bDisCRC = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000902 u8 byFBOption = AUTO_FB_NONE;
Forest Bond92b96792009-06-13 07:38:31 -0400903
904 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter...\n");
905 PSTxBufHead pFifoHead = (PSTxBufHead)pTxBufHead;
906 pFifoHead->wReserved = wCurrentRate;
907 wFifoCtl = pFifoHead->wFIFOCtl;
908
909 if (wFifoCtl & FIFOCTL_CRCDIS) {
Andres More4e9b5e22013-02-12 20:36:30 -0500910 bDisCRC = true;
Forest Bond92b96792009-06-13 07:38:31 -0400911 }
912
913 if (wFifoCtl & FIFOCTL_AUTO_FB_0) {
914 byFBOption = AUTO_FB_0;
915 }
916 else if (wFifoCtl & FIFOCTL_AUTO_FB_1) {
917 byFBOption = AUTO_FB_1;
918 }
919
920 if (pDevice->bLongHeader)
921 cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
922
923 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
924
925 if (pvRTS != NULL) { //RTS_need
926 //Fill RsvTime
927 if (pvRrvTime) {
Malcolm Priestley6398a592013-08-16 21:26:55 +0100928 struct vnt_rrv_time_rts *pBuf =
929 (struct vnt_rrv_time_rts *)pvRrvTime;
Andres More3eaca0d2013-02-25 20:32:52 -0500930 pBuf->wRTSTxRrvTime_aa = cpu_to_le16((u16)s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 1:2.4GHz
931 pBuf->wRTSTxRrvTime_ba = cpu_to_le16((u16)s_uGetRTSCTSRsvTime(pDevice, 1, byPktType, cbFrameSize, wCurrentRate));//1:RTSTxRrvTime_ba, 1:2.4GHz
932 pBuf->wRTSTxRrvTime_bb = cpu_to_le16((u16)s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz
933 pBuf->wTxRrvTime_a = cpu_to_le16((u16) s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM
934 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 -0400935 }
936 //Fill RTS
937 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
938 }
939 else {//RTS_needless, PCF mode
940
941 //Fill RsvTime
942 if (pvRrvTime) {
Malcolm Priestley4f990052013-08-16 23:38:57 +0100943 struct vnt_rrv_time_cts *pBuf =
944 (struct vnt_rrv_time_cts *)pvRrvTime;
Andres More3eaca0d2013-02-25 20:32:52 -0500945 pBuf->wTxRrvTime_a = cpu_to_le16((u16)s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM
946 pBuf->wTxRrvTime_b = cpu_to_le16((u16)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK));//1:CCK
947 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 -0400948 }
949 //Fill CTS
950 s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
951 }
952 }
953 else if (byPktType == PK_TYPE_11A) {
954
955 if (pvRTS != NULL) {//RTS_need, non PCF mode
956 //Fill RsvTime
957 if (pvRrvTime) {
Malcolm Priestley976467d2013-08-16 23:44:04 +0100958 struct vnt_rrv_time_ab *pBuf =
959 (struct vnt_rrv_time_ab *)pvRrvTime;
Andres More3eaca0d2013-02-25 20:32:52 -0500960 pBuf->wRTSTxRrvTime = cpu_to_le16((u16)s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 0:5GHz
961 pBuf->wTxRrvTime = cpu_to_le16((u16)s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//0:OFDM
Forest Bond92b96792009-06-13 07:38:31 -0400962 }
963 //Fill RTS
964 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
965 }
966 else if (pvRTS == NULL) {//RTS_needless, non PCF mode
967 //Fill RsvTime
968 if (pvRrvTime) {
Malcolm Priestley976467d2013-08-16 23:44:04 +0100969 struct vnt_rrv_time_ab *pBuf =
970 (struct vnt_rrv_time_ab *)pvRrvTime;
Andres More3eaca0d2013-02-25 20:32:52 -0500971 pBuf->wTxRrvTime = cpu_to_le16((u16)s_uGetTxRsvTime(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK)); //0:OFDM
Forest Bond92b96792009-06-13 07:38:31 -0400972 }
973 }
974 }
975 else if (byPktType == PK_TYPE_11B) {
976
977 if ((pvRTS != NULL)) {//RTS_need, non PCF mode
978 //Fill RsvTime
979 if (pvRrvTime) {
Malcolm Priestley976467d2013-08-16 23:44:04 +0100980 struct vnt_rrv_time_ab *pBuf =
981 (struct vnt_rrv_time_ab *)pvRrvTime;
Andres More3eaca0d2013-02-25 20:32:52 -0500982 pBuf->wRTSTxRrvTime = cpu_to_le16((u16)s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz
983 pBuf->wTxRrvTime = cpu_to_le16((u16)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK));//1:CCK
Forest Bond92b96792009-06-13 07:38:31 -0400984 }
985 //Fill RTS
986 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
987 }
988 else { //RTS_needless, non PCF mode
989 //Fill RsvTime
990 if (pvRrvTime) {
Malcolm Priestley976467d2013-08-16 23:44:04 +0100991 struct vnt_rrv_time_ab *pBuf =
992 (struct vnt_rrv_time_ab *)pvRrvTime;
Andres More3eaca0d2013-02-25 20:32:52 -0500993 pBuf->wTxRrvTime = cpu_to_le16((u16)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK)); //1:CCK
Forest Bond92b96792009-06-13 07:38:31 -0400994 }
995 }
996 }
997 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter END.\n");
998}
999/*
Andres Moreb902fbf2013-02-25 20:32:51 -05001000 u8 * pbyBuffer,//point to pTxBufHead
Andres More3eaca0d2013-02-25 20:32:52 -05001001 u16 wFragType,//00:Non-Frag, 01:Start, 02:Mid, 03:Last
Andres Morecc856e62010-05-17 21:34:01 -03001002 unsigned int cbFragmentSize,//Hdr+payoad+FCS
Forest Bond92b96792009-06-13 07:38:31 -04001003*/
1004
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001005static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
Malcolm Priestleyd0a2b8f2013-08-15 19:37:04 +01001006 struct vnt_tx_buffer *pTxBufHead, int bNeedEncryption,
1007 u32 uSkbPacketLen, u32 uDMAIdx, struct ethhdr *psEthHeader,
1008 u8 *pPacket, PSKeyItem pTransmitKey, u32 uNodeIndex, u16 wCurrentRate,
1009 u32 *pcbHeaderLen, u32 *pcbTotalLen)
Forest Bond92b96792009-06-13 07:38:31 -04001010{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001011 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
1012 u32 cbFrameSize, cbFrameBodySize;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001013 u32 cb802_1_H_len;
1014 u32 cbIVlen = 0, cbICVlen = 0, cbMIClen = 0, cbMACHdLen = 0;
1015 u32 cbFCSlen = 4, cbMICHDR = 0;
1016 int bNeedACK, bRTS;
1017 u8 *pbyType, *pbyMacHdr, *pbyIVHead, *pbyPayloadHead, *pbyTxBufferAddr;
1018 u8 abySNAP_RFC1042[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
1019 u8 abySNAP_Bridgetunnel[ETH_ALEN]
1020 = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8};
1021 u32 uDuration;
1022 u32 cbHeaderLength = 0, uPadding = 0;
1023 void *pvRrvTime;
1024 PSMICHDRHead pMICHDR;
1025 void *pvRTS;
1026 void *pvCTS;
1027 void *pvTxDataHd;
1028 u8 byFBOption = AUTO_FB_NONE, byFragType;
1029 u16 wTxBufSize;
1030 u32 dwMICKey0, dwMICKey1, dwMIC_Priority, dwCRC;
1031 u32 *pdwMIC_L, *pdwMIC_R;
Andres Moree269fc22013-02-12 20:36:29 -05001032 int bSoftWEP = false;
Forest Bond92b96792009-06-13 07:38:31 -04001033
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001034 pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
Forest Bond92b96792009-06-13 07:38:31 -04001035
Malcolm Priestleye2efba72012-11-11 15:20:52 +00001036 if (bNeedEncryption && pTransmitKey->pvKeyTable) {
Andres More4e9b5e22013-02-12 20:36:30 -05001037 if (((PSKeyTable)pTransmitKey->pvKeyTable)->bSoftWEP == true)
1038 bSoftWEP = true; /* WEP 256 */
Malcolm Priestleye2efba72012-11-11 15:20:52 +00001039 }
Forest Bond92b96792009-06-13 07:38:31 -04001040
Forest Bond92b96792009-06-13 07:38:31 -04001041 // Get pkt type
Andres Moreceb8c5d2013-03-18 20:33:49 -05001042 if (ntohs(psEthHeader->h_proto) > ETH_DATA_LEN) {
Forest Bond92b96792009-06-13 07:38:31 -04001043 if (pDevice->dwDiagRefCount == 0) {
1044 cb802_1_H_len = 8;
1045 } else {
1046 cb802_1_H_len = 2;
1047 }
1048 } else {
1049 cb802_1_H_len = 0;
1050 }
1051
Charles Clément21ec51f2010-05-18 10:08:14 -07001052 cbFrameBodySize = uSkbPacketLen - ETH_HLEN + cb802_1_H_len;
Forest Bond92b96792009-06-13 07:38:31 -04001053
1054 //Set packet type
Andres More3eaca0d2013-02-25 20:32:52 -05001055 pTxBufHead->wFIFOCtl |= (u16)(byPktType<<8);
Forest Bond92b96792009-06-13 07:38:31 -04001056
1057 if (pDevice->dwDiagRefCount != 0) {
Andres Moree269fc22013-02-12 20:36:29 -05001058 bNeedACK = false;
Forest Bond92b96792009-06-13 07:38:31 -04001059 pTxBufHead->wFIFOCtl = pTxBufHead->wFIFOCtl & (~FIFOCTL_NEEDACK);
1060 } else { //if (pDevice->dwDiagRefCount != 0) {
Andres More22040bb2010-08-02 20:21:44 -03001061 if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
1062 (pDevice->eOPMode == OP_MODE_AP)) {
Andres Moreceb8c5d2013-03-18 20:33:49 -05001063 if (is_multicast_ether_addr(psEthHeader->h_dest)) {
Andres Moree269fc22013-02-12 20:36:29 -05001064 bNeedACK = false;
Andres More22040bb2010-08-02 20:21:44 -03001065 pTxBufHead->wFIFOCtl =
1066 pTxBufHead->wFIFOCtl & (~FIFOCTL_NEEDACK);
1067 } else {
Andres More4e9b5e22013-02-12 20:36:30 -05001068 bNeedACK = true;
Andres More22040bb2010-08-02 20:21:44 -03001069 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
1070 }
Forest Bond92b96792009-06-13 07:38:31 -04001071 }
1072 else {
1073 // MSDUs in Infra mode always need ACK
Andres More4e9b5e22013-02-12 20:36:30 -05001074 bNeedACK = true;
Forest Bond92b96792009-06-13 07:38:31 -04001075 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
1076 }
1077 } //if (pDevice->dwDiagRefCount != 0) {
1078
1079 pTxBufHead->wTimeStamp = DEFAULT_MSDU_LIFETIME_RES_64us;
1080
1081 //Set FIFOCTL_LHEAD
1082 if (pDevice->bLongHeader)
1083 pTxBufHead->wFIFOCtl |= FIFOCTL_LHEAD;
1084
1085 if (pDevice->bSoftwareGenCrcErr) {
1086 pTxBufHead->wFIFOCtl |= FIFOCTL_CRCDIS; // set tx descriptors to NO hardware CRC
1087 }
1088
1089 //Set FRAGCTL_MACHDCNT
1090 if (pDevice->bLongHeader) {
1091 cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
1092 } else {
1093 cbMACHdLen = WLAN_HDR_ADDR3_LEN;
1094 }
Andres More3eaca0d2013-02-25 20:32:52 -05001095 pTxBufHead->wFragCtl |= (u16)(cbMACHdLen << 10);
Forest Bond92b96792009-06-13 07:38:31 -04001096
1097 //Set FIFOCTL_GrpAckPolicy
Andres More4e9b5e22013-02-12 20:36:30 -05001098 if (pDevice->bGrpAckPolicy == true) {//0000 0100 0000 0000
Forest Bond92b96792009-06-13 07:38:31 -04001099 pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK;
1100 }
1101
1102 //Set Auto Fallback Ctl
1103 if (wCurrentRate >= RATE_18M) {
1104 if (pDevice->byAutoFBCtrl == AUTO_FB_0) {
1105 pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_0;
1106 byFBOption = AUTO_FB_0;
1107 } else if (pDevice->byAutoFBCtrl == AUTO_FB_1) {
1108 pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_1;
1109 byFBOption = AUTO_FB_1;
1110 }
1111 }
1112
Andres More4e9b5e22013-02-12 20:36:30 -05001113 if (bSoftWEP != true) {
Forest Bond92b96792009-06-13 07:38:31 -04001114 if ((bNeedEncryption) && (pTransmitKey != NULL)) { //WEP enabled
1115 if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { //WEP40 or WEP104
1116 pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
1117 }
1118 if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
1119 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Tx Set wFragCtl == FRAGCTL_TKIP\n");
1120 pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
1121 }
1122 else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { //CCMP
1123 pTxBufHead->wFragCtl |= FRAGCTL_AES;
1124 }
1125 }
1126 }
1127
Forest Bond92b96792009-06-13 07:38:31 -04001128 if ((bNeedEncryption) && (pTransmitKey != NULL)) {
1129 if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
1130 cbIVlen = 4;
1131 cbICVlen = 4;
1132 }
1133 else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
1134 cbIVlen = 8;//IV+ExtIV
1135 cbMIClen = 8;
1136 cbICVlen = 4;
1137 }
1138 if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) {
1139 cbIVlen = 8;//RSN Header
1140 cbICVlen = 8;//MIC
1141 cbMICHDR = sizeof(SMICHDRHead);
1142 }
Andres Moree269fc22013-02-12 20:36:29 -05001143 if (bSoftWEP == false) {
Forest Bond92b96792009-06-13 07:38:31 -04001144 //MAC Header should be padding 0 to DW alignment.
1145 uPadding = 4 - (cbMACHdLen%4);
1146 uPadding %= 4;
1147 }
1148 }
1149
1150 cbFrameSize = cbMACHdLen + cbIVlen + (cbFrameBodySize + cbMIClen) + cbICVlen + cbFCSlen;
1151
Andres Moree269fc22013-02-12 20:36:29 -05001152 if ( (bNeedACK == false) ||(cbFrameSize < pDevice->wRTSThreshold) ) {
1153 bRTS = false;
Forest Bond92b96792009-06-13 07:38:31 -04001154 } else {
Andres More4e9b5e22013-02-12 20:36:30 -05001155 bRTS = true;
Forest Bond92b96792009-06-13 07:38:31 -04001156 pTxBufHead->wFIFOCtl |= (FIFOCTL_RTS | FIFOCTL_LRETRY);
1157 }
1158
Andres Moreb902fbf2013-02-25 20:32:51 -05001159 pbyTxBufferAddr = (u8 *) &(pTxBufHead->adwTxKey[0]);
Forest Bond92b96792009-06-13 07:38:31 -04001160 wTxBufSize = sizeof(STxBufHead);
1161 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
1162 if (byFBOption == AUTO_FB_NONE) {
Andres More4e9b5e22013-02-12 20:36:30 -05001163 if (bRTS == true) {//RTS_need
Malcolm Priestley6398a592013-08-16 21:26:55 +01001164 pvRrvTime = (struct vnt_rrv_time_rts *)
1165 (pbyTxBufferAddr + wTxBufSize);
1166 pMICHDR = (PSMICHDRHead)(pbyTxBufferAddr + wTxBufSize +
1167 sizeof(struct vnt_rrv_time_rts));
Malcolm Priestleyc521cb52013-08-15 21:23:25 +01001168 pvRTS = (struct vnt_rts_g *) (pbyTxBufferAddr + wTxBufSize +
Malcolm Priestley6398a592013-08-16 21:26:55 +01001169 sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
Forest Bond92b96792009-06-13 07:38:31 -04001170 pvCTS = NULL;
Malcolm Priestley7e60a3de2013-08-16 23:48:03 +01001171 pvTxDataHd = (struct vnt_tx_datahead_g *) (pbyTxBufferAddr +
1172 wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1173 cbMICHDR + sizeof(struct vnt_rts_g));
Malcolm Priestley6398a592013-08-16 21:26:55 +01001174 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
Malcolm Priestleyc521cb52013-08-15 21:23:25 +01001175 cbMICHDR + sizeof(struct vnt_rts_g) +
Malcolm Priestley7e60a3de2013-08-16 23:48:03 +01001176 sizeof(struct vnt_tx_datahead_g);
Forest Bond92b96792009-06-13 07:38:31 -04001177 }
1178 else { //RTS_needless
Malcolm Priestley4f990052013-08-16 23:38:57 +01001179 pvRrvTime = (struct vnt_rrv_time_cts *)
1180 (pbyTxBufferAddr + wTxBufSize);
1181 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize +
1182 sizeof(struct vnt_rrv_time_cts));
Forest Bond92b96792009-06-13 07:38:31 -04001183 pvRTS = NULL;
Malcolm Priestleyf0c5ba22013-08-15 21:27:22 +01001184 pvCTS = (struct vnt_cts *) (pbyTxBufferAddr + wTxBufSize +
Malcolm Priestley4f990052013-08-16 23:38:57 +01001185 sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
Malcolm Priestley7e60a3de2013-08-16 23:48:03 +01001186 pvTxDataHd = (struct vnt_tx_datahead_g *)(pbyTxBufferAddr +
1187 wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1188 cbMICHDR + sizeof(struct vnt_cts));
Malcolm Priestley4f990052013-08-16 23:38:57 +01001189 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1190 cbMICHDR + sizeof(struct vnt_cts) +
Malcolm Priestley7e60a3de2013-08-16 23:48:03 +01001191 sizeof(struct vnt_tx_datahead_g);
Forest Bond92b96792009-06-13 07:38:31 -04001192 }
1193 } else {
1194 // Auto Fall Back
Andres More4e9b5e22013-02-12 20:36:30 -05001195 if (bRTS == true) {//RTS_need
Malcolm Priestley6398a592013-08-16 21:26:55 +01001196 pvRrvTime = (struct vnt_rrv_time_rts *)(pbyTxBufferAddr +
1197 wTxBufSize);
1198 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize +
1199 sizeof(struct vnt_rrv_time_rts));
Malcolm Priestleyc521cb52013-08-15 21:23:25 +01001200 pvRTS = (struct vnt_rts_g_fb *) (pbyTxBufferAddr + wTxBufSize +
Malcolm Priestley6398a592013-08-16 21:26:55 +01001201 sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
Forest Bond92b96792009-06-13 07:38:31 -04001202 pvCTS = NULL;
Malcolm Priestley7c05c542013-08-16 23:49:15 +01001203 pvTxDataHd = (struct vnt_tx_datahead_g_fb *) (pbyTxBufferAddr +
1204 wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1205 cbMICHDR + sizeof(struct vnt_rts_g_fb));
Malcolm Priestley6398a592013-08-16 21:26:55 +01001206 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1207 cbMICHDR + sizeof(struct vnt_rts_g_fb) +
Malcolm Priestley7c05c542013-08-16 23:49:15 +01001208 sizeof(struct vnt_tx_datahead_g_fb);
Forest Bond92b96792009-06-13 07:38:31 -04001209 }
Andres Moree269fc22013-02-12 20:36:29 -05001210 else if (bRTS == false) { //RTS_needless
Malcolm Priestley4f990052013-08-16 23:38:57 +01001211 pvRrvTime = (struct vnt_rrv_time_cts *)
1212 (pbyTxBufferAddr + wTxBufSize);
1213 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize +
1214 sizeof(struct vnt_rrv_time_cts));
Forest Bond92b96792009-06-13 07:38:31 -04001215 pvRTS = NULL;
Malcolm Priestleyf0c5ba22013-08-15 21:27:22 +01001216 pvCTS = (struct vnt_cts_fb *) (pbyTxBufferAddr + wTxBufSize +
Malcolm Priestley4f990052013-08-16 23:38:57 +01001217 sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
Malcolm Priestley7c05c542013-08-16 23:49:15 +01001218 pvTxDataHd = (struct vnt_tx_datahead_g_fb *) (pbyTxBufferAddr +
Malcolm Priestley4f990052013-08-16 23:38:57 +01001219 wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1220 cbMICHDR + sizeof(struct vnt_cts_fb));
1221 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
Malcolm Priestleyf0c5ba22013-08-15 21:27:22 +01001222 cbMICHDR + sizeof(struct vnt_cts_fb) +
Malcolm Priestley7c05c542013-08-16 23:49:15 +01001223 sizeof(struct vnt_tx_datahead_g_fb);
Forest Bond92b96792009-06-13 07:38:31 -04001224 }
1225 } // Auto Fall Back
1226 }
1227 else {//802.11a/b packet
1228 if (byFBOption == AUTO_FB_NONE) {
Andres More4e9b5e22013-02-12 20:36:30 -05001229 if (bRTS == true) {//RTS_need
Malcolm Priestley976467d2013-08-16 23:44:04 +01001230 pvRrvTime = (struct vnt_rrv_time_ab *) (pbyTxBufferAddr +
1231 wTxBufSize);
1232 pMICHDR = (PSMICHDRHead)(pbyTxBufferAddr + wTxBufSize +
1233 sizeof(struct vnt_rrv_time_ab));
Malcolm Priestleyc521cb52013-08-15 21:23:25 +01001234 pvRTS = (struct vnt_rts_ab *) (pbyTxBufferAddr + wTxBufSize +
Malcolm Priestley976467d2013-08-16 23:44:04 +01001235 sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
Forest Bond92b96792009-06-13 07:38:31 -04001236 pvCTS = NULL;
Malcolm Priestley558becf2013-08-16 23:50:32 +01001237 pvTxDataHd = (struct vnt_tx_datahead_ab *)(pbyTxBufferAddr +
1238 wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR +
Malcolm Priestleyc521cb52013-08-15 21:23:25 +01001239 sizeof(struct vnt_rts_ab));
Malcolm Priestley976467d2013-08-16 23:44:04 +01001240 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1241 cbMICHDR + sizeof(struct vnt_rts_ab) +
Malcolm Priestley558becf2013-08-16 23:50:32 +01001242 sizeof(struct vnt_tx_datahead_ab);
Forest Bond92b96792009-06-13 07:38:31 -04001243 }
Andres Moree269fc22013-02-12 20:36:29 -05001244 else if (bRTS == false) { //RTS_needless, no MICHDR
Malcolm Priestley976467d2013-08-16 23:44:04 +01001245 pvRrvTime = (struct vnt_rrv_time_ab *)(pbyTxBufferAddr +
1246 wTxBufSize);
1247 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize +
1248 sizeof(struct vnt_rrv_time_ab));
Forest Bond92b96792009-06-13 07:38:31 -04001249 pvRTS = NULL;
1250 pvCTS = NULL;
Malcolm Priestley558becf2013-08-16 23:50:32 +01001251 pvTxDataHd = (struct vnt_tx_datahead_ab *)(pbyTxBufferAddr +
1252 wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
Malcolm Priestley976467d2013-08-16 23:44:04 +01001253 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
Malcolm Priestley558becf2013-08-16 23:50:32 +01001254 cbMICHDR + sizeof(struct vnt_tx_datahead_ab);
Forest Bond92b96792009-06-13 07:38:31 -04001255 }
1256 } else {
1257 // Auto Fall Back
Andres More4e9b5e22013-02-12 20:36:30 -05001258 if (bRTS == true) {//RTS_need
Malcolm Priestley976467d2013-08-16 23:44:04 +01001259 pvRrvTime = (struct vnt_rrv_time_ab *)(pbyTxBufferAddr +
1260 wTxBufSize);
1261 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize +
1262 sizeof(struct vnt_rrv_time_ab));
Malcolm Priestleyc521cb52013-08-15 21:23:25 +01001263 pvRTS = (struct vnt_rts_a_fb *) (pbyTxBufferAddr + wTxBufSize +
Malcolm Priestley976467d2013-08-16 23:44:04 +01001264 sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
Forest Bond92b96792009-06-13 07:38:31 -04001265 pvCTS = NULL;
Malcolm Priestley1da4ee22013-08-16 23:51:38 +01001266 pvTxDataHd = (struct vnt_tx_datahead_a_fb *)(pbyTxBufferAddr +
1267 wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR +
Malcolm Priestleyc521cb52013-08-15 21:23:25 +01001268 sizeof(struct vnt_rts_a_fb));
Malcolm Priestley976467d2013-08-16 23:44:04 +01001269 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1270 cbMICHDR + sizeof(struct vnt_rts_a_fb) +
Malcolm Priestley1da4ee22013-08-16 23:51:38 +01001271 sizeof(struct vnt_tx_datahead_a_fb);
Forest Bond92b96792009-06-13 07:38:31 -04001272 }
Andres Moree269fc22013-02-12 20:36:29 -05001273 else if (bRTS == false) { //RTS_needless
Malcolm Priestley976467d2013-08-16 23:44:04 +01001274 pvRrvTime = (struct vnt_rrv_time_ab *)(pbyTxBufferAddr +
1275 wTxBufSize);
1276 pMICHDR = (PSMICHDRHead)(pbyTxBufferAddr + wTxBufSize +
1277 sizeof(struct vnt_rrv_time_ab));
Forest Bond92b96792009-06-13 07:38:31 -04001278 pvRTS = NULL;
1279 pvCTS = NULL;
Malcolm Priestley1da4ee22013-08-16 23:51:38 +01001280 pvTxDataHd = (struct vnt_tx_datahead_a_fb *)(pbyTxBufferAddr +
1281 wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
Malcolm Priestley976467d2013-08-16 23:44:04 +01001282 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
Malcolm Priestley1da4ee22013-08-16 23:51:38 +01001283 cbMICHDR + sizeof(struct vnt_tx_datahead_a_fb);
Forest Bond92b96792009-06-13 07:38:31 -04001284 }
1285 } // Auto Fall Back
1286 }
1287
Andres Moreb902fbf2013-02-25 20:32:51 -05001288 pbyMacHdr = (u8 *)(pbyTxBufferAddr + cbHeaderLength);
1289 pbyIVHead = (u8 *)(pbyMacHdr + cbMACHdLen + uPadding);
1290 pbyPayloadHead = (u8 *)(pbyMacHdr + cbMACHdLen + uPadding + cbIVlen);
Forest Bond92b96792009-06-13 07:38:31 -04001291
Forest Bond92b96792009-06-13 07:38:31 -04001292 //=========================
1293 // No Fragmentation
1294 //=========================
1295 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No Fragmentation...\n");
1296 byFragType = FRAGCTL_NONFRAG;
1297 //uDMAIdx = TYPE_AC0DMA;
1298 //pTxBufHead = (PSTxBufHead) &(pTxBufHead->adwTxKey[0]);
1299
Forest Bond92b96792009-06-13 07:38:31 -04001300 //Fill FIFO,RrvTime,RTS,and CTS
Andres More8611a292010-05-01 14:25:00 -03001301 s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate,
1302 (void *)pbyTxBufferAddr, pvRrvTime, pvRTS, pvCTS,
Forest Bond92b96792009-06-13 07:38:31 -04001303 cbFrameSize, bNeedACK, uDMAIdx, psEthHeader);
1304 //Fill DataHead
1305 uDuration = s_uFillDataHead(pDevice, byPktType, wCurrentRate, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,
Malcolm Priestleyab01fed2013-08-07 21:31:48 +01001306 byFBOption);
Forest Bond92b96792009-06-13 07:38:31 -04001307 // Generate TX MAC Header
Andres More3eaca0d2013-02-25 20:32:52 -05001308 s_vGenerateMACHeader(pDevice, pbyMacHdr, (u16)uDuration, psEthHeader, bNeedEncryption,
Forest Bond92b96792009-06-13 07:38:31 -04001309 byFragType, uDMAIdx, 0);
1310
Andres More4e9b5e22013-02-12 20:36:30 -05001311 if (bNeedEncryption == true) {
Forest Bond92b96792009-06-13 07:38:31 -04001312 //Fill TXKEY
Andres Moreb902fbf2013-02-25 20:32:51 -05001313 s_vFillTxKey(pDevice, (u8 *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
Andres More3eaca0d2013-02-25 20:32:52 -05001314 pbyMacHdr, (u16)cbFrameBodySize, (u8 *)pMICHDR);
Forest Bond92b96792009-06-13 07:38:31 -04001315
1316 if (pDevice->bEnableHostWEP) {
1317 pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
1318 pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0;
1319 }
1320 }
1321
1322 // 802.1H
Andres Moreceb8c5d2013-03-18 20:33:49 -05001323 if (ntohs(psEthHeader->h_proto) > ETH_DATA_LEN) {
Andres More203e4612010-08-04 19:12:34 -03001324 if (pDevice->dwDiagRefCount == 0) {
Andres Moreceb8c5d2013-03-18 20:33:49 -05001325 if ((psEthHeader->h_proto == cpu_to_be16(ETH_P_IPX)) ||
1326 (psEthHeader->h_proto == cpu_to_le16(0xF380))) {
Andres Moreb902fbf2013-02-25 20:32:51 -05001327 memcpy((u8 *) (pbyPayloadHead),
Andres More203e4612010-08-04 19:12:34 -03001328 abySNAP_Bridgetunnel, 6);
Forest Bond92b96792009-06-13 07:38:31 -04001329 } else {
Andres Moreb902fbf2013-02-25 20:32:51 -05001330 memcpy((u8 *) (pbyPayloadHead), &abySNAP_RFC1042[0], 6);
Forest Bond92b96792009-06-13 07:38:31 -04001331 }
Andres Moreb902fbf2013-02-25 20:32:51 -05001332 pbyType = (u8 *) (pbyPayloadHead + 6);
Andres Moreceb8c5d2013-03-18 20:33:49 -05001333 memcpy(pbyType, &(psEthHeader->h_proto), sizeof(u16));
Forest Bond92b96792009-06-13 07:38:31 -04001334 } else {
Andres Moreceb8c5d2013-03-18 20:33:49 -05001335 memcpy((u8 *) (pbyPayloadHead), &(psEthHeader->h_proto), sizeof(u16));
Forest Bond92b96792009-06-13 07:38:31 -04001336
1337 }
1338
1339 }
1340
Forest Bond92b96792009-06-13 07:38:31 -04001341 if (pPacket != NULL) {
1342 // Copy the Packet into a tx Buffer
Jim Lieb3e362592009-08-12 14:54:11 -07001343 memcpy((pbyPayloadHead + cb802_1_H_len),
Charles Clément21ec51f2010-05-18 10:08:14 -07001344 (pPacket + ETH_HLEN),
1345 uSkbPacketLen - ETH_HLEN
Forest Bond92b96792009-06-13 07:38:31 -04001346 );
1347
1348 } else {
1349 // while bRelayPacketSend psEthHeader is point to header+payload
Andres Moreb902fbf2013-02-25 20:32:51 -05001350 memcpy((pbyPayloadHead + cb802_1_H_len), ((u8 *)psEthHeader) + ETH_HLEN, uSkbPacketLen - ETH_HLEN);
Forest Bond92b96792009-06-13 07:38:31 -04001351 }
1352
Andres More4e9b5e22013-02-12 20:36:30 -05001353 if ((bNeedEncryption == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
Forest Bond92b96792009-06-13 07:38:31 -04001354
1355 ///////////////////////////////////////////////////////////////////
1356
Malcolm Priestley14c5ef52013-01-17 23:19:37 +00001357 if (pDevice->vnt_mgmt.eAuthenMode == WMAC_AUTH_WPANONE) {
1358 dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]);
1359 dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]);
1360 }
Forest Bond92b96792009-06-13 07:38:31 -04001361 else if ((pTransmitKey->dwKeyIndex & AUTHENTICATOR_KEY) != 0) {
Andres More52a7e642013-02-25 20:32:53 -05001362 dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]);
1363 dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]);
Forest Bond92b96792009-06-13 07:38:31 -04001364 }
1365 else {
Andres More52a7e642013-02-25 20:32:53 -05001366 dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[24]);
1367 dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[28]);
Forest Bond92b96792009-06-13 07:38:31 -04001368 }
1369 // DO Software Michael
1370 MIC_vInit(dwMICKey0, dwMICKey1);
Andres Moreceb8c5d2013-03-18 20:33:49 -05001371 MIC_vAppend((u8 *)&(psEthHeader->h_dest[0]), 12);
Forest Bond92b96792009-06-13 07:38:31 -04001372 dwMIC_Priority = 0;
Andres Moreb902fbf2013-02-25 20:32:51 -05001373 MIC_vAppend((u8 *)&dwMIC_Priority, 4);
Malcolm Priestleyb4dc03a2012-11-11 15:45:52 +00001374 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC KEY: %X, %X\n",
1375 dwMICKey0, dwMICKey1);
Forest Bond92b96792009-06-13 07:38:31 -04001376
1377 ///////////////////////////////////////////////////////////////////
1378
1379 //DBG_PRN_GRP12(("Length:%d, %d\n", cbFrameBodySize, uFromHDtoPLDLength));
1380 //for (ii = 0; ii < cbFrameBodySize; ii++) {
Andres Moreb902fbf2013-02-25 20:32:51 -05001381 // DBG_PRN_GRP12(("%02x ", *((u8 *)((pbyPayloadHead + cb802_1_H_len) + ii))));
Forest Bond92b96792009-06-13 07:38:31 -04001382 //}
1383 //DBG_PRN_GRP12(("\n\n\n"));
1384
1385 MIC_vAppend(pbyPayloadHead, cbFrameBodySize);
1386
Andres More52a7e642013-02-25 20:32:53 -05001387 pdwMIC_L = (u32 *)(pbyPayloadHead + cbFrameBodySize);
1388 pdwMIC_R = (u32 *)(pbyPayloadHead + cbFrameBodySize + 4);
Forest Bond92b96792009-06-13 07:38:31 -04001389
1390 MIC_vGetMIC(pdwMIC_L, pdwMIC_R);
1391 MIC_vUnInit();
1392
Andres More4e9b5e22013-02-12 20:36:30 -05001393 if (pDevice->bTxMICFail == true) {
Forest Bond92b96792009-06-13 07:38:31 -04001394 *pdwMIC_L = 0;
1395 *pdwMIC_R = 0;
Andres Moree269fc22013-02-12 20:36:29 -05001396 pDevice->bTxMICFail = false;
Forest Bond92b96792009-06-13 07:38:31 -04001397 }
1398 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize);
1399 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderLength, uPadding, cbIVlen);
1400 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%lX, %lX\n", *pdwMIC_L, *pdwMIC_R);
1401 }
1402
Andres More4e9b5e22013-02-12 20:36:30 -05001403 if (bSoftWEP == true) {
Forest Bond92b96792009-06-13 07:38:31 -04001404
Andres More3eaca0d2013-02-25 20:32:52 -05001405 s_vSWencryption(pDevice, pTransmitKey, (pbyPayloadHead), (u16)(cbFrameBodySize + cbMIClen));
Forest Bond92b96792009-06-13 07:38:31 -04001406
Andres More4e9b5e22013-02-12 20:36:30 -05001407 } else if ( ((pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) && (bNeedEncryption == true)) ||
1408 ((pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) && (bNeedEncryption == true)) ||
1409 ((pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) && (bNeedEncryption == true)) ) {
Forest Bond92b96792009-06-13 07:38:31 -04001410 cbFrameSize -= cbICVlen;
1411 }
1412
Andres More4e9b5e22013-02-12 20:36:30 -05001413 if (pDevice->bSoftwareGenCrcErr == true) {
Andres Morecc856e62010-05-17 21:34:01 -03001414 unsigned int cbLen;
Andres More52a7e642013-02-25 20:32:53 -05001415 u32 * pdwCRC;
Forest Bond92b96792009-06-13 07:38:31 -04001416
1417 dwCRC = 0xFFFFFFFFL;
1418 cbLen = cbFrameSize - cbFCSlen;
1419 // calculate CRC, and wrtie CRC value to end of TD
1420 dwCRC = CRCdwGetCrc32Ex(pbyMacHdr, cbLen, dwCRC);
Andres More52a7e642013-02-25 20:32:53 -05001421 pdwCRC = (u32 *)(pbyMacHdr + cbLen);
Forest Bond92b96792009-06-13 07:38:31 -04001422 // finally, we must invert dwCRC to get the correct answer
1423 *pdwCRC = ~dwCRC;
1424 // Force Error
1425 *pdwCRC -= 1;
1426 } else {
1427 cbFrameSize -= cbFCSlen;
1428 }
1429
1430 *pcbHeaderLen = cbHeaderLength;
1431 *pcbTotalLen = cbHeaderLength + cbFrameSize ;
1432
Forest Bond92b96792009-06-13 07:38:31 -04001433 //Set FragCtl in TxBufferHead
Andres More3eaca0d2013-02-25 20:32:52 -05001434 pTxBufHead->wFragCtl |= (u16)byFragType;
Forest Bond92b96792009-06-13 07:38:31 -04001435
Andres More4e9b5e22013-02-12 20:36:30 -05001436 return true;
Forest Bond92b96792009-06-13 07:38:31 -04001437
1438}
1439
Forest Bond92b96792009-06-13 07:38:31 -04001440/*+
1441 *
1442 * Description:
1443 * Translate 802.3 to 802.11 header
1444 *
1445 * Parameters:
1446 * In:
Justin P. Mattocka0a1f612012-08-26 08:16:43 -07001447 * pDevice - Pointer to adapter
Forest Bond92b96792009-06-13 07:38:31 -04001448 * dwTxBufferAddr - Transmit Buffer
1449 * pPacket - Packet from upper layer
1450 * cbPacketSize - Transmit Data Length
1451 * Out:
1452 * pcbHeadSize - Header size of MAC&Baseband control and 802.11 Header
1453 * pcbAppendPayload - size of append payload for 802.1H translation
1454 *
1455 * Return Value: none
1456 *
1457-*/
1458
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001459static void s_vGenerateMACHeader(struct vnt_private *pDevice,
Andres Moreceb8c5d2013-03-18 20:33:49 -05001460 u8 *pbyBufferAddr, u16 wDuration, struct ethhdr *psEthHeader,
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001461 int bNeedEncrypt, u16 wFragType, u32 uDMAIdx, u32 uFragIdx)
Forest Bond92b96792009-06-13 07:38:31 -04001462{
Andres More1cac4a42013-03-18 20:33:50 -05001463 struct ieee80211_hdr *pMACHeader = (struct ieee80211_hdr *)pbyBufferAddr;
Forest Bond92b96792009-06-13 07:38:31 -04001464
Forest Bond92b96792009-06-13 07:38:31 -04001465 if (uDMAIdx == TYPE_ATIMDMA) {
Andres More1cac4a42013-03-18 20:33:50 -05001466 pMACHeader->frame_control = TYPE_802_11_ATIM;
Forest Bond92b96792009-06-13 07:38:31 -04001467 } else {
Andres More1cac4a42013-03-18 20:33:50 -05001468 pMACHeader->frame_control = TYPE_802_11_DATA;
Forest Bond92b96792009-06-13 07:38:31 -04001469 }
1470
1471 if (pDevice->eOPMode == OP_MODE_AP) {
Andres More1cac4a42013-03-18 20:33:50 -05001472 memcpy(&(pMACHeader->addr1[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -05001473 &(psEthHeader->h_dest[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001474 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001475 memcpy(&(pMACHeader->addr2[0]), &(pDevice->abyBSSID[0]), ETH_ALEN);
1476 memcpy(&(pMACHeader->addr3[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -05001477 &(psEthHeader->h_source[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001478 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001479 pMACHeader->frame_control |= FC_FROMDS;
Andres More9a0e7562010-04-13 21:54:48 -03001480 } else {
1481 if (pDevice->eOPMode == OP_MODE_ADHOC) {
Andres More1cac4a42013-03-18 20:33:50 -05001482 memcpy(&(pMACHeader->addr1[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -05001483 &(psEthHeader->h_dest[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001484 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001485 memcpy(&(pMACHeader->addr2[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -05001486 &(psEthHeader->h_source[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001487 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001488 memcpy(&(pMACHeader->addr3[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001489 &(pDevice->abyBSSID[0]),
1490 ETH_ALEN);
1491 } else {
Andres More1cac4a42013-03-18 20:33:50 -05001492 memcpy(&(pMACHeader->addr3[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -05001493 &(psEthHeader->h_dest[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001494 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001495 memcpy(&(pMACHeader->addr2[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -05001496 &(psEthHeader->h_source[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001497 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001498 memcpy(&(pMACHeader->addr1[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001499 &(pDevice->abyBSSID[0]),
1500 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001501 pMACHeader->frame_control |= FC_TODS;
Forest Bond92b96792009-06-13 07:38:31 -04001502 }
1503 }
1504
1505 if (bNeedEncrypt)
Andres More1cac4a42013-03-18 20:33:50 -05001506 pMACHeader->frame_control |= cpu_to_le16((u16)WLAN_SET_FC_ISWEP(1));
Forest Bond92b96792009-06-13 07:38:31 -04001507
Andres More1cac4a42013-03-18 20:33:50 -05001508 pMACHeader->duration_id = cpu_to_le16(wDuration);
Forest Bond92b96792009-06-13 07:38:31 -04001509
1510 if (pDevice->bLongHeader) {
1511 PWLAN_80211HDR_A4 pMACA4Header = (PWLAN_80211HDR_A4) pbyBufferAddr;
Andres More1cac4a42013-03-18 20:33:50 -05001512 pMACHeader->frame_control |= (FC_TODS | FC_FROMDS);
Jim Lieb3e362592009-08-12 14:54:11 -07001513 memcpy(pMACA4Header->abyAddr4, pDevice->abyBSSID, WLAN_ADDR_LEN);
Forest Bond92b96792009-06-13 07:38:31 -04001514 }
Andres More1cac4a42013-03-18 20:33:50 -05001515 pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4);
Forest Bond92b96792009-06-13 07:38:31 -04001516
1517 //Set FragNumber in Sequence Control
Andres More1cac4a42013-03-18 20:33:50 -05001518 pMACHeader->seq_ctrl |= cpu_to_le16((u16)uFragIdx);
Forest Bond92b96792009-06-13 07:38:31 -04001519
1520 if ((wFragType == FRAGCTL_ENDFRAG) || (wFragType == FRAGCTL_NONFRAG)) {
1521 pDevice->wSeqCounter++;
1522 if (pDevice->wSeqCounter > 0x0fff)
1523 pDevice->wSeqCounter = 0;
1524 }
1525
1526 if ((wFragType == FRAGCTL_STAFRAG) || (wFragType == FRAGCTL_MIDFRAG)) { //StartFrag or MidFrag
Andres More1cac4a42013-03-18 20:33:50 -05001527 pMACHeader->frame_control |= FC_MOREFRAG;
Forest Bond92b96792009-06-13 07:38:31 -04001528 }
1529}
1530
Forest Bond92b96792009-06-13 07:38:31 -04001531/*+
1532 *
1533 * Description:
1534 * Request instructs a MAC to transmit a 802.11 management packet through
1535 * the adapter onto the medium.
1536 *
1537 * Parameters:
1538 * In:
1539 * hDeviceContext - Pointer to the adapter
1540 * pPacket - A pointer to a descriptor for the packet to transmit
1541 * Out:
1542 * none
1543 *
Andres Moree269fc22013-02-12 20:36:29 -05001544 * Return Value: CMD_STATUS_PENDING if MAC Tx resource available; otherwise false
Forest Bond92b96792009-06-13 07:38:31 -04001545 *
1546-*/
1547
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001548CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice,
1549 struct vnt_tx_mgmt *pPacket)
Forest Bond92b96792009-06-13 07:38:31 -04001550{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001551 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
Malcolm Priestleyf39c0d82013-08-15 19:34:37 +01001552 struct vnt_tx_buffer *pTX_Buffer;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001553 PSTxBufHead pTxBufHead;
1554 PUSB_SEND_CONTEXT pContext;
Andres More1cac4a42013-03-18 20:33:50 -05001555 struct ieee80211_hdr *pMACHeader;
Malcolm Priestleyf0c5ba22013-08-15 21:27:22 +01001556 struct vnt_cts *pCTS;
Andres Moreceb8c5d2013-03-18 20:33:49 -05001557 struct ethhdr sEthHeader;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001558 u8 byPktType, *pbyTxBufferAddr;
1559 void *pvRTS, *pvTxDataHd, *pvRrvTime, *pMICHDR;
1560 u32 uDuration, cbReqCount, cbHeaderSize, cbFrameBodySize, cbFrameSize;
Andres Moree269fc22013-02-12 20:36:29 -05001561 int bNeedACK, bIsPSPOLL = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001562 u32 cbIVlen = 0, cbICVlen = 0, cbMIClen = 0, cbFCSlen = 4;
1563 u32 uPadding = 0;
1564 u16 wTxBufSize;
1565 u32 cbMacHdLen;
1566 u16 wCurrentRate = RATE_1M;
Forest Bond92b96792009-06-13 07:38:31 -04001567
Forest Bond92b96792009-06-13 07:38:31 -04001568 pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
1569
1570 if (NULL == pContext) {
1571 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ManagementSend TX...NO CONTEXT!\n");
1572 return CMD_STATUS_RESOURCES;
1573 }
1574
Malcolm Priestleyf39c0d82013-08-15 19:34:37 +01001575 pTX_Buffer = (struct vnt_tx_buffer *)&pContext->Data[0];
Andres Moreb902fbf2013-02-25 20:32:51 -05001576 pbyTxBufferAddr = (u8 *)&(pTX_Buffer->adwTxKey[0]);
Forest Bond92b96792009-06-13 07:38:31 -04001577 cbFrameBodySize = pPacket->cbPayloadLen;
1578 pTxBufHead = (PSTxBufHead) pbyTxBufferAddr;
1579 wTxBufSize = sizeof(STxBufHead);
Forest Bond92b96792009-06-13 07:38:31 -04001580
1581 if (pDevice->byBBType == BB_TYPE_11A) {
1582 wCurrentRate = RATE_6M;
1583 byPktType = PK_TYPE_11A;
1584 } else {
1585 wCurrentRate = RATE_1M;
1586 byPktType = PK_TYPE_11B;
1587 }
1588
1589 // SetPower will cause error power TX state for OFDM Date packet in TX buffer.
1590 // 2004.11.11 Kyle -- Using OFDM power to tx MngPkt will decrease the connection capability.
1591 // And cmd timer will wait data pkt TX finish before scanning so it's OK
1592 // to set power here.
1593 if (pMgmt->eScanState != WMAC_NO_SCANNING) {
1594 RFbSetPower(pDevice, wCurrentRate, pDevice->byCurrentCh);
1595 } else {
1596 RFbSetPower(pDevice, wCurrentRate, pMgmt->uCurrChannel);
1597 }
1598 pDevice->wCurrentRate = wCurrentRate;
1599
Forest Bond92b96792009-06-13 07:38:31 -04001600 //Set packet type
1601 if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000
1602 pTxBufHead->wFIFOCtl = 0;
1603 }
1604 else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000
1605 pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
1606 }
1607 else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000
1608 pTxBufHead->wFIFOCtl |= FIFOCTL_11GB;
1609 }
1610 else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000
1611 pTxBufHead->wFIFOCtl |= FIFOCTL_11GA;
1612 }
1613
1614 pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN;
1615 pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
1616
Andres More22040bb2010-08-02 20:21:44 -03001617 if (is_multicast_ether_addr(pPacket->p80211Header->sA3.abyAddr1)) {
Andres Moree269fc22013-02-12 20:36:29 -05001618 bNeedACK = false;
Forest Bond92b96792009-06-13 07:38:31 -04001619 }
1620 else {
Andres More4e9b5e22013-02-12 20:36:30 -05001621 bNeedACK = true;
Forest Bond92b96792009-06-13 07:38:31 -04001622 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
1623 };
1624
1625 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) ||
1626 (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ) {
1627
1628 pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY;
1629 //Set Preamble type always long
1630 //pDevice->byPreambleType = PREAMBLE_LONG;
1631 // probe-response don't retry
1632 //if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_MGMT_PROBE_RSP) {
Andres Moree269fc22013-02-12 20:36:29 -05001633 // bNeedACK = false;
Forest Bond92b96792009-06-13 07:38:31 -04001634 // pTxBufHead->wFIFOCtl &= (~FIFOCTL_NEEDACK);
1635 //}
1636 }
1637
1638 pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0);
1639
1640 if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) {
Andres More4e9b5e22013-02-12 20:36:30 -05001641 bIsPSPOLL = true;
Forest Bond92b96792009-06-13 07:38:31 -04001642 cbMacHdLen = WLAN_HDR_ADDR2_LEN;
1643 } else {
1644 cbMacHdLen = WLAN_HDR_ADDR3_LEN;
1645 }
1646
1647 //Set FRAGCTL_MACHDCNT
Andres More3eaca0d2013-02-25 20:32:52 -05001648 pTxBufHead->wFragCtl |= cpu_to_le16((u16)(cbMacHdLen << 10));
Forest Bond92b96792009-06-13 07:38:31 -04001649
1650 // Notes:
1651 // Although spec says MMPDU can be fragmented; In most case,
1652 // no one will send a MMPDU under fragmentation. With RTS may occur.
Andres Moree269fc22013-02-12 20:36:29 -05001653 pDevice->bAES = false; //Set FRAGCTL_WEPTYP
Forest Bond92b96792009-06-13 07:38:31 -04001654
1655 if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) {
1656 if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) {
1657 cbIVlen = 4;
1658 cbICVlen = 4;
1659 pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
1660 }
1661 else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
1662 cbIVlen = 8;//IV+ExtIV
1663 cbMIClen = 8;
1664 cbICVlen = 4;
1665 pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
1666 //We need to get seed here for filling TxKey entry.
1667 //TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr,
1668 // pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG);
1669 }
1670 else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
1671 cbIVlen = 8;//RSN Header
1672 cbICVlen = 8;//MIC
1673 pTxBufHead->wFragCtl |= FRAGCTL_AES;
Andres More4e9b5e22013-02-12 20:36:30 -05001674 pDevice->bAES = true;
Forest Bond92b96792009-06-13 07:38:31 -04001675 }
1676 //MAC Header should be padding 0 to DW alignment.
1677 uPadding = 4 - (cbMacHdLen%4);
1678 uPadding %= 4;
1679 }
1680
1681 cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen;
1682
1683 //Set FIFOCTL_GrpAckPolicy
Andres More4e9b5e22013-02-12 20:36:30 -05001684 if (pDevice->bGrpAckPolicy == true) {//0000 0100 0000 0000
Forest Bond92b96792009-06-13 07:38:31 -04001685 pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK;
1686 }
1687 //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter()
1688
1689 //Set RrvTime/RTS/CTS Buffer
1690 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
1691
Malcolm Priestley4f990052013-08-16 23:38:57 +01001692 pvRrvTime = (struct vnt_rrv_time_cts *) (pbyTxBufferAddr + wTxBufSize);
Forest Bond92b96792009-06-13 07:38:31 -04001693 pMICHDR = NULL;
1694 pvRTS = NULL;
Malcolm Priestleyf0c5ba22013-08-15 21:27:22 +01001695 pCTS = (struct vnt_cts *) (pbyTxBufferAddr + wTxBufSize +
Malcolm Priestley4f990052013-08-16 23:38:57 +01001696 sizeof(struct vnt_rrv_time_cts));
Malcolm Priestley7e60a3de2013-08-16 23:48:03 +01001697 pvTxDataHd = (struct vnt_tx_datahead_g *)(pbyTxBufferAddr + wTxBufSize +
Malcolm Priestley4f990052013-08-16 23:38:57 +01001698 sizeof(struct vnt_rrv_time_cts) + sizeof(struct vnt_cts));
1699 cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
Malcolm Priestley7e60a3de2013-08-16 23:48:03 +01001700 sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
Forest Bond92b96792009-06-13 07:38:31 -04001701 }
1702 else { // 802.11a/b packet
Malcolm Priestley976467d2013-08-16 23:44:04 +01001703 pvRrvTime = (struct vnt_rrv_time_ab *) (pbyTxBufferAddr + wTxBufSize);
Forest Bond92b96792009-06-13 07:38:31 -04001704 pMICHDR = NULL;
1705 pvRTS = NULL;
1706 pCTS = NULL;
Malcolm Priestley558becf2013-08-16 23:50:32 +01001707 pvTxDataHd = (struct vnt_tx_datahead_ab *) (pbyTxBufferAddr +
1708 wTxBufSize + sizeof(struct vnt_rrv_time_ab));
Malcolm Priestley976467d2013-08-16 23:44:04 +01001709 cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
Malcolm Priestley558becf2013-08-16 23:50:32 +01001710 sizeof(struct vnt_tx_datahead_ab);
Forest Bond92b96792009-06-13 07:38:31 -04001711 }
1712
Andres Moreceb8c5d2013-03-18 20:33:49 -05001713 memcpy(&(sEthHeader.h_dest[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001714 &(pPacket->p80211Header->sA3.abyAddr1[0]),
1715 ETH_ALEN);
Andres Moreceb8c5d2013-03-18 20:33:49 -05001716 memcpy(&(sEthHeader.h_source[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001717 &(pPacket->p80211Header->sA3.abyAddr2[0]),
1718 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -04001719 //=========================
1720 // No Fragmentation
1721 //=========================
Andres More3eaca0d2013-02-25 20:32:52 -05001722 pTxBufHead->wFragCtl |= (u16)FRAGCTL_NONFRAG;
Forest Bond92b96792009-06-13 07:38:31 -04001723
Forest Bond92b96792009-06-13 07:38:31 -04001724 //Fill FIFO,RrvTime,RTS,and CTS
1725 s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate, pbyTxBufferAddr, pvRrvTime, pvRTS, pCTS,
1726 cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader);
1727
1728 //Fill DataHead
1729 uDuration = s_uFillDataHead(pDevice, byPktType, wCurrentRate, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK,
Malcolm Priestleyab01fed2013-08-07 21:31:48 +01001730 AUTO_FB_NONE);
Forest Bond92b96792009-06-13 07:38:31 -04001731
Andres More1cac4a42013-03-18 20:33:50 -05001732 pMACHeader = (struct ieee80211_hdr *) (pbyTxBufferAddr + cbHeaderSize);
Forest Bond92b96792009-06-13 07:38:31 -04001733
1734 cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + cbFrameBodySize;
1735
1736 if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) {
Andres Moreb902fbf2013-02-25 20:32:51 -05001737 u8 * pbyIVHead;
1738 u8 * pbyPayloadHead;
1739 u8 * pbyBSSID;
Forest Bond92b96792009-06-13 07:38:31 -04001740 PSKeyItem pTransmitKey = NULL;
1741
Andres Moreb902fbf2013-02-25 20:32:51 -05001742 pbyIVHead = (u8 *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding);
1743 pbyPayloadHead = (u8 *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding + cbIVlen);
Forest Bond92b96792009-06-13 07:38:31 -04001744 do {
1745 if ((pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) &&
Andres More4e9b5e22013-02-12 20:36:30 -05001746 (pDevice->bLinkPass == true)) {
Forest Bond92b96792009-06-13 07:38:31 -04001747 pbyBSSID = pDevice->abyBSSID;
1748 // get pairwise key
Andres Moree269fc22013-02-12 20:36:29 -05001749 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == false) {
Forest Bond92b96792009-06-13 07:38:31 -04001750 // get group key
Andres More4e9b5e22013-02-12 20:36:30 -05001751 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == true) {
Forest Bond92b96792009-06-13 07:38:31 -04001752 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get GTK.\n");
1753 break;
1754 }
1755 } else {
1756 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get PTK.\n");
1757 break;
1758 }
1759 }
1760 // get group key
1761 pbyBSSID = pDevice->abyBroadcastAddr;
Andres Moree269fc22013-02-12 20:36:29 -05001762 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) {
Forest Bond92b96792009-06-13 07:38:31 -04001763 pTransmitKey = NULL;
1764 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KEY is NULL. OP Mode[%d]\n", pDevice->eOPMode);
1765 } else {
1766 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get GTK.\n");
1767 }
Andres Moree269fc22013-02-12 20:36:29 -05001768 } while(false);
Forest Bond92b96792009-06-13 07:38:31 -04001769 //Fill TXKEY
Andres Moreb902fbf2013-02-25 20:32:51 -05001770 s_vFillTxKey(pDevice, (u8 *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
Andres More3eaca0d2013-02-25 20:32:52 -05001771 (u8 *)pMACHeader, (u16)cbFrameBodySize, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04001772
Jim Lieb3e362592009-08-12 14:54:11 -07001773 memcpy(pMACHeader, pPacket->p80211Header, cbMacHdLen);
Andres Moreb902fbf2013-02-25 20:32:51 -05001774 memcpy(pbyPayloadHead, ((u8 *)(pPacket->p80211Header) + cbMacHdLen),
Forest Bond92b96792009-06-13 07:38:31 -04001775 cbFrameBodySize);
1776 }
1777 else {
1778 // Copy the Packet into a tx Buffer
Jim Lieb3e362592009-08-12 14:54:11 -07001779 memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen);
Forest Bond92b96792009-06-13 07:38:31 -04001780 }
1781
Andres More1cac4a42013-03-18 20:33:50 -05001782 pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4);
Forest Bond92b96792009-06-13 07:38:31 -04001783 pDevice->wSeqCounter++ ;
1784 if (pDevice->wSeqCounter > 0x0fff)
1785 pDevice->wSeqCounter = 0;
1786
1787 if (bIsPSPOLL) {
1788 // The MAC will automatically replace the Duration-field of MAC header by Duration-field
Justin P. Mattocka0a1f612012-08-26 08:16:43 -07001789 // of FIFO control header.
Forest Bond92b96792009-06-13 07:38:31 -04001790 // This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is
1791 // in the same place of other packet's Duration-field).
1792 // And it will cause Cisco-AP to issue Disassociation-packet
Malcolm Priestley7e60a3de2013-08-16 23:48:03 +01001793 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
1794 ((struct vnt_tx_datahead_g *)pvTxDataHd)->wDuration_a =
1795 cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
1796 ((struct vnt_tx_datahead_g *)pvTxDataHd)->wDuration_b =
1797 cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
1798 } else {
Malcolm Priestley558becf2013-08-16 23:50:32 +01001799 ((struct vnt_tx_datahead_ab *)pvTxDataHd)->wDuration =
1800 cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
1801 }
Forest Bond92b96792009-06-13 07:38:31 -04001802 }
1803
Andres More3eaca0d2013-02-25 20:32:52 -05001804 pTX_Buffer->wTxByteCount = cpu_to_le16((u16)(cbReqCount));
Andres Moreb902fbf2013-02-25 20:32:51 -05001805 pTX_Buffer->byPKTNO = (u8) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
Forest Bond92b96792009-06-13 07:38:31 -04001806 pTX_Buffer->byType = 0x00;
1807
1808 pContext->pPacket = NULL;
1809 pContext->Type = CONTEXT_MGMT_PACKET;
Andres More3eaca0d2013-02-25 20:32:52 -05001810 pContext->uBufLen = (u16)cbReqCount + 4; //USB header
Forest Bond92b96792009-06-13 07:38:31 -04001811
Andres More1cac4a42013-03-18 20:33:50 -05001812 if (WLAN_GET_FC_TODS(pMACHeader->frame_control) == 0) {
1813 s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->addr1[0]), (u16)cbFrameSize, pTX_Buffer->wFIFOCtl);
Forest Bond92b96792009-06-13 07:38:31 -04001814 }
1815 else {
Andres More1cac4a42013-03-18 20:33:50 -05001816 s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->addr3[0]), (u16)cbFrameSize, pTX_Buffer->wFIFOCtl);
Forest Bond92b96792009-06-13 07:38:31 -04001817 }
1818
1819 PIPEnsSendBulkOut(pDevice,pContext);
1820 return CMD_STATUS_PENDING;
1821}
1822
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001823CMD_STATUS csBeacon_xmit(struct vnt_private *pDevice,
1824 struct vnt_tx_mgmt *pPacket)
Forest Bond92b96792009-06-13 07:38:31 -04001825{
Malcolm Priestley01f865b2013-08-15 19:40:08 +01001826 struct vnt_beacon_buffer *pTX_Buffer;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001827 u32 cbFrameSize = pPacket->cbMPDULen + WLAN_FCS_LEN;
1828 u32 cbHeaderSize = 0;
1829 u16 wTxBufSize = sizeof(STxShortBufHead);
1830 PSTxShortBufHead pTxBufHead;
Andres More1cac4a42013-03-18 20:33:50 -05001831 struct ieee80211_hdr *pMACHeader;
Malcolm Priestley558becf2013-08-16 23:50:32 +01001832 struct vnt_tx_datahead_ab *pTxDataHead;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001833 u16 wCurrentRate;
1834 u32 cbFrameBodySize;
1835 u32 cbReqCount;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001836 u8 *pbyTxBufferAddr;
1837 PUSB_SEND_CONTEXT pContext;
1838 CMD_STATUS status;
Forest Bond92b96792009-06-13 07:38:31 -04001839
Forest Bond92b96792009-06-13 07:38:31 -04001840 pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
1841 if (NULL == pContext) {
1842 status = CMD_STATUS_RESOURCES;
1843 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ManagementSend TX...NO CONTEXT!\n");
1844 return status ;
1845 }
Malcolm Priestley01f865b2013-08-15 19:40:08 +01001846
1847 pTX_Buffer = (struct vnt_beacon_buffer *)&pContext->Data[0];
Andres Moreb902fbf2013-02-25 20:32:51 -05001848 pbyTxBufferAddr = (u8 *)&(pTX_Buffer->wFIFOCtl);
Forest Bond92b96792009-06-13 07:38:31 -04001849
1850 cbFrameBodySize = pPacket->cbPayloadLen;
1851
1852 pTxBufHead = (PSTxShortBufHead) pbyTxBufferAddr;
1853 wTxBufSize = sizeof(STxShortBufHead);
Forest Bond92b96792009-06-13 07:38:31 -04001854
1855 if (pDevice->byBBType == BB_TYPE_11A) {
1856 wCurrentRate = RATE_6M;
Malcolm Priestley558becf2013-08-16 23:50:32 +01001857 pTxDataHead = (struct vnt_tx_datahead_ab *)
1858 (pbyTxBufferAddr + wTxBufSize);
Forest Bond92b96792009-06-13 07:38:31 -04001859 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -07001860 BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate, PK_TYPE_11A,
Andres More3eaca0d2013-02-25 20:32:52 -05001861 (u16 *)&(pTxDataHead->wTransmitLength), (u8 *)&(pTxDataHead->byServiceField), (u8 *)&(pTxDataHead->bySignalField)
Forest Bond92b96792009-06-13 07:38:31 -04001862 );
1863 //Get Duration and TimeStampOff
Malcolm Priestley3ed210e2013-08-07 21:28:45 +01001864 pTxDataHead->wDuration = cpu_to_le16((u16)s_uGetDataDuration(pDevice,
1865 DATADUR_A, PK_TYPE_11A, false));
Forest Bond92b96792009-06-13 07:38:31 -04001866 pTxDataHead->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
Malcolm Priestley558becf2013-08-16 23:50:32 +01001867 cbHeaderSize = wTxBufSize + sizeof(struct vnt_tx_datahead_ab);
Forest Bond92b96792009-06-13 07:38:31 -04001868 } else {
1869 wCurrentRate = RATE_1M;
1870 pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
Malcolm Priestley558becf2013-08-16 23:50:32 +01001871 pTxDataHead = (struct vnt_tx_datahead_ab *)
1872 (pbyTxBufferAddr + wTxBufSize);
Forest Bond92b96792009-06-13 07:38:31 -04001873 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -07001874 BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate, PK_TYPE_11B,
Andres More3eaca0d2013-02-25 20:32:52 -05001875 (u16 *)&(pTxDataHead->wTransmitLength), (u8 *)&(pTxDataHead->byServiceField), (u8 *)&(pTxDataHead->bySignalField)
Forest Bond92b96792009-06-13 07:38:31 -04001876 );
1877 //Get Duration and TimeStampOff
Malcolm Priestley3ed210e2013-08-07 21:28:45 +01001878 pTxDataHead->wDuration = cpu_to_le16((u16)s_uGetDataDuration(pDevice,
1879 DATADUR_B, PK_TYPE_11B, false));
Forest Bond92b96792009-06-13 07:38:31 -04001880 pTxDataHead->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
Malcolm Priestley558becf2013-08-16 23:50:32 +01001881 cbHeaderSize = wTxBufSize + sizeof(struct vnt_tx_datahead_ab);
Forest Bond92b96792009-06-13 07:38:31 -04001882 }
1883
1884 //Generate Beacon Header
Andres More1cac4a42013-03-18 20:33:50 -05001885 pMACHeader = (struct ieee80211_hdr *)(pbyTxBufferAddr + cbHeaderSize);
Jim Lieb3e362592009-08-12 14:54:11 -07001886 memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen);
Forest Bond92b96792009-06-13 07:38:31 -04001887
Andres More1cac4a42013-03-18 20:33:50 -05001888 pMACHeader->duration_id = 0;
1889 pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4);
Forest Bond92b96792009-06-13 07:38:31 -04001890 pDevice->wSeqCounter++ ;
1891 if (pDevice->wSeqCounter > 0x0fff)
1892 pDevice->wSeqCounter = 0;
1893
1894 cbReqCount = cbHeaderSize + WLAN_HDR_ADDR3_LEN + cbFrameBodySize;
1895
Andres More3eaca0d2013-02-25 20:32:52 -05001896 pTX_Buffer->wTxByteCount = (u16)cbReqCount;
Andres Moreb902fbf2013-02-25 20:32:51 -05001897 pTX_Buffer->byPKTNO = (u8) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
Forest Bond92b96792009-06-13 07:38:31 -04001898 pTX_Buffer->byType = 0x01;
1899
1900 pContext->pPacket = NULL;
1901 pContext->Type = CONTEXT_MGMT_PACKET;
Andres More3eaca0d2013-02-25 20:32:52 -05001902 pContext->uBufLen = (u16)cbReqCount + 4; //USB header
Forest Bond92b96792009-06-13 07:38:31 -04001903
1904 PIPEnsSendBulkOut(pDevice,pContext);
1905 return CMD_STATUS_PENDING;
1906
1907}
1908
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001909void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
1910{
1911 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
Malcolm Priestleyf39c0d82013-08-15 19:34:37 +01001912 struct vnt_tx_buffer *pTX_Buffer;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001913 u8 byPktType;
1914 u8 *pbyTxBufferAddr;
1915 void *pvRTS, *pvCTS, *pvTxDataHd;
1916 u32 uDuration, cbReqCount;
Andres More1cac4a42013-03-18 20:33:50 -05001917 struct ieee80211_hdr *pMACHeader;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001918 u32 cbHeaderSize, cbFrameBodySize;
Andres Moree269fc22013-02-12 20:36:29 -05001919 int bNeedACK, bIsPSPOLL = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001920 PSTxBufHead pTxBufHead;
1921 u32 cbFrameSize;
1922 u32 cbIVlen = 0, cbICVlen = 0, cbMIClen = 0, cbFCSlen = 4;
1923 u32 uPadding = 0;
1924 u32 cbMICHDR = 0, uLength = 0;
1925 u32 dwMICKey0, dwMICKey1;
1926 u32 dwMIC_Priority;
1927 u32 *pdwMIC_L, *pdwMIC_R;
1928 u16 wTxBufSize;
1929 u32 cbMacHdLen;
Andres Moreceb8c5d2013-03-18 20:33:49 -05001930 struct ethhdr sEthHeader;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001931 void *pvRrvTime, *pMICHDR;
1932 u32 wCurrentRate = RATE_1M;
1933 PUWLAN_80211HDR p80211Header;
1934 u32 uNodeIndex = 0;
Andres Moree269fc22013-02-12 20:36:29 -05001935 int bNodeExist = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001936 SKeyItem STempKey;
1937 PSKeyItem pTransmitKey = NULL;
1938 u8 *pbyIVHead, *pbyPayloadHead, *pbyMacHdr;
1939 u32 cbExtSuppRate = 0;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001940 PUSB_SEND_CONTEXT pContext;
Forest Bond92b96792009-06-13 07:38:31 -04001941
Forest Bond92b96792009-06-13 07:38:31 -04001942 pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
1943
1944 if(skb->len <= WLAN_HDR_ADDR3_LEN) {
1945 cbFrameBodySize = 0;
1946 }
1947 else {
1948 cbFrameBodySize = skb->len - WLAN_HDR_ADDR3_LEN;
1949 }
1950 p80211Header = (PUWLAN_80211HDR)skb->data;
1951
1952 pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
1953
1954 if (NULL == pContext) {
1955 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"DMA0 TX...NO CONTEXT!\n");
1956 dev_kfree_skb_irq(skb);
1957 return ;
1958 }
1959
Malcolm Priestleyf39c0d82013-08-15 19:34:37 +01001960 pTX_Buffer = (struct vnt_tx_buffer *)&pContext->Data[0];
Andres Moreb902fbf2013-02-25 20:32:51 -05001961 pbyTxBufferAddr = (u8 *)(&pTX_Buffer->adwTxKey[0]);
Forest Bond92b96792009-06-13 07:38:31 -04001962 pTxBufHead = (PSTxBufHead) pbyTxBufferAddr;
1963 wTxBufSize = sizeof(STxBufHead);
Forest Bond92b96792009-06-13 07:38:31 -04001964
1965 if (pDevice->byBBType == BB_TYPE_11A) {
1966 wCurrentRate = RATE_6M;
1967 byPktType = PK_TYPE_11A;
1968 } else {
1969 wCurrentRate = RATE_1M;
1970 byPktType = PK_TYPE_11B;
1971 }
1972
1973 // SetPower will cause error power TX state for OFDM Date packet in TX buffer.
1974 // 2004.11.11 Kyle -- Using OFDM power to tx MngPkt will decrease the connection capability.
1975 // And cmd timer will wait data pkt TX finish before scanning so it's OK
1976 // to set power here.
1977 if (pMgmt->eScanState != WMAC_NO_SCANNING) {
1978 RFbSetPower(pDevice, wCurrentRate, pDevice->byCurrentCh);
1979 } else {
1980 RFbSetPower(pDevice, wCurrentRate, pMgmt->uCurrChannel);
1981 }
1982
1983 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vDMA0_tx_80211: p80211Header->sA3.wFrameCtl = %x \n", p80211Header->sA3.wFrameCtl);
1984
1985 //Set packet type
1986 if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000
1987 pTxBufHead->wFIFOCtl = 0;
1988 }
1989 else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000
1990 pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
1991 }
1992 else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000
1993 pTxBufHead->wFIFOCtl |= FIFOCTL_11GB;
1994 }
1995 else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000
1996 pTxBufHead->wFIFOCtl |= FIFOCTL_11GA;
1997 }
1998
1999 pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN;
2000 pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
2001
Andres More22040bb2010-08-02 20:21:44 -03002002 if (is_multicast_ether_addr(p80211Header->sA3.abyAddr1)) {
Andres Moree269fc22013-02-12 20:36:29 -05002003 bNeedACK = false;
Forest Bond92b96792009-06-13 07:38:31 -04002004 if (pDevice->bEnableHostWEP) {
2005 uNodeIndex = 0;
Andres More4e9b5e22013-02-12 20:36:30 -05002006 bNodeExist = true;
Joe Perches9fc86022011-04-10 14:31:32 -07002007 }
Forest Bond92b96792009-06-13 07:38:31 -04002008 }
2009 else {
2010 if (pDevice->bEnableHostWEP) {
Andres Moreb902fbf2013-02-25 20:32:51 -05002011 if (BSSbIsSTAInNodeDB(pDevice, (u8 *)(p80211Header->sA3.abyAddr1), &uNodeIndex))
Andres More4e9b5e22013-02-12 20:36:30 -05002012 bNodeExist = true;
Joe Perches9fc86022011-04-10 14:31:32 -07002013 }
Andres More4e9b5e22013-02-12 20:36:30 -05002014 bNeedACK = true;
Forest Bond92b96792009-06-13 07:38:31 -04002015 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
2016 };
2017
2018 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) ||
2019 (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ) {
2020
2021 pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY;
2022 //Set Preamble type always long
2023 //pDevice->byPreambleType = PREAMBLE_LONG;
2024
2025 // probe-response don't retry
2026 //if ((p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_MGMT_PROBE_RSP) {
Andres Moree269fc22013-02-12 20:36:29 -05002027 // bNeedACK = false;
Forest Bond92b96792009-06-13 07:38:31 -04002028 // pTxBufHead->wFIFOCtl &= (~FIFOCTL_NEEDACK);
2029 //}
2030 }
2031
2032 pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0);
2033
2034 if ((p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) {
Andres More4e9b5e22013-02-12 20:36:30 -05002035 bIsPSPOLL = true;
Forest Bond92b96792009-06-13 07:38:31 -04002036 cbMacHdLen = WLAN_HDR_ADDR2_LEN;
2037 } else {
2038 cbMacHdLen = WLAN_HDR_ADDR3_LEN;
2039 }
2040
Justin P. Mattocka0a1f612012-08-26 08:16:43 -07002041 // hostapd daemon ext support rate patch
Forest Bond92b96792009-06-13 07:38:31 -04002042 if (WLAN_GET_FC_FSTYPE(p80211Header->sA4.wFrameCtl) == WLAN_FSTYPE_ASSOCRESP) {
2043
2044 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len != 0) {
2045 cbExtSuppRate += ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN;
2046 }
2047
2048 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len != 0) {
2049 cbExtSuppRate += ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
2050 }
2051
2052 if (cbExtSuppRate >0) {
2053 cbFrameBodySize = WLAN_ASSOCRESP_OFF_SUPP_RATES;
2054 }
2055 }
2056
Forest Bond92b96792009-06-13 07:38:31 -04002057 //Set FRAGCTL_MACHDCNT
Andres More3eaca0d2013-02-25 20:32:52 -05002058 pTxBufHead->wFragCtl |= cpu_to_le16((u16)cbMacHdLen << 10);
Forest Bond92b96792009-06-13 07:38:31 -04002059
2060 // Notes:
2061 // Although spec says MMPDU can be fragmented; In most case,
2062 // no one will send a MMPDU under fragmentation. With RTS may occur.
Andres Moree269fc22013-02-12 20:36:29 -05002063 pDevice->bAES = false; //Set FRAGCTL_WEPTYP
Forest Bond92b96792009-06-13 07:38:31 -04002064
Forest Bond92b96792009-06-13 07:38:31 -04002065 if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) {
2066 if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) {
2067 cbIVlen = 4;
2068 cbICVlen = 4;
2069 pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
2070 }
2071 else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
2072 cbIVlen = 8;//IV+ExtIV
2073 cbMIClen = 8;
2074 cbICVlen = 4;
2075 pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
2076 //We need to get seed here for filling TxKey entry.
2077 //TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr,
2078 // pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG);
2079 }
2080 else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
2081 cbIVlen = 8;//RSN Header
2082 cbICVlen = 8;//MIC
2083 cbMICHDR = sizeof(SMICHDRHead);
2084 pTxBufHead->wFragCtl |= FRAGCTL_AES;
Andres More4e9b5e22013-02-12 20:36:30 -05002085 pDevice->bAES = true;
Forest Bond92b96792009-06-13 07:38:31 -04002086 }
2087 //MAC Header should be padding 0 to DW alignment.
2088 uPadding = 4 - (cbMacHdLen%4);
2089 uPadding %= 4;
2090 }
2091
2092 cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen + cbExtSuppRate;
2093
2094 //Set FIFOCTL_GrpAckPolicy
Andres More4e9b5e22013-02-12 20:36:30 -05002095 if (pDevice->bGrpAckPolicy == true) {//0000 0100 0000 0000
Forest Bond92b96792009-06-13 07:38:31 -04002096 pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK;
2097 }
2098 //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter()
2099
Forest Bond92b96792009-06-13 07:38:31 -04002100 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
Malcolm Priestley4f990052013-08-16 23:38:57 +01002101 pvRrvTime = (struct vnt_rrv_time_cts *) (pbyTxBufferAddr + wTxBufSize);
2102 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize +
2103 sizeof(struct vnt_rrv_time_cts));
Forest Bond92b96792009-06-13 07:38:31 -04002104 pvRTS = NULL;
Malcolm Priestleyf0c5ba22013-08-15 21:27:22 +01002105 pvCTS = (struct vnt_cts *) (pbyTxBufferAddr + wTxBufSize +
Malcolm Priestley4f990052013-08-16 23:38:57 +01002106 sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
Malcolm Priestley7e60a3de2013-08-16 23:48:03 +01002107 pvTxDataHd = (struct vnt_tx_datahead_g *) (pbyTxBufferAddr +
2108 wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR +
Malcolm Priestley4f990052013-08-16 23:38:57 +01002109 sizeof(struct vnt_cts));
2110 cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR +
Malcolm Priestley7e60a3de2013-08-16 23:48:03 +01002111 sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
Forest Bond92b96792009-06-13 07:38:31 -04002112
2113 }
2114 else {//802.11a/b packet
2115
Malcolm Priestley976467d2013-08-16 23:44:04 +01002116 pvRrvTime = (struct vnt_rrv_time_ab *) (pbyTxBufferAddr + wTxBufSize);
2117 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize +
2118 sizeof(struct vnt_rrv_time_ab));
Forest Bond92b96792009-06-13 07:38:31 -04002119 pvRTS = NULL;
2120 pvCTS = NULL;
Malcolm Priestley558becf2013-08-16 23:50:32 +01002121 pvTxDataHd = (struct vnt_tx_datahead_ab *)(pbyTxBufferAddr +
2122 wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
Malcolm Priestley976467d2013-08-16 23:44:04 +01002123 cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR +
Malcolm Priestley558becf2013-08-16 23:50:32 +01002124 sizeof(struct vnt_tx_datahead_ab);
Forest Bond92b96792009-06-13 07:38:31 -04002125 }
Andres Moreceb8c5d2013-03-18 20:33:49 -05002126 memcpy(&(sEthHeader.h_dest[0]),
Andres More9a0e7562010-04-13 21:54:48 -03002127 &(p80211Header->sA3.abyAddr1[0]),
2128 ETH_ALEN);
Andres Moreceb8c5d2013-03-18 20:33:49 -05002129 memcpy(&(sEthHeader.h_source[0]),
Andres More9a0e7562010-04-13 21:54:48 -03002130 &(p80211Header->sA3.abyAddr2[0]),
2131 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -04002132 //=========================
2133 // No Fragmentation
2134 //=========================
Andres More3eaca0d2013-02-25 20:32:52 -05002135 pTxBufHead->wFragCtl |= (u16)FRAGCTL_NONFRAG;
Forest Bond92b96792009-06-13 07:38:31 -04002136
Forest Bond92b96792009-06-13 07:38:31 -04002137 //Fill FIFO,RrvTime,RTS,and CTS
2138 s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate, pbyTxBufferAddr, pvRrvTime, pvRTS, pvCTS,
2139 cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader);
2140
2141 //Fill DataHead
2142 uDuration = s_uFillDataHead(pDevice, byPktType, wCurrentRate, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK,
Malcolm Priestleyab01fed2013-08-07 21:31:48 +01002143 AUTO_FB_NONE);
Forest Bond92b96792009-06-13 07:38:31 -04002144
Andres More1cac4a42013-03-18 20:33:50 -05002145 pMACHeader = (struct ieee80211_hdr *) (pbyTxBufferAddr + cbHeaderSize);
Forest Bond92b96792009-06-13 07:38:31 -04002146
2147 cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + (cbFrameBodySize + cbMIClen) + cbExtSuppRate;
2148
Andres Moreb902fbf2013-02-25 20:32:51 -05002149 pbyMacHdr = (u8 *)(pbyTxBufferAddr + cbHeaderSize);
2150 pbyPayloadHead = (u8 *)(pbyMacHdr + cbMacHdLen + uPadding + cbIVlen);
2151 pbyIVHead = (u8 *)(pbyMacHdr + cbMacHdLen + uPadding);
Forest Bond92b96792009-06-13 07:38:31 -04002152
2153 // Copy the Packet into a tx Buffer
2154 memcpy(pbyMacHdr, skb->data, cbMacHdLen);
2155
2156 // version set to 0, patch for hostapd deamon
Andres More1cac4a42013-03-18 20:33:50 -05002157 pMACHeader->frame_control &= cpu_to_le16(0xfffc);
Forest Bond92b96792009-06-13 07:38:31 -04002158 memcpy(pbyPayloadHead, (skb->data + cbMacHdLen), cbFrameBodySize);
2159
Justin P. Mattocka0a1f612012-08-26 08:16:43 -07002160 // replace support rate, patch for hostapd daemon( only support 11M)
Forest Bond92b96792009-06-13 07:38:31 -04002161 if (WLAN_GET_FC_FSTYPE(p80211Header->sA4.wFrameCtl) == WLAN_FSTYPE_ASSOCRESP) {
2162 if (cbExtSuppRate != 0) {
2163 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len != 0)
2164 memcpy((pbyPayloadHead + cbFrameBodySize),
2165 pMgmt->abyCurrSuppRates,
2166 ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN
2167 );
2168 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len != 0)
2169 memcpy((pbyPayloadHead + cbFrameBodySize) + ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN,
2170 pMgmt->abyCurrExtSuppRates,
2171 ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len + WLAN_IEHDR_LEN
2172 );
2173 }
2174 }
2175
2176 // Set wep
2177 if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) {
2178
2179 if (pDevice->bEnableHostWEP) {
2180 pTransmitKey = &STempKey;
2181 pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
2182 pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
2183 pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
2184 pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
2185 pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
2186 memcpy(pTransmitKey->abyKey,
2187 &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
2188 pTransmitKey->uKeyLength
2189 );
2190 }
2191
2192 if ((pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
2193
Andres More52a7e642013-02-25 20:32:53 -05002194 dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]);
2195 dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]);
Forest Bond92b96792009-06-13 07:38:31 -04002196
2197 // DO Software Michael
2198 MIC_vInit(dwMICKey0, dwMICKey1);
Andres Moreceb8c5d2013-03-18 20:33:49 -05002199 MIC_vAppend((u8 *)&(sEthHeader.h_dest[0]), 12);
Forest Bond92b96792009-06-13 07:38:31 -04002200 dwMIC_Priority = 0;
Andres Moreb902fbf2013-02-25 20:32:51 -05002201 MIC_vAppend((u8 *)&dwMIC_Priority, 4);
Malcolm Priestleyb4dc03a2012-11-11 15:45:52 +00002202 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"DMA0_tx_8021:MIC KEY:"\
2203 " %X, %X\n", dwMICKey0, dwMICKey1);
Forest Bond92b96792009-06-13 07:38:31 -04002204
2205 uLength = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen;
2206
2207 MIC_vAppend((pbyTxBufferAddr + uLength), cbFrameBodySize);
2208
Andres More52a7e642013-02-25 20:32:53 -05002209 pdwMIC_L = (u32 *)(pbyTxBufferAddr + uLength + cbFrameBodySize);
2210 pdwMIC_R = (u32 *)(pbyTxBufferAddr + uLength + cbFrameBodySize + 4);
Forest Bond92b96792009-06-13 07:38:31 -04002211
2212 MIC_vGetMIC(pdwMIC_L, pdwMIC_R);
2213 MIC_vUnInit();
2214
Andres More4e9b5e22013-02-12 20:36:30 -05002215 if (pDevice->bTxMICFail == true) {
Forest Bond92b96792009-06-13 07:38:31 -04002216 *pdwMIC_L = 0;
2217 *pdwMIC_R = 0;
Andres Moree269fc22013-02-12 20:36:29 -05002218 pDevice->bTxMICFail = false;
Forest Bond92b96792009-06-13 07:38:31 -04002219 }
2220
2221 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize);
2222 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderSize, uPadding, cbIVlen);
Malcolm Priestleyb4dc03a2012-11-11 15:45:52 +00002223 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%x, %x\n",
2224 *pdwMIC_L, *pdwMIC_R);
Forest Bond92b96792009-06-13 07:38:31 -04002225
2226 }
2227
Andres Moreb902fbf2013-02-25 20:32:51 -05002228 s_vFillTxKey(pDevice, (u8 *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
Andres More3eaca0d2013-02-25 20:32:52 -05002229 pbyMacHdr, (u16)cbFrameBodySize, (u8 *)pMICHDR);
Forest Bond92b96792009-06-13 07:38:31 -04002230
2231 if (pDevice->bEnableHostWEP) {
2232 pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
2233 pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0;
2234 }
2235
2236 if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) {
Andres More3eaca0d2013-02-25 20:32:52 -05002237 s_vSWencryption(pDevice, pTransmitKey, pbyPayloadHead, (u16)(cbFrameBodySize + cbMIClen));
Forest Bond92b96792009-06-13 07:38:31 -04002238 }
2239 }
2240
Andres More1cac4a42013-03-18 20:33:50 -05002241 pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4);
Forest Bond92b96792009-06-13 07:38:31 -04002242 pDevice->wSeqCounter++ ;
2243 if (pDevice->wSeqCounter > 0x0fff)
2244 pDevice->wSeqCounter = 0;
2245
Forest Bond92b96792009-06-13 07:38:31 -04002246 if (bIsPSPOLL) {
2247 // The MAC will automatically replace the Duration-field of MAC header by Duration-field
2248 // of FIFO control header.
2249 // This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is
2250 // in the same place of other packet's Duration-field).
2251 // And it will cause Cisco-AP to issue Disassociation-packet
Malcolm Priestley7e60a3de2013-08-16 23:48:03 +01002252 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
2253 ((struct vnt_tx_datahead_g *)pvTxDataHd)->wDuration_a =
2254 cpu_to_le16(p80211Header->sA2.wDurationID);
2255 ((struct vnt_tx_datahead_g *)pvTxDataHd)->wDuration_b =
2256 cpu_to_le16(p80211Header->sA2.wDurationID);
2257 } else {
Malcolm Priestley558becf2013-08-16 23:50:32 +01002258 ((struct vnt_tx_datahead_ab *)pvTxDataHd)->wDuration =
2259 cpu_to_le16(p80211Header->sA2.wDurationID);
2260 }
Forest Bond92b96792009-06-13 07:38:31 -04002261 }
2262
Andres More3eaca0d2013-02-25 20:32:52 -05002263 pTX_Buffer->wTxByteCount = cpu_to_le16((u16)(cbReqCount));
Andres Moreb902fbf2013-02-25 20:32:51 -05002264 pTX_Buffer->byPKTNO = (u8) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
Forest Bond92b96792009-06-13 07:38:31 -04002265 pTX_Buffer->byType = 0x00;
2266
2267 pContext->pPacket = skb;
2268 pContext->Type = CONTEXT_MGMT_PACKET;
Andres More3eaca0d2013-02-25 20:32:52 -05002269 pContext->uBufLen = (u16)cbReqCount + 4; //USB header
Forest Bond92b96792009-06-13 07:38:31 -04002270
Andres More1cac4a42013-03-18 20:33:50 -05002271 if (WLAN_GET_FC_TODS(pMACHeader->frame_control) == 0) {
2272 s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->addr1[0]), (u16)cbFrameSize, pTX_Buffer->wFIFOCtl);
Forest Bond92b96792009-06-13 07:38:31 -04002273 }
2274 else {
Andres More1cac4a42013-03-18 20:33:50 -05002275 s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->addr3[0]), (u16)cbFrameSize, pTX_Buffer->wFIFOCtl);
Forest Bond92b96792009-06-13 07:38:31 -04002276 }
2277 PIPEnsSendBulkOut(pDevice,pContext);
2278 return ;
2279
2280}
2281
Forest Bond92b96792009-06-13 07:38:31 -04002282//TYPE_AC0DMA data tx
2283/*
2284 * Description:
2285 * Tx packet via AC0DMA(DMA1)
2286 *
2287 * Parameters:
2288 * In:
2289 * pDevice - Pointer to the adapter
2290 * skb - Pointer to tx skb packet
2291 * Out:
2292 * void
2293 *
2294 * Return Value: NULL
2295 */
2296
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002297int nsDMA_tx_packet(struct vnt_private *pDevice,
2298 u32 uDMAIdx, struct sk_buff *skb)
Forest Bond92b96792009-06-13 07:38:31 -04002299{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002300 struct net_device_stats *pStats = &pDevice->stats;
2301 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
Malcolm Priestleyf39c0d82013-08-15 19:34:37 +01002302 struct vnt_tx_buffer *pTX_Buffer;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002303 u32 BytesToWrite = 0, uHeaderLen = 0;
2304 u32 uNodeIndex = 0;
2305 u8 byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
2306 u16 wAID;
2307 u8 byPktType;
Andres Moree269fc22013-02-12 20:36:29 -05002308 int bNeedEncryption = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002309 PSKeyItem pTransmitKey = NULL;
2310 SKeyItem STempKey;
2311 int ii;
Andres Moree269fc22013-02-12 20:36:29 -05002312 int bTKIP_UseGTK = false;
2313 int bNeedDeAuth = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002314 u8 *pbyBSSID;
Andres Moree269fc22013-02-12 20:36:29 -05002315 int bNodeExist = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002316 PUSB_SEND_CONTEXT pContext;
Andres Moredfdcc422013-02-12 20:36:28 -05002317 bool fConvertedPacket;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002318 u32 status;
2319 u16 wKeepRate = pDevice->wCurrentRate;
Andres Moree269fc22013-02-12 20:36:29 -05002320 int bTxeapol_key = false;
Forest Bond92b96792009-06-13 07:38:31 -04002321
Forest Bond92b96792009-06-13 07:38:31 -04002322 if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
2323
2324 if (pDevice->uAssocCount == 0) {
2325 dev_kfree_skb_irq(skb);
2326 return 0;
2327 }
2328
Andres Moreb902fbf2013-02-25 20:32:51 -05002329 if (is_multicast_ether_addr((u8 *)(skb->data))) {
Forest Bond92b96792009-06-13 07:38:31 -04002330 uNodeIndex = 0;
Andres More4e9b5e22013-02-12 20:36:30 -05002331 bNodeExist = true;
Forest Bond92b96792009-06-13 07:38:31 -04002332 if (pMgmt->sNodeDBTable[0].bPSEnable) {
2333
2334 skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skb);
2335 pMgmt->sNodeDBTable[0].wEnQueueCnt++;
2336 // set tx map
2337 pMgmt->abyPSTxMap[0] |= byMask[0];
2338 return 0;
2339 }
Masanari Iida93184692012-08-13 21:21:50 +09002340 // multicast/broadcast data rate
Forest Bond92b96792009-06-13 07:38:31 -04002341
2342 if (pDevice->byBBType != BB_TYPE_11A)
2343 pDevice->wCurrentRate = RATE_2M;
2344 else
2345 pDevice->wCurrentRate = RATE_24M;
2346 // long preamble type
2347 pDevice->byPreambleType = PREAMBLE_SHORT;
2348
2349 }else {
2350
Andres Moreb902fbf2013-02-25 20:32:51 -05002351 if (BSSbIsSTAInNodeDB(pDevice, (u8 *)(skb->data), &uNodeIndex)) {
Forest Bond92b96792009-06-13 07:38:31 -04002352
2353 if (pMgmt->sNodeDBTable[uNodeIndex].bPSEnable) {
2354
2355 skb_queue_tail(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue, skb);
2356
2357 pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt++;
2358 // set tx map
2359 wAID = pMgmt->sNodeDBTable[uNodeIndex].wAID;
2360 pMgmt->abyPSTxMap[wAID >> 3] |= byMask[wAID & 7];
2361 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set:pMgmt->abyPSTxMap[%d]= %d\n",
2362 (wAID >> 3), pMgmt->abyPSTxMap[wAID >> 3]);
2363
2364 return 0;
2365 }
2366 // AP rate decided from node
2367 pDevice->wCurrentRate = pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
2368 // tx preamble decided from node
2369
2370 if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) {
2371 pDevice->byPreambleType = pDevice->byShortPreamble;
2372
2373 }else {
2374 pDevice->byPreambleType = PREAMBLE_LONG;
2375 }
Andres More4e9b5e22013-02-12 20:36:30 -05002376 bNodeExist = true;
Forest Bond92b96792009-06-13 07:38:31 -04002377 }
2378 }
2379
Andres Moree269fc22013-02-12 20:36:29 -05002380 if (bNodeExist == false) {
Forest Bond92b96792009-06-13 07:38:31 -04002381 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Unknown STA not found in node DB \n");
2382 dev_kfree_skb_irq(skb);
2383 return 0;
2384 }
2385 }
2386
2387 pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
2388
2389 if (pContext == NULL) {
2390 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG" pContext == NULL\n");
2391 dev_kfree_skb_irq(skb);
2392 return STATUS_RESOURCES;
2393 }
2394
Andres Moreceb8c5d2013-03-18 20:33:49 -05002395 memcpy(pDevice->sTxEthHeader.h_dest, (u8 *)(skb->data), ETH_HLEN);
Forest Bond92b96792009-06-13 07:38:31 -04002396
2397//mike add:station mode check eapol-key challenge--->
2398{
Andres Moreb902fbf2013-02-25 20:32:51 -05002399 u8 Protocol_Version; //802.1x Authentication
2400 u8 Packet_Type; //802.1x Authentication
2401 u8 Descriptor_type;
Andres More3eaca0d2013-02-25 20:32:52 -05002402 u16 Key_info;
Forest Bond92b96792009-06-13 07:38:31 -04002403
Charles Clément21ec51f2010-05-18 10:08:14 -07002404 Protocol_Version = skb->data[ETH_HLEN];
2405 Packet_Type = skb->data[ETH_HLEN+1];
2406 Descriptor_type = skb->data[ETH_HLEN+1+1+2];
2407 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 -05002408 if (pDevice->sTxEthHeader.h_proto == cpu_to_be16(ETH_P_PAE)) {
Malcolm Priestleyaa209ee2012-08-29 23:08:21 +01002409 /* 802.1x OR eapol-key challenge frame transfer */
2410 if (((Protocol_Version == 1) || (Protocol_Version == 2)) &&
2411 (Packet_Type == 3)) {
Andres More4e9b5e22013-02-12 20:36:30 -05002412 bTxeapol_key = true;
Forest Bond92b96792009-06-13 07:38:31 -04002413 if(!(Key_info & BIT3) && //WPA or RSN group-key challenge
2414 (Key_info & BIT8) && (Key_info & BIT9)) { //send 2/2 key
2415 if(Descriptor_type==254) {
Andres More4e9b5e22013-02-12 20:36:30 -05002416 pDevice->fWPA_Authened = true;
Forest Bond92b96792009-06-13 07:38:31 -04002417 PRINT_K("WPA ");
2418 }
2419 else {
Andres More4e9b5e22013-02-12 20:36:30 -05002420 pDevice->fWPA_Authened = true;
Forest Bond92b96792009-06-13 07:38:31 -04002421 PRINT_K("WPA2(re-keying) ");
2422 }
2423 PRINT_K("Authentication completed!!\n");
2424 }
Justin P. Mattocka0a1f612012-08-26 08:16:43 -07002425 else if((Key_info & BIT3) && (Descriptor_type==2) && //RSN pairwise-key challenge
Forest Bond92b96792009-06-13 07:38:31 -04002426 (Key_info & BIT8) && (Key_info & BIT9)) {
Andres More4e9b5e22013-02-12 20:36:30 -05002427 pDevice->fWPA_Authened = true;
Forest Bond92b96792009-06-13 07:38:31 -04002428 PRINT_K("WPA2 Authentication completed!!\n");
2429 }
2430 }
2431 }
2432}
2433//mike add:station mode check eapol-key challenge<---
2434
Andres More4e9b5e22013-02-12 20:36:30 -05002435 if (pDevice->bEncryptionEnable == true) {
2436 bNeedEncryption = true;
Forest Bond92b96792009-06-13 07:38:31 -04002437 // get Transmit key
2438 do {
2439 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
2440 (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
2441 pbyBSSID = pDevice->abyBSSID;
2442 // get pairwise key
Andres Moree269fc22013-02-12 20:36:29 -05002443 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == false) {
Forest Bond92b96792009-06-13 07:38:31 -04002444 // get group key
Andres More4e9b5e22013-02-12 20:36:30 -05002445 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == true) {
2446 bTKIP_UseGTK = true;
Forest Bond92b96792009-06-13 07:38:31 -04002447 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
2448 break;
2449 }
2450 } else {
2451 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get PTK.\n");
2452 break;
2453 }
2454 }else if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
Andres Moreceb8c5d2013-03-18 20:33:49 -05002455 /* TO_DS = 0 and FROM_DS = 0 --> 802.11 MAC Address1 */
2456 pbyBSSID = pDevice->sTxEthHeader.h_dest;
Forest Bond92b96792009-06-13 07:38:31 -04002457 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"IBSS Serach Key: \n");
2458 for (ii = 0; ii< 6; ii++)
2459 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"%x \n", *(pbyBSSID+ii));
2460 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"\n");
2461
2462 // get pairwise key
Andres More4e9b5e22013-02-12 20:36:30 -05002463 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == true)
Forest Bond92b96792009-06-13 07:38:31 -04002464 break;
2465 }
2466 // get group key
2467 pbyBSSID = pDevice->abyBroadcastAddr;
Andres Moree269fc22013-02-12 20:36:29 -05002468 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) {
Forest Bond92b96792009-06-13 07:38:31 -04002469 pTransmitKey = NULL;
2470 if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
2471 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"IBSS and KEY is NULL. [%d]\n", pMgmt->eCurrMode);
2472 }
2473 else
2474 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"NOT IBSS and KEY is NULL. [%d]\n", pMgmt->eCurrMode);
2475 } else {
Andres More4e9b5e22013-02-12 20:36:30 -05002476 bTKIP_UseGTK = true;
Forest Bond92b96792009-06-13 07:38:31 -04002477 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
2478 }
Andres Moree269fc22013-02-12 20:36:29 -05002479 } while(false);
Forest Bond92b96792009-06-13 07:38:31 -04002480 }
2481
2482 if (pDevice->bEnableHostWEP) {
2483 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"acdma0: STA index %d\n", uNodeIndex);
Andres More4e9b5e22013-02-12 20:36:30 -05002484 if (pDevice->bEncryptionEnable == true) {
Forest Bond92b96792009-06-13 07:38:31 -04002485 pTransmitKey = &STempKey;
2486 pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
2487 pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
2488 pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
2489 pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
2490 pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
2491 memcpy(pTransmitKey->abyKey,
2492 &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
2493 pTransmitKey->uKeyLength
2494 );
2495 }
2496 }
2497
Andres Moreb902fbf2013-02-25 20:32:51 -05002498 byPktType = (u8)pDevice->byPacketType;
Forest Bond92b96792009-06-13 07:38:31 -04002499
2500 if (pDevice->bFixRate) {
2501 if (pDevice->byBBType == BB_TYPE_11B) {
2502 if (pDevice->uConnectionRate >= RATE_11M) {
2503 pDevice->wCurrentRate = RATE_11M;
2504 } else {
Andres More3eaca0d2013-02-25 20:32:52 -05002505 pDevice->wCurrentRate = (u16)pDevice->uConnectionRate;
Forest Bond92b96792009-06-13 07:38:31 -04002506 }
2507 } else {
2508 if ((pDevice->byBBType == BB_TYPE_11A) &&
2509 (pDevice->uConnectionRate <= RATE_6M)) {
2510 pDevice->wCurrentRate = RATE_6M;
2511 } else {
2512 if (pDevice->uConnectionRate >= RATE_54M)
2513 pDevice->wCurrentRate = RATE_54M;
2514 else
Andres More3eaca0d2013-02-25 20:32:52 -05002515 pDevice->wCurrentRate = (u16)pDevice->uConnectionRate;
Forest Bond92b96792009-06-13 07:38:31 -04002516 }
2517 }
2518 }
2519 else {
2520 if (pDevice->eOPMode == OP_MODE_ADHOC) {
2521 // Adhoc Tx rate decided from node DB
Andres Moreceb8c5d2013-03-18 20:33:49 -05002522 if (is_multicast_ether_addr(pDevice->sTxEthHeader.h_dest)) {
Forest Bond92b96792009-06-13 07:38:31 -04002523 // Multicast use highest data rate
2524 pDevice->wCurrentRate = pMgmt->sNodeDBTable[0].wTxDataRate;
2525 // preamble type
2526 pDevice->byPreambleType = pDevice->byShortPreamble;
2527 }
2528 else {
Andres Moreceb8c5d2013-03-18 20:33:49 -05002529 if (BSSbIsSTAInNodeDB(pDevice, &(pDevice->sTxEthHeader.h_dest[0]), &uNodeIndex)) {
Forest Bond92b96792009-06-13 07:38:31 -04002530 pDevice->wCurrentRate = pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
2531 if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) {
2532 pDevice->byPreambleType = pDevice->byShortPreamble;
2533
2534 }
2535 else {
2536 pDevice->byPreambleType = PREAMBLE_LONG;
2537 }
2538 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Found Node Index is [%d] Tx Data Rate:[%d]\n",uNodeIndex, pDevice->wCurrentRate);
2539 }
2540 else {
2541 if (pDevice->byBBType != BB_TYPE_11A)
2542 pDevice->wCurrentRate = RATE_2M;
2543 else
2544 pDevice->wCurrentRate = RATE_24M; // refer to vMgrCreateOwnIBSS()'s
2545 // abyCurrExtSuppRates[]
2546 pDevice->byPreambleType = PREAMBLE_SHORT;
2547 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Not Found Node use highest basic Rate.....\n");
2548 }
2549 }
2550 }
2551 if (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) {
2552 // Infra STA rate decided from AP Node, index = 0
2553 pDevice->wCurrentRate = pMgmt->sNodeDBTable[0].wTxDataRate;
2554 }
2555 }
2556
Andres Moreceb8c5d2013-03-18 20:33:49 -05002557 if (pDevice->sTxEthHeader.h_proto == cpu_to_be16(ETH_P_PAE)) {
Malcolm Priestleyaa209ee2012-08-29 23:08:21 +01002558 if (pDevice->byBBType != BB_TYPE_11A) {
2559 pDevice->wCurrentRate = RATE_1M;
2560 pDevice->byACKRate = RATE_1M;
2561 pDevice->byTopCCKBasicRate = RATE_1M;
2562 pDevice->byTopOFDMBasicRate = RATE_6M;
2563 } else {
2564 pDevice->wCurrentRate = RATE_6M;
2565 pDevice->byACKRate = RATE_6M;
2566 pDevice->byTopCCKBasicRate = RATE_1M;
2567 pDevice->byTopOFDMBasicRate = RATE_6M;
2568 }
2569 }
Forest Bond92b96792009-06-13 07:38:31 -04002570
Andres More0cbd8d92010-05-06 20:34:29 -03002571 DBG_PRT(MSG_LEVEL_DEBUG,
2572 KERN_INFO "dma_tx: pDevice->wCurrentRate = %d\n",
2573 pDevice->wCurrentRate);
Forest Bond92b96792009-06-13 07:38:31 -04002574
2575 if (wKeepRate != pDevice->wCurrentRate) {
Andres More0cbd8d92010-05-06 20:34:29 -03002576 bScheduleCommand((void *) pDevice, WLAN_CMD_SETPOWER, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002577 }
2578
2579 if (pDevice->wCurrentRate <= RATE_11M) {
2580 byPktType = PK_TYPE_11B;
2581 }
2582
Andres More4e9b5e22013-02-12 20:36:30 -05002583 if (bNeedEncryption == true) {
Andres Moreceb8c5d2013-03-18 20:33:49 -05002584 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ntohs Pkt Type=%04x\n", ntohs(pDevice->sTxEthHeader.h_proto));
2585 if ((pDevice->sTxEthHeader.h_proto) == cpu_to_be16(ETH_P_PAE)) {
Andres Moree269fc22013-02-12 20:36:29 -05002586 bNeedEncryption = false;
Andres Moreceb8c5d2013-03-18 20:33:49 -05002587 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Pkt Type=%04x\n", (pDevice->sTxEthHeader.h_proto));
Forest Bond92b96792009-06-13 07:38:31 -04002588 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
2589 if (pTransmitKey == NULL) {
2590 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Don't Find TX KEY\n");
2591 }
2592 else {
Andres More4e9b5e22013-02-12 20:36:30 -05002593 if (bTKIP_UseGTK == true) {
Forest Bond92b96792009-06-13 07:38:31 -04002594 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"error: KEY is GTK!!~~\n");
2595 }
2596 else {
Malcolm Priestleyb4dc03a2012-11-11 15:45:52 +00002597 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%X]\n",
2598 pTransmitKey->dwKeyIndex);
Andres More4e9b5e22013-02-12 20:36:30 -05002599 bNeedEncryption = true;
Forest Bond92b96792009-06-13 07:38:31 -04002600 }
2601 }
2602 }
2603
Forest Bond92b96792009-06-13 07:38:31 -04002604 if (pDevice->bEnableHostWEP) {
2605 if ((uNodeIndex != 0) &&
2606 (pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex & PAIRWISE_KEY)) {
Malcolm Priestleyb4dc03a2012-11-11 15:45:52 +00002607 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%X]\n",
2608 pTransmitKey->dwKeyIndex);
Andres More4e9b5e22013-02-12 20:36:30 -05002609 bNeedEncryption = true;
Forest Bond92b96792009-06-13 07:38:31 -04002610 }
2611 }
2612 }
2613 else {
2614
Forest Bond92b96792009-06-13 07:38:31 -04002615 if (pTransmitKey == NULL) {
2616 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"return no tx key\n");
Andres Moree269fc22013-02-12 20:36:29 -05002617 pContext->bBoolInUse = false;
Forest Bond92b96792009-06-13 07:38:31 -04002618 dev_kfree_skb_irq(skb);
2619 pStats->tx_dropped++;
2620 return STATUS_FAILURE;
2621 }
Forest Bond92b96792009-06-13 07:38:31 -04002622 }
2623 }
2624
Malcolm Priestleyd0a2b8f2013-08-15 19:37:04 +01002625 pTX_Buffer = (struct vnt_tx_buffer *)&pContext->Data[0];
2626
Forest Bond92b96792009-06-13 07:38:31 -04002627 fConvertedPacket = s_bPacketToWirelessUsb(pDevice, byPktType,
Malcolm Priestleyd0a2b8f2013-08-15 19:37:04 +01002628 pTX_Buffer, bNeedEncryption,
Forest Bond92b96792009-06-13 07:38:31 -04002629 skb->len, uDMAIdx, &pDevice->sTxEthHeader,
Andres Moreb902fbf2013-02-25 20:32:51 -05002630 (u8 *)skb->data, pTransmitKey, uNodeIndex,
Forest Bond92b96792009-06-13 07:38:31 -04002631 pDevice->wCurrentRate,
2632 &uHeaderLen, &BytesToWrite
2633 );
2634
Andres Moree269fc22013-02-12 20:36:29 -05002635 if (fConvertedPacket == false) {
2636 pContext->bBoolInUse = false;
Forest Bond92b96792009-06-13 07:38:31 -04002637 dev_kfree_skb_irq(skb);
2638 return STATUS_FAILURE;
2639 }
2640
Andres More4e9b5e22013-02-12 20:36:30 -05002641 if ( pDevice->bEnablePSMode == true ) {
Forest Bond92b96792009-06-13 07:38:31 -04002642 if ( !pDevice->bPSModeTxBurst ) {
Andres More0cbd8d92010-05-06 20:34:29 -03002643 bScheduleCommand((void *) pDevice,
2644 WLAN_CMD_MAC_DISPOWERSAVING,
2645 NULL);
Andres More4e9b5e22013-02-12 20:36:30 -05002646 pDevice->bPSModeTxBurst = true;
Forest Bond92b96792009-06-13 07:38:31 -04002647 }
2648 }
2649
Andres Moreb902fbf2013-02-25 20:32:51 -05002650 pTX_Buffer->byPKTNO = (u8) (((pDevice->wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
Andres More3eaca0d2013-02-25 20:32:52 -05002651 pTX_Buffer->wTxByteCount = (u16)BytesToWrite;
Forest Bond92b96792009-06-13 07:38:31 -04002652
2653 pContext->pPacket = skb;
2654 pContext->Type = CONTEXT_DATA_PACKET;
Andres More3eaca0d2013-02-25 20:32:52 -05002655 pContext->uBufLen = (u16)BytesToWrite + 4 ; //USB header
Forest Bond92b96792009-06-13 07:38:31 -04002656
Andres Moreceb8c5d2013-03-18 20:33:49 -05002657 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 -04002658
2659 status = PIPEnsSendBulkOut(pDevice,pContext);
2660
Andres More4e9b5e22013-02-12 20:36:30 -05002661 if (bNeedDeAuth == true) {
Andres More3eaca0d2013-02-25 20:32:52 -05002662 u16 wReason = WLAN_MGMT_REASON_MIC_FAILURE;
Forest Bond92b96792009-06-13 07:38:31 -04002663
Andres Moreb902fbf2013-02-25 20:32:51 -05002664 bScheduleCommand((void *) pDevice, WLAN_CMD_DEAUTH, (u8 *) &wReason);
Forest Bond92b96792009-06-13 07:38:31 -04002665 }
2666
2667 if(status!=STATUS_PENDING) {
Andres Moree269fc22013-02-12 20:36:29 -05002668 pContext->bBoolInUse = false;
Forest Bond92b96792009-06-13 07:38:31 -04002669 dev_kfree_skb_irq(skb);
2670 return STATUS_FAILURE;
2671 }
2672 else
2673 return 0;
2674
2675}
2676
Forest Bond92b96792009-06-13 07:38:31 -04002677/*
2678 * Description:
2679 * Relay packet send (AC1DMA) from rx dpc.
2680 *
2681 * Parameters:
2682 * In:
2683 * pDevice - Pointer to the adapter
2684 * pPacket - Pointer to rx packet
2685 * cbPacketSize - rx ethernet frame size
2686 * Out:
Andres Moree269fc22013-02-12 20:36:29 -05002687 * TURE, false
Forest Bond92b96792009-06-13 07:38:31 -04002688 *
Andres More4e9b5e22013-02-12 20:36:30 -05002689 * Return Value: Return true if packet is copy to dma1; otherwise false
Forest Bond92b96792009-06-13 07:38:31 -04002690 */
2691
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002692int bRelayPacketSend(struct vnt_private *pDevice, u8 *pbySkbData, u32 uDataLen,
2693 u32 uNodeIndex)
Forest Bond92b96792009-06-13 07:38:31 -04002694{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002695 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
Malcolm Priestleyf39c0d82013-08-15 19:34:37 +01002696 struct vnt_tx_buffer *pTX_Buffer;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002697 u32 BytesToWrite = 0, uHeaderLen = 0;
2698 u8 byPktType = PK_TYPE_11B;
Andres Moree269fc22013-02-12 20:36:29 -05002699 int bNeedEncryption = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002700 SKeyItem STempKey;
2701 PSKeyItem pTransmitKey = NULL;
2702 u8 *pbyBSSID;
2703 PUSB_SEND_CONTEXT pContext;
2704 u8 byPktTyp;
2705 int fConvertedPacket;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002706 u32 status;
2707 u16 wKeepRate = pDevice->wCurrentRate;
Forest Bond92b96792009-06-13 07:38:31 -04002708
Forest Bond92b96792009-06-13 07:38:31 -04002709 pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
2710
2711 if (NULL == pContext) {
Andres Moree269fc22013-02-12 20:36:29 -05002712 return false;
Forest Bond92b96792009-06-13 07:38:31 -04002713 }
2714
Andres Moreceb8c5d2013-03-18 20:33:49 -05002715 memcpy(pDevice->sTxEthHeader.h_dest, (u8 *)pbySkbData, ETH_HLEN);
Forest Bond92b96792009-06-13 07:38:31 -04002716
Andres More4e9b5e22013-02-12 20:36:30 -05002717 if (pDevice->bEncryptionEnable == true) {
2718 bNeedEncryption = true;
Forest Bond92b96792009-06-13 07:38:31 -04002719 // get group key
2720 pbyBSSID = pDevice->abyBroadcastAddr;
Andres Moree269fc22013-02-12 20:36:29 -05002721 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) {
Forest Bond92b96792009-06-13 07:38:31 -04002722 pTransmitKey = NULL;
2723 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"KEY is NULL. [%d]\n", pMgmt->eCurrMode);
2724 } else {
2725 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
2726 }
2727 }
2728
2729 if (pDevice->bEnableHostWEP) {
Roel Kluinee93e192009-10-16 20:17:57 +02002730 if (uNodeIndex < MAX_NODE_NUM + 1) {
Forest Bond92b96792009-06-13 07:38:31 -04002731 pTransmitKey = &STempKey;
2732 pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
2733 pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
2734 pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
2735 pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
2736 pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
2737 memcpy(pTransmitKey->abyKey,
2738 &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
2739 pTransmitKey->uKeyLength
2740 );
2741 }
2742 }
2743
2744 if ( bNeedEncryption && (pTransmitKey == NULL) ) {
Andres Moree269fc22013-02-12 20:36:29 -05002745 pContext->bBoolInUse = false;
2746 return false;
Forest Bond92b96792009-06-13 07:38:31 -04002747 }
2748
Andres Moreb902fbf2013-02-25 20:32:51 -05002749 byPktTyp = (u8)pDevice->byPacketType;
Forest Bond92b96792009-06-13 07:38:31 -04002750
2751 if (pDevice->bFixRate) {
2752 if (pDevice->byBBType == BB_TYPE_11B) {
2753 if (pDevice->uConnectionRate >= RATE_11M) {
2754 pDevice->wCurrentRate = RATE_11M;
2755 } else {
Andres More3eaca0d2013-02-25 20:32:52 -05002756 pDevice->wCurrentRate = (u16)pDevice->uConnectionRate;
Forest Bond92b96792009-06-13 07:38:31 -04002757 }
2758 } else {
2759 if ((pDevice->byBBType == BB_TYPE_11A) &&
2760 (pDevice->uConnectionRate <= RATE_6M)) {
2761 pDevice->wCurrentRate = RATE_6M;
2762 } else {
2763 if (pDevice->uConnectionRate >= RATE_54M)
2764 pDevice->wCurrentRate = RATE_54M;
2765 else
Andres More3eaca0d2013-02-25 20:32:52 -05002766 pDevice->wCurrentRate = (u16)pDevice->uConnectionRate;
Forest Bond92b96792009-06-13 07:38:31 -04002767 }
2768 }
2769 }
2770 else {
2771 pDevice->wCurrentRate = pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
2772 }
2773
Forest Bond92b96792009-06-13 07:38:31 -04002774 if (wKeepRate != pDevice->wCurrentRate) {
Andres More0cbd8d92010-05-06 20:34:29 -03002775 bScheduleCommand((void *) pDevice, WLAN_CMD_SETPOWER, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002776 }
2777
2778 if (pDevice->wCurrentRate <= RATE_11M)
2779 byPktType = PK_TYPE_11B;
2780
Andres Moreabad19d2010-07-12 16:28:32 -03002781 BytesToWrite = uDataLen + ETH_FCS_LEN;
2782
Forest Bond92b96792009-06-13 07:38:31 -04002783 // Convert the packet to an usb frame and copy into our buffer
2784 // and send the irp.
2785
Malcolm Priestleyd0a2b8f2013-08-15 19:37:04 +01002786 pTX_Buffer = (struct vnt_tx_buffer *)&pContext->Data[0];
2787
Forest Bond92b96792009-06-13 07:38:31 -04002788 fConvertedPacket = s_bPacketToWirelessUsb(pDevice, byPktType,
Malcolm Priestleyd0a2b8f2013-08-15 19:37:04 +01002789 pTX_Buffer, bNeedEncryption,
Forest Bond92b96792009-06-13 07:38:31 -04002790 uDataLen, TYPE_AC0DMA, &pDevice->sTxEthHeader,
2791 pbySkbData, pTransmitKey, uNodeIndex,
2792 pDevice->wCurrentRate,
2793 &uHeaderLen, &BytesToWrite
2794 );
2795
Andres Moree269fc22013-02-12 20:36:29 -05002796 if (fConvertedPacket == false) {
2797 pContext->bBoolInUse = false;
2798 return false;
Forest Bond92b96792009-06-13 07:38:31 -04002799 }
2800
Andres Moreb902fbf2013-02-25 20:32:51 -05002801 pTX_Buffer->byPKTNO = (u8) (((pDevice->wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
Andres More3eaca0d2013-02-25 20:32:52 -05002802 pTX_Buffer->wTxByteCount = (u16)BytesToWrite;
Forest Bond92b96792009-06-13 07:38:31 -04002803
2804 pContext->pPacket = NULL;
2805 pContext->Type = CONTEXT_DATA_PACKET;
Andres More3eaca0d2013-02-25 20:32:52 -05002806 pContext->uBufLen = (u16)BytesToWrite + 4 ; //USB header
Forest Bond92b96792009-06-13 07:38:31 -04002807
Andres Moreceb8c5d2013-03-18 20:33:49 -05002808 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 -04002809
2810 status = PIPEnsSendBulkOut(pDevice,pContext);
2811
Andres More4e9b5e22013-02-12 20:36:30 -05002812 return true;
Forest Bond92b96792009-06-13 07:38:31 -04002813}
2814