blob: 06290be36db733c7c686ca7529a6fd84ce450929 [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 "michael.h"
Forest Bond92b96792009-06-13 07:38:31 -040056#include "tkip.h"
Forest Bond92b96792009-06-13 07:38:31 -040057#include "tcrc.h"
Forest Bond92b96792009-06-13 07:38:31 -040058#include "wctl.h"
Forest Bond92b96792009-06-13 07:38:31 -040059#include "hostap.h"
Forest Bond92b96792009-06-13 07:38:31 -040060#include "rf.h"
Forest Bond92b96792009-06-13 07:38:31 -040061#include "datarate.h"
Forest Bond92b96792009-06-13 07:38:31 -040062#include "usbpipe.h"
Forest Bond92b96792009-06-13 07:38:31 -040063#include "iocmd.h"
Jim Lieb9d26d602009-08-12 14:54:08 -070064
Mariano Reingart4a499de2010-10-29 19:15:26 -030065static int msglevel = MSG_LEVEL_INFO;
Forest Bond92b96792009-06-13 07:38:31 -040066
Valentina Manea3b138852013-11-04 10:44:02 +020067static const u16 wTimeStampOff[2][MAX_RATE] = {
Forest Bond92b96792009-06-13 07:38:31 -040068 {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, // Long Preamble
69 {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, // Short Preamble
70 };
71
Valentina Manea3b138852013-11-04 10:44:02 +020072static const u16 wFB_Opt0[2][5] = {
Forest Bond92b96792009-06-13 07:38:31 -040073 {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, // fallback_rate0
74 {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, // fallback_rate1
75 };
Valentina Manea3b138852013-11-04 10:44:02 +020076static const u16 wFB_Opt1[2][5] = {
Forest Bond92b96792009-06-13 07:38:31 -040077 {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, // fallback_rate0
78 {RATE_6M , RATE_6M, RATE_12M, RATE_12M, RATE_18M}, // fallback_rate1
79 };
80
Forest Bond92b96792009-06-13 07:38:31 -040081#define RTSDUR_BB 0
82#define RTSDUR_BA 1
83#define RTSDUR_AA 2
84#define CTSDUR_BA 3
85#define RTSDUR_BA_F0 4
86#define RTSDUR_AA_F0 5
87#define RTSDUR_BA_F1 6
88#define RTSDUR_AA_F1 7
89#define CTSDUR_BA_F0 8
90#define CTSDUR_BA_F1 9
91#define DATADUR_B 10
92#define DATADUR_A 11
93#define DATADUR_A_F0 12
94#define DATADUR_A_F1 13
95
Malcolm Priestleyd56131d2013-01-17 23:15:22 +000096static void s_vSaveTxPktInfo(struct vnt_private *pDevice, u8 byPktNum,
97 u8 *pbyDestAddr, u16 wPktLength, u16 wFIFOCtl);
Forest Bond92b96792009-06-13 07:38:31 -040098
Malcolm Priestleyb89f3b92013-11-26 19:16:59 +000099static struct vnt_usb_send_context *s_vGetFreeContext(struct vnt_private *);
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000100
Malcolm Priestley0a0f4b62013-10-01 15:50:24 +0100101static u16 s_vGenerateTxParameter(struct vnt_private *pDevice,
Malcolm Priestley8e344c82013-09-17 19:58:11 +0100102 u8 byPktType, u16 wCurrentRate, struct vnt_tx_buffer *tx_buffer,
Malcolm Priestleyfa575602013-09-26 19:00:41 +0100103 struct vnt_mic_hdr **mic_hdr, u32 need_mic, u32 cbFrameSize,
104 int bNeedACK, u32 uDMAIdx, struct ethhdr *psEthHeader, bool need_rts);
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000105
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000106static void s_vGenerateMACHeader(struct vnt_private *pDevice,
Andres Moreceb8c5d2013-03-18 20:33:49 -0500107 u8 *pbyBufferAddr, u16 wDuration, struct ethhdr *psEthHeader,
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000108 int bNeedEncrypt, u16 wFragType, u32 uDMAIdx, u32 uFragIdx);
Forest Bond92b96792009-06-13 07:38:31 -0400109
Malcolm Priestley3ba09382013-10-15 21:41:38 +0100110static void s_vFillTxKey(struct vnt_private *pDevice,
111 struct vnt_tx_fifo_head *fifo_head, u8 *pbyIVHead,
112 PSKeyItem pTransmitKey, u8 *pbyHdrBuf, u16 wPayloadLen,
Malcolm Priestleyec37d8b2013-08-23 14:37:48 +0100113 struct vnt_mic_hdr *mic_hdr);
Forest Bond92b96792009-06-13 07:38:31 -0400114
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000115static void s_vSWencryption(struct vnt_private *pDevice,
116 PSKeyItem pTransmitKey, u8 *pbyPayloadHead, u16 wPayloadSize);
Forest Bond92b96792009-06-13 07:38:31 -0400117
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000118static unsigned int s_uGetTxRsvTime(struct vnt_private *pDevice, u8 byPktType,
119 u32 cbFrameLength, u16 wRate, int bNeedAck);
Forest Bond92b96792009-06-13 07:38:31 -0400120
Malcolm Priestleycfabe4b2013-08-22 21:03:40 +0100121static u16 s_uGetRTSCTSRsvTime(struct vnt_private *pDevice, u8 byRTSRsvType,
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000122 u8 byPktType, u32 cbFrameLength, u16 wCurrentRate);
Forest Bond92b96792009-06-13 07:38:31 -0400123
Malcolm Priestley0a0f4b62013-10-01 15:50:24 +0100124static u16 s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
Malcolm Priestley5fb8e412013-08-27 12:07:58 +0100125 u8 byPktType, union vnt_tx_data_head *head, u32 cbFrameLength,
126 int bNeedAck, u16 wCurrentRate, u8 byFBOption);
Forest Bond92b96792009-06-13 07:38:31 -0400127
Malcolm Priestley0a0f4b62013-10-01 15:50:24 +0100128static u16 s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
Malcolm Priestley5fb8e412013-08-27 12:07:58 +0100129 union vnt_tx_data_head *head, u32 cbFrameLength, int bNeedAck,
Andres Moreceb8c5d2013-03-18 20:33:49 -0500130 struct ethhdr *psEthHeader, u16 wCurrentRate, u8 byFBOption);
Forest Bond92b96792009-06-13 07:38:31 -0400131
Malcolm Priestley6b5ad9d2013-08-21 22:16:04 +0100132static u16 s_uGetDataDuration(struct vnt_private *pDevice,
Malcolm Priestley3ed210e2013-08-07 21:28:45 +0100133 u8 byPktType, int bNeedAck);
Forest Bond92b96792009-06-13 07:38:31 -0400134
Malcolm Priestleye34f9db2013-08-13 20:17:11 +0100135static u16 s_uGetRTSCTSDuration(struct vnt_private *pDevice,
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000136 u8 byDurType, u32 cbFrameLength, u8 byPktType, u16 wRate,
137 int bNeedAck, u8 byFBOption);
Forest Bond92b96792009-06-13 07:38:31 -0400138
Malcolm Priestleyaceaf012013-11-26 19:06:35 +0000139static struct vnt_usb_send_context
Malcolm Priestleyb89f3b92013-11-26 19:16:59 +0000140 *s_vGetFreeContext(struct vnt_private *priv)
Forest Bond92b96792009-06-13 07:38:31 -0400141{
Malcolm Priestleyb89f3b92013-11-26 19:16:59 +0000142 struct vnt_usb_send_context *context = NULL;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000143 int ii;
Forest Bond92b96792009-06-13 07:38:31 -0400144
Malcolm Priestleyb89f3b92013-11-26 19:16:59 +0000145 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GetFreeContext()\n");
Forest Bond92b96792009-06-13 07:38:31 -0400146
Malcolm Priestleyb89f3b92013-11-26 19:16:59 +0000147 for (ii = 0; ii < priv->cbTD; ii++) {
148 if (!priv->apTD[ii])
149 return NULL;
150
151 context = priv->apTD[ii];
152 if (context->bBoolInUse == false) {
153 context->bBoolInUse = true;
154 memset(context->Data, 0,
155 MAX_TOTAL_SIZE_WITH_ALL_HEADERS);
156 return context;
157 }
158 }
159
160 if (ii == priv->cbTD)
161 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No Free Tx Context\n");
Malcolm Priestleyaceaf012013-11-26 19:06:35 +0000162
Malcolm Priestley5c851382013-11-26 19:12:38 +0000163 return NULL;
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 Priestleyae27b142013-12-09 22:23:19 +0000169 struct net_device_stats *stats = &pDevice->stats;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000170 PSStatCounter pStatistic = &pDevice->scStatistic;
Forest Bond92b96792009-06-13 07:38:31 -0400171
Andres More4b50fb42010-06-22 21:57:42 -0300172 if (is_broadcast_ether_addr(pbyDestAddr))
Forest Bond92b96792009-06-13 07:38:31 -0400173 pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni = TX_PKT_BROAD;
Andres More4b50fb42010-06-22 21:57:42 -0300174 else if (is_multicast_ether_addr(pbyDestAddr))
Forest Bond92b96792009-06-13 07:38:31 -0400175 pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni = TX_PKT_MULTI;
176 else
177 pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni = TX_PKT_UNI;
178
179 pStatistic->abyTxPktInfo[byPktNum].wLength = wPktLength;
180 pStatistic->abyTxPktInfo[byPktNum].wFIFOCtl = wFIFOCtl;
Andres More9a0e7562010-04-13 21:54:48 -0300181 memcpy(pStatistic->abyTxPktInfo[byPktNum].abyDestAddr,
182 pbyDestAddr,
183 ETH_ALEN);
Malcolm Priestleyae27b142013-12-09 22:23:19 +0000184
185 stats->tx_bytes += wPktLength;
Forest Bond92b96792009-06-13 07:38:31 -0400186}
187
Malcolm Priestley3ba09382013-10-15 21:41:38 +0100188static void s_vFillTxKey(struct vnt_private *pDevice,
189 struct vnt_tx_fifo_head *fifo_head, u8 *pbyIVHead,
190 PSKeyItem pTransmitKey, u8 *pbyHdrBuf, u16 wPayloadLen,
191 struct vnt_mic_hdr *mic_hdr)
Forest Bond92b96792009-06-13 07:38:31 -0400192{
Malcolm Priestley3ba09382013-10-15 21:41:38 +0100193 u8 *pbyBuf = (u8 *)&fifo_head->adwTxKey[0];
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000194 u32 *pdwIV = (u32 *)pbyIVHead;
195 u32 *pdwExtIV = (u32 *)((u8 *)pbyIVHead + 4);
Andres More1cac4a42013-03-18 20:33:50 -0500196 struct ieee80211_hdr *pMACHeader = (struct ieee80211_hdr *)pbyHdrBuf;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000197 u32 dwRevIVCounter;
Forest Bond92b96792009-06-13 07:38:31 -0400198
Malcolm Priestley95bfb1a2013-08-27 12:29:10 +0100199 /* Fill TXKEY */
200 if (pTransmitKey == NULL)
Malcolm Priestleyec37d8b2013-08-23 14:37:48 +0100201 return;
Forest Bond92b96792009-06-13 07:38:31 -0400202
Malcolm Priestley95bfb1a2013-08-27 12:29:10 +0100203 dwRevIVCounter = cpu_to_le32(pDevice->dwIVCounter);
204 *pdwIV = pDevice->dwIVCounter;
205 pDevice->byKeyIndex = pTransmitKey->dwKeyIndex & 0xf;
Forest Bond92b96792009-06-13 07:38:31 -0400206
Malcolm Priestleyf6804f32013-08-27 12:32:01 +0100207 switch (pTransmitKey->byCipherSuite) {
208 case KEY_CTL_WEP:
Malcolm Priestley95bfb1a2013-08-27 12:29:10 +0100209 if (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN) {
210 memcpy(pDevice->abyPRNG, (u8 *)&dwRevIVCounter, 3);
211 memcpy(pDevice->abyPRNG + 3, pTransmitKey->abyKey,
212 pTransmitKey->uKeyLength);
213 } else {
214 memcpy(pbyBuf, (u8 *)&dwRevIVCounter, 3);
215 memcpy(pbyBuf + 3, pTransmitKey->abyKey,
216 pTransmitKey->uKeyLength);
217 if (pTransmitKey->uKeyLength == WLAN_WEP40_KEYLEN) {
218 memcpy(pbyBuf+8, (u8 *)&dwRevIVCounter, 3);
219 memcpy(pbyBuf+11, pTransmitKey->abyKey,
220 pTransmitKey->uKeyLength);
221 }
Malcolm Priestleyec37d8b2013-08-23 14:37:48 +0100222
Malcolm Priestley95bfb1a2013-08-27 12:29:10 +0100223 memcpy(pDevice->abyPRNG, pbyBuf, 16);
224 }
225 /* Append IV after Mac Header */
226 *pdwIV &= WEP_IV_MASK;
227 *pdwIV |= (u32)pDevice->byKeyIndex << 30;
228 *pdwIV = cpu_to_le32(*pdwIV);
Malcolm Priestleyec37d8b2013-08-23 14:37:48 +0100229
Malcolm Priestley95bfb1a2013-08-27 12:29:10 +0100230 pDevice->dwIVCounter++;
231 if (pDevice->dwIVCounter > WEP_IV_MASK)
232 pDevice->dwIVCounter = 0;
Malcolm Priestleyf6804f32013-08-27 12:32:01 +0100233
234 break;
235 case KEY_CTL_TKIP:
Malcolm Priestley95bfb1a2013-08-27 12:29:10 +0100236 pTransmitKey->wTSC15_0++;
237 if (pTransmitKey->wTSC15_0 == 0)
238 pTransmitKey->dwTSC47_16++;
Malcolm Priestleyec37d8b2013-08-23 14:37:48 +0100239
Malcolm Priestley95bfb1a2013-08-27 12:29:10 +0100240 TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr,
241 pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16,
242 pDevice->abyPRNG);
243 memcpy(pbyBuf, pDevice->abyPRNG, 16);
244
245 /* Make IV */
246 memcpy(pdwIV, pDevice->abyPRNG, 3);
247
248 *(pbyIVHead+3) = (u8)(((pDevice->byKeyIndex << 6) &
249 0xc0) | 0x20);
250 /* Append IV&ExtIV after Mac Header */
251 *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16);
252
253 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
254 "vFillTxKey()---- pdwExtIV: %x\n", *pdwExtIV);
255
Malcolm Priestleyf6804f32013-08-27 12:32:01 +0100256 break;
257 case KEY_CTL_CCMP:
Malcolm Priestley95bfb1a2013-08-27 12:29:10 +0100258 pTransmitKey->wTSC15_0++;
259 if (pTransmitKey->wTSC15_0 == 0)
260 pTransmitKey->dwTSC47_16++;
261
262 memcpy(pbyBuf, pTransmitKey->abyKey, 16);
263
264 /* Make IV */
265 *pdwIV = 0;
266 *(pbyIVHead+3) = (u8)(((pDevice->byKeyIndex << 6) &
267 0xc0) | 0x20);
268
269 *pdwIV |= cpu_to_le16((u16)(pTransmitKey->wTSC15_0));
270
271 /* Append IV&ExtIV after Mac Header */
272 *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16);
273
274 if (!mic_hdr)
275 return;
276
277 /* MICHDR0 */
278 mic_hdr->id = 0x59;
279 mic_hdr->payload_len = cpu_to_be16(wPayloadLen);
280 memcpy(mic_hdr->mic_addr2, pMACHeader->addr2, ETH_ALEN);
281
282 mic_hdr->tsc_47_16 = cpu_to_be32(pTransmitKey->dwTSC47_16);
283 mic_hdr->tsc_15_0 = cpu_to_be16(pTransmitKey->wTSC15_0);
284
285 /* MICHDR1 */
Malcolm Priestley078d0cf2013-11-25 22:14:16 +0000286 if (ieee80211_has_a4(pMACHeader->frame_control))
Malcolm Priestley95bfb1a2013-08-27 12:29:10 +0100287 mic_hdr->hlen = cpu_to_be16(28);
288 else
289 mic_hdr->hlen = cpu_to_be16(22);
290
291 memcpy(mic_hdr->addr1, pMACHeader->addr1, ETH_ALEN);
292 memcpy(mic_hdr->addr2, pMACHeader->addr2, ETH_ALEN);
293
294 /* MICHDR2 */
295 memcpy(mic_hdr->addr3, pMACHeader->addr3, ETH_ALEN);
296 mic_hdr->frame_control = cpu_to_le16(pMACHeader->frame_control
Malcolm Priestleyec37d8b2013-08-23 14:37:48 +0100297 & 0xc78f);
Malcolm Priestley95bfb1a2013-08-27 12:29:10 +0100298 mic_hdr->seq_ctrl = cpu_to_le16(pMACHeader->seq_ctrl & 0xf);
Malcolm Priestleyec37d8b2013-08-23 14:37:48 +0100299
Malcolm Priestley078d0cf2013-11-25 22:14:16 +0000300 if (ieee80211_has_a4(pMACHeader->frame_control))
Malcolm Priestley95bfb1a2013-08-27 12:29:10 +0100301 memcpy(mic_hdr->addr4, pMACHeader->addr4, ETH_ALEN);
302 }
Forest Bond92b96792009-06-13 07:38:31 -0400303}
304
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000305static void s_vSWencryption(struct vnt_private *pDevice,
306 PSKeyItem pTransmitKey, u8 *pbyPayloadHead, u16 wPayloadSize)
Forest Bond92b96792009-06-13 07:38:31 -0400307{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000308 u32 cbICVlen = 4;
309 u32 dwICV = 0xffffffff;
310 u32 *pdwICV;
Forest Bond92b96792009-06-13 07:38:31 -0400311
312 if (pTransmitKey == NULL)
313 return;
314
315 if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
316 //=======================================================================
317 // Append ICV after payload
318 dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload)
Andres More52a7e642013-02-25 20:32:53 -0500319 pdwICV = (u32 *)(pbyPayloadHead + wPayloadSize);
Forest Bond92b96792009-06-13 07:38:31 -0400320 // finally, we must invert dwCRC to get the correct answer
321 *pdwICV = cpu_to_le32(~dwICV);
322 // RC4 encryption
323 rc4_init(&pDevice->SBox, pDevice->abyPRNG, pTransmitKey->uKeyLength + 3);
324 rc4_encrypt(&pDevice->SBox, pbyPayloadHead, pbyPayloadHead, wPayloadSize+cbICVlen);
325 //=======================================================================
326 } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
327 //=======================================================================
328 //Append ICV after payload
329 dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload)
Andres More52a7e642013-02-25 20:32:53 -0500330 pdwICV = (u32 *)(pbyPayloadHead + wPayloadSize);
Forest Bond92b96792009-06-13 07:38:31 -0400331 // finally, we must invert dwCRC to get the correct answer
332 *pdwICV = cpu_to_le32(~dwICV);
333 // RC4 encryption
334 rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN);
335 rc4_encrypt(&pDevice->SBox, pbyPayloadHead, pbyPayloadHead, wPayloadSize+cbICVlen);
336 //=======================================================================
337 }
338}
339
Malcolm Priestleyf115e762013-08-23 11:48:46 +0100340static u16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate)
341{
342 return cpu_to_le16(wTimeStampOff[priv->byPreambleType % 2]
343 [rate % MAX_RATE]);
344}
345
Forest Bond92b96792009-06-13 07:38:31 -0400346/*byPktType : PK_TYPE_11A 0
347 PK_TYPE_11B 1
348 PK_TYPE_11GB 2
349 PK_TYPE_11GA 3
350*/
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000351static u32 s_uGetTxRsvTime(struct vnt_private *pDevice, u8 byPktType,
352 u32 cbFrameLength, u16 wRate, int bNeedAck)
Forest Bond92b96792009-06-13 07:38:31 -0400353{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000354 u32 uDataTime, uAckTime;
Forest Bond92b96792009-06-13 07:38:31 -0400355
356 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wRate);
357 if (byPktType == PK_TYPE_11B) {//llb,CCK mode
Andres More3eaca0d2013-02-25 20:32:52 -0500358 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (u16)pDevice->byTopCCKBasicRate);
Forest Bond92b96792009-06-13 07:38:31 -0400359 } else {//11g 2.4G OFDM mode & 11a 5G OFDM mode
Andres More3eaca0d2013-02-25 20:32:52 -0500360 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (u16)pDevice->byTopOFDMBasicRate);
Forest Bond92b96792009-06-13 07:38:31 -0400361 }
362
363 if (bNeedAck) {
364 return (uDataTime + pDevice->uSIFS + uAckTime);
365 }
366 else {
367 return uDataTime;
368 }
369}
370
Malcolm Priestley9c3806d2013-08-23 11:32:26 +0100371static u16 vnt_rxtx_rsvtime_le16(struct vnt_private *priv, u8 pkt_type,
372 u32 frame_length, u16 rate, int need_ack)
373{
374 return cpu_to_le16((u16)s_uGetTxRsvTime(priv, pkt_type,
375 frame_length, rate, need_ack));
376}
377
Forest Bond92b96792009-06-13 07:38:31 -0400378//byFreqType: 0=>5GHZ 1=>2.4GHZ
Malcolm Priestleycfabe4b2013-08-22 21:03:40 +0100379static u16 s_uGetRTSCTSRsvTime(struct vnt_private *pDevice,
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000380 u8 byRTSRsvType, u8 byPktType, u32 cbFrameLength, u16 wCurrentRate)
Forest Bond92b96792009-06-13 07:38:31 -0400381{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000382 u32 uRrvTime, uRTSTime, uCTSTime, uAckTime, uDataTime;
Forest Bond92b96792009-06-13 07:38:31 -0400383
384 uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0;
385
Forest Bond92b96792009-06-13 07:38:31 -0400386 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wCurrentRate);
387 if (byRTSRsvType == 0) { //RTSTxRrvTime_bb
388 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
389 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
390 }
391 else if (byRTSRsvType == 1){ //RTSTxRrvTime_ba, only in 2.4GHZ
392 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
393 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
394 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
395 }
396 else if (byRTSRsvType == 2) { //RTSTxRrvTime_aa
397 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopOFDMBasicRate);
398 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
399 }
400 else if (byRTSRsvType == 3) { //CTSTxRrvTime_ba, only in 2.4GHZ
401 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
402 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
403 uRrvTime = uCTSTime + uAckTime + uDataTime + 2*pDevice->uSIFS;
404 return uRrvTime;
405 }
406
407 //RTSRrvTime
408 uRrvTime = uRTSTime + uCTSTime + uAckTime + uDataTime + 3*pDevice->uSIFS;
Malcolm Priestleycfabe4b2013-08-22 21:03:40 +0100409 return cpu_to_le16((u16)uRrvTime);
Forest Bond92b96792009-06-13 07:38:31 -0400410}
411
412//byFreqType 0: 5GHz, 1:2.4Ghz
Malcolm Priestley6b5ad9d2013-08-21 22:16:04 +0100413static u16 s_uGetDataDuration(struct vnt_private *pDevice,
414 u8 byPktType, int bNeedAck)
Forest Bond92b96792009-06-13 07:38:31 -0400415{
Malcolm Priestley0005cb02013-08-07 21:26:12 +0100416 u32 uAckTime = 0;
Forest Bond92b96792009-06-13 07:38:31 -0400417
Malcolm Priestleyb02ccd52013-08-13 19:59:31 +0100418 if (bNeedAck) {
Malcolm Priestley6b5ad9d2013-08-21 22:16:04 +0100419 if (byPktType == PK_TYPE_11B)
Malcolm Priestleyb02ccd52013-08-13 19:59:31 +0100420 uAckTime = BBuGetFrameTime(pDevice->byPreambleType,
421 byPktType, 14, pDevice->byTopCCKBasicRate);
422 else
423 uAckTime = BBuGetFrameTime(pDevice->byPreambleType,
424 byPktType, 14, pDevice->byTopOFDMBasicRate);
Malcolm Priestleyd5005952013-08-21 21:58:37 +0100425 return cpu_to_le16((u16)(pDevice->uSIFS + uAckTime));
Malcolm Priestleyb02ccd52013-08-13 19:59:31 +0100426 }
Forest Bond92b96792009-06-13 07:38:31 -0400427
Forest Bond92b96792009-06-13 07:38:31 -0400428 return 0;
429}
430
Forest Bond92b96792009-06-13 07:38:31 -0400431//byFreqType: 0=>5GHZ 1=>2.4GHZ
Malcolm Priestleye34f9db2013-08-13 20:17:11 +0100432static u16 s_uGetRTSCTSDuration(struct vnt_private *pDevice, u8 byDurType,
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000433 u32 cbFrameLength, u8 byPktType, u16 wRate, int bNeedAck,
434 u8 byFBOption)
Forest Bond92b96792009-06-13 07:38:31 -0400435{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000436 u32 uCTSTime = 0, uDurTime = 0;
Forest Bond92b96792009-06-13 07:38:31 -0400437
Malcolm Priestleyecd80242013-10-15 21:05:02 +0100438 switch (byDurType) {
439 case RTSDUR_BB:
440 case RTSDUR_BA:
441 case RTSDUR_BA_F0:
442 case RTSDUR_BA_F1:
443 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType,
444 14, pDevice->byTopCCKBasicRate);
445 uDurTime = uCTSTime + 2 * pDevice->uSIFS +
446 s_uGetTxRsvTime(pDevice, byPktType,
447 cbFrameLength, wRate, bNeedAck);
448 break;
Forest Bond92b96792009-06-13 07:38:31 -0400449
Malcolm Priestleyecd80242013-10-15 21:05:02 +0100450 case RTSDUR_AA:
451 case RTSDUR_AA_F0:
452 case RTSDUR_AA_F1:
453 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType,
454 14, pDevice->byTopOFDMBasicRate);
455 uDurTime = uCTSTime + 2 * pDevice->uSIFS +
456 s_uGetTxRsvTime(pDevice, byPktType,
457 cbFrameLength, wRate, bNeedAck);
458 break;
Forest Bond92b96792009-06-13 07:38:31 -0400459
Malcolm Priestleyecd80242013-10-15 21:05:02 +0100460 case CTSDUR_BA:
461 case CTSDUR_BA_F0:
462 case CTSDUR_BA_F1:
463 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice,
Malcolm Priestleyf84cdf62013-10-15 21:00:09 +0100464 byPktType, cbFrameLength, wRate, bNeedAck);
Malcolm Priestleyecd80242013-10-15 21:05:02 +0100465 break;
Forest Bond92b96792009-06-13 07:38:31 -0400466
Malcolm Priestleyecd80242013-10-15 21:05:02 +0100467 default:
468 break;
469 }
Forest Bond92b96792009-06-13 07:38:31 -0400470
Malcolm Priestleye34f9db2013-08-13 20:17:11 +0100471 return cpu_to_le16((u16)uDurTime);
Forest Bond92b96792009-06-13 07:38:31 -0400472}
473
Malcolm Priestley78363fd2013-10-01 15:52:16 +0100474static u16 vnt_rxtx_datahead_g(struct vnt_private *priv, u8 pkt_type, u16 rate,
475 struct vnt_tx_datahead_g *buf, u32 frame_len, int need_ack)
476{
477 /* Get SignalField,ServiceField,Length */
478 BBvCalculateParameter(priv, frame_len, rate, pkt_type, &buf->a);
479 BBvCalculateParameter(priv, frame_len, priv->byTopCCKBasicRate,
480 PK_TYPE_11B, &buf->b);
481
482 /* Get Duration and TimeStamp */
483 buf->wDuration_a = s_uGetDataDuration(priv, pkt_type, need_ack);
484 buf->wDuration_b = s_uGetDataDuration(priv, PK_TYPE_11B, need_ack);
485
486 buf->wTimeStampOff_a = vnt_time_stamp_off(priv, rate);
487 buf->wTimeStampOff_b = vnt_time_stamp_off(priv,
488 priv->byTopCCKBasicRate);
489
490 return buf->wDuration_a;
491}
492
Malcolm Priestley5b852f52013-10-01 15:54:56 +0100493static u16 vnt_rxtx_datahead_g_fb(struct vnt_private *priv, u8 pkt_type,
494 u16 rate, struct vnt_tx_datahead_g_fb *buf,
495 u32 frame_len, int need_ack)
496{
497 /* Get SignalField,ServiceField,Length */
498 BBvCalculateParameter(priv, frame_len, rate, pkt_type, &buf->a);
499
500 BBvCalculateParameter(priv, frame_len, priv->byTopCCKBasicRate,
501 PK_TYPE_11B, &buf->b);
502
503 /* Get Duration and TimeStamp */
504 buf->wDuration_a = s_uGetDataDuration(priv, pkt_type, need_ack);
505 buf->wDuration_b = s_uGetDataDuration(priv, PK_TYPE_11B, need_ack);
506
507 buf->wDuration_a_f0 = s_uGetDataDuration(priv, pkt_type, need_ack);
508 buf->wDuration_a_f1 = s_uGetDataDuration(priv, pkt_type, need_ack);
509
510 buf->wTimeStampOff_a = vnt_time_stamp_off(priv, rate);
511 buf->wTimeStampOff_b = vnt_time_stamp_off(priv,
512 priv->byTopCCKBasicRate);
513
514 return buf->wDuration_a;
515}
516
Malcolm Priestleybd3f51f2013-10-01 15:56:48 +0100517static u16 vnt_rxtx_datahead_a_fb(struct vnt_private *priv, u8 pkt_type,
518 u16 rate, struct vnt_tx_datahead_a_fb *buf,
519 u32 frame_len, int need_ack)
520{
521 /* Get SignalField,ServiceField,Length */
522 BBvCalculateParameter(priv, frame_len, rate, pkt_type, &buf->a);
523 /* Get Duration and TimeStampOff */
524 buf->wDuration = s_uGetDataDuration(priv, pkt_type, need_ack);
525
526 buf->wDuration_f0 = s_uGetDataDuration(priv, pkt_type, need_ack);
527 buf->wDuration_f1 = s_uGetDataDuration(priv, pkt_type, need_ack);
528
529 buf->wTimeStampOff = vnt_time_stamp_off(priv, rate);
530
531 return buf->wDuration;
532}
533
Malcolm Priestley5634a5a2013-10-01 16:00:20 +0100534static u16 vnt_rxtx_datahead_ab(struct vnt_private *priv, u8 pkt_type,
535 u16 rate, struct vnt_tx_datahead_ab *buf,
536 u32 frame_len, int need_ack)
537{
538 /* Get SignalField,ServiceField,Length */
539 BBvCalculateParameter(priv, frame_len, rate, pkt_type, &buf->ab);
540 /* Get Duration and TimeStampOff */
541 buf->wDuration = s_uGetDataDuration(priv, pkt_type, need_ack);
542
543 buf->wTimeStampOff = vnt_time_stamp_off(priv, rate);
544
545 return buf->wDuration;
546}
547
Malcolm Priestley5e67ee42013-08-26 11:04:50 +0100548static int vnt_fill_ieee80211_rts(struct vnt_private *priv,
549 struct ieee80211_rts *rts, struct ethhdr *eth_hdr,
550 u16 duration)
551{
552 rts->duration = duration;
553 rts->frame_control = TYPE_CTL_RTS;
554
555 if (priv->eOPMode == OP_MODE_ADHOC || priv->eOPMode == OP_MODE_AP)
556 memcpy(rts->ra, eth_hdr->h_dest, ETH_ALEN);
557 else
558 memcpy(rts->ra, priv->abyBSSID, ETH_ALEN);
559
560 if (priv->eOPMode == OP_MODE_AP)
561 memcpy(rts->ta, priv->abyBSSID, ETH_ALEN);
562 else
563 memcpy(rts->ta, eth_hdr->h_source, ETH_ALEN);
564
565 return 0;
566}
567
Malcolm Priestley0a0f4b62013-10-01 15:50:24 +0100568static u16 vnt_rxtx_rts_g_head(struct vnt_private *priv,
Malcolm Priestley5e67ee42013-08-26 11:04:50 +0100569 struct vnt_rts_g *buf, struct ethhdr *eth_hdr,
570 u8 pkt_type, u32 frame_len, int need_ack,
571 u16 current_rate, u8 fb_option)
572{
573 u16 rts_frame_len = 20;
574
575 BBvCalculateParameter(priv, rts_frame_len, priv->byTopCCKBasicRate,
576 PK_TYPE_11B, &buf->b);
577 BBvCalculateParameter(priv, rts_frame_len,
578 priv->byTopOFDMBasicRate, pkt_type, &buf->a);
579
580 buf->wDuration_bb = s_uGetRTSCTSDuration(priv, RTSDUR_BB, frame_len,
581 PK_TYPE_11B, priv->byTopCCKBasicRate, need_ack, fb_option);
582 buf->wDuration_aa = s_uGetRTSCTSDuration(priv, RTSDUR_AA, frame_len,
583 pkt_type, current_rate, need_ack, fb_option);
584 buf->wDuration_ba = s_uGetRTSCTSDuration(priv, RTSDUR_BA, frame_len,
585 pkt_type, current_rate, need_ack, fb_option);
586
587 vnt_fill_ieee80211_rts(priv, &buf->data, eth_hdr, buf->wDuration_aa);
588
Malcolm Priestley78363fd2013-10-01 15:52:16 +0100589 return vnt_rxtx_datahead_g(priv, pkt_type, current_rate,
590 &buf->data_head, frame_len, need_ack);
Malcolm Priestley5e67ee42013-08-26 11:04:50 +0100591}
592
Malcolm Priestley0a0f4b62013-10-01 15:50:24 +0100593static u16 vnt_rxtx_rts_g_fb_head(struct vnt_private *priv,
Malcolm Priestleyec917132013-08-26 11:07:46 +0100594 struct vnt_rts_g_fb *buf, struct ethhdr *eth_hdr,
595 u8 pkt_type, u32 frame_len, int need_ack,
596 u16 current_rate, u8 fb_option)
597{
598 u16 rts_frame_len = 20;
599
600 BBvCalculateParameter(priv, rts_frame_len, priv->byTopCCKBasicRate,
601 PK_TYPE_11B, &buf->b);
602 BBvCalculateParameter(priv, rts_frame_len,
603 priv->byTopOFDMBasicRate, pkt_type, &buf->a);
604
605
606 buf->wDuration_bb = s_uGetRTSCTSDuration(priv, RTSDUR_BB, frame_len,
607 PK_TYPE_11B, priv->byTopCCKBasicRate, need_ack, fb_option);
608 buf->wDuration_aa = s_uGetRTSCTSDuration(priv, RTSDUR_AA, frame_len,
609 pkt_type, current_rate, need_ack, fb_option);
610 buf->wDuration_ba = s_uGetRTSCTSDuration(priv, RTSDUR_BA, frame_len,
611 pkt_type, current_rate, need_ack, fb_option);
612
613
614 buf->wRTSDuration_ba_f0 = s_uGetRTSCTSDuration(priv, RTSDUR_BA_F0,
Malcolm Priestleyf84cdf62013-10-15 21:00:09 +0100615 frame_len, pkt_type, priv->tx_rate_fb0, need_ack, fb_option);
Malcolm Priestleyec917132013-08-26 11:07:46 +0100616 buf->wRTSDuration_aa_f0 = s_uGetRTSCTSDuration(priv, RTSDUR_AA_F0,
Malcolm Priestleyf84cdf62013-10-15 21:00:09 +0100617 frame_len, pkt_type, priv->tx_rate_fb0, need_ack, fb_option);
Malcolm Priestleyec917132013-08-26 11:07:46 +0100618 buf->wRTSDuration_ba_f1 = s_uGetRTSCTSDuration(priv, RTSDUR_BA_F1,
Malcolm Priestleyf84cdf62013-10-15 21:00:09 +0100619 frame_len, pkt_type, priv->tx_rate_fb1, need_ack, fb_option);
Malcolm Priestleyec917132013-08-26 11:07:46 +0100620 buf->wRTSDuration_aa_f1 = s_uGetRTSCTSDuration(priv, RTSDUR_AA_F1,
Malcolm Priestleyf84cdf62013-10-15 21:00:09 +0100621 frame_len, pkt_type, priv->tx_rate_fb1, need_ack, fb_option);
Malcolm Priestleyec917132013-08-26 11:07:46 +0100622
623 vnt_fill_ieee80211_rts(priv, &buf->data, eth_hdr, buf->wDuration_aa);
624
Malcolm Priestley5b852f52013-10-01 15:54:56 +0100625 return vnt_rxtx_datahead_g_fb(priv, pkt_type, current_rate,
626 &buf->data_head, frame_len, need_ack);
Malcolm Priestleyec917132013-08-26 11:07:46 +0100627}
628
Malcolm Priestley0a0f4b62013-10-01 15:50:24 +0100629static u16 vnt_rxtx_rts_ab_head(struct vnt_private *priv,
Malcolm Priestley17126332013-08-26 11:09:38 +0100630 struct vnt_rts_ab *buf, struct ethhdr *eth_hdr,
631 u8 pkt_type, u32 frame_len, int need_ack,
632 u16 current_rate, u8 fb_option)
633{
634 u16 rts_frame_len = 20;
635
636 BBvCalculateParameter(priv, rts_frame_len,
637 priv->byTopOFDMBasicRate, pkt_type, &buf->ab);
638
639 buf->wDuration = s_uGetRTSCTSDuration(priv, RTSDUR_AA, frame_len,
640 pkt_type, current_rate, need_ack, fb_option);
641
642 vnt_fill_ieee80211_rts(priv, &buf->data, eth_hdr, buf->wDuration);
643
Malcolm Priestley5634a5a2013-10-01 16:00:20 +0100644 return vnt_rxtx_datahead_ab(priv, pkt_type, current_rate,
645 &buf->data_head, frame_len, need_ack);
Malcolm Priestley17126332013-08-26 11:09:38 +0100646}
647
Malcolm Priestley0a0f4b62013-10-01 15:50:24 +0100648static u16 vnt_rxtx_rts_a_fb_head(struct vnt_private *priv,
Malcolm Priestley9d2578c2013-08-26 11:12:00 +0100649 struct vnt_rts_a_fb *buf, struct ethhdr *eth_hdr,
650 u8 pkt_type, u32 frame_len, int need_ack,
651 u16 current_rate, u8 fb_option)
652{
653 u16 rts_frame_len = 20;
654
655 BBvCalculateParameter(priv, rts_frame_len,
656 priv->byTopOFDMBasicRate, pkt_type, &buf->a);
657
658 buf->wDuration = s_uGetRTSCTSDuration(priv, RTSDUR_AA, frame_len,
659 pkt_type, current_rate, need_ack, fb_option);
660
661 buf->wRTSDuration_f0 = s_uGetRTSCTSDuration(priv, RTSDUR_AA_F0,
Malcolm Priestleyf84cdf62013-10-15 21:00:09 +0100662 frame_len, pkt_type, priv->tx_rate_fb0, need_ack, fb_option);
Malcolm Priestley9d2578c2013-08-26 11:12:00 +0100663
664 buf->wRTSDuration_f1 = s_uGetRTSCTSDuration(priv, RTSDUR_AA_F1,
Malcolm Priestleyf84cdf62013-10-15 21:00:09 +0100665 frame_len, pkt_type, priv->tx_rate_fb1, need_ack, fb_option);
Malcolm Priestley9d2578c2013-08-26 11:12:00 +0100666
667 vnt_fill_ieee80211_rts(priv, &buf->data, eth_hdr, buf->wDuration);
668
Malcolm Priestleybd3f51f2013-10-01 15:56:48 +0100669 return vnt_rxtx_datahead_a_fb(priv, pkt_type, current_rate,
670 &buf->data_head, frame_len, need_ack);
Malcolm Priestley9d2578c2013-08-26 11:12:00 +0100671}
672
Malcolm Priestley0a0f4b62013-10-01 15:50:24 +0100673static u16 s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
Malcolm Priestley5fb8e412013-08-27 12:07:58 +0100674 union vnt_tx_data_head *head, u32 cbFrameLength, int bNeedAck,
Andres Moreceb8c5d2013-03-18 20:33:49 -0500675 struct ethhdr *psEthHeader, u16 wCurrentRate, u8 byFBOption)
Forest Bond92b96792009-06-13 07:38:31 -0400676{
Forest Bond92b96792009-06-13 07:38:31 -0400677
Malcolm Priestley13fe62a2013-08-26 11:17:52 +0100678 if (!head)
Malcolm Priestley0a0f4b62013-10-01 15:50:24 +0100679 return 0;
Forest Bond92b96792009-06-13 07:38:31 -0400680
Malcolm Priestley9d5829b2013-08-26 11:21:11 +0100681 /* Note: So far RTSHead doesn't appear in ATIM
682 * & Beacom DMA, so we don't need to take them
683 * into account.
684 * Otherwise, we need to modified codes for them.
685 */
Malcolm Priestley0bddd302013-08-27 09:56:50 +0100686 switch (byPktType) {
687 case PK_TYPE_11GB:
688 case PK_TYPE_11GA:
Malcolm Priestley9d5829b2013-08-26 11:21:11 +0100689 if (byFBOption == AUTO_FB_NONE)
Malcolm Priestley78363fd2013-10-01 15:52:16 +0100690 return vnt_rxtx_rts_g_head(pDevice, &head->rts_g,
Malcolm Priestley5e67ee42013-08-26 11:04:50 +0100691 psEthHeader, byPktType, cbFrameLength,
692 bNeedAck, wCurrentRate, byFBOption);
Malcolm Priestley9d5829b2013-08-26 11:21:11 +0100693 else
Malcolm Priestley5b852f52013-10-01 15:54:56 +0100694 return vnt_rxtx_rts_g_fb_head(pDevice, &head->rts_g_fb,
Malcolm Priestleyec917132013-08-26 11:07:46 +0100695 psEthHeader, byPktType, cbFrameLength,
696 bNeedAck, wCurrentRate, byFBOption);
Malcolm Priestley0bddd302013-08-27 09:56:50 +0100697 break;
698 case PK_TYPE_11A:
Malcolm Priestley2b83ebd2013-08-27 09:58:21 +0100699 if (byFBOption) {
Malcolm Priestleybd3f51f2013-10-01 15:56:48 +0100700 return vnt_rxtx_rts_a_fb_head(pDevice, &head->rts_a_fb,
Malcolm Priestley9d5829b2013-08-26 11:21:11 +0100701 psEthHeader, byPktType, cbFrameLength,
702 bNeedAck, wCurrentRate, byFBOption);
Malcolm Priestley2b83ebd2013-08-27 09:58:21 +0100703 break;
704 }
Malcolm Priestley0bddd302013-08-27 09:56:50 +0100705 case PK_TYPE_11B:
Malcolm Priestley5634a5a2013-10-01 16:00:20 +0100706 return vnt_rxtx_rts_ab_head(pDevice, &head->rts_ab,
Malcolm Priestley17126332013-08-26 11:09:38 +0100707 psEthHeader, byPktType, cbFrameLength,
708 bNeedAck, wCurrentRate, byFBOption);
Malcolm Priestley9d5829b2013-08-26 11:21:11 +0100709 }
Malcolm Priestley0a0f4b62013-10-01 15:50:24 +0100710
711 return 0;
Forest Bond92b96792009-06-13 07:38:31 -0400712}
713
Malcolm Priestley0a0f4b62013-10-01 15:50:24 +0100714static u16 s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
Malcolm Priestley5fb8e412013-08-27 12:07:58 +0100715 u8 byPktType, union vnt_tx_data_head *head, u32 cbFrameLength,
716 int bNeedAck, u16 wCurrentRate, u8 byFBOption)
Forest Bond92b96792009-06-13 07:38:31 -0400717{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000718 u32 uCTSFrameLen = 14;
Forest Bond92b96792009-06-13 07:38:31 -0400719
Malcolm Priestley27df3eb2013-08-27 11:48:34 +0100720 if (!head)
Malcolm Priestley0a0f4b62013-10-01 15:50:24 +0100721 return 0;
Forest Bond92b96792009-06-13 07:38:31 -0400722
Malcolm Priestleyc921cc82013-08-20 20:47:49 +0100723 if (byFBOption != AUTO_FB_NONE) {
724 /* Auto Fall back */
Malcolm Priestley27df3eb2013-08-27 11:48:34 +0100725 struct vnt_cts_fb *pBuf = &head->cts_g_fb;
Malcolm Priestleyaed387c2013-08-20 22:52:30 +0100726 /* Get SignalField,ServiceField,Length */
727 BBvCalculateParameter(pDevice, uCTSFrameLen,
728 pDevice->byTopCCKBasicRate, PK_TYPE_11B, &pBuf->b);
Malcolm Priestleye34f9db2013-08-13 20:17:11 +0100729 pBuf->wDuration_ba = s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
730 cbFrameLength, byPktType,
731 wCurrentRate, bNeedAck, byFBOption);
732 /* Get CTSDuration_ba_f0 */
733 pBuf->wCTSDuration_ba_f0 = s_uGetRTSCTSDuration(pDevice,
Malcolm Priestleyf84cdf62013-10-15 21:00:09 +0100734 CTSDUR_BA_F0, cbFrameLength, byPktType,
735 pDevice->tx_rate_fb0, bNeedAck, byFBOption);
Malcolm Priestleye34f9db2013-08-13 20:17:11 +0100736 /* Get CTSDuration_ba_f1 */
737 pBuf->wCTSDuration_ba_f1 = s_uGetRTSCTSDuration(pDevice,
Malcolm Priestleyf84cdf62013-10-15 21:00:09 +0100738 CTSDUR_BA_F1, cbFrameLength, byPktType,
739 pDevice->tx_rate_fb1, bNeedAck, byFBOption);
Malcolm Priestley14840cd2013-08-05 22:12:42 +0100740 /* Get CTS Frame body */
741 pBuf->data.duration = pBuf->wDuration_ba;
742 pBuf->data.frame_control = TYPE_CTL_CTS;
743 memcpy(pBuf->data.ra, pDevice->abyCurrentNetAddr, ETH_ALEN);
Malcolm Priestley5b852f52013-10-01 15:54:56 +0100744
745 return vnt_rxtx_datahead_g_fb(pDevice, byPktType, wCurrentRate,
746 &pBuf->data_head, cbFrameLength, bNeedAck);
Malcolm Priestleyc921cc82013-08-20 20:47:49 +0100747 } else {
Malcolm Priestley27df3eb2013-08-27 11:48:34 +0100748 struct vnt_cts *pBuf = &head->cts_g;
Malcolm Priestleyaed387c2013-08-20 22:52:30 +0100749 /* Get SignalField,ServiceField,Length */
750 BBvCalculateParameter(pDevice, uCTSFrameLen,
751 pDevice->byTopCCKBasicRate, PK_TYPE_11B, &pBuf->b);
Malcolm Priestleye34f9db2013-08-13 20:17:11 +0100752 /* Get CTSDuration_ba */
753 pBuf->wDuration_ba = s_uGetRTSCTSDuration(pDevice,
754 CTSDUR_BA, cbFrameLength, byPktType,
755 wCurrentRate, bNeedAck, byFBOption);
Malcolm Priestley14840cd2013-08-05 22:12:42 +0100756 /*Get CTS Frame body*/
757 pBuf->data.duration = pBuf->wDuration_ba;
758 pBuf->data.frame_control = TYPE_CTL_CTS;
759 memcpy(pBuf->data.ra, pDevice->abyCurrentNetAddr, ETH_ALEN);
Malcolm Priestley78363fd2013-10-01 15:52:16 +0100760
761 return vnt_rxtx_datahead_g(pDevice, byPktType, wCurrentRate,
762 &pBuf->data_head, cbFrameLength, bNeedAck);
Forest Bond92b96792009-06-13 07:38:31 -0400763 }
Malcolm Priestley0a0f4b62013-10-01 15:50:24 +0100764
765 return 0;
Forest Bond92b96792009-06-13 07:38:31 -0400766}
767
Forest Bond92b96792009-06-13 07:38:31 -0400768/*+
769 *
770 * Description:
771 * Generate FIFO control for MAC & Baseband controller
772 *
773 * Parameters:
774 * In:
775 * pDevice - Pointer to adpater
776 * pTxDataHead - Transmit Data Buffer
777 * pTxBufHead - pTxBufHead
778 * pvRrvTime - pvRrvTime
779 * pvRTS - RTS Buffer
780 * pCTS - CTS Buffer
781 * cbFrameSize - Transmit Data Length (Hdr+Payload+FCS)
782 * bNeedACK - If need ACK
783 * uDMAIdx - DMA Index
784 * Out:
785 * none
786 *
787 * Return Value: none
788 *
789-*/
Andres Morecc856e62010-05-17 21:34:01 -0300790
Malcolm Priestley0a0f4b62013-10-01 15:50:24 +0100791static u16 s_vGenerateTxParameter(struct vnt_private *pDevice,
Malcolm Priestley8e344c82013-09-17 19:58:11 +0100792 u8 byPktType, u16 wCurrentRate, struct vnt_tx_buffer *tx_buffer,
Malcolm Priestleyfa575602013-09-26 19:00:41 +0100793 struct vnt_mic_hdr **mic_hdr, u32 need_mic, u32 cbFrameSize,
794 int bNeedACK, u32 uDMAIdx, struct ethhdr *psEthHeader, bool need_rts)
Forest Bond92b96792009-06-13 07:38:31 -0400795{
Malcolm Priestley8e344c82013-09-17 19:58:11 +0100796 struct vnt_tx_fifo_head *pFifoHead = &tx_buffer->fifo_head;
Malcolm Priestleyb9cc2fc2013-09-26 18:57:34 +0100797 union vnt_tx_data_head *head = NULL;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000798 u16 wFifoCtl;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000799 u8 byFBOption = AUTO_FB_NONE;
Forest Bond92b96792009-06-13 07:38:31 -0400800
Malcolm Priestley92928f12013-10-07 20:14:01 +0100801 pFifoHead->wReserved = wCurrentRate;
802 wFifoCtl = pFifoHead->wFIFOCtl;
Forest Bond92b96792009-06-13 07:38:31 -0400803
Malcolm Priestley92928f12013-10-07 20:14:01 +0100804 if (wFifoCtl & FIFOCTL_AUTO_FB_0)
805 byFBOption = AUTO_FB_0;
806 else if (wFifoCtl & FIFOCTL_AUTO_FB_1)
807 byFBOption = AUTO_FB_1;
Forest Bond92b96792009-06-13 07:38:31 -0400808
Malcolm Priestley9e38a5c2013-09-26 18:47:25 +0100809 if (!pFifoHead)
Malcolm Priestley0a0f4b62013-10-01 15:50:24 +0100810 return 0;
Malcolm Priestley2dc22d52013-08-24 13:15:32 +0100811
Malcolm Priestley92928f12013-10-07 20:14:01 +0100812 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
813 if (need_rts) {
814 struct vnt_rrv_time_rts *pBuf =
815 &tx_buffer->tx_head.tx_rts.rts;
Malcolm Priestley9e38a5c2013-09-26 18:47:25 +0100816
Malcolm Priestley92928f12013-10-07 20:14:01 +0100817 pBuf->wRTSTxRrvTime_aa = s_uGetRTSCTSRsvTime(pDevice, 2,
818 byPktType, cbFrameSize, wCurrentRate);
819 pBuf->wRTSTxRrvTime_ba = s_uGetRTSCTSRsvTime(pDevice, 1,
820 byPktType, cbFrameSize, wCurrentRate);
821 pBuf->wRTSTxRrvTime_bb = s_uGetRTSCTSRsvTime(pDevice, 0,
Malcolm Priestleycfabe4b2013-08-22 21:03:40 +0100822 byPktType, cbFrameSize, wCurrentRate);
Malcolm Priestleyb9cc2fc2013-09-26 18:57:34 +0100823
Malcolm Priestley92928f12013-10-07 20:14:01 +0100824 pBuf->wTxRrvTime_a = vnt_rxtx_rsvtime_le16(pDevice,
825 byPktType, cbFrameSize, wCurrentRate, bNeedACK);
826 pBuf->wTxRrvTime_b = vnt_rxtx_rsvtime_le16(pDevice,
827 PK_TYPE_11B, cbFrameSize,
828 pDevice->byTopCCKBasicRate, bNeedACK);
829
830 if (need_mic) {
831 *mic_hdr = &tx_buffer->
832 tx_head.tx_rts.tx.mic.hdr;
833 head = &tx_buffer->tx_head.tx_rts.tx.mic.head;
834 } else {
835 head = &tx_buffer->tx_head.tx_rts.tx.head;
836 }
837
838 /* Fill RTS */
839 return s_vFillRTSHead(pDevice, byPktType, head,
840 cbFrameSize, bNeedACK, psEthHeader,
841 wCurrentRate, byFBOption);
842
Malcolm Priestleyb9cc2fc2013-09-26 18:57:34 +0100843 } else {
Malcolm Priestley92928f12013-10-07 20:14:01 +0100844 struct vnt_rrv_time_cts *pBuf = &tx_buffer->
845 tx_head.tx_cts.cts;
846
847 pBuf->wTxRrvTime_a = vnt_rxtx_rsvtime_le16(pDevice,
848 byPktType, cbFrameSize, wCurrentRate, bNeedACK);
849 pBuf->wTxRrvTime_b = vnt_rxtx_rsvtime_le16(pDevice,
850 PK_TYPE_11B, cbFrameSize,
851 pDevice->byTopCCKBasicRate, bNeedACK);
852
853 pBuf->wCTSTxRrvTime_ba = s_uGetRTSCTSRsvTime(pDevice, 3,
854 byPktType, cbFrameSize, wCurrentRate);
855
856 if (need_mic) {
857 *mic_hdr = &tx_buffer->
858 tx_head.tx_cts.tx.mic.hdr;
859 head = &tx_buffer->tx_head.tx_cts.tx.mic.head;
860 } else {
861 head = &tx_buffer->tx_head.tx_cts.tx.head;
862 }
863
864 /* Fill CTS */
865 return s_vFillCTSHead(pDevice, uDMAIdx, byPktType,
866 head, cbFrameSize, bNeedACK, wCurrentRate,
867 byFBOption);
868 }
869 } else if (byPktType == PK_TYPE_11A) {
870 if (need_mic) {
871 *mic_hdr = &tx_buffer->tx_head.tx_ab.tx.mic.hdr;
872 head = &tx_buffer->tx_head.tx_ab.tx.mic.head;
873 } else {
874 head = &tx_buffer->tx_head.tx_ab.tx.head;
Malcolm Priestleyb9cc2fc2013-09-26 18:57:34 +0100875 }
Malcolm Priestleyf0e0d502013-09-26 18:52:10 +0100876
Malcolm Priestley92928f12013-10-07 20:14:01 +0100877 if (need_rts) {
878 struct vnt_rrv_time_ab *pBuf = &tx_buffer->
879 tx_head.tx_ab.ab;
Malcolm Priestley9e38a5c2013-09-26 18:47:25 +0100880
Malcolm Priestley92928f12013-10-07 20:14:01 +0100881 pBuf->wRTSTxRrvTime = s_uGetRTSCTSRsvTime(pDevice, 2,
Malcolm Priestleycfabe4b2013-08-22 21:03:40 +0100882 byPktType, cbFrameSize, wCurrentRate);
Malcolm Priestleyf0e0d502013-09-26 18:52:10 +0100883
Malcolm Priestley92928f12013-10-07 20:14:01 +0100884 pBuf->wTxRrvTime = vnt_rxtx_rsvtime_le16(pDevice,
885 byPktType, cbFrameSize, wCurrentRate, bNeedACK);
886
887 /* Fill RTS */
888 return s_vFillRTSHead(pDevice, byPktType, head,
889 cbFrameSize, bNeedACK, psEthHeader,
890 wCurrentRate, byFBOption);
Malcolm Priestleyb9cc2fc2013-09-26 18:57:34 +0100891 } else {
Malcolm Priestley92928f12013-10-07 20:14:01 +0100892 struct vnt_rrv_time_ab *pBuf = &tx_buffer->
893 tx_head.tx_ab.ab;
894
895 pBuf->wTxRrvTime = vnt_rxtx_rsvtime_le16(pDevice,
896 PK_TYPE_11A, cbFrameSize,
897 wCurrentRate, bNeedACK);
898
899 return vnt_rxtx_datahead_a_fb(pDevice, byPktType,
900 wCurrentRate, &head->data_head_a_fb,
901 cbFrameSize, bNeedACK);
902 }
903 } else if (byPktType == PK_TYPE_11B) {
904 if (need_mic) {
905 *mic_hdr = &tx_buffer->tx_head.tx_ab.tx.mic.hdr;
906 head = &tx_buffer->tx_head.tx_ab.tx.mic.head;
907 } else {
908 head = &tx_buffer->tx_head.tx_ab.tx.head;
Malcolm Priestleyb9cc2fc2013-09-26 18:57:34 +0100909 }
Malcolm Priestleyf0e0d502013-09-26 18:52:10 +0100910
Malcolm Priestley92928f12013-10-07 20:14:01 +0100911 if (need_rts) {
912 struct vnt_rrv_time_ab *pBuf = &tx_buffer->
913 tx_head.tx_ab.ab;
Malcolm Priestleya90186e2013-10-01 15:58:54 +0100914
Malcolm Priestley92928f12013-10-07 20:14:01 +0100915 pBuf->wRTSTxRrvTime = s_uGetRTSCTSRsvTime(pDevice, 0,
Malcolm Priestleycfabe4b2013-08-22 21:03:40 +0100916 byPktType, cbFrameSize, wCurrentRate);
Malcolm Priestleyb9cc2fc2013-09-26 18:57:34 +0100917
Malcolm Priestley92928f12013-10-07 20:14:01 +0100918 pBuf->wTxRrvTime = vnt_rxtx_rsvtime_le16(pDevice,
919 PK_TYPE_11B, cbFrameSize, wCurrentRate,
920 bNeedACK);
921
922 /* Fill RTS */
923 return s_vFillRTSHead(pDevice, byPktType, head,
924 cbFrameSize,
Malcolm Priestley351c7dc2013-08-27 12:02:54 +0100925 bNeedACK, psEthHeader, wCurrentRate, byFBOption);
Malcolm Priestley92928f12013-10-07 20:14:01 +0100926 } else {
927 struct vnt_rrv_time_ab *pBuf = &tx_buffer->
928 tx_head.tx_ab.ab;
Malcolm Priestley9e38a5c2013-09-26 18:47:25 +0100929
Malcolm Priestley92928f12013-10-07 20:14:01 +0100930 pBuf->wTxRrvTime = vnt_rxtx_rsvtime_le16(pDevice,
931 PK_TYPE_11B, cbFrameSize,
932 wCurrentRate, bNeedACK);
Malcolm Priestleya90186e2013-10-01 15:58:54 +0100933
Malcolm Priestley92928f12013-10-07 20:14:01 +0100934 return vnt_rxtx_datahead_ab(pDevice, byPktType,
935 wCurrentRate, &head->data_head_ab,
936 cbFrameSize, bNeedACK);
937 }
Malcolm Priestleyc12dca02013-10-01 16:03:40 +0100938 }
939
Malcolm Priestley0a0f4b62013-10-01 15:50:24 +0100940 return 0;
Forest Bond92b96792009-06-13 07:38:31 -0400941}
942/*
Andres Moreb902fbf2013-02-25 20:32:51 -0500943 u8 * pbyBuffer,//point to pTxBufHead
Andres More3eaca0d2013-02-25 20:32:52 -0500944 u16 wFragType,//00:Non-Frag, 01:Start, 02:Mid, 03:Last
Andres Morecc856e62010-05-17 21:34:01 -0300945 unsigned int cbFragmentSize,//Hdr+payoad+FCS
Forest Bond92b96792009-06-13 07:38:31 -0400946*/
947
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000948static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
Malcolm Priestleyd66caad2013-09-17 19:54:35 +0100949 struct vnt_tx_buffer *tx_buffer, int bNeedEncryption,
Malcolm Priestleyd0a2b8f2013-08-15 19:37:04 +0100950 u32 uSkbPacketLen, u32 uDMAIdx, struct ethhdr *psEthHeader,
951 u8 *pPacket, PSKeyItem pTransmitKey, u32 uNodeIndex, u16 wCurrentRate,
952 u32 *pcbHeaderLen, u32 *pcbTotalLen)
Forest Bond92b96792009-06-13 07:38:31 -0400953{
Malcolm Priestleyd66caad2013-09-17 19:54:35 +0100954 struct vnt_tx_fifo_head *pTxBufHead = &tx_buffer->fifo_head;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000955 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
956 u32 cbFrameSize, cbFrameBodySize;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000957 u32 cb802_1_H_len;
958 u32 cbIVlen = 0, cbICVlen = 0, cbMIClen = 0, cbMACHdLen = 0;
959 u32 cbFCSlen = 4, cbMICHDR = 0;
Malcolm Priestleyf46142b2013-08-27 11:56:33 +0100960 int bNeedACK;
961 bool bRTS = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000962 u8 *pbyType, *pbyMacHdr, *pbyIVHead, *pbyPayloadHead, *pbyTxBufferAddr;
963 u8 abySNAP_RFC1042[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
964 u8 abySNAP_Bridgetunnel[ETH_ALEN]
965 = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8};
966 u32 uDuration;
967 u32 cbHeaderLength = 0, uPadding = 0;
Malcolm Priestley5a5d6a82013-08-23 14:33:55 +0100968 struct vnt_mic_hdr *pMICHDR;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000969 u8 byFBOption = AUTO_FB_NONE, byFragType;
970 u16 wTxBufSize;
Malcolm Priestley4235f722013-08-24 12:42:01 +0100971 u32 dwMICKey0, dwMICKey1, dwMIC_Priority;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000972 u32 *pdwMIC_L, *pdwMIC_R;
Andres Moree269fc22013-02-12 20:36:29 -0500973 int bSoftWEP = false;
Malcolm Priestley9e38a5c2013-09-26 18:47:25 +0100974
Malcolm Priestleyc545e6a2013-10-01 16:07:25 +0100975 pMICHDR = NULL;
Forest Bond92b96792009-06-13 07:38:31 -0400976
Malcolm Priestleye2efba72012-11-11 15:20:52 +0000977 if (bNeedEncryption && pTransmitKey->pvKeyTable) {
Andres More4e9b5e22013-02-12 20:36:30 -0500978 if (((PSKeyTable)pTransmitKey->pvKeyTable)->bSoftWEP == true)
979 bSoftWEP = true; /* WEP 256 */
Malcolm Priestleye2efba72012-11-11 15:20:52 +0000980 }
Forest Bond92b96792009-06-13 07:38:31 -0400981
Malcolm Priestleyc47b0a32013-11-24 11:51:49 +0000982 /* Get pkt type */
983 if (ntohs(psEthHeader->h_proto) > ETH_DATA_LEN)
984 cb802_1_H_len = 8;
985 else
986 cb802_1_H_len = 0;
Forest Bond92b96792009-06-13 07:38:31 -0400987
Charles Clément21ec51f2010-05-18 10:08:14 -0700988 cbFrameBodySize = uSkbPacketLen - ETH_HLEN + cb802_1_H_len;
Forest Bond92b96792009-06-13 07:38:31 -0400989
990 //Set packet type
Andres More3eaca0d2013-02-25 20:32:52 -0500991 pTxBufHead->wFIFOCtl |= (u16)(byPktType<<8);
Forest Bond92b96792009-06-13 07:38:31 -0400992
Andres More22040bb2010-08-02 20:21:44 -0300993 if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
Malcolm Priestleyc47b0a32013-11-24 11:51:49 +0000994 (pDevice->eOPMode == OP_MODE_AP)) {
Andres Moreceb8c5d2013-03-18 20:33:49 -0500995 if (is_multicast_ether_addr(psEthHeader->h_dest)) {
Andres Moree269fc22013-02-12 20:36:29 -0500996 bNeedACK = false;
Andres More22040bb2010-08-02 20:21:44 -0300997 pTxBufHead->wFIFOCtl =
998 pTxBufHead->wFIFOCtl & (~FIFOCTL_NEEDACK);
999 } else {
Andres More4e9b5e22013-02-12 20:36:30 -05001000 bNeedACK = true;
Andres More22040bb2010-08-02 20:21:44 -03001001 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
1002 }
Malcolm Priestleyc47b0a32013-11-24 11:51:49 +00001003 } else {
1004 /* MSDUs in Infra mode always need ACK */
1005 bNeedACK = true;
1006 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
1007 }
Forest Bond92b96792009-06-13 07:38:31 -04001008
1009 pTxBufHead->wTimeStamp = DEFAULT_MSDU_LIFETIME_RES_64us;
1010
Forest Bond92b96792009-06-13 07:38:31 -04001011 //Set FRAGCTL_MACHDCNT
Malcolm Priestley078d0cf2013-11-25 22:14:16 +00001012 cbMACHdLen = WLAN_HDR_ADDR3_LEN;
1013
Andres More3eaca0d2013-02-25 20:32:52 -05001014 pTxBufHead->wFragCtl |= (u16)(cbMACHdLen << 10);
Forest Bond92b96792009-06-13 07:38:31 -04001015
1016 //Set FIFOCTL_GrpAckPolicy
Andres More4e9b5e22013-02-12 20:36:30 -05001017 if (pDevice->bGrpAckPolicy == true) {//0000 0100 0000 0000
Forest Bond92b96792009-06-13 07:38:31 -04001018 pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK;
1019 }
1020
Malcolm Priestleyf84cdf62013-10-15 21:00:09 +01001021 /* Set Auto Fallback Ctl */
1022 if (wCurrentRate >= RATE_18M) {
1023 if (pDevice->byAutoFBCtrl == AUTO_FB_0) {
1024 pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_0;
1025
1026 pDevice->tx_rate_fb0 =
1027 wFB_Opt0[FB_RATE0][wCurrentRate - RATE_18M];
1028 pDevice->tx_rate_fb1 =
1029 wFB_Opt0[FB_RATE1][wCurrentRate - RATE_18M];
1030
1031 byFBOption = AUTO_FB_0;
1032 } else if (pDevice->byAutoFBCtrl == AUTO_FB_1) {
1033 pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_1;
1034 pDevice->tx_rate_fb0 =
1035 wFB_Opt1[FB_RATE0][wCurrentRate - RATE_18M];
1036 pDevice->tx_rate_fb1 =
1037 wFB_Opt1[FB_RATE1][wCurrentRate - RATE_18M];
1038
1039 byFBOption = AUTO_FB_1;
1040 }
1041 }
Forest Bond92b96792009-06-13 07:38:31 -04001042
Andres More4e9b5e22013-02-12 20:36:30 -05001043 if (bSoftWEP != true) {
Forest Bond92b96792009-06-13 07:38:31 -04001044 if ((bNeedEncryption) && (pTransmitKey != NULL)) { //WEP enabled
1045 if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { //WEP40 or WEP104
1046 pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
1047 }
1048 if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
1049 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Tx Set wFragCtl == FRAGCTL_TKIP\n");
1050 pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
1051 }
1052 else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { //CCMP
1053 pTxBufHead->wFragCtl |= FRAGCTL_AES;
1054 }
1055 }
1056 }
1057
Forest Bond92b96792009-06-13 07:38:31 -04001058 if ((bNeedEncryption) && (pTransmitKey != NULL)) {
1059 if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
1060 cbIVlen = 4;
1061 cbICVlen = 4;
1062 }
1063 else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
1064 cbIVlen = 8;//IV+ExtIV
1065 cbMIClen = 8;
1066 cbICVlen = 4;
1067 }
1068 if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) {
1069 cbIVlen = 8;//RSN Header
1070 cbICVlen = 8;//MIC
Malcolm Priestley5a5d6a82013-08-23 14:33:55 +01001071 cbMICHDR = sizeof(struct vnt_mic_hdr);
Forest Bond92b96792009-06-13 07:38:31 -04001072 }
Andres Moree269fc22013-02-12 20:36:29 -05001073 if (bSoftWEP == false) {
Forest Bond92b96792009-06-13 07:38:31 -04001074 //MAC Header should be padding 0 to DW alignment.
1075 uPadding = 4 - (cbMACHdLen%4);
1076 uPadding %= 4;
1077 }
1078 }
1079
1080 cbFrameSize = cbMACHdLen + cbIVlen + (cbFrameBodySize + cbMIClen) + cbICVlen + cbFCSlen;
1081
Andres Moree269fc22013-02-12 20:36:29 -05001082 if ( (bNeedACK == false) ||(cbFrameSize < pDevice->wRTSThreshold) ) {
1083 bRTS = false;
Forest Bond92b96792009-06-13 07:38:31 -04001084 } else {
Andres More4e9b5e22013-02-12 20:36:30 -05001085 bRTS = true;
Forest Bond92b96792009-06-13 07:38:31 -04001086 pTxBufHead->wFIFOCtl |= (FIFOCTL_RTS | FIFOCTL_LRETRY);
1087 }
1088
Andres Moreb902fbf2013-02-25 20:32:51 -05001089 pbyTxBufferAddr = (u8 *) &(pTxBufHead->adwTxKey[0]);
Malcolm Priestleyd66caad2013-09-17 19:54:35 +01001090 wTxBufSize = sizeof(struct vnt_tx_fifo_head);
1091
Forest Bond92b96792009-06-13 07:38:31 -04001092 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
1093 if (byFBOption == AUTO_FB_NONE) {
Andres More4e9b5e22013-02-12 20:36:30 -05001094 if (bRTS == true) {//RTS_need
Malcolm Priestley6398a592013-08-16 21:26:55 +01001095 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
Malcolm Priestley78363fd2013-10-01 15:52:16 +01001096 cbMICHDR + sizeof(struct vnt_rts_g);
Forest Bond92b96792009-06-13 07:38:31 -04001097 }
1098 else { //RTS_needless
Malcolm Priestley4f990052013-08-16 23:38:57 +01001099 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
Malcolm Priestley78363fd2013-10-01 15:52:16 +01001100 cbMICHDR + sizeof(struct vnt_cts);
Forest Bond92b96792009-06-13 07:38:31 -04001101 }
1102 } else {
1103 // Auto Fall Back
Andres More4e9b5e22013-02-12 20:36:30 -05001104 if (bRTS == true) {//RTS_need
Malcolm Priestley6398a592013-08-16 21:26:55 +01001105 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
Malcolm Priestley5b852f52013-10-01 15:54:56 +01001106 cbMICHDR + sizeof(struct vnt_rts_g_fb);
Forest Bond92b96792009-06-13 07:38:31 -04001107 }
Andres Moree269fc22013-02-12 20:36:29 -05001108 else if (bRTS == false) { //RTS_needless
Malcolm Priestley4f990052013-08-16 23:38:57 +01001109 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
Malcolm Priestley5b852f52013-10-01 15:54:56 +01001110 cbMICHDR + sizeof(struct vnt_cts_fb);
Forest Bond92b96792009-06-13 07:38:31 -04001111 }
1112 } // Auto Fall Back
1113 }
1114 else {//802.11a/b packet
1115 if (byFBOption == AUTO_FB_NONE) {
Andres More4e9b5e22013-02-12 20:36:30 -05001116 if (bRTS == true) {//RTS_need
Malcolm Priestley976467d2013-08-16 23:44:04 +01001117 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
Malcolm Priestley5634a5a2013-10-01 16:00:20 +01001118 cbMICHDR + sizeof(struct vnt_rts_ab);
Forest Bond92b96792009-06-13 07:38:31 -04001119 }
Andres Moree269fc22013-02-12 20:36:29 -05001120 else if (bRTS == false) { //RTS_needless, no MICHDR
Malcolm Priestley976467d2013-08-16 23:44:04 +01001121 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
Malcolm Priestley558becf2013-08-16 23:50:32 +01001122 cbMICHDR + sizeof(struct vnt_tx_datahead_ab);
Forest Bond92b96792009-06-13 07:38:31 -04001123 }
1124 } else {
1125 // Auto Fall Back
Andres More4e9b5e22013-02-12 20:36:30 -05001126 if (bRTS == true) {//RTS_need
Malcolm Priestley976467d2013-08-16 23:44:04 +01001127 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
Malcolm Priestleybd3f51f2013-10-01 15:56:48 +01001128 cbMICHDR + sizeof(struct vnt_rts_a_fb);
Forest Bond92b96792009-06-13 07:38:31 -04001129 }
Andres Moree269fc22013-02-12 20:36:29 -05001130 else if (bRTS == false) { //RTS_needless
Malcolm Priestley976467d2013-08-16 23:44:04 +01001131 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
Malcolm Priestley1da4ee22013-08-16 23:51:38 +01001132 cbMICHDR + sizeof(struct vnt_tx_datahead_a_fb);
Forest Bond92b96792009-06-13 07:38:31 -04001133 }
1134 } // Auto Fall Back
1135 }
1136
Andres Moreb902fbf2013-02-25 20:32:51 -05001137 pbyMacHdr = (u8 *)(pbyTxBufferAddr + cbHeaderLength);
1138 pbyIVHead = (u8 *)(pbyMacHdr + cbMACHdLen + uPadding);
1139 pbyPayloadHead = (u8 *)(pbyMacHdr + cbMACHdLen + uPadding + cbIVlen);
Forest Bond92b96792009-06-13 07:38:31 -04001140
Forest Bond92b96792009-06-13 07:38:31 -04001141 //=========================
1142 // No Fragmentation
1143 //=========================
1144 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No Fragmentation...\n");
1145 byFragType = FRAGCTL_NONFRAG;
1146 //uDMAIdx = TYPE_AC0DMA;
1147 //pTxBufHead = (PSTxBufHead) &(pTxBufHead->adwTxKey[0]);
1148
Malcolm Priestley78363fd2013-10-01 15:52:16 +01001149 /* Fill FIFO, RrvTime, RTS and CTS */
1150 uDuration = s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate,
1151 tx_buffer, &pMICHDR, cbMICHDR,
1152 cbFrameSize, bNeedACK, uDMAIdx, psEthHeader, bRTS);
Malcolm Priestleyc12dca02013-10-01 16:03:40 +01001153
Forest Bond92b96792009-06-13 07:38:31 -04001154 // Generate TX MAC Header
Andres More3eaca0d2013-02-25 20:32:52 -05001155 s_vGenerateMACHeader(pDevice, pbyMacHdr, (u16)uDuration, psEthHeader, bNeedEncryption,
Forest Bond92b96792009-06-13 07:38:31 -04001156 byFragType, uDMAIdx, 0);
1157
Andres More4e9b5e22013-02-12 20:36:30 -05001158 if (bNeedEncryption == true) {
Forest Bond92b96792009-06-13 07:38:31 -04001159 //Fill TXKEY
Malcolm Priestley3ba09382013-10-15 21:41:38 +01001160 s_vFillTxKey(pDevice, pTxBufHead, pbyIVHead, pTransmitKey,
Malcolm Priestleyec37d8b2013-08-23 14:37:48 +01001161 pbyMacHdr, (u16)cbFrameBodySize, pMICHDR);
Forest Bond92b96792009-06-13 07:38:31 -04001162
1163 if (pDevice->bEnableHostWEP) {
1164 pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
1165 pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0;
1166 }
1167 }
1168
Malcolm Priestleyc47b0a32013-11-24 11:51:49 +00001169 /* 802.1H */
1170 if (ntohs(psEthHeader->h_proto) > ETH_DATA_LEN) {
Andres Moreceb8c5d2013-03-18 20:33:49 -05001171 if ((psEthHeader->h_proto == cpu_to_be16(ETH_P_IPX)) ||
Malcolm Priestleyc47b0a32013-11-24 11:51:49 +00001172 (psEthHeader->h_proto == cpu_to_le16(0xF380)))
Andres Moreb902fbf2013-02-25 20:32:51 -05001173 memcpy((u8 *) (pbyPayloadHead),
Malcolm Priestleyc47b0a32013-11-24 11:51:49 +00001174 abySNAP_Bridgetunnel, 6);
1175 else
1176 memcpy((u8 *) (pbyPayloadHead), &abySNAP_RFC1042[0], 6);
Forest Bond92b96792009-06-13 07:38:31 -04001177
Malcolm Priestleyc47b0a32013-11-24 11:51:49 +00001178 pbyType = (u8 *) (pbyPayloadHead + 6);
Forest Bond92b96792009-06-13 07:38:31 -04001179
Malcolm Priestleyc47b0a32013-11-24 11:51:49 +00001180 memcpy(pbyType, &(psEthHeader->h_proto), sizeof(u16));
1181 }
Forest Bond92b96792009-06-13 07:38:31 -04001182
Forest Bond92b96792009-06-13 07:38:31 -04001183 if (pPacket != NULL) {
1184 // Copy the Packet into a tx Buffer
Jim Lieb3e362592009-08-12 14:54:11 -07001185 memcpy((pbyPayloadHead + cb802_1_H_len),
Charles Clément21ec51f2010-05-18 10:08:14 -07001186 (pPacket + ETH_HLEN),
1187 uSkbPacketLen - ETH_HLEN
Forest Bond92b96792009-06-13 07:38:31 -04001188 );
1189
1190 } else {
1191 // while bRelayPacketSend psEthHeader is point to header+payload
Andres Moreb902fbf2013-02-25 20:32:51 -05001192 memcpy((pbyPayloadHead + cb802_1_H_len), ((u8 *)psEthHeader) + ETH_HLEN, uSkbPacketLen - ETH_HLEN);
Forest Bond92b96792009-06-13 07:38:31 -04001193 }
1194
Andres More4e9b5e22013-02-12 20:36:30 -05001195 if ((bNeedEncryption == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
Forest Bond92b96792009-06-13 07:38:31 -04001196
1197 ///////////////////////////////////////////////////////////////////
1198
Malcolm Priestley14c5ef52013-01-17 23:19:37 +00001199 if (pDevice->vnt_mgmt.eAuthenMode == WMAC_AUTH_WPANONE) {
1200 dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]);
1201 dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]);
1202 }
Forest Bond92b96792009-06-13 07:38:31 -04001203 else if ((pTransmitKey->dwKeyIndex & AUTHENTICATOR_KEY) != 0) {
Andres More52a7e642013-02-25 20:32:53 -05001204 dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]);
1205 dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]);
Forest Bond92b96792009-06-13 07:38:31 -04001206 }
1207 else {
Andres More52a7e642013-02-25 20:32:53 -05001208 dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[24]);
1209 dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[28]);
Forest Bond92b96792009-06-13 07:38:31 -04001210 }
1211 // DO Software Michael
1212 MIC_vInit(dwMICKey0, dwMICKey1);
Andres Moreceb8c5d2013-03-18 20:33:49 -05001213 MIC_vAppend((u8 *)&(psEthHeader->h_dest[0]), 12);
Forest Bond92b96792009-06-13 07:38:31 -04001214 dwMIC_Priority = 0;
Andres Moreb902fbf2013-02-25 20:32:51 -05001215 MIC_vAppend((u8 *)&dwMIC_Priority, 4);
Malcolm Priestleyb4dc03a2012-11-11 15:45:52 +00001216 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC KEY: %X, %X\n",
1217 dwMICKey0, dwMICKey1);
Forest Bond92b96792009-06-13 07:38:31 -04001218
1219 ///////////////////////////////////////////////////////////////////
1220
1221 //DBG_PRN_GRP12(("Length:%d, %d\n", cbFrameBodySize, uFromHDtoPLDLength));
1222 //for (ii = 0; ii < cbFrameBodySize; ii++) {
Andres Moreb902fbf2013-02-25 20:32:51 -05001223 // DBG_PRN_GRP12(("%02x ", *((u8 *)((pbyPayloadHead + cb802_1_H_len) + ii))));
Forest Bond92b96792009-06-13 07:38:31 -04001224 //}
1225 //DBG_PRN_GRP12(("\n\n\n"));
1226
1227 MIC_vAppend(pbyPayloadHead, cbFrameBodySize);
1228
Andres More52a7e642013-02-25 20:32:53 -05001229 pdwMIC_L = (u32 *)(pbyPayloadHead + cbFrameBodySize);
1230 pdwMIC_R = (u32 *)(pbyPayloadHead + cbFrameBodySize + 4);
Forest Bond92b96792009-06-13 07:38:31 -04001231
1232 MIC_vGetMIC(pdwMIC_L, pdwMIC_R);
1233 MIC_vUnInit();
1234
Andres More4e9b5e22013-02-12 20:36:30 -05001235 if (pDevice->bTxMICFail == true) {
Forest Bond92b96792009-06-13 07:38:31 -04001236 *pdwMIC_L = 0;
1237 *pdwMIC_R = 0;
Andres Moree269fc22013-02-12 20:36:29 -05001238 pDevice->bTxMICFail = false;
Forest Bond92b96792009-06-13 07:38:31 -04001239 }
1240 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize);
1241 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderLength, uPadding, cbIVlen);
1242 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%lX, %lX\n", *pdwMIC_L, *pdwMIC_R);
1243 }
1244
Andres More4e9b5e22013-02-12 20:36:30 -05001245 if (bSoftWEP == true) {
Forest Bond92b96792009-06-13 07:38:31 -04001246
Andres More3eaca0d2013-02-25 20:32:52 -05001247 s_vSWencryption(pDevice, pTransmitKey, (pbyPayloadHead), (u16)(cbFrameBodySize + cbMIClen));
Forest Bond92b96792009-06-13 07:38:31 -04001248
Andres More4e9b5e22013-02-12 20:36:30 -05001249 } else if ( ((pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) && (bNeedEncryption == true)) ||
1250 ((pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) && (bNeedEncryption == true)) ||
1251 ((pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) && (bNeedEncryption == true)) ) {
Forest Bond92b96792009-06-13 07:38:31 -04001252 cbFrameSize -= cbICVlen;
1253 }
1254
Forest Bond92b96792009-06-13 07:38:31 -04001255 cbFrameSize -= cbFCSlen;
Forest Bond92b96792009-06-13 07:38:31 -04001256
1257 *pcbHeaderLen = cbHeaderLength;
1258 *pcbTotalLen = cbHeaderLength + cbFrameSize ;
1259
Forest Bond92b96792009-06-13 07:38:31 -04001260 //Set FragCtl in TxBufferHead
Andres More3eaca0d2013-02-25 20:32:52 -05001261 pTxBufHead->wFragCtl |= (u16)byFragType;
Forest Bond92b96792009-06-13 07:38:31 -04001262
Andres More4e9b5e22013-02-12 20:36:30 -05001263 return true;
Forest Bond92b96792009-06-13 07:38:31 -04001264
1265}
1266
Forest Bond92b96792009-06-13 07:38:31 -04001267/*+
1268 *
1269 * Description:
1270 * Translate 802.3 to 802.11 header
1271 *
1272 * Parameters:
1273 * In:
Justin P. Mattocka0a1f612012-08-26 08:16:43 -07001274 * pDevice - Pointer to adapter
Forest Bond92b96792009-06-13 07:38:31 -04001275 * dwTxBufferAddr - Transmit Buffer
1276 * pPacket - Packet from upper layer
1277 * cbPacketSize - Transmit Data Length
1278 * Out:
1279 * pcbHeadSize - Header size of MAC&Baseband control and 802.11 Header
1280 * pcbAppendPayload - size of append payload for 802.1H translation
1281 *
1282 * Return Value: none
1283 *
1284-*/
1285
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001286static void s_vGenerateMACHeader(struct vnt_private *pDevice,
Andres Moreceb8c5d2013-03-18 20:33:49 -05001287 u8 *pbyBufferAddr, u16 wDuration, struct ethhdr *psEthHeader,
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001288 int bNeedEncrypt, u16 wFragType, u32 uDMAIdx, u32 uFragIdx)
Forest Bond92b96792009-06-13 07:38:31 -04001289{
Andres More1cac4a42013-03-18 20:33:50 -05001290 struct ieee80211_hdr *pMACHeader = (struct ieee80211_hdr *)pbyBufferAddr;
Forest Bond92b96792009-06-13 07:38:31 -04001291
Malcolm Priestleyc921cc82013-08-20 20:47:49 +01001292 pMACHeader->frame_control = TYPE_802_11_DATA;
Forest Bond92b96792009-06-13 07:38:31 -04001293
1294 if (pDevice->eOPMode == OP_MODE_AP) {
Andres More1cac4a42013-03-18 20:33:50 -05001295 memcpy(&(pMACHeader->addr1[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -05001296 &(psEthHeader->h_dest[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001297 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001298 memcpy(&(pMACHeader->addr2[0]), &(pDevice->abyBSSID[0]), ETH_ALEN);
1299 memcpy(&(pMACHeader->addr3[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -05001300 &(psEthHeader->h_source[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001301 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001302 pMACHeader->frame_control |= FC_FROMDS;
Andres More9a0e7562010-04-13 21:54:48 -03001303 } else {
1304 if (pDevice->eOPMode == OP_MODE_ADHOC) {
Andres More1cac4a42013-03-18 20:33:50 -05001305 memcpy(&(pMACHeader->addr1[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -05001306 &(psEthHeader->h_dest[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001307 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001308 memcpy(&(pMACHeader->addr2[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -05001309 &(psEthHeader->h_source[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001310 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001311 memcpy(&(pMACHeader->addr3[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001312 &(pDevice->abyBSSID[0]),
1313 ETH_ALEN);
1314 } else {
Andres More1cac4a42013-03-18 20:33:50 -05001315 memcpy(&(pMACHeader->addr3[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -05001316 &(psEthHeader->h_dest[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001317 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001318 memcpy(&(pMACHeader->addr2[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -05001319 &(psEthHeader->h_source[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001320 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001321 memcpy(&(pMACHeader->addr1[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001322 &(pDevice->abyBSSID[0]),
1323 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001324 pMACHeader->frame_control |= FC_TODS;
Forest Bond92b96792009-06-13 07:38:31 -04001325 }
1326 }
1327
1328 if (bNeedEncrypt)
Andres More1cac4a42013-03-18 20:33:50 -05001329 pMACHeader->frame_control |= cpu_to_le16((u16)WLAN_SET_FC_ISWEP(1));
Forest Bond92b96792009-06-13 07:38:31 -04001330
Andres More1cac4a42013-03-18 20:33:50 -05001331 pMACHeader->duration_id = cpu_to_le16(wDuration);
Forest Bond92b96792009-06-13 07:38:31 -04001332
Andres More1cac4a42013-03-18 20:33:50 -05001333 pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4);
Forest Bond92b96792009-06-13 07:38:31 -04001334
1335 //Set FragNumber in Sequence Control
Andres More1cac4a42013-03-18 20:33:50 -05001336 pMACHeader->seq_ctrl |= cpu_to_le16((u16)uFragIdx);
Forest Bond92b96792009-06-13 07:38:31 -04001337
1338 if ((wFragType == FRAGCTL_ENDFRAG) || (wFragType == FRAGCTL_NONFRAG)) {
1339 pDevice->wSeqCounter++;
1340 if (pDevice->wSeqCounter > 0x0fff)
1341 pDevice->wSeqCounter = 0;
1342 }
1343
1344 if ((wFragType == FRAGCTL_STAFRAG) || (wFragType == FRAGCTL_MIDFRAG)) { //StartFrag or MidFrag
Andres More1cac4a42013-03-18 20:33:50 -05001345 pMACHeader->frame_control |= FC_MOREFRAG;
Forest Bond92b96792009-06-13 07:38:31 -04001346 }
1347}
1348
Forest Bond92b96792009-06-13 07:38:31 -04001349/*+
1350 *
1351 * Description:
1352 * Request instructs a MAC to transmit a 802.11 management packet through
1353 * the adapter onto the medium.
1354 *
1355 * Parameters:
1356 * In:
1357 * hDeviceContext - Pointer to the adapter
1358 * pPacket - A pointer to a descriptor for the packet to transmit
1359 * Out:
1360 * none
1361 *
Andres Moree269fc22013-02-12 20:36:29 -05001362 * Return Value: CMD_STATUS_PENDING if MAC Tx resource available; otherwise false
Forest Bond92b96792009-06-13 07:38:31 -04001363 *
1364-*/
1365
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001366CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice,
1367 struct vnt_tx_mgmt *pPacket)
Forest Bond92b96792009-06-13 07:38:31 -04001368{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001369 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
Malcolm Priestleyf39c0d82013-08-15 19:34:37 +01001370 struct vnt_tx_buffer *pTX_Buffer;
Malcolm Priestleydcdf1d02013-08-27 12:41:50 +01001371 struct vnt_usb_send_context *pContext;
Malcolm Priestleyd66caad2013-09-17 19:54:35 +01001372 struct vnt_tx_fifo_head *pTxBufHead;
Andres More1cac4a42013-03-18 20:33:50 -05001373 struct ieee80211_hdr *pMACHeader;
Andres Moreceb8c5d2013-03-18 20:33:49 -05001374 struct ethhdr sEthHeader;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001375 u8 byPktType, *pbyTxBufferAddr;
Malcolm Priestleyf0e0d502013-09-26 18:52:10 +01001376 struct vnt_mic_hdr *pMICHDR = NULL;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001377 u32 uDuration, cbReqCount, cbHeaderSize, cbFrameBodySize, cbFrameSize;
Andres Moree269fc22013-02-12 20:36:29 -05001378 int bNeedACK, bIsPSPOLL = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001379 u32 cbIVlen = 0, cbICVlen = 0, cbMIClen = 0, cbFCSlen = 4;
1380 u32 uPadding = 0;
1381 u16 wTxBufSize;
1382 u32 cbMacHdLen;
1383 u16 wCurrentRate = RATE_1M;
Forest Bond92b96792009-06-13 07:38:31 -04001384
Malcolm Priestleyaceaf012013-11-26 19:06:35 +00001385 pContext = s_vGetFreeContext(pDevice);
Forest Bond92b96792009-06-13 07:38:31 -04001386
1387 if (NULL == pContext) {
1388 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ManagementSend TX...NO CONTEXT!\n");
1389 return CMD_STATUS_RESOURCES;
1390 }
1391
Malcolm Priestleyf39c0d82013-08-15 19:34:37 +01001392 pTX_Buffer = (struct vnt_tx_buffer *)&pContext->Data[0];
Forest Bond92b96792009-06-13 07:38:31 -04001393 cbFrameBodySize = pPacket->cbPayloadLen;
Malcolm Priestleyd66caad2013-09-17 19:54:35 +01001394 pTxBufHead = &pTX_Buffer->fifo_head;
1395 pbyTxBufferAddr = (u8 *)&pTxBufHead->adwTxKey[0];
1396 wTxBufSize = sizeof(struct vnt_tx_fifo_head);
Forest Bond92b96792009-06-13 07:38:31 -04001397
1398 if (pDevice->byBBType == BB_TYPE_11A) {
1399 wCurrentRate = RATE_6M;
1400 byPktType = PK_TYPE_11A;
1401 } else {
1402 wCurrentRate = RATE_1M;
1403 byPktType = PK_TYPE_11B;
1404 }
1405
1406 // SetPower will cause error power TX state for OFDM Date packet in TX buffer.
1407 // 2004.11.11 Kyle -- Using OFDM power to tx MngPkt will decrease the connection capability.
1408 // And cmd timer will wait data pkt TX finish before scanning so it's OK
1409 // to set power here.
1410 if (pMgmt->eScanState != WMAC_NO_SCANNING) {
1411 RFbSetPower(pDevice, wCurrentRate, pDevice->byCurrentCh);
1412 } else {
1413 RFbSetPower(pDevice, wCurrentRate, pMgmt->uCurrChannel);
1414 }
1415 pDevice->wCurrentRate = wCurrentRate;
1416
Forest Bond92b96792009-06-13 07:38:31 -04001417 //Set packet type
1418 if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000
1419 pTxBufHead->wFIFOCtl = 0;
1420 }
1421 else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000
1422 pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
1423 }
1424 else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000
1425 pTxBufHead->wFIFOCtl |= FIFOCTL_11GB;
1426 }
1427 else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000
1428 pTxBufHead->wFIFOCtl |= FIFOCTL_11GA;
1429 }
1430
1431 pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN;
1432 pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
1433
Andres More22040bb2010-08-02 20:21:44 -03001434 if (is_multicast_ether_addr(pPacket->p80211Header->sA3.abyAddr1)) {
Andres Moree269fc22013-02-12 20:36:29 -05001435 bNeedACK = false;
Forest Bond92b96792009-06-13 07:38:31 -04001436 }
1437 else {
Andres More4e9b5e22013-02-12 20:36:30 -05001438 bNeedACK = true;
Forest Bond92b96792009-06-13 07:38:31 -04001439 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
1440 };
1441
1442 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) ||
1443 (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ) {
1444
1445 pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY;
1446 //Set Preamble type always long
1447 //pDevice->byPreambleType = PREAMBLE_LONG;
1448 // probe-response don't retry
1449 //if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_MGMT_PROBE_RSP) {
Andres Moree269fc22013-02-12 20:36:29 -05001450 // bNeedACK = false;
Forest Bond92b96792009-06-13 07:38:31 -04001451 // pTxBufHead->wFIFOCtl &= (~FIFOCTL_NEEDACK);
1452 //}
1453 }
1454
1455 pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0);
1456
1457 if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) {
Andres More4e9b5e22013-02-12 20:36:30 -05001458 bIsPSPOLL = true;
Forest Bond92b96792009-06-13 07:38:31 -04001459 cbMacHdLen = WLAN_HDR_ADDR2_LEN;
1460 } else {
1461 cbMacHdLen = WLAN_HDR_ADDR3_LEN;
1462 }
1463
1464 //Set FRAGCTL_MACHDCNT
Andres More3eaca0d2013-02-25 20:32:52 -05001465 pTxBufHead->wFragCtl |= cpu_to_le16((u16)(cbMacHdLen << 10));
Forest Bond92b96792009-06-13 07:38:31 -04001466
1467 // Notes:
1468 // Although spec says MMPDU can be fragmented; In most case,
1469 // no one will send a MMPDU under fragmentation. With RTS may occur.
Forest Bond92b96792009-06-13 07:38:31 -04001470
1471 if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) {
1472 if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) {
1473 cbIVlen = 4;
1474 cbICVlen = 4;
1475 pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
1476 }
1477 else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
1478 cbIVlen = 8;//IV+ExtIV
1479 cbMIClen = 8;
1480 cbICVlen = 4;
1481 pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
1482 //We need to get seed here for filling TxKey entry.
1483 //TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr,
1484 // pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG);
1485 }
1486 else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
1487 cbIVlen = 8;//RSN Header
1488 cbICVlen = 8;//MIC
1489 pTxBufHead->wFragCtl |= FRAGCTL_AES;
Forest Bond92b96792009-06-13 07:38:31 -04001490 }
1491 //MAC Header should be padding 0 to DW alignment.
1492 uPadding = 4 - (cbMacHdLen%4);
1493 uPadding %= 4;
1494 }
1495
1496 cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen;
1497
1498 //Set FIFOCTL_GrpAckPolicy
Andres More4e9b5e22013-02-12 20:36:30 -05001499 if (pDevice->bGrpAckPolicy == true) {//0000 0100 0000 0000
Forest Bond92b96792009-06-13 07:38:31 -04001500 pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK;
1501 }
1502 //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter()
1503
1504 //Set RrvTime/RTS/CTS Buffer
1505 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
Malcolm Priestley4f990052013-08-16 23:38:57 +01001506 cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
Malcolm Priestley78363fd2013-10-01 15:52:16 +01001507 sizeof(struct vnt_cts);
Forest Bond92b96792009-06-13 07:38:31 -04001508 }
1509 else { // 802.11a/b packet
Malcolm Priestley976467d2013-08-16 23:44:04 +01001510 cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
Malcolm Priestley558becf2013-08-16 23:50:32 +01001511 sizeof(struct vnt_tx_datahead_ab);
Forest Bond92b96792009-06-13 07:38:31 -04001512 }
1513
Andres Moreceb8c5d2013-03-18 20:33:49 -05001514 memcpy(&(sEthHeader.h_dest[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001515 &(pPacket->p80211Header->sA3.abyAddr1[0]),
1516 ETH_ALEN);
Andres Moreceb8c5d2013-03-18 20:33:49 -05001517 memcpy(&(sEthHeader.h_source[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001518 &(pPacket->p80211Header->sA3.abyAddr2[0]),
1519 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -04001520 //=========================
1521 // No Fragmentation
1522 //=========================
Andres More3eaca0d2013-02-25 20:32:52 -05001523 pTxBufHead->wFragCtl |= (u16)FRAGCTL_NONFRAG;
Forest Bond92b96792009-06-13 07:38:31 -04001524
Malcolm Priestley351c7dc2013-08-27 12:02:54 +01001525 /* Fill FIFO,RrvTime,RTS,and CTS */
Malcolm Priestley78363fd2013-10-01 15:52:16 +01001526 uDuration = s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate,
Malcolm Priestleyfa575602013-09-26 19:00:41 +01001527 pTX_Buffer, &pMICHDR, 0,
Malcolm Priestleyf46142b2013-08-27 11:56:33 +01001528 cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader, false);
Forest Bond92b96792009-06-13 07:38:31 -04001529
Andres More1cac4a42013-03-18 20:33:50 -05001530 pMACHeader = (struct ieee80211_hdr *) (pbyTxBufferAddr + cbHeaderSize);
Forest Bond92b96792009-06-13 07:38:31 -04001531
1532 cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + cbFrameBodySize;
1533
1534 if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) {
Andres Moreb902fbf2013-02-25 20:32:51 -05001535 u8 * pbyIVHead;
1536 u8 * pbyPayloadHead;
1537 u8 * pbyBSSID;
Forest Bond92b96792009-06-13 07:38:31 -04001538 PSKeyItem pTransmitKey = NULL;
1539
Andres Moreb902fbf2013-02-25 20:32:51 -05001540 pbyIVHead = (u8 *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding);
1541 pbyPayloadHead = (u8 *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding + cbIVlen);
Forest Bond92b96792009-06-13 07:38:31 -04001542 do {
1543 if ((pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) &&
Andres More4e9b5e22013-02-12 20:36:30 -05001544 (pDevice->bLinkPass == true)) {
Forest Bond92b96792009-06-13 07:38:31 -04001545 pbyBSSID = pDevice->abyBSSID;
1546 // get pairwise key
Andres Moree269fc22013-02-12 20:36:29 -05001547 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == false) {
Forest Bond92b96792009-06-13 07:38:31 -04001548 // get group key
Andres More4e9b5e22013-02-12 20:36:30 -05001549 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == true) {
Forest Bond92b96792009-06-13 07:38:31 -04001550 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get GTK.\n");
1551 break;
1552 }
1553 } else {
1554 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get PTK.\n");
1555 break;
1556 }
1557 }
1558 // get group key
1559 pbyBSSID = pDevice->abyBroadcastAddr;
Andres Moree269fc22013-02-12 20:36:29 -05001560 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) {
Forest Bond92b96792009-06-13 07:38:31 -04001561 pTransmitKey = NULL;
1562 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KEY is NULL. OP Mode[%d]\n", pDevice->eOPMode);
1563 } else {
1564 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get GTK.\n");
1565 }
Andres Moree269fc22013-02-12 20:36:29 -05001566 } while(false);
Forest Bond92b96792009-06-13 07:38:31 -04001567 //Fill TXKEY
Malcolm Priestley3ba09382013-10-15 21:41:38 +01001568 s_vFillTxKey(pDevice, pTxBufHead, pbyIVHead, pTransmitKey,
Andres More3eaca0d2013-02-25 20:32:52 -05001569 (u8 *)pMACHeader, (u16)cbFrameBodySize, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04001570
Jim Lieb3e362592009-08-12 14:54:11 -07001571 memcpy(pMACHeader, pPacket->p80211Header, cbMacHdLen);
Andres Moreb902fbf2013-02-25 20:32:51 -05001572 memcpy(pbyPayloadHead, ((u8 *)(pPacket->p80211Header) + cbMacHdLen),
Forest Bond92b96792009-06-13 07:38:31 -04001573 cbFrameBodySize);
1574 }
1575 else {
1576 // Copy the Packet into a tx Buffer
Jim Lieb3e362592009-08-12 14:54:11 -07001577 memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen);
Forest Bond92b96792009-06-13 07:38:31 -04001578 }
1579
Andres More1cac4a42013-03-18 20:33:50 -05001580 pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4);
Forest Bond92b96792009-06-13 07:38:31 -04001581 pDevice->wSeqCounter++ ;
1582 if (pDevice->wSeqCounter > 0x0fff)
1583 pDevice->wSeqCounter = 0;
1584
1585 if (bIsPSPOLL) {
1586 // The MAC will automatically replace the Duration-field of MAC header by Duration-field
Justin P. Mattocka0a1f612012-08-26 08:16:43 -07001587 // of FIFO control header.
Forest Bond92b96792009-06-13 07:38:31 -04001588 // This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is
1589 // in the same place of other packet's Duration-field).
1590 // And it will cause Cisco-AP to issue Disassociation-packet
Malcolm Priestley7e60a3de2013-08-16 23:48:03 +01001591 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
Malcolm Priestley78363fd2013-10-01 15:52:16 +01001592 struct vnt_tx_datahead_g *data_head = &pTX_Buffer->tx_head.
1593 tx_cts.tx.head.cts_g.data_head;
1594 data_head->wDuration_a =
Malcolm Priestley7e60a3de2013-08-16 23:48:03 +01001595 cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
Malcolm Priestley78363fd2013-10-01 15:52:16 +01001596 data_head->wDuration_b =
Malcolm Priestley7e60a3de2013-08-16 23:48:03 +01001597 cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
1598 } else {
Malcolm Priestleyc12dca02013-10-01 16:03:40 +01001599 struct vnt_tx_datahead_ab *data_head = &pTX_Buffer->tx_head.
1600 tx_ab.tx.head.data_head_ab;
1601 data_head->wDuration =
Malcolm Priestley558becf2013-08-16 23:50:32 +01001602 cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
1603 }
Forest Bond92b96792009-06-13 07:38:31 -04001604 }
1605
Andres More3eaca0d2013-02-25 20:32:52 -05001606 pTX_Buffer->wTxByteCount = cpu_to_le16((u16)(cbReqCount));
Andres Moreb902fbf2013-02-25 20:32:51 -05001607 pTX_Buffer->byPKTNO = (u8) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
Forest Bond92b96792009-06-13 07:38:31 -04001608 pTX_Buffer->byType = 0x00;
1609
1610 pContext->pPacket = NULL;
1611 pContext->Type = CONTEXT_MGMT_PACKET;
Andres More3eaca0d2013-02-25 20:32:52 -05001612 pContext->uBufLen = (u16)cbReqCount + 4; //USB header
Forest Bond92b96792009-06-13 07:38:31 -04001613
Andres More1cac4a42013-03-18 20:33:50 -05001614 if (WLAN_GET_FC_TODS(pMACHeader->frame_control) == 0) {
Malcolm Priestleyd66caad2013-09-17 19:54:35 +01001615 s_vSaveTxPktInfo(pDevice, (u8)(pTX_Buffer->byPKTNO & 0x0F),
1616 &pMACHeader->addr1[0], (u16)cbFrameSize,
1617 pTxBufHead->wFIFOCtl);
Forest Bond92b96792009-06-13 07:38:31 -04001618 }
1619 else {
Malcolm Priestleyd66caad2013-09-17 19:54:35 +01001620 s_vSaveTxPktInfo(pDevice, (u8)(pTX_Buffer->byPKTNO & 0x0F),
1621 &pMACHeader->addr3[0], (u16)cbFrameSize,
1622 pTxBufHead->wFIFOCtl);
Forest Bond92b96792009-06-13 07:38:31 -04001623 }
1624
1625 PIPEnsSendBulkOut(pDevice,pContext);
1626 return CMD_STATUS_PENDING;
1627}
1628
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001629CMD_STATUS csBeacon_xmit(struct vnt_private *pDevice,
1630 struct vnt_tx_mgmt *pPacket)
Forest Bond92b96792009-06-13 07:38:31 -04001631{
Malcolm Priestley01f865b2013-08-15 19:40:08 +01001632 struct vnt_beacon_buffer *pTX_Buffer;
Malcolm Priestleyc7c57b22013-11-24 13:25:25 +00001633 struct vnt_tx_short_buf_head *short_head;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001634 u32 cbFrameSize = pPacket->cbMPDULen + WLAN_FCS_LEN;
1635 u32 cbHeaderSize = 0;
Andres More1cac4a42013-03-18 20:33:50 -05001636 struct ieee80211_hdr *pMACHeader;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001637 u16 wCurrentRate;
1638 u32 cbFrameBodySize;
1639 u32 cbReqCount;
Malcolm Priestleydcdf1d02013-08-27 12:41:50 +01001640 struct vnt_usb_send_context *pContext;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001641 CMD_STATUS status;
Forest Bond92b96792009-06-13 07:38:31 -04001642
Malcolm Priestleyaceaf012013-11-26 19:06:35 +00001643 pContext = s_vGetFreeContext(pDevice);
Forest Bond92b96792009-06-13 07:38:31 -04001644 if (NULL == pContext) {
1645 status = CMD_STATUS_RESOURCES;
1646 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ManagementSend TX...NO CONTEXT!\n");
1647 return status ;
1648 }
Malcolm Priestley01f865b2013-08-15 19:40:08 +01001649
1650 pTX_Buffer = (struct vnt_beacon_buffer *)&pContext->Data[0];
Malcolm Priestleyc7c57b22013-11-24 13:25:25 +00001651 short_head = &pTX_Buffer->short_head;
Forest Bond92b96792009-06-13 07:38:31 -04001652
1653 cbFrameBodySize = pPacket->cbPayloadLen;
1654
Malcolm Priestleyc7c57b22013-11-24 13:25:25 +00001655 cbHeaderSize = sizeof(struct vnt_tx_short_buf_head);
Forest Bond92b96792009-06-13 07:38:31 -04001656
Malcolm Priestleyc7c57b22013-11-24 13:25:25 +00001657 if (pDevice->byBBType == BB_TYPE_11A) {
1658 wCurrentRate = RATE_6M;
1659
1660 /* Get SignalField,ServiceField,Length */
1661 BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate,
1662 PK_TYPE_11A, &short_head->ab);
1663
1664 /* Get Duration and TimeStampOff */
1665 short_head->duration = s_uGetDataDuration(pDevice,
1666 PK_TYPE_11A, false);
1667 short_head->time_stamp_off =
1668 vnt_time_stamp_off(pDevice, wCurrentRate);
1669 } else {
1670 wCurrentRate = RATE_1M;
1671 short_head->fifo_ctl |= FIFOCTL_11B;
1672
1673 /* Get SignalField,ServiceField,Length */
1674 BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate,
1675 PK_TYPE_11B, &short_head->ab);
1676
1677 /* Get Duration and TimeStampOff */
1678 short_head->duration = s_uGetDataDuration(pDevice,
Malcolm Priestley6b5ad9d2013-08-21 22:16:04 +01001679 PK_TYPE_11B, false);
Malcolm Priestleyc7c57b22013-11-24 13:25:25 +00001680 short_head->time_stamp_off =
1681 vnt_time_stamp_off(pDevice, wCurrentRate);
1682 }
1683
Forest Bond92b96792009-06-13 07:38:31 -04001684
Malcolm Priestley0b71fe32013-11-24 13:27:32 +00001685 /* Generate Beacon Header */
1686 pMACHeader = &pTX_Buffer->hdr;
Forest Bond92b96792009-06-13 07:38:31 -04001687
Malcolm Priestley0b71fe32013-11-24 13:27:32 +00001688 memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen);
1689
1690 pMACHeader->duration_id = 0;
1691 pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4);
1692 pDevice->wSeqCounter++;
1693 if (pDevice->wSeqCounter > 0x0fff)
1694 pDevice->wSeqCounter = 0;
Forest Bond92b96792009-06-13 07:38:31 -04001695
1696 cbReqCount = cbHeaderSize + WLAN_HDR_ADDR3_LEN + cbFrameBodySize;
1697
Andres More3eaca0d2013-02-25 20:32:52 -05001698 pTX_Buffer->wTxByteCount = (u16)cbReqCount;
Andres Moreb902fbf2013-02-25 20:32:51 -05001699 pTX_Buffer->byPKTNO = (u8) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
Forest Bond92b96792009-06-13 07:38:31 -04001700 pTX_Buffer->byType = 0x01;
1701
1702 pContext->pPacket = NULL;
1703 pContext->Type = CONTEXT_MGMT_PACKET;
Andres More3eaca0d2013-02-25 20:32:52 -05001704 pContext->uBufLen = (u16)cbReqCount + 4; //USB header
Forest Bond92b96792009-06-13 07:38:31 -04001705
1706 PIPEnsSendBulkOut(pDevice,pContext);
1707 return CMD_STATUS_PENDING;
1708
1709}
1710
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001711void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
1712{
1713 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
Malcolm Priestleyf39c0d82013-08-15 19:34:37 +01001714 struct vnt_tx_buffer *pTX_Buffer;
Malcolm Priestleyd66caad2013-09-17 19:54:35 +01001715 struct vnt_tx_fifo_head *pTxBufHead;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001716 u8 byPktType;
1717 u8 *pbyTxBufferAddr;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001718 u32 uDuration, cbReqCount;
Andres More1cac4a42013-03-18 20:33:50 -05001719 struct ieee80211_hdr *pMACHeader;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001720 u32 cbHeaderSize, cbFrameBodySize;
Andres Moree269fc22013-02-12 20:36:29 -05001721 int bNeedACK, bIsPSPOLL = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001722 u32 cbFrameSize;
1723 u32 cbIVlen = 0, cbICVlen = 0, cbMIClen = 0, cbFCSlen = 4;
1724 u32 uPadding = 0;
1725 u32 cbMICHDR = 0, uLength = 0;
1726 u32 dwMICKey0, dwMICKey1;
1727 u32 dwMIC_Priority;
1728 u32 *pdwMIC_L, *pdwMIC_R;
1729 u16 wTxBufSize;
1730 u32 cbMacHdLen;
Andres Moreceb8c5d2013-03-18 20:33:49 -05001731 struct ethhdr sEthHeader;
Malcolm Priestleyf0e0d502013-09-26 18:52:10 +01001732 struct vnt_mic_hdr *pMICHDR;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001733 u32 wCurrentRate = RATE_1M;
1734 PUWLAN_80211HDR p80211Header;
1735 u32 uNodeIndex = 0;
Andres Moree269fc22013-02-12 20:36:29 -05001736 int bNodeExist = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001737 SKeyItem STempKey;
1738 PSKeyItem pTransmitKey = NULL;
1739 u8 *pbyIVHead, *pbyPayloadHead, *pbyMacHdr;
1740 u32 cbExtSuppRate = 0;
Malcolm Priestleydcdf1d02013-08-27 12:41:50 +01001741 struct vnt_usb_send_context *pContext;
Forest Bond92b96792009-06-13 07:38:31 -04001742
Malcolm Priestleyc545e6a2013-10-01 16:07:25 +01001743 pMICHDR = NULL;
Forest Bond92b96792009-06-13 07:38:31 -04001744
1745 if(skb->len <= WLAN_HDR_ADDR3_LEN) {
1746 cbFrameBodySize = 0;
1747 }
1748 else {
1749 cbFrameBodySize = skb->len - WLAN_HDR_ADDR3_LEN;
1750 }
1751 p80211Header = (PUWLAN_80211HDR)skb->data;
1752
Malcolm Priestleyaceaf012013-11-26 19:06:35 +00001753 pContext = s_vGetFreeContext(pDevice);
Forest Bond92b96792009-06-13 07:38:31 -04001754
1755 if (NULL == pContext) {
1756 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"DMA0 TX...NO CONTEXT!\n");
1757 dev_kfree_skb_irq(skb);
1758 return ;
1759 }
1760
Malcolm Priestleyf39c0d82013-08-15 19:34:37 +01001761 pTX_Buffer = (struct vnt_tx_buffer *)&pContext->Data[0];
Malcolm Priestleyd66caad2013-09-17 19:54:35 +01001762 pTxBufHead = &pTX_Buffer->fifo_head;
1763 pbyTxBufferAddr = (u8 *)&pTxBufHead->adwTxKey[0];
1764 wTxBufSize = sizeof(struct vnt_tx_fifo_head);
Forest Bond92b96792009-06-13 07:38:31 -04001765
1766 if (pDevice->byBBType == BB_TYPE_11A) {
1767 wCurrentRate = RATE_6M;
1768 byPktType = PK_TYPE_11A;
1769 } else {
1770 wCurrentRate = RATE_1M;
1771 byPktType = PK_TYPE_11B;
1772 }
1773
1774 // SetPower will cause error power TX state for OFDM Date packet in TX buffer.
1775 // 2004.11.11 Kyle -- Using OFDM power to tx MngPkt will decrease the connection capability.
1776 // And cmd timer will wait data pkt TX finish before scanning so it's OK
1777 // to set power here.
1778 if (pMgmt->eScanState != WMAC_NO_SCANNING) {
1779 RFbSetPower(pDevice, wCurrentRate, pDevice->byCurrentCh);
1780 } else {
1781 RFbSetPower(pDevice, wCurrentRate, pMgmt->uCurrChannel);
1782 }
1783
1784 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vDMA0_tx_80211: p80211Header->sA3.wFrameCtl = %x \n", p80211Header->sA3.wFrameCtl);
1785
1786 //Set packet type
1787 if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000
1788 pTxBufHead->wFIFOCtl = 0;
1789 }
1790 else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000
1791 pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
1792 }
1793 else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000
1794 pTxBufHead->wFIFOCtl |= FIFOCTL_11GB;
1795 }
1796 else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000
1797 pTxBufHead->wFIFOCtl |= FIFOCTL_11GA;
1798 }
1799
1800 pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN;
1801 pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
1802
Andres More22040bb2010-08-02 20:21:44 -03001803 if (is_multicast_ether_addr(p80211Header->sA3.abyAddr1)) {
Andres Moree269fc22013-02-12 20:36:29 -05001804 bNeedACK = false;
Forest Bond92b96792009-06-13 07:38:31 -04001805 if (pDevice->bEnableHostWEP) {
1806 uNodeIndex = 0;
Andres More4e9b5e22013-02-12 20:36:30 -05001807 bNodeExist = true;
Joe Perches9fc86022011-04-10 14:31:32 -07001808 }
Forest Bond92b96792009-06-13 07:38:31 -04001809 }
1810 else {
1811 if (pDevice->bEnableHostWEP) {
Andres Moreb902fbf2013-02-25 20:32:51 -05001812 if (BSSbIsSTAInNodeDB(pDevice, (u8 *)(p80211Header->sA3.abyAddr1), &uNodeIndex))
Andres More4e9b5e22013-02-12 20:36:30 -05001813 bNodeExist = true;
Joe Perches9fc86022011-04-10 14:31:32 -07001814 }
Andres More4e9b5e22013-02-12 20:36:30 -05001815 bNeedACK = true;
Forest Bond92b96792009-06-13 07:38:31 -04001816 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
1817 };
1818
1819 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) ||
1820 (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ) {
1821
1822 pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY;
1823 //Set Preamble type always long
1824 //pDevice->byPreambleType = PREAMBLE_LONG;
1825
1826 // probe-response don't retry
1827 //if ((p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_MGMT_PROBE_RSP) {
Andres Moree269fc22013-02-12 20:36:29 -05001828 // bNeedACK = false;
Forest Bond92b96792009-06-13 07:38:31 -04001829 // pTxBufHead->wFIFOCtl &= (~FIFOCTL_NEEDACK);
1830 //}
1831 }
1832
1833 pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0);
1834
1835 if ((p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) {
Andres More4e9b5e22013-02-12 20:36:30 -05001836 bIsPSPOLL = true;
Forest Bond92b96792009-06-13 07:38:31 -04001837 cbMacHdLen = WLAN_HDR_ADDR2_LEN;
1838 } else {
1839 cbMacHdLen = WLAN_HDR_ADDR3_LEN;
1840 }
1841
Justin P. Mattocka0a1f612012-08-26 08:16:43 -07001842 // hostapd daemon ext support rate patch
Forest Bond92b96792009-06-13 07:38:31 -04001843 if (WLAN_GET_FC_FSTYPE(p80211Header->sA4.wFrameCtl) == WLAN_FSTYPE_ASSOCRESP) {
1844
1845 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len != 0) {
1846 cbExtSuppRate += ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN;
1847 }
1848
1849 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len != 0) {
1850 cbExtSuppRate += ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
1851 }
1852
1853 if (cbExtSuppRate >0) {
1854 cbFrameBodySize = WLAN_ASSOCRESP_OFF_SUPP_RATES;
1855 }
1856 }
1857
Forest Bond92b96792009-06-13 07:38:31 -04001858 //Set FRAGCTL_MACHDCNT
Andres More3eaca0d2013-02-25 20:32:52 -05001859 pTxBufHead->wFragCtl |= cpu_to_le16((u16)cbMacHdLen << 10);
Forest Bond92b96792009-06-13 07:38:31 -04001860
1861 // Notes:
1862 // Although spec says MMPDU can be fragmented; In most case,
1863 // no one will send a MMPDU under fragmentation. With RTS may occur.
Forest Bond92b96792009-06-13 07:38:31 -04001864
Forest Bond92b96792009-06-13 07:38:31 -04001865 if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) {
1866 if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) {
1867 cbIVlen = 4;
1868 cbICVlen = 4;
1869 pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
1870 }
1871 else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
1872 cbIVlen = 8;//IV+ExtIV
1873 cbMIClen = 8;
1874 cbICVlen = 4;
1875 pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
1876 //We need to get seed here for filling TxKey entry.
1877 //TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr,
1878 // pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG);
1879 }
1880 else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
1881 cbIVlen = 8;//RSN Header
1882 cbICVlen = 8;//MIC
Malcolm Priestley5a5d6a82013-08-23 14:33:55 +01001883 cbMICHDR = sizeof(struct vnt_mic_hdr);
Forest Bond92b96792009-06-13 07:38:31 -04001884 pTxBufHead->wFragCtl |= FRAGCTL_AES;
Forest Bond92b96792009-06-13 07:38:31 -04001885 }
1886 //MAC Header should be padding 0 to DW alignment.
1887 uPadding = 4 - (cbMacHdLen%4);
1888 uPadding %= 4;
1889 }
1890
1891 cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen + cbExtSuppRate;
1892
1893 //Set FIFOCTL_GrpAckPolicy
Andres More4e9b5e22013-02-12 20:36:30 -05001894 if (pDevice->bGrpAckPolicy == true) {//0000 0100 0000 0000
Forest Bond92b96792009-06-13 07:38:31 -04001895 pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK;
1896 }
1897 //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter()
1898
Forest Bond92b96792009-06-13 07:38:31 -04001899 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
Malcolm Priestley4f990052013-08-16 23:38:57 +01001900 cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR +
Malcolm Priestley78363fd2013-10-01 15:52:16 +01001901 sizeof(struct vnt_cts);
Forest Bond92b96792009-06-13 07:38:31 -04001902
1903 }
1904 else {//802.11a/b packet
Malcolm Priestley976467d2013-08-16 23:44:04 +01001905 cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR +
Malcolm Priestley558becf2013-08-16 23:50:32 +01001906 sizeof(struct vnt_tx_datahead_ab);
Forest Bond92b96792009-06-13 07:38:31 -04001907 }
Andres Moreceb8c5d2013-03-18 20:33:49 -05001908 memcpy(&(sEthHeader.h_dest[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001909 &(p80211Header->sA3.abyAddr1[0]),
1910 ETH_ALEN);
Andres Moreceb8c5d2013-03-18 20:33:49 -05001911 memcpy(&(sEthHeader.h_source[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001912 &(p80211Header->sA3.abyAddr2[0]),
1913 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -04001914 //=========================
1915 // No Fragmentation
1916 //=========================
Andres More3eaca0d2013-02-25 20:32:52 -05001917 pTxBufHead->wFragCtl |= (u16)FRAGCTL_NONFRAG;
Forest Bond92b96792009-06-13 07:38:31 -04001918
Malcolm Priestley351c7dc2013-08-27 12:02:54 +01001919 /* Fill FIFO,RrvTime,RTS,and CTS */
Malcolm Priestley78363fd2013-10-01 15:52:16 +01001920 uDuration = s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate,
Malcolm Priestleyfa575602013-09-26 19:00:41 +01001921 pTX_Buffer, &pMICHDR, cbMICHDR,
Malcolm Priestleyf46142b2013-08-27 11:56:33 +01001922 cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader, false);
Forest Bond92b96792009-06-13 07:38:31 -04001923
Malcolm Priestleyc545e6a2013-10-01 16:07:25 +01001924 pMACHeader = (struct ieee80211_hdr *) (pbyTxBufferAddr + cbHeaderSize);
Forest Bond92b96792009-06-13 07:38:31 -04001925
1926 cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + (cbFrameBodySize + cbMIClen) + cbExtSuppRate;
1927
Andres Moreb902fbf2013-02-25 20:32:51 -05001928 pbyMacHdr = (u8 *)(pbyTxBufferAddr + cbHeaderSize);
1929 pbyPayloadHead = (u8 *)(pbyMacHdr + cbMacHdLen + uPadding + cbIVlen);
1930 pbyIVHead = (u8 *)(pbyMacHdr + cbMacHdLen + uPadding);
Forest Bond92b96792009-06-13 07:38:31 -04001931
1932 // Copy the Packet into a tx Buffer
1933 memcpy(pbyMacHdr, skb->data, cbMacHdLen);
1934
1935 // version set to 0, patch for hostapd deamon
Andres More1cac4a42013-03-18 20:33:50 -05001936 pMACHeader->frame_control &= cpu_to_le16(0xfffc);
Forest Bond92b96792009-06-13 07:38:31 -04001937 memcpy(pbyPayloadHead, (skb->data + cbMacHdLen), cbFrameBodySize);
1938
Justin P. Mattocka0a1f612012-08-26 08:16:43 -07001939 // replace support rate, patch for hostapd daemon( only support 11M)
Forest Bond92b96792009-06-13 07:38:31 -04001940 if (WLAN_GET_FC_FSTYPE(p80211Header->sA4.wFrameCtl) == WLAN_FSTYPE_ASSOCRESP) {
1941 if (cbExtSuppRate != 0) {
1942 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len != 0)
1943 memcpy((pbyPayloadHead + cbFrameBodySize),
1944 pMgmt->abyCurrSuppRates,
1945 ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN
1946 );
1947 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len != 0)
1948 memcpy((pbyPayloadHead + cbFrameBodySize) + ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN,
1949 pMgmt->abyCurrExtSuppRates,
1950 ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len + WLAN_IEHDR_LEN
1951 );
1952 }
1953 }
1954
1955 // Set wep
1956 if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) {
1957
1958 if (pDevice->bEnableHostWEP) {
1959 pTransmitKey = &STempKey;
1960 pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
1961 pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
1962 pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
1963 pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
1964 pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
1965 memcpy(pTransmitKey->abyKey,
1966 &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
1967 pTransmitKey->uKeyLength
1968 );
1969 }
1970
1971 if ((pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
1972
Andres More52a7e642013-02-25 20:32:53 -05001973 dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]);
1974 dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]);
Forest Bond92b96792009-06-13 07:38:31 -04001975
1976 // DO Software Michael
1977 MIC_vInit(dwMICKey0, dwMICKey1);
Andres Moreceb8c5d2013-03-18 20:33:49 -05001978 MIC_vAppend((u8 *)&(sEthHeader.h_dest[0]), 12);
Forest Bond92b96792009-06-13 07:38:31 -04001979 dwMIC_Priority = 0;
Andres Moreb902fbf2013-02-25 20:32:51 -05001980 MIC_vAppend((u8 *)&dwMIC_Priority, 4);
Malcolm Priestleyb4dc03a2012-11-11 15:45:52 +00001981 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"DMA0_tx_8021:MIC KEY:"\
1982 " %X, %X\n", dwMICKey0, dwMICKey1);
Forest Bond92b96792009-06-13 07:38:31 -04001983
1984 uLength = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen;
1985
1986 MIC_vAppend((pbyTxBufferAddr + uLength), cbFrameBodySize);
1987
Andres More52a7e642013-02-25 20:32:53 -05001988 pdwMIC_L = (u32 *)(pbyTxBufferAddr + uLength + cbFrameBodySize);
1989 pdwMIC_R = (u32 *)(pbyTxBufferAddr + uLength + cbFrameBodySize + 4);
Forest Bond92b96792009-06-13 07:38:31 -04001990
1991 MIC_vGetMIC(pdwMIC_L, pdwMIC_R);
1992 MIC_vUnInit();
1993
Andres More4e9b5e22013-02-12 20:36:30 -05001994 if (pDevice->bTxMICFail == true) {
Forest Bond92b96792009-06-13 07:38:31 -04001995 *pdwMIC_L = 0;
1996 *pdwMIC_R = 0;
Andres Moree269fc22013-02-12 20:36:29 -05001997 pDevice->bTxMICFail = false;
Forest Bond92b96792009-06-13 07:38:31 -04001998 }
1999
2000 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize);
2001 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderSize, uPadding, cbIVlen);
Malcolm Priestleyb4dc03a2012-11-11 15:45:52 +00002002 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%x, %x\n",
2003 *pdwMIC_L, *pdwMIC_R);
Forest Bond92b96792009-06-13 07:38:31 -04002004
2005 }
2006
Malcolm Priestley3ba09382013-10-15 21:41:38 +01002007 s_vFillTxKey(pDevice, pTxBufHead, pbyIVHead, pTransmitKey,
Malcolm Priestleyec37d8b2013-08-23 14:37:48 +01002008 pbyMacHdr, (u16)cbFrameBodySize, pMICHDR);
Forest Bond92b96792009-06-13 07:38:31 -04002009
2010 if (pDevice->bEnableHostWEP) {
2011 pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
2012 pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0;
2013 }
2014
2015 if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) {
Andres More3eaca0d2013-02-25 20:32:52 -05002016 s_vSWencryption(pDevice, pTransmitKey, pbyPayloadHead, (u16)(cbFrameBodySize + cbMIClen));
Forest Bond92b96792009-06-13 07:38:31 -04002017 }
2018 }
2019
Andres More1cac4a42013-03-18 20:33:50 -05002020 pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4);
Forest Bond92b96792009-06-13 07:38:31 -04002021 pDevice->wSeqCounter++ ;
2022 if (pDevice->wSeqCounter > 0x0fff)
2023 pDevice->wSeqCounter = 0;
2024
Forest Bond92b96792009-06-13 07:38:31 -04002025 if (bIsPSPOLL) {
2026 // The MAC will automatically replace the Duration-field of MAC header by Duration-field
2027 // of FIFO control header.
2028 // This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is
2029 // in the same place of other packet's Duration-field).
2030 // And it will cause Cisco-AP to issue Disassociation-packet
Malcolm Priestley7e60a3de2013-08-16 23:48:03 +01002031 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
Malcolm Priestley78363fd2013-10-01 15:52:16 +01002032 struct vnt_tx_datahead_g *data_head = &pTX_Buffer->tx_head.
2033 tx_cts.tx.head.cts_g.data_head;
2034 data_head->wDuration_a =
Malcolm Priestley7e60a3de2013-08-16 23:48:03 +01002035 cpu_to_le16(p80211Header->sA2.wDurationID);
Malcolm Priestley78363fd2013-10-01 15:52:16 +01002036 data_head->wDuration_b =
Malcolm Priestley7e60a3de2013-08-16 23:48:03 +01002037 cpu_to_le16(p80211Header->sA2.wDurationID);
2038 } else {
Malcolm Priestleyc12dca02013-10-01 16:03:40 +01002039 struct vnt_tx_datahead_ab *data_head = &pTX_Buffer->tx_head.
2040 tx_ab.tx.head.data_head_ab;
2041 data_head->wDuration =
Malcolm Priestley558becf2013-08-16 23:50:32 +01002042 cpu_to_le16(p80211Header->sA2.wDurationID);
2043 }
Forest Bond92b96792009-06-13 07:38:31 -04002044 }
2045
Andres More3eaca0d2013-02-25 20:32:52 -05002046 pTX_Buffer->wTxByteCount = cpu_to_le16((u16)(cbReqCount));
Andres Moreb902fbf2013-02-25 20:32:51 -05002047 pTX_Buffer->byPKTNO = (u8) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
Forest Bond92b96792009-06-13 07:38:31 -04002048 pTX_Buffer->byType = 0x00;
2049
2050 pContext->pPacket = skb;
2051 pContext->Type = CONTEXT_MGMT_PACKET;
Andres More3eaca0d2013-02-25 20:32:52 -05002052 pContext->uBufLen = (u16)cbReqCount + 4; //USB header
Forest Bond92b96792009-06-13 07:38:31 -04002053
Andres More1cac4a42013-03-18 20:33:50 -05002054 if (WLAN_GET_FC_TODS(pMACHeader->frame_control) == 0) {
Malcolm Priestleyd66caad2013-09-17 19:54:35 +01002055 s_vSaveTxPktInfo(pDevice, (u8)(pTX_Buffer->byPKTNO & 0x0F),
2056 &pMACHeader->addr1[0], (u16)cbFrameSize,
2057 pTxBufHead->wFIFOCtl);
Forest Bond92b96792009-06-13 07:38:31 -04002058 }
2059 else {
Malcolm Priestleyd66caad2013-09-17 19:54:35 +01002060 s_vSaveTxPktInfo(pDevice, (u8)(pTX_Buffer->byPKTNO & 0x0F),
2061 &pMACHeader->addr3[0], (u16)cbFrameSize,
2062 pTxBufHead->wFIFOCtl);
Forest Bond92b96792009-06-13 07:38:31 -04002063 }
2064 PIPEnsSendBulkOut(pDevice,pContext);
2065 return ;
2066
2067}
2068
Forest Bond92b96792009-06-13 07:38:31 -04002069//TYPE_AC0DMA data tx
2070/*
2071 * Description:
2072 * Tx packet via AC0DMA(DMA1)
2073 *
2074 * Parameters:
2075 * In:
2076 * pDevice - Pointer to the adapter
2077 * skb - Pointer to tx skb packet
2078 * Out:
2079 * void
2080 *
2081 * Return Value: NULL
2082 */
2083
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002084int nsDMA_tx_packet(struct vnt_private *pDevice,
2085 u32 uDMAIdx, struct sk_buff *skb)
Forest Bond92b96792009-06-13 07:38:31 -04002086{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002087 struct net_device_stats *pStats = &pDevice->stats;
2088 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
Malcolm Priestleyf39c0d82013-08-15 19:34:37 +01002089 struct vnt_tx_buffer *pTX_Buffer;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002090 u32 BytesToWrite = 0, uHeaderLen = 0;
2091 u32 uNodeIndex = 0;
2092 u8 byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
2093 u16 wAID;
2094 u8 byPktType;
Andres Moree269fc22013-02-12 20:36:29 -05002095 int bNeedEncryption = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002096 PSKeyItem pTransmitKey = NULL;
2097 SKeyItem STempKey;
2098 int ii;
Andres Moree269fc22013-02-12 20:36:29 -05002099 int bTKIP_UseGTK = false;
2100 int bNeedDeAuth = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002101 u8 *pbyBSSID;
Andres Moree269fc22013-02-12 20:36:29 -05002102 int bNodeExist = false;
Malcolm Priestleydcdf1d02013-08-27 12:41:50 +01002103 struct vnt_usb_send_context *pContext;
Andres Moredfdcc422013-02-12 20:36:28 -05002104 bool fConvertedPacket;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002105 u32 status;
2106 u16 wKeepRate = pDevice->wCurrentRate;
Andres Moree269fc22013-02-12 20:36:29 -05002107 int bTxeapol_key = false;
Forest Bond92b96792009-06-13 07:38:31 -04002108
Forest Bond92b96792009-06-13 07:38:31 -04002109 if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
2110
2111 if (pDevice->uAssocCount == 0) {
2112 dev_kfree_skb_irq(skb);
2113 return 0;
2114 }
2115
Andres Moreb902fbf2013-02-25 20:32:51 -05002116 if (is_multicast_ether_addr((u8 *)(skb->data))) {
Forest Bond92b96792009-06-13 07:38:31 -04002117 uNodeIndex = 0;
Andres More4e9b5e22013-02-12 20:36:30 -05002118 bNodeExist = true;
Forest Bond92b96792009-06-13 07:38:31 -04002119 if (pMgmt->sNodeDBTable[0].bPSEnable) {
2120
2121 skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skb);
2122 pMgmt->sNodeDBTable[0].wEnQueueCnt++;
2123 // set tx map
2124 pMgmt->abyPSTxMap[0] |= byMask[0];
2125 return 0;
2126 }
Masanari Iida93184692012-08-13 21:21:50 +09002127 // multicast/broadcast data rate
Forest Bond92b96792009-06-13 07:38:31 -04002128
2129 if (pDevice->byBBType != BB_TYPE_11A)
2130 pDevice->wCurrentRate = RATE_2M;
2131 else
2132 pDevice->wCurrentRate = RATE_24M;
2133 // long preamble type
2134 pDevice->byPreambleType = PREAMBLE_SHORT;
2135
2136 }else {
2137
Andres Moreb902fbf2013-02-25 20:32:51 -05002138 if (BSSbIsSTAInNodeDB(pDevice, (u8 *)(skb->data), &uNodeIndex)) {
Forest Bond92b96792009-06-13 07:38:31 -04002139
2140 if (pMgmt->sNodeDBTable[uNodeIndex].bPSEnable) {
2141
2142 skb_queue_tail(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue, skb);
2143
2144 pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt++;
2145 // set tx map
2146 wAID = pMgmt->sNodeDBTable[uNodeIndex].wAID;
2147 pMgmt->abyPSTxMap[wAID >> 3] |= byMask[wAID & 7];
2148 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set:pMgmt->abyPSTxMap[%d]= %d\n",
2149 (wAID >> 3), pMgmt->abyPSTxMap[wAID >> 3]);
2150
2151 return 0;
2152 }
2153 // AP rate decided from node
2154 pDevice->wCurrentRate = pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
2155 // tx preamble decided from node
2156
2157 if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) {
2158 pDevice->byPreambleType = pDevice->byShortPreamble;
2159
2160 }else {
2161 pDevice->byPreambleType = PREAMBLE_LONG;
2162 }
Andres More4e9b5e22013-02-12 20:36:30 -05002163 bNodeExist = true;
Forest Bond92b96792009-06-13 07:38:31 -04002164 }
2165 }
2166
Andres Moree269fc22013-02-12 20:36:29 -05002167 if (bNodeExist == false) {
Forest Bond92b96792009-06-13 07:38:31 -04002168 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Unknown STA not found in node DB \n");
2169 dev_kfree_skb_irq(skb);
2170 return 0;
2171 }
2172 }
2173
Malcolm Priestleyaceaf012013-11-26 19:06:35 +00002174 pContext = s_vGetFreeContext(pDevice);
Forest Bond92b96792009-06-13 07:38:31 -04002175
2176 if (pContext == NULL) {
2177 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG" pContext == NULL\n");
2178 dev_kfree_skb_irq(skb);
2179 return STATUS_RESOURCES;
2180 }
2181
Andres Moreceb8c5d2013-03-18 20:33:49 -05002182 memcpy(pDevice->sTxEthHeader.h_dest, (u8 *)(skb->data), ETH_HLEN);
Forest Bond92b96792009-06-13 07:38:31 -04002183
2184//mike add:station mode check eapol-key challenge--->
2185{
Andres Moreb902fbf2013-02-25 20:32:51 -05002186 u8 Protocol_Version; //802.1x Authentication
2187 u8 Packet_Type; //802.1x Authentication
2188 u8 Descriptor_type;
Andres More3eaca0d2013-02-25 20:32:52 -05002189 u16 Key_info;
Forest Bond92b96792009-06-13 07:38:31 -04002190
Charles Clément21ec51f2010-05-18 10:08:14 -07002191 Protocol_Version = skb->data[ETH_HLEN];
2192 Packet_Type = skb->data[ETH_HLEN+1];
2193 Descriptor_type = skb->data[ETH_HLEN+1+1+2];
2194 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 -05002195 if (pDevice->sTxEthHeader.h_proto == cpu_to_be16(ETH_P_PAE)) {
Malcolm Priestleyaa209ee2012-08-29 23:08:21 +01002196 /* 802.1x OR eapol-key challenge frame transfer */
2197 if (((Protocol_Version == 1) || (Protocol_Version == 2)) &&
2198 (Packet_Type == 3)) {
Andres More4e9b5e22013-02-12 20:36:30 -05002199 bTxeapol_key = true;
Forest Bond92b96792009-06-13 07:38:31 -04002200 if(!(Key_info & BIT3) && //WPA or RSN group-key challenge
2201 (Key_info & BIT8) && (Key_info & BIT9)) { //send 2/2 key
2202 if(Descriptor_type==254) {
Andres More4e9b5e22013-02-12 20:36:30 -05002203 pDevice->fWPA_Authened = true;
Forest Bond92b96792009-06-13 07:38:31 -04002204 PRINT_K("WPA ");
2205 }
2206 else {
Andres More4e9b5e22013-02-12 20:36:30 -05002207 pDevice->fWPA_Authened = true;
Forest Bond92b96792009-06-13 07:38:31 -04002208 PRINT_K("WPA2(re-keying) ");
2209 }
2210 PRINT_K("Authentication completed!!\n");
2211 }
Justin P. Mattocka0a1f612012-08-26 08:16:43 -07002212 else if((Key_info & BIT3) && (Descriptor_type==2) && //RSN pairwise-key challenge
Forest Bond92b96792009-06-13 07:38:31 -04002213 (Key_info & BIT8) && (Key_info & BIT9)) {
Andres More4e9b5e22013-02-12 20:36:30 -05002214 pDevice->fWPA_Authened = true;
Forest Bond92b96792009-06-13 07:38:31 -04002215 PRINT_K("WPA2 Authentication completed!!\n");
2216 }
2217 }
2218 }
2219}
2220//mike add:station mode check eapol-key challenge<---
2221
Andres More4e9b5e22013-02-12 20:36:30 -05002222 if (pDevice->bEncryptionEnable == true) {
2223 bNeedEncryption = true;
Forest Bond92b96792009-06-13 07:38:31 -04002224 // get Transmit key
2225 do {
2226 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
2227 (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
2228 pbyBSSID = pDevice->abyBSSID;
2229 // get pairwise key
Andres Moree269fc22013-02-12 20:36:29 -05002230 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == false) {
Forest Bond92b96792009-06-13 07:38:31 -04002231 // get group key
Andres More4e9b5e22013-02-12 20:36:30 -05002232 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == true) {
2233 bTKIP_UseGTK = true;
Forest Bond92b96792009-06-13 07:38:31 -04002234 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
2235 break;
2236 }
2237 } else {
2238 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get PTK.\n");
2239 break;
2240 }
2241 }else if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
Andres Moreceb8c5d2013-03-18 20:33:49 -05002242 /* TO_DS = 0 and FROM_DS = 0 --> 802.11 MAC Address1 */
2243 pbyBSSID = pDevice->sTxEthHeader.h_dest;
Forest Bond92b96792009-06-13 07:38:31 -04002244 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"IBSS Serach Key: \n");
2245 for (ii = 0; ii< 6; ii++)
2246 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"%x \n", *(pbyBSSID+ii));
2247 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"\n");
2248
2249 // get pairwise key
Andres More4e9b5e22013-02-12 20:36:30 -05002250 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == true)
Forest Bond92b96792009-06-13 07:38:31 -04002251 break;
2252 }
2253 // get group key
2254 pbyBSSID = pDevice->abyBroadcastAddr;
Andres Moree269fc22013-02-12 20:36:29 -05002255 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) {
Forest Bond92b96792009-06-13 07:38:31 -04002256 pTransmitKey = NULL;
2257 if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
2258 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"IBSS and KEY is NULL. [%d]\n", pMgmt->eCurrMode);
2259 }
2260 else
2261 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"NOT IBSS and KEY is NULL. [%d]\n", pMgmt->eCurrMode);
2262 } else {
Andres More4e9b5e22013-02-12 20:36:30 -05002263 bTKIP_UseGTK = true;
Forest Bond92b96792009-06-13 07:38:31 -04002264 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
2265 }
Andres Moree269fc22013-02-12 20:36:29 -05002266 } while(false);
Forest Bond92b96792009-06-13 07:38:31 -04002267 }
2268
2269 if (pDevice->bEnableHostWEP) {
2270 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"acdma0: STA index %d\n", uNodeIndex);
Andres More4e9b5e22013-02-12 20:36:30 -05002271 if (pDevice->bEncryptionEnable == true) {
Forest Bond92b96792009-06-13 07:38:31 -04002272 pTransmitKey = &STempKey;
2273 pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
2274 pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
2275 pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
2276 pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
2277 pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
2278 memcpy(pTransmitKey->abyKey,
2279 &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
2280 pTransmitKey->uKeyLength
2281 );
2282 }
2283 }
2284
Andres Moreb902fbf2013-02-25 20:32:51 -05002285 byPktType = (u8)pDevice->byPacketType;
Forest Bond92b96792009-06-13 07:38:31 -04002286
2287 if (pDevice->bFixRate) {
2288 if (pDevice->byBBType == BB_TYPE_11B) {
2289 if (pDevice->uConnectionRate >= RATE_11M) {
2290 pDevice->wCurrentRate = RATE_11M;
2291 } else {
Andres More3eaca0d2013-02-25 20:32:52 -05002292 pDevice->wCurrentRate = (u16)pDevice->uConnectionRate;
Forest Bond92b96792009-06-13 07:38:31 -04002293 }
2294 } else {
2295 if ((pDevice->byBBType == BB_TYPE_11A) &&
2296 (pDevice->uConnectionRate <= RATE_6M)) {
2297 pDevice->wCurrentRate = RATE_6M;
2298 } else {
2299 if (pDevice->uConnectionRate >= RATE_54M)
2300 pDevice->wCurrentRate = RATE_54M;
2301 else
Andres More3eaca0d2013-02-25 20:32:52 -05002302 pDevice->wCurrentRate = (u16)pDevice->uConnectionRate;
Forest Bond92b96792009-06-13 07:38:31 -04002303 }
2304 }
2305 }
2306 else {
2307 if (pDevice->eOPMode == OP_MODE_ADHOC) {
2308 // Adhoc Tx rate decided from node DB
Andres Moreceb8c5d2013-03-18 20:33:49 -05002309 if (is_multicast_ether_addr(pDevice->sTxEthHeader.h_dest)) {
Forest Bond92b96792009-06-13 07:38:31 -04002310 // Multicast use highest data rate
2311 pDevice->wCurrentRate = pMgmt->sNodeDBTable[0].wTxDataRate;
2312 // preamble type
2313 pDevice->byPreambleType = pDevice->byShortPreamble;
2314 }
2315 else {
Andres Moreceb8c5d2013-03-18 20:33:49 -05002316 if (BSSbIsSTAInNodeDB(pDevice, &(pDevice->sTxEthHeader.h_dest[0]), &uNodeIndex)) {
Forest Bond92b96792009-06-13 07:38:31 -04002317 pDevice->wCurrentRate = pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
2318 if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) {
2319 pDevice->byPreambleType = pDevice->byShortPreamble;
2320
2321 }
2322 else {
2323 pDevice->byPreambleType = PREAMBLE_LONG;
2324 }
2325 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Found Node Index is [%d] Tx Data Rate:[%d]\n",uNodeIndex, pDevice->wCurrentRate);
2326 }
2327 else {
2328 if (pDevice->byBBType != BB_TYPE_11A)
2329 pDevice->wCurrentRate = RATE_2M;
2330 else
2331 pDevice->wCurrentRate = RATE_24M; // refer to vMgrCreateOwnIBSS()'s
2332 // abyCurrExtSuppRates[]
2333 pDevice->byPreambleType = PREAMBLE_SHORT;
2334 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Not Found Node use highest basic Rate.....\n");
2335 }
2336 }
2337 }
2338 if (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) {
2339 // Infra STA rate decided from AP Node, index = 0
2340 pDevice->wCurrentRate = pMgmt->sNodeDBTable[0].wTxDataRate;
2341 }
2342 }
2343
Andres Moreceb8c5d2013-03-18 20:33:49 -05002344 if (pDevice->sTxEthHeader.h_proto == cpu_to_be16(ETH_P_PAE)) {
Malcolm Priestleyaa209ee2012-08-29 23:08:21 +01002345 if (pDevice->byBBType != BB_TYPE_11A) {
2346 pDevice->wCurrentRate = RATE_1M;
2347 pDevice->byACKRate = RATE_1M;
2348 pDevice->byTopCCKBasicRate = RATE_1M;
2349 pDevice->byTopOFDMBasicRate = RATE_6M;
2350 } else {
2351 pDevice->wCurrentRate = RATE_6M;
2352 pDevice->byACKRate = RATE_6M;
2353 pDevice->byTopCCKBasicRate = RATE_1M;
2354 pDevice->byTopOFDMBasicRate = RATE_6M;
2355 }
2356 }
Forest Bond92b96792009-06-13 07:38:31 -04002357
Andres More0cbd8d92010-05-06 20:34:29 -03002358 DBG_PRT(MSG_LEVEL_DEBUG,
2359 KERN_INFO "dma_tx: pDevice->wCurrentRate = %d\n",
2360 pDevice->wCurrentRate);
Forest Bond92b96792009-06-13 07:38:31 -04002361
2362 if (wKeepRate != pDevice->wCurrentRate) {
Andres More0cbd8d92010-05-06 20:34:29 -03002363 bScheduleCommand((void *) pDevice, WLAN_CMD_SETPOWER, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002364 }
2365
2366 if (pDevice->wCurrentRate <= RATE_11M) {
2367 byPktType = PK_TYPE_11B;
2368 }
2369
Andres More4e9b5e22013-02-12 20:36:30 -05002370 if (bNeedEncryption == true) {
Andres Moreceb8c5d2013-03-18 20:33:49 -05002371 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ntohs Pkt Type=%04x\n", ntohs(pDevice->sTxEthHeader.h_proto));
2372 if ((pDevice->sTxEthHeader.h_proto) == cpu_to_be16(ETH_P_PAE)) {
Andres Moree269fc22013-02-12 20:36:29 -05002373 bNeedEncryption = false;
Andres Moreceb8c5d2013-03-18 20:33:49 -05002374 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Pkt Type=%04x\n", (pDevice->sTxEthHeader.h_proto));
Forest Bond92b96792009-06-13 07:38:31 -04002375 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
2376 if (pTransmitKey == NULL) {
2377 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Don't Find TX KEY\n");
2378 }
2379 else {
Andres More4e9b5e22013-02-12 20:36:30 -05002380 if (bTKIP_UseGTK == true) {
Forest Bond92b96792009-06-13 07:38:31 -04002381 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"error: KEY is GTK!!~~\n");
2382 }
2383 else {
Malcolm Priestleyb4dc03a2012-11-11 15:45:52 +00002384 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%X]\n",
2385 pTransmitKey->dwKeyIndex);
Andres More4e9b5e22013-02-12 20:36:30 -05002386 bNeedEncryption = true;
Forest Bond92b96792009-06-13 07:38:31 -04002387 }
2388 }
2389 }
2390
Forest Bond92b96792009-06-13 07:38:31 -04002391 if (pDevice->bEnableHostWEP) {
2392 if ((uNodeIndex != 0) &&
2393 (pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex & PAIRWISE_KEY)) {
Malcolm Priestleyb4dc03a2012-11-11 15:45:52 +00002394 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%X]\n",
2395 pTransmitKey->dwKeyIndex);
Andres More4e9b5e22013-02-12 20:36:30 -05002396 bNeedEncryption = true;
Forest Bond92b96792009-06-13 07:38:31 -04002397 }
2398 }
2399 }
2400 else {
2401
Forest Bond92b96792009-06-13 07:38:31 -04002402 if (pTransmitKey == NULL) {
2403 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"return no tx key\n");
Andres Moree269fc22013-02-12 20:36:29 -05002404 pContext->bBoolInUse = false;
Forest Bond92b96792009-06-13 07:38:31 -04002405 dev_kfree_skb_irq(skb);
2406 pStats->tx_dropped++;
2407 return STATUS_FAILURE;
2408 }
Forest Bond92b96792009-06-13 07:38:31 -04002409 }
2410 }
2411
Malcolm Priestleyd0a2b8f2013-08-15 19:37:04 +01002412 pTX_Buffer = (struct vnt_tx_buffer *)&pContext->Data[0];
2413
Forest Bond92b96792009-06-13 07:38:31 -04002414 fConvertedPacket = s_bPacketToWirelessUsb(pDevice, byPktType,
Malcolm Priestleyd0a2b8f2013-08-15 19:37:04 +01002415 pTX_Buffer, bNeedEncryption,
Forest Bond92b96792009-06-13 07:38:31 -04002416 skb->len, uDMAIdx, &pDevice->sTxEthHeader,
Andres Moreb902fbf2013-02-25 20:32:51 -05002417 (u8 *)skb->data, pTransmitKey, uNodeIndex,
Forest Bond92b96792009-06-13 07:38:31 -04002418 pDevice->wCurrentRate,
2419 &uHeaderLen, &BytesToWrite
2420 );
2421
Andres Moree269fc22013-02-12 20:36:29 -05002422 if (fConvertedPacket == false) {
2423 pContext->bBoolInUse = false;
Forest Bond92b96792009-06-13 07:38:31 -04002424 dev_kfree_skb_irq(skb);
2425 return STATUS_FAILURE;
2426 }
2427
Andres More4e9b5e22013-02-12 20:36:30 -05002428 if ( pDevice->bEnablePSMode == true ) {
Forest Bond92b96792009-06-13 07:38:31 -04002429 if ( !pDevice->bPSModeTxBurst ) {
Andres More0cbd8d92010-05-06 20:34:29 -03002430 bScheduleCommand((void *) pDevice,
2431 WLAN_CMD_MAC_DISPOWERSAVING,
2432 NULL);
Andres More4e9b5e22013-02-12 20:36:30 -05002433 pDevice->bPSModeTxBurst = true;
Forest Bond92b96792009-06-13 07:38:31 -04002434 }
2435 }
2436
Andres Moreb902fbf2013-02-25 20:32:51 -05002437 pTX_Buffer->byPKTNO = (u8) (((pDevice->wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
Andres More3eaca0d2013-02-25 20:32:52 -05002438 pTX_Buffer->wTxByteCount = (u16)BytesToWrite;
Forest Bond92b96792009-06-13 07:38:31 -04002439
2440 pContext->pPacket = skb;
2441 pContext->Type = CONTEXT_DATA_PACKET;
Andres More3eaca0d2013-02-25 20:32:52 -05002442 pContext->uBufLen = (u16)BytesToWrite + 4 ; //USB header
Forest Bond92b96792009-06-13 07:38:31 -04002443
Malcolm Priestleyd66caad2013-09-17 19:54:35 +01002444 s_vSaveTxPktInfo(pDevice, (u8)(pTX_Buffer->byPKTNO & 0x0F),
2445 &pContext->sEthHeader.h_dest[0],
2446 (u16)(BytesToWrite-uHeaderLen),
2447 pTX_Buffer->fifo_head.wFIFOCtl);
Forest Bond92b96792009-06-13 07:38:31 -04002448
2449 status = PIPEnsSendBulkOut(pDevice,pContext);
2450
Andres More4e9b5e22013-02-12 20:36:30 -05002451 if (bNeedDeAuth == true) {
Andres More3eaca0d2013-02-25 20:32:52 -05002452 u16 wReason = WLAN_MGMT_REASON_MIC_FAILURE;
Forest Bond92b96792009-06-13 07:38:31 -04002453
Andres Moreb902fbf2013-02-25 20:32:51 -05002454 bScheduleCommand((void *) pDevice, WLAN_CMD_DEAUTH, (u8 *) &wReason);
Forest Bond92b96792009-06-13 07:38:31 -04002455 }
2456
2457 if(status!=STATUS_PENDING) {
Andres Moree269fc22013-02-12 20:36:29 -05002458 pContext->bBoolInUse = false;
Forest Bond92b96792009-06-13 07:38:31 -04002459 dev_kfree_skb_irq(skb);
2460 return STATUS_FAILURE;
2461 }
2462 else
2463 return 0;
2464
2465}
2466
Forest Bond92b96792009-06-13 07:38:31 -04002467/*
2468 * Description:
2469 * Relay packet send (AC1DMA) from rx dpc.
2470 *
2471 * Parameters:
2472 * In:
2473 * pDevice - Pointer to the adapter
2474 * pPacket - Pointer to rx packet
2475 * cbPacketSize - rx ethernet frame size
2476 * Out:
Andres Moree269fc22013-02-12 20:36:29 -05002477 * TURE, false
Forest Bond92b96792009-06-13 07:38:31 -04002478 *
Andres More4e9b5e22013-02-12 20:36:30 -05002479 * Return Value: Return true if packet is copy to dma1; otherwise false
Forest Bond92b96792009-06-13 07:38:31 -04002480 */
2481
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002482int bRelayPacketSend(struct vnt_private *pDevice, u8 *pbySkbData, u32 uDataLen,
2483 u32 uNodeIndex)
Forest Bond92b96792009-06-13 07:38:31 -04002484{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002485 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
Malcolm Priestleyf39c0d82013-08-15 19:34:37 +01002486 struct vnt_tx_buffer *pTX_Buffer;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002487 u32 BytesToWrite = 0, uHeaderLen = 0;
2488 u8 byPktType = PK_TYPE_11B;
Andres Moree269fc22013-02-12 20:36:29 -05002489 int bNeedEncryption = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002490 SKeyItem STempKey;
2491 PSKeyItem pTransmitKey = NULL;
2492 u8 *pbyBSSID;
Malcolm Priestleydcdf1d02013-08-27 12:41:50 +01002493 struct vnt_usb_send_context *pContext;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002494 u8 byPktTyp;
2495 int fConvertedPacket;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002496 u32 status;
2497 u16 wKeepRate = pDevice->wCurrentRate;
Forest Bond92b96792009-06-13 07:38:31 -04002498
Malcolm Priestleyaceaf012013-11-26 19:06:35 +00002499 pContext = s_vGetFreeContext(pDevice);
Forest Bond92b96792009-06-13 07:38:31 -04002500
2501 if (NULL == pContext) {
Andres Moree269fc22013-02-12 20:36:29 -05002502 return false;
Forest Bond92b96792009-06-13 07:38:31 -04002503 }
2504
Andres Moreceb8c5d2013-03-18 20:33:49 -05002505 memcpy(pDevice->sTxEthHeader.h_dest, (u8 *)pbySkbData, ETH_HLEN);
Forest Bond92b96792009-06-13 07:38:31 -04002506
Andres More4e9b5e22013-02-12 20:36:30 -05002507 if (pDevice->bEncryptionEnable == true) {
2508 bNeedEncryption = true;
Forest Bond92b96792009-06-13 07:38:31 -04002509 // get group key
2510 pbyBSSID = pDevice->abyBroadcastAddr;
Andres Moree269fc22013-02-12 20:36:29 -05002511 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) {
Forest Bond92b96792009-06-13 07:38:31 -04002512 pTransmitKey = NULL;
2513 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"KEY is NULL. [%d]\n", pMgmt->eCurrMode);
2514 } else {
2515 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
2516 }
2517 }
2518
2519 if (pDevice->bEnableHostWEP) {
Roel Kluinee93e192009-10-16 20:17:57 +02002520 if (uNodeIndex < MAX_NODE_NUM + 1) {
Forest Bond92b96792009-06-13 07:38:31 -04002521 pTransmitKey = &STempKey;
2522 pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
2523 pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
2524 pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
2525 pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
2526 pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
2527 memcpy(pTransmitKey->abyKey,
2528 &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
2529 pTransmitKey->uKeyLength
2530 );
2531 }
2532 }
2533
2534 if ( bNeedEncryption && (pTransmitKey == NULL) ) {
Andres Moree269fc22013-02-12 20:36:29 -05002535 pContext->bBoolInUse = false;
2536 return false;
Forest Bond92b96792009-06-13 07:38:31 -04002537 }
2538
Andres Moreb902fbf2013-02-25 20:32:51 -05002539 byPktTyp = (u8)pDevice->byPacketType;
Forest Bond92b96792009-06-13 07:38:31 -04002540
2541 if (pDevice->bFixRate) {
2542 if (pDevice->byBBType == BB_TYPE_11B) {
2543 if (pDevice->uConnectionRate >= RATE_11M) {
2544 pDevice->wCurrentRate = RATE_11M;
2545 } else {
Andres More3eaca0d2013-02-25 20:32:52 -05002546 pDevice->wCurrentRate = (u16)pDevice->uConnectionRate;
Forest Bond92b96792009-06-13 07:38:31 -04002547 }
2548 } else {
2549 if ((pDevice->byBBType == BB_TYPE_11A) &&
2550 (pDevice->uConnectionRate <= RATE_6M)) {
2551 pDevice->wCurrentRate = RATE_6M;
2552 } else {
2553 if (pDevice->uConnectionRate >= RATE_54M)
2554 pDevice->wCurrentRate = RATE_54M;
2555 else
Andres More3eaca0d2013-02-25 20:32:52 -05002556 pDevice->wCurrentRate = (u16)pDevice->uConnectionRate;
Forest Bond92b96792009-06-13 07:38:31 -04002557 }
2558 }
2559 }
2560 else {
2561 pDevice->wCurrentRate = pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
2562 }
2563
Forest Bond92b96792009-06-13 07:38:31 -04002564 if (wKeepRate != pDevice->wCurrentRate) {
Andres More0cbd8d92010-05-06 20:34:29 -03002565 bScheduleCommand((void *) pDevice, WLAN_CMD_SETPOWER, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002566 }
2567
2568 if (pDevice->wCurrentRate <= RATE_11M)
2569 byPktType = PK_TYPE_11B;
2570
Andres Moreabad19d2010-07-12 16:28:32 -03002571 BytesToWrite = uDataLen + ETH_FCS_LEN;
2572
Forest Bond92b96792009-06-13 07:38:31 -04002573 // Convert the packet to an usb frame and copy into our buffer
2574 // and send the irp.
2575
Malcolm Priestleyd0a2b8f2013-08-15 19:37:04 +01002576 pTX_Buffer = (struct vnt_tx_buffer *)&pContext->Data[0];
2577
Forest Bond92b96792009-06-13 07:38:31 -04002578 fConvertedPacket = s_bPacketToWirelessUsb(pDevice, byPktType,
Malcolm Priestleyd0a2b8f2013-08-15 19:37:04 +01002579 pTX_Buffer, bNeedEncryption,
Forest Bond92b96792009-06-13 07:38:31 -04002580 uDataLen, TYPE_AC0DMA, &pDevice->sTxEthHeader,
2581 pbySkbData, pTransmitKey, uNodeIndex,
2582 pDevice->wCurrentRate,
2583 &uHeaderLen, &BytesToWrite
2584 );
2585
Andres Moree269fc22013-02-12 20:36:29 -05002586 if (fConvertedPacket == false) {
2587 pContext->bBoolInUse = false;
2588 return false;
Forest Bond92b96792009-06-13 07:38:31 -04002589 }
2590
Andres Moreb902fbf2013-02-25 20:32:51 -05002591 pTX_Buffer->byPKTNO = (u8) (((pDevice->wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
Andres More3eaca0d2013-02-25 20:32:52 -05002592 pTX_Buffer->wTxByteCount = (u16)BytesToWrite;
Forest Bond92b96792009-06-13 07:38:31 -04002593
2594 pContext->pPacket = NULL;
2595 pContext->Type = CONTEXT_DATA_PACKET;
Andres More3eaca0d2013-02-25 20:32:52 -05002596 pContext->uBufLen = (u16)BytesToWrite + 4 ; //USB header
Forest Bond92b96792009-06-13 07:38:31 -04002597
Malcolm Priestleyd66caad2013-09-17 19:54:35 +01002598 s_vSaveTxPktInfo(pDevice, (u8)(pTX_Buffer->byPKTNO & 0x0F),
2599 &pContext->sEthHeader.h_dest[0],
2600 (u16)(BytesToWrite - uHeaderLen),
2601 pTX_Buffer->fifo_head.wFIFOCtl);
Forest Bond92b96792009-06-13 07:38:31 -04002602
2603 status = PIPEnsSendBulkOut(pDevice,pContext);
2604
Andres More4e9b5e22013-02-12 20:36:30 -05002605 return true;
Forest Bond92b96792009-06-13 07:38:31 -04002606}
2607