blob: da7c0a8674b6f441d2c4bca9d9d0ee05a21cf801 [file] [log] [blame]
Forest Bond5449c682009-04-25 10:30:44 -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 Bond5449c682009-04-25 10:30:44 -040029 * vGenerateMACHeader - Translate 802.3 to 802.11 header
Justin P. Mattock7664ec82012-08-20 08:43:15 -070030 * cbGetFragCount - Calculate fragment number count
Forest Bond5449c682009-04-25 10:30:44 -040031 * csBeacon_xmit - beacon tx function
32 * csMgmt_xmit - management tx function
33 * s_cbFillTxBufHead - fulfill tx dma buffer header
34 * s_uGetDataDuration - get tx data required duration
35 * s_uFillDataHead- fulfill tx data duration header
Gilles Espinassef77f13e2010-03-29 15:41:47 +020036 * s_uGetRTSCTSDuration- get rtx/cts required duration
Forest Bond5449c682009-04-25 10:30:44 -040037 * s_uGetRTSCTSRsvTime- get rts/cts reserved time
38 * s_uGetTxRsvTime- get frame reserved time
39 * s_vFillCTSHead- fulfill CTS ctl header
Gilles Espinassef77f13e2010-03-29 15:41:47 +020040 * s_vFillFragParameter- Set fragment ctl parameter.
Forest Bond5449c682009-04-25 10:30:44 -040041 * s_vFillRTSHead- fulfill RTS ctl header
42 * s_vFillTxKey- fulfill tx encrypt key
43 * s_vSWencryption- Software encrypt header
44 * vDMA0_tx_80211- tx 802.11 frame via dma0
45 * vGenerateFIFOHeader- Generate tx FIFO ctl header
46 *
47 * Revision History:
48 *
49 */
50
Forest Bond5449c682009-04-25 10:30:44 -040051#include "device.h"
Forest Bond5449c682009-04-25 10:30:44 -040052#include "rxtx.h"
Forest Bond5449c682009-04-25 10:30:44 -040053#include "tether.h"
Forest Bond5449c682009-04-25 10:30:44 -040054#include "card.h"
Forest Bond5449c682009-04-25 10:30:44 -040055#include "bssdb.h"
Forest Bond5449c682009-04-25 10:30:44 -040056#include "mac.h"
Forest Bond5449c682009-04-25 10:30:44 -040057#include "baseband.h"
Forest Bond5449c682009-04-25 10:30:44 -040058#include "michael.h"
Forest Bond5449c682009-04-25 10:30:44 -040059#include "tkip.h"
Forest Bond5449c682009-04-25 10:30:44 -040060#include "tcrc.h"
Forest Bond5449c682009-04-25 10:30:44 -040061#include "wctl.h"
Forest Bond5449c682009-04-25 10:30:44 -040062#include "wroute.h"
Forest Bond5449c682009-04-25 10:30:44 -040063#include "hostap.h"
Forest Bond5449c682009-04-25 10:30:44 -040064#include "rf.h"
Forest Bond5449c682009-04-25 10:30:44 -040065
66/*--------------------- Static Definitions -------------------------*/
67
68/*--------------------- Static Classes ----------------------------*/
69
70/*--------------------- Static Variables --------------------------*/
Forest Bond5449c682009-04-25 10:30:44 -040071
Forest Bond5449c682009-04-25 10:30:44 -040072/*--------------------- Static Functions --------------------------*/
73
74/*--------------------- Static Definitions -------------------------*/
75#define CRITICAL_PACKET_LEN 256 // if packet size < 256 -> in-direct send
76 // packet size >= 256 -> direct send
77
Anton Protopopov83e771f2014-07-01 21:06:29 +040078static const unsigned short wTimeStampOff[2][MAX_RATE] = {
Joe Perches547f1cf2013-03-18 10:45:01 -070079 {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, // Long Preamble
80 {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, // Short Preamble
81};
Forest Bond5449c682009-04-25 10:30:44 -040082
Anton Protopopov83e771f2014-07-01 21:06:29 +040083static const unsigned short wFB_Opt0[2][5] = {
Joe Perches547f1cf2013-03-18 10:45:01 -070084 {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, // fallback_rate0
85 {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, // fallback_rate1
86};
Anton Protopopov83e771f2014-07-01 21:06:29 +040087static const unsigned short wFB_Opt1[2][5] = {
Joe Perches547f1cf2013-03-18 10:45:01 -070088 {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, // fallback_rate0
89 {RATE_6M , RATE_6M, RATE_12M, RATE_12M, RATE_18M}, // fallback_rate1
90};
Forest Bond5449c682009-04-25 10:30:44 -040091
Forest Bond5449c682009-04-25 10:30:44 -040092#define RTSDUR_BB 0
93#define RTSDUR_BA 1
94#define RTSDUR_AA 2
95#define CTSDUR_BA 3
96#define RTSDUR_BA_F0 4
97#define RTSDUR_AA_F0 5
98#define RTSDUR_BA_F1 6
99#define RTSDUR_AA_F1 7
100#define CTSDUR_BA_F0 8
101#define CTSDUR_BA_F1 9
102#define DATADUR_B 10
103#define DATADUR_A 11
104#define DATADUR_A_F0 12
105#define DATADUR_A_F1 13
106
107/*--------------------- Static Functions --------------------------*/
108
Forest Bond5449c682009-04-25 10:30:44 -0400109static
Charles Clément6b35b7b2010-05-07 12:30:19 -0700110void
Forest Bond5449c682009-04-25 10:30:44 -0400111s_vFillTxKey(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100112 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700113 unsigned char *pbyBuf,
114 unsigned char *pbyIVHead,
115 PSKeyItem pTransmitKey,
116 unsigned char *pbyHdrBuf,
117 unsigned short wPayloadLen,
118 unsigned char *pMICHDR
119);
Forest Bond5449c682009-04-25 10:30:44 -0400120
Forest Bond5449c682009-04-25 10:30:44 -0400121static
Charles Clément6b35b7b2010-05-07 12:30:19 -0700122void
Forest Bond5449c682009-04-25 10:30:44 -0400123s_vFillRTSHead(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100124 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700125 unsigned char byPktType,
126 void *pvRTS,
127 unsigned int cbFrameLength,
128 bool bNeedAck,
129 bool bDisCRC,
130 PSEthernetHeader psEthHeader,
131 unsigned short wCurrentRate,
132 unsigned char byFBOption
133);
Forest Bond5449c682009-04-25 10:30:44 -0400134
135static
Charles Clément6b35b7b2010-05-07 12:30:19 -0700136void
Forest Bond5449c682009-04-25 10:30:44 -0400137s_vGenerateTxParameter(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100138 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700139 unsigned char byPktType,
140 void *pTxBufHead,
141 void *pvRrvTime,
142 void *pvRTS,
143 void *pvCTS,
144 unsigned int cbFrameSize,
145 bool bNeedACK,
146 unsigned int uDMAIdx,
147 PSEthernetHeader psEthHeader,
148 unsigned short wCurrentRate
149);
Forest Bond5449c682009-04-25 10:30:44 -0400150
Forest Bond5449c682009-04-25 10:30:44 -0400151static void s_vFillFragParameter(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100152 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700153 unsigned char *pbyBuffer,
154 unsigned int uTxType,
155 void *pvtdCurr,
156 unsigned short wFragType,
157 unsigned int cbReqCount
158);
Forest Bond5449c682009-04-25 10:30:44 -0400159
Charles Clémentfe4f34b2010-06-25 10:48:53 -0700160static unsigned int
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100161s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
162 unsigned char *pbyTxBufferAddr, unsigned int cbFrameBodySize,
163 unsigned int uDMAIdx, PSTxDesc pHeadTD,
164 PSEthernetHeader psEthHeader, unsigned char *pPacket,
165 bool bNeedEncrypt, PSKeyItem pTransmitKey,
166 unsigned int uNodeIndex, unsigned int *puMACfragNum);
Forest Bond5449c682009-04-25 10:30:44 -0400167
Forest Bond5449c682009-04-25 10:30:44 -0400168static
Malcolm Priestleya479ffc2014-08-30 22:25:38 +0100169__le16
Joe Perches547f1cf2013-03-18 10:45:01 -0700170s_uFillDataHead(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100171 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700172 unsigned char byPktType,
173 void *pTxDataHead,
174 unsigned int cbFrameLength,
175 unsigned int uDMAIdx,
176 bool bNeedAck,
177 unsigned int uFragIdx,
178 unsigned int cbLastFragmentSize,
179 unsigned int uMACfragNum,
180 unsigned char byFBOption,
181 unsigned short wCurrentRate
182);
Forest Bond5449c682009-04-25 10:30:44 -0400183
Forest Bond5449c682009-04-25 10:30:44 -0400184/*--------------------- Export Variables --------------------------*/
185
Forest Bond5449c682009-04-25 10:30:44 -0400186static
Charles Clément6b35b7b2010-05-07 12:30:19 -0700187void
Joe Perches547f1cf2013-03-18 10:45:01 -0700188s_vFillTxKey(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100189 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700190 unsigned char *pbyBuf,
191 unsigned char *pbyIVHead,
192 PSKeyItem pTransmitKey,
193 unsigned char *pbyHdrBuf,
194 unsigned short wPayloadLen,
195 unsigned char *pMICHDR
196)
Forest Bond5449c682009-04-25 10:30:44 -0400197{
Malcolm Priestley11a72e52014-08-09 20:15:56 +0100198 struct vnt_mic_hdr *mic_hdr = (struct vnt_mic_hdr *)pMICHDR;
Joe Perches547f1cf2013-03-18 10:45:01 -0700199 unsigned long *pdwIV = (unsigned long *)pbyIVHead;
200 unsigned long *pdwExtIV = (unsigned long *)((unsigned char *)pbyIVHead+4);
Joe Perches547f1cf2013-03-18 10:45:01 -0700201 PS802_11Header pMACHeader = (PS802_11Header)pbyHdrBuf;
202 unsigned long dwRevIVCounter;
203 unsigned char byKeyIndex = 0;
Forest Bond5449c682009-04-25 10:30:44 -0400204
Joe Perches547f1cf2013-03-18 10:45:01 -0700205 //Fill TXKEY
206 if (pTransmitKey == NULL)
207 return;
Forest Bond5449c682009-04-25 10:30:44 -0400208
Joe Perches547f1cf2013-03-18 10:45:01 -0700209 dwRevIVCounter = cpu_to_le32(pDevice->dwIVCounter);
210 *pdwIV = pDevice->dwIVCounter;
211 byKeyIndex = pTransmitKey->dwKeyIndex & 0xf;
Forest Bond5449c682009-04-25 10:30:44 -0400212
Joe Perches547f1cf2013-03-18 10:45:01 -0700213 if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
214 if (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN) {
215 memcpy(pDevice->abyPRNG, (unsigned char *)&(dwRevIVCounter), 3);
216 memcpy(pDevice->abyPRNG+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
217 } else {
218 memcpy(pbyBuf, (unsigned char *)&(dwRevIVCounter), 3);
219 memcpy(pbyBuf+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
220 if (pTransmitKey->uKeyLength == WLAN_WEP40_KEYLEN) {
221 memcpy(pbyBuf+8, (unsigned char *)&(dwRevIVCounter), 3);
222 memcpy(pbyBuf+11, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
223 }
224 memcpy(pDevice->abyPRNG, pbyBuf, 16);
225 }
226 // Append IV after Mac Header
227 *pdwIV &= WEP_IV_MASK;//00000000 11111111 11111111 11111111
228 *pdwIV |= (unsigned long)byKeyIndex << 30;
229 *pdwIV = cpu_to_le32(*pdwIV);
230 pDevice->dwIVCounter++;
Guido Martínezbc5cf652014-04-19 16:45:00 -0300231 if (pDevice->dwIVCounter > WEP_IV_MASK)
Joe Perches547f1cf2013-03-18 10:45:01 -0700232 pDevice->dwIVCounter = 0;
Guido Martínezbc5cf652014-04-19 16:45:00 -0300233
Joe Perches547f1cf2013-03-18 10:45:01 -0700234 } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
235 pTransmitKey->wTSC15_0++;
Guido Martínezbc5cf652014-04-19 16:45:00 -0300236 if (pTransmitKey->wTSC15_0 == 0)
Joe Perches547f1cf2013-03-18 10:45:01 -0700237 pTransmitKey->dwTSC47_16++;
Guido Martínezbc5cf652014-04-19 16:45:00 -0300238
Joe Perches547f1cf2013-03-18 10:45:01 -0700239 TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr,
240 pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG);
241 memcpy(pbyBuf, pDevice->abyPRNG, 16);
242 // Make IV
243 memcpy(pdwIV, pDevice->abyPRNG, 3);
Forest Bond5449c682009-04-25 10:30:44 -0400244
Joe Perches547f1cf2013-03-18 10:45:01 -0700245 *(pbyIVHead+3) = (unsigned char)(((byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV
246 // Append IV&ExtIV after Mac Header
247 *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16);
Joe Perches48caf5a2014-08-17 09:17:04 -0700248 pr_debug("vFillTxKey()---- pdwExtIV: %lx\n", *pdwExtIV);
Forest Bond5449c682009-04-25 10:30:44 -0400249
Joe Perches547f1cf2013-03-18 10:45:01 -0700250 } else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) {
251 pTransmitKey->wTSC15_0++;
Guido Martínezbc5cf652014-04-19 16:45:00 -0300252 if (pTransmitKey->wTSC15_0 == 0)
Joe Perches547f1cf2013-03-18 10:45:01 -0700253 pTransmitKey->dwTSC47_16++;
Guido Martínezbc5cf652014-04-19 16:45:00 -0300254
Joe Perches547f1cf2013-03-18 10:45:01 -0700255 memcpy(pbyBuf, pTransmitKey->abyKey, 16);
Forest Bond5449c682009-04-25 10:30:44 -0400256
Joe Perches547f1cf2013-03-18 10:45:01 -0700257 // Make IV
258 *pdwIV = 0;
259 *(pbyIVHead+3) = (unsigned char)(((byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV
260 *pdwIV |= cpu_to_le16((unsigned short)(pTransmitKey->wTSC15_0));
261 //Append IV&ExtIV after Mac Header
262 *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16);
Forest Bond5449c682009-04-25 10:30:44 -0400263
Malcolm Priestley11a72e52014-08-09 20:15:56 +0100264 /* MICHDR0 */
265 mic_hdr->id = 0x59;
266 mic_hdr->tx_priority = 0;
Aya Mahfouz2359b5c2014-10-11 02:42:45 +0200267 ether_addr_copy(mic_hdr->mic_addr2, pMACHeader->abyAddr2);
Forest Bond5449c682009-04-25 10:30:44 -0400268
Malcolm Priestley11a72e52014-08-09 20:15:56 +0100269 /* ccmp pn big endian order */
270 mic_hdr->ccmp_pn[0] = (u8)(pTransmitKey->dwTSC47_16 >> 24);
271 mic_hdr->ccmp_pn[1] = (u8)(pTransmitKey->dwTSC47_16 >> 16);
272 mic_hdr->ccmp_pn[2] = (u8)(pTransmitKey->dwTSC47_16 >> 8);
273 mic_hdr->ccmp_pn[3] = (u8)pTransmitKey->dwTSC47_16;
274 mic_hdr->ccmp_pn[4] = (u8)(pTransmitKey->wTSC15_0 >> 8);
275 mic_hdr->ccmp_pn[5] = (u8)pTransmitKey->wTSC15_0;
276
277 /* MICHDR1 */
278 mic_hdr->payload_len = cpu_to_be16(wPayloadLen);
279
Guido Martínezbc5cf652014-04-19 16:45:00 -0300280 if (pDevice->bLongHeader)
Malcolm Priestley11a72e52014-08-09 20:15:56 +0100281 mic_hdr->hlen = cpu_to_be16(28);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300282 else
Malcolm Priestley11a72e52014-08-09 20:15:56 +0100283 mic_hdr->hlen = cpu_to_be16(22);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300284
Aya Mahfouz2359b5c2014-10-11 02:42:45 +0200285 ether_addr_copy(mic_hdr->addr1, pMACHeader->abyAddr1);
286 ether_addr_copy(mic_hdr->addr2, pMACHeader->abyAddr2);
Forest Bond5449c682009-04-25 10:30:44 -0400287
Malcolm Priestley11a72e52014-08-09 20:15:56 +0100288 /* MICHDR2 */
Aya Mahfouz2359b5c2014-10-11 02:42:45 +0200289 ether_addr_copy(mic_hdr->addr3, pMACHeader->abyAddr3);
Malcolm Priestley11a72e52014-08-09 20:15:56 +0100290 mic_hdr->frame_control =
291 cpu_to_le16(pMACHeader->wFrameCtl & 0xc78f);
292 mic_hdr->seq_ctrl = cpu_to_le16(pMACHeader->wSeqCtl & 0xf);
293
Guido Martínezbc5cf652014-04-19 16:45:00 -0300294 if (pDevice->bLongHeader)
Aya Mahfouz2359b5c2014-10-11 02:42:45 +0200295 ether_addr_copy(mic_hdr->addr4, pMACHeader->abyAddr4);
Joe Perches547f1cf2013-03-18 10:45:01 -0700296 }
Forest Bond5449c682009-04-25 10:30:44 -0400297}
298
Forest Bond5449c682009-04-25 10:30:44 -0400299static
Charles Clément6b35b7b2010-05-07 12:30:19 -0700300void
Joe Perches547f1cf2013-03-18 10:45:01 -0700301s_vSWencryption(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100302 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700303 PSKeyItem pTransmitKey,
304 unsigned char *pbyPayloadHead,
305 unsigned short wPayloadSize
306)
Forest Bond5449c682009-04-25 10:30:44 -0400307{
Joe Perches547f1cf2013-03-18 10:45:01 -0700308 unsigned int cbICVlen = 4;
309 unsigned long dwICV = 0xFFFFFFFFL;
310 unsigned long *pdwICV;
Forest Bond5449c682009-04-25 10:30:44 -0400311
Joe Perches547f1cf2013-03-18 10:45:01 -0700312 if (pTransmitKey == NULL)
313 return;
Forest Bond5449c682009-04-25 10:30:44 -0400314
Joe Perches547f1cf2013-03-18 10:45:01 -0700315 if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
316 //=======================================================================
317 // Append ICV after payload
318 dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload)
319 pdwICV = (unsigned long *)(pbyPayloadHead + wPayloadSize);
320 // 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)
330 pdwICV = (unsigned long *)(pbyPayloadHead + wPayloadSize);
331 // 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 }
Forest Bond5449c682009-04-25 10:30:44 -0400338}
339
Malcolm Priestleyd6b95c02014-08-30 22:25:33 +0100340static __le16 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
Jim Lieb7e809a92009-07-30 10:27:21 -0700346/*byPktType : PK_TYPE_11A 0
Joe Perches547f1cf2013-03-18 10:45:01 -0700347 PK_TYPE_11B 1
348 PK_TYPE_11GB 2
349 PK_TYPE_11GA 3
Forest Bond5449c682009-04-25 10:30:44 -0400350*/
351static
Charles Clémentb6e95cd2010-06-02 09:52:01 -0700352unsigned int
Joe Perches547f1cf2013-03-18 10:45:01 -0700353s_uGetTxRsvTime(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100354 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700355 unsigned char byPktType,
356 unsigned int cbFrameLength,
357 unsigned short wRate,
358 bool bNeedAck
359)
Forest Bond5449c682009-04-25 10:30:44 -0400360{
Joe Perches547f1cf2013-03-18 10:45:01 -0700361 unsigned int uDataTime, uAckTime;
Forest Bond5449c682009-04-25 10:30:44 -0400362
Joe Perches547f1cf2013-03-18 10:45:01 -0700363 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wRate);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300364 if (byPktType == PK_TYPE_11B) //llb,CCK mode
Joe Perches547f1cf2013-03-18 10:45:01 -0700365 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopCCKBasicRate);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300366 else //11g 2.4G OFDM mode & 11a 5G OFDM mode
Joe Perches547f1cf2013-03-18 10:45:01 -0700367 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopOFDMBasicRate);
Forest Bond5449c682009-04-25 10:30:44 -0400368
Guido Martínezbc5cf652014-04-19 16:45:00 -0300369 if (bNeedAck)
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700370 return uDataTime + pDevice->uSIFS + uAckTime;
Guido Martínezbc5cf652014-04-19 16:45:00 -0300371 else
Joe Perches547f1cf2013-03-18 10:45:01 -0700372 return uDataTime;
Forest Bond5449c682009-04-25 10:30:44 -0400373}
374
Malcolm Priestleye7a3481b2014-08-30 22:25:30 +0100375static __le16 vnt_rxtx_rsvtime_le16(struct vnt_private *priv, u8 pkt_type,
376 u32 frame_length, u16 rate, bool need_ack)
377{
378 return cpu_to_le16((u16)s_uGetTxRsvTime(priv, pkt_type,
379 frame_length, rate, need_ack));
380}
381
Forest Bond5449c682009-04-25 10:30:44 -0400382//byFreqType: 0=>5GHZ 1=>2.4GHZ
383static
Malcolm Priestley853532d2014-08-30 22:25:31 +0100384__le16
Joe Perches547f1cf2013-03-18 10:45:01 -0700385s_uGetRTSCTSRsvTime(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100386 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700387 unsigned char byRTSRsvType,
388 unsigned char byPktType,
389 unsigned int cbFrameLength,
390 unsigned short wCurrentRate
391)
Forest Bond5449c682009-04-25 10:30:44 -0400392{
Joe Perches547f1cf2013-03-18 10:45:01 -0700393 unsigned int uRrvTime , uRTSTime, uCTSTime, uAckTime, uDataTime;
Forest Bond5449c682009-04-25 10:30:44 -0400394
Joe Perches547f1cf2013-03-18 10:45:01 -0700395 uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0;
Forest Bond5449c682009-04-25 10:30:44 -0400396
Joe Perches547f1cf2013-03-18 10:45:01 -0700397 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wCurrentRate);
398 if (byRTSRsvType == 0) { //RTSTxRrvTime_bb
399 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
400 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700401 } else if (byRTSRsvType == 1) { //RTSTxRrvTime_ba, only in 2.4GHZ
Joe Perches547f1cf2013-03-18 10:45:01 -0700402 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
403 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
404 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700405 } else if (byRTSRsvType == 2) { //RTSTxRrvTime_aa
Joe Perches547f1cf2013-03-18 10:45:01 -0700406 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopOFDMBasicRate);
407 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700408 } else if (byRTSRsvType == 3) { //CTSTxRrvTime_ba, only in 2.4GHZ
Joe Perches547f1cf2013-03-18 10:45:01 -0700409 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
410 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
411 uRrvTime = uCTSTime + uAckTime + uDataTime + 2*pDevice->uSIFS;
Malcolm Priestley853532d2014-08-30 22:25:31 +0100412 return cpu_to_le16((u16)uRrvTime);
Joe Perches547f1cf2013-03-18 10:45:01 -0700413 }
Forest Bond5449c682009-04-25 10:30:44 -0400414
Joe Perches547f1cf2013-03-18 10:45:01 -0700415 //RTSRrvTime
416 uRrvTime = uRTSTime + uCTSTime + uAckTime + uDataTime + 3*pDevice->uSIFS;
Malcolm Priestley853532d2014-08-30 22:25:31 +0100417 return cpu_to_le16((u16)uRrvTime);
Forest Bond5449c682009-04-25 10:30:44 -0400418}
419
420//byFreqType 0: 5GHz, 1:2.4Ghz
421static
Charles Clémentb6e95cd2010-06-02 09:52:01 -0700422unsigned int
Joe Perches547f1cf2013-03-18 10:45:01 -0700423s_uGetDataDuration(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100424 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700425 unsigned char byDurType,
426 unsigned int cbFrameLength,
427 unsigned char byPktType,
428 unsigned short wRate,
429 bool bNeedAck,
430 unsigned int uFragIdx,
431 unsigned int cbLastFragmentSize,
432 unsigned int uMACfragNum,
433 unsigned char byFBOption
434)
Forest Bond5449c682009-04-25 10:30:44 -0400435{
Joe Perches547f1cf2013-03-18 10:45:01 -0700436 bool bLastFrag = 0;
437 unsigned int uAckTime = 0, uNextPktTime = 0;
Forest Bond5449c682009-04-25 10:30:44 -0400438
Guido Martínezbc5cf652014-04-19 16:45:00 -0300439 if (uFragIdx == (uMACfragNum-1))
Joe Perches547f1cf2013-03-18 10:45:01 -0700440 bLastFrag = 1;
Forest Bond5449c682009-04-25 10:30:44 -0400441
Joe Perches547f1cf2013-03-18 10:45:01 -0700442 switch (byDurType) {
Joe Perches547f1cf2013-03-18 10:45:01 -0700443 case DATADUR_B: //DATADUR_B
Teodora Baluta649520b2013-11-10 17:12:44 +0200444 if (((uMACfragNum == 1)) || bLastFrag) {//Non Frag or Last Frag
Joe Perches547f1cf2013-03-18 10:45:01 -0700445 if (bNeedAck) {
446 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700447 return pDevice->uSIFS + uAckTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700448 } else {
449 return 0;
450 }
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700451 } else {//First Frag or Mid Frag
Guido Martínezbc5cf652014-04-19 16:45:00 -0300452 if (uFragIdx == (uMACfragNum-2))
Joe Perches547f1cf2013-03-18 10:45:01 -0700453 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300454 else
Joe Perches547f1cf2013-03-18 10:45:01 -0700455 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300456
Joe Perches547f1cf2013-03-18 10:45:01 -0700457 if (bNeedAck) {
458 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700459 return pDevice->uSIFS + uAckTime + uNextPktTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700460 } else {
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700461 return pDevice->uSIFS + uNextPktTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700462 }
463 }
464 break;
Forest Bond5449c682009-04-25 10:30:44 -0400465
Joe Perches547f1cf2013-03-18 10:45:01 -0700466 case DATADUR_A: //DATADUR_A
Teodora Baluta649520b2013-11-10 17:12:44 +0200467 if (((uMACfragNum == 1)) || bLastFrag) {//Non Frag or Last Frag
Joe Perches547f1cf2013-03-18 10:45:01 -0700468 if (bNeedAck) {
469 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700470 return pDevice->uSIFS + uAckTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700471 } else {
472 return 0;
473 }
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700474 } else {//First Frag or Mid Frag
Guido Martínezbc5cf652014-04-19 16:45:00 -0300475 if (uFragIdx == (uMACfragNum-2))
Joe Perches547f1cf2013-03-18 10:45:01 -0700476 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300477 else
Joe Perches547f1cf2013-03-18 10:45:01 -0700478 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300479
Joe Perches547f1cf2013-03-18 10:45:01 -0700480 if (bNeedAck) {
481 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700482 return pDevice->uSIFS + uAckTime + uNextPktTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700483 } else {
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700484 return pDevice->uSIFS + uNextPktTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700485 }
486 }
487 break;
Forest Bond5449c682009-04-25 10:30:44 -0400488
Joe Perches547f1cf2013-03-18 10:45:01 -0700489 case DATADUR_A_F0: //DATADUR_A_F0
Teodora Baluta649520b2013-11-10 17:12:44 +0200490 if (((uMACfragNum == 1)) || bLastFrag) {//Non Frag or Last Frag
Joe Perches547f1cf2013-03-18 10:45:01 -0700491 if (bNeedAck) {
492 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700493 return pDevice->uSIFS + uAckTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700494 } else {
495 return 0;
496 }
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700497 } else { //First Frag or Mid Frag
Joe Perches547f1cf2013-03-18 10:45:01 -0700498 if (byFBOption == AUTO_FB_0) {
499 if (wRate < RATE_18M)
500 wRate = RATE_18M;
501 else if (wRate > RATE_54M)
502 wRate = RATE_54M;
Forest Bond5449c682009-04-25 10:30:44 -0400503
Guido Martínezbc5cf652014-04-19 16:45:00 -0300504 if (uFragIdx == (uMACfragNum-2))
Joe Perches547f1cf2013-03-18 10:45:01 -0700505 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300506 else
Joe Perches547f1cf2013-03-18 10:45:01 -0700507 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300508
Joe Perches547f1cf2013-03-18 10:45:01 -0700509 } else { // (byFBOption == AUTO_FB_1)
510 if (wRate < RATE_18M)
511 wRate = RATE_18M;
512 else if (wRate > RATE_54M)
513 wRate = RATE_54M;
Forest Bond5449c682009-04-25 10:30:44 -0400514
Guido Martínezbc5cf652014-04-19 16:45:00 -0300515 if (uFragIdx == (uMACfragNum-2))
Joe Perches547f1cf2013-03-18 10:45:01 -0700516 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300517 else
Joe Perches547f1cf2013-03-18 10:45:01 -0700518 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300519
Joe Perches547f1cf2013-03-18 10:45:01 -0700520 }
Forest Bond5449c682009-04-25 10:30:44 -0400521
Joe Perches547f1cf2013-03-18 10:45:01 -0700522 if (bNeedAck) {
523 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700524 return pDevice->uSIFS + uAckTime + uNextPktTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700525 } else {
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700526 return pDevice->uSIFS + uNextPktTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700527 }
528 }
529 break;
Forest Bond5449c682009-04-25 10:30:44 -0400530
Joe Perches547f1cf2013-03-18 10:45:01 -0700531 case DATADUR_A_F1: //DATADUR_A_F1
Teodora Baluta649520b2013-11-10 17:12:44 +0200532 if (((uMACfragNum == 1)) || bLastFrag) {//Non Frag or Last Frag
Joe Perches547f1cf2013-03-18 10:45:01 -0700533 if (bNeedAck) {
534 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700535 return pDevice->uSIFS + uAckTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700536 } else {
537 return 0;
538 }
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700539 } else { //First Frag or Mid Frag
Joe Perches547f1cf2013-03-18 10:45:01 -0700540 if (byFBOption == AUTO_FB_0) {
541 if (wRate < RATE_18M)
542 wRate = RATE_18M;
543 else if (wRate > RATE_54M)
544 wRate = RATE_54M;
Forest Bond5449c682009-04-25 10:30:44 -0400545
Guido Martínezbc5cf652014-04-19 16:45:00 -0300546 if (uFragIdx == (uMACfragNum-2))
Joe Perches547f1cf2013-03-18 10:45:01 -0700547 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300548 else
Joe Perches547f1cf2013-03-18 10:45:01 -0700549 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
Forest Bond5449c682009-04-25 10:30:44 -0400550
Joe Perches547f1cf2013-03-18 10:45:01 -0700551 } else { // (byFBOption == AUTO_FB_1)
552 if (wRate < RATE_18M)
553 wRate = RATE_18M;
554 else if (wRate > RATE_54M)
555 wRate = RATE_54M;
Forest Bond5449c682009-04-25 10:30:44 -0400556
Guido Martínezbc5cf652014-04-19 16:45:00 -0300557 if (uFragIdx == (uMACfragNum-2))
Joe Perches547f1cf2013-03-18 10:45:01 -0700558 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300559 else
Joe Perches547f1cf2013-03-18 10:45:01 -0700560 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
Joe Perches547f1cf2013-03-18 10:45:01 -0700561 }
562 if (bNeedAck) {
563 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700564 return pDevice->uSIFS + uAckTime + uNextPktTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700565 } else {
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700566 return pDevice->uSIFS + uNextPktTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700567 }
568 }
569 break;
Forest Bond5449c682009-04-25 10:30:44 -0400570
Joe Perches547f1cf2013-03-18 10:45:01 -0700571 default:
572 break;
573 }
Forest Bond5449c682009-04-25 10:30:44 -0400574
Charles Clément5a5a2a62010-08-01 17:15:49 +0200575 ASSERT(false);
Forest Bond5449c682009-04-25 10:30:44 -0400576 return 0;
577}
578
Forest Bond5449c682009-04-25 10:30:44 -0400579//byFreqType: 0=>5GHZ 1=>2.4GHZ
580static
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100581__le16
Joe Perches547f1cf2013-03-18 10:45:01 -0700582s_uGetRTSCTSDuration(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100583 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700584 unsigned char byDurType,
585 unsigned int cbFrameLength,
586 unsigned char byPktType,
587 unsigned short wRate,
588 bool bNeedAck,
589 unsigned char byFBOption
590)
Forest Bond5449c682009-04-25 10:30:44 -0400591{
Joe Perches547f1cf2013-03-18 10:45:01 -0700592 unsigned int uCTSTime = 0, uDurTime = 0;
Forest Bond5449c682009-04-25 10:30:44 -0400593
Joe Perches547f1cf2013-03-18 10:45:01 -0700594 switch (byDurType) {
Joe Perches547f1cf2013-03-18 10:45:01 -0700595 case RTSDUR_BB: //RTSDuration_bb
596 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
597 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
598 break;
Forest Bond5449c682009-04-25 10:30:44 -0400599
Joe Perches547f1cf2013-03-18 10:45:01 -0700600 case RTSDUR_BA: //RTSDuration_ba
601 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
602 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
603 break;
Forest Bond5449c682009-04-25 10:30:44 -0400604
Joe Perches547f1cf2013-03-18 10:45:01 -0700605 case RTSDUR_AA: //RTSDuration_aa
606 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
607 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
608 break;
Forest Bond5449c682009-04-25 10:30:44 -0400609
Joe Perches547f1cf2013-03-18 10:45:01 -0700610 case CTSDUR_BA: //CTSDuration_ba
611 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
612 break;
Forest Bond5449c682009-04-25 10:30:44 -0400613
Joe Perches547f1cf2013-03-18 10:45:01 -0700614 case RTSDUR_BA_F0: //RTSDuration_ba_f0
615 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300616 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700617 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300618 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700619 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300620
Joe Perches547f1cf2013-03-18 10:45:01 -0700621 break;
Forest Bond5449c682009-04-25 10:30:44 -0400622
Joe Perches547f1cf2013-03-18 10:45:01 -0700623 case RTSDUR_AA_F0: //RTSDuration_aa_f0
624 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300625 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700626 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300627 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700628 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300629
Joe Perches547f1cf2013-03-18 10:45:01 -0700630 break;
Forest Bond5449c682009-04-25 10:30:44 -0400631
Joe Perches547f1cf2013-03-18 10:45:01 -0700632 case RTSDUR_BA_F1: //RTSDuration_ba_f1
633 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300634 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700635 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300636 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700637 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300638
Joe Perches547f1cf2013-03-18 10:45:01 -0700639 break;
Forest Bond5449c682009-04-25 10:30:44 -0400640
Joe Perches547f1cf2013-03-18 10:45:01 -0700641 case RTSDUR_AA_F1: //RTSDuration_aa_f1
642 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300643 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700644 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300645 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700646 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300647
Joe Perches547f1cf2013-03-18 10:45:01 -0700648 break;
Forest Bond5449c682009-04-25 10:30:44 -0400649
Joe Perches547f1cf2013-03-18 10:45:01 -0700650 case CTSDUR_BA_F0: //CTSDuration_ba_f0
Guido Martínezbc5cf652014-04-19 16:45:00 -0300651 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700652 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300653 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700654 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300655
Joe Perches547f1cf2013-03-18 10:45:01 -0700656 break;
Forest Bond5449c682009-04-25 10:30:44 -0400657
Joe Perches547f1cf2013-03-18 10:45:01 -0700658 case CTSDUR_BA_F1: //CTSDuration_ba_f1
Guido Martínezbc5cf652014-04-19 16:45:00 -0300659 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700660 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300661 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700662 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300663
Joe Perches547f1cf2013-03-18 10:45:01 -0700664 break;
Forest Bond5449c682009-04-25 10:30:44 -0400665
Joe Perches547f1cf2013-03-18 10:45:01 -0700666 default:
667 break;
668 }
Forest Bond5449c682009-04-25 10:30:44 -0400669
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100670 return cpu_to_le16((u16)uDurTime);
Forest Bond5449c682009-04-25 10:30:44 -0400671}
672
Forest Bond5449c682009-04-25 10:30:44 -0400673static
Malcolm Priestleya479ffc2014-08-30 22:25:38 +0100674__le16
Joe Perches547f1cf2013-03-18 10:45:01 -0700675s_uFillDataHead(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100676 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700677 unsigned char byPktType,
678 void *pTxDataHead,
679 unsigned int cbFrameLength,
680 unsigned int uDMAIdx,
681 bool bNeedAck,
682 unsigned int uFragIdx,
683 unsigned int cbLastFragmentSize,
684 unsigned int uMACfragNum,
685 unsigned char byFBOption,
686 unsigned short wCurrentRate
687)
Forest Bond5449c682009-04-25 10:30:44 -0400688{
Forest Bond5449c682009-04-25 10:30:44 -0400689
Guido Martínezbc5cf652014-04-19 16:45:00 -0300690 if (pTxDataHead == NULL)
Joe Perches547f1cf2013-03-18 10:45:01 -0700691 return 0;
Guido Martínezbc5cf652014-04-19 16:45:00 -0300692
Forest Bond5449c682009-04-25 10:30:44 -0400693
Joe Perches547f1cf2013-03-18 10:45:01 -0700694 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
695 if (byFBOption == AUTO_FB_NONE) {
Malcolm Priestley72edb7e2014-08-30 22:25:34 +0100696 struct vnt_tx_datahead_g *buf = pTxDataHead;
Malcolm Priestley429a2472014-08-20 22:30:29 +0100697 /* Get SignalField, ServiceField & Length */
698 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
Malcolm Priestley72edb7e2014-08-30 22:25:34 +0100699 byPktType, &buf->a);
Malcolm Priestley429a2472014-08-20 22:30:29 +0100700
701 vnt_get_phy_field(pDevice, cbFrameLength,
702 pDevice->byTopCCKBasicRate,
Malcolm Priestley72edb7e2014-08-30 22:25:34 +0100703 PK_TYPE_11B, &buf->b);
Malcolm Priestley429a2472014-08-20 22:30:29 +0100704
Malcolm Priestley72edb7e2014-08-30 22:25:34 +0100705 /* Get Duration and TimeStamp */
706 buf->duration_a = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength,
707 byPktType, wCurrentRate, bNeedAck, uFragIdx,
708 cbLastFragmentSize, uMACfragNum,
709 byFBOption));
710 buf->duration_b = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength,
711 PK_TYPE_11B, pDevice->byTopCCKBasicRate,
712 bNeedAck, uFragIdx, cbLastFragmentSize,
713 uMACfragNum, byFBOption));
Forest Bond5449c682009-04-25 10:30:44 -0400714
Malcolm Priestley72edb7e2014-08-30 22:25:34 +0100715 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
716 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
Forest Bond5449c682009-04-25 10:30:44 -0400717
Malcolm Priestley72edb7e2014-08-30 22:25:34 +0100718 return buf->duration_a;
Joe Perches547f1cf2013-03-18 10:45:01 -0700719 } else {
Malcolm Priestley2dd76672014-08-30 22:25:35 +0100720 /* Auto Fallback */
721 struct vnt_tx_datahead_g_fb *buf = pTxDataHead;
Malcolm Priestley429a2472014-08-20 22:30:29 +0100722 /* Get SignalField, ServiceField & Length */
723 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
Malcolm Priestley2dd76672014-08-30 22:25:35 +0100724 byPktType, &buf->a);
Malcolm Priestley429a2472014-08-20 22:30:29 +0100725
726 vnt_get_phy_field(pDevice, cbFrameLength,
727 pDevice->byTopCCKBasicRate,
Malcolm Priestley2dd76672014-08-30 22:25:35 +0100728 PK_TYPE_11B, &buf->b);
729 /* Get Duration and TimeStamp */
730 buf->duration_a = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
731 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
732 buf->duration_b = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B,
733 pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
734 buf->duration_a_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
735 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
736 buf->duration_a_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
737 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
Forest Bond5449c682009-04-25 10:30:44 -0400738
Malcolm Priestley2dd76672014-08-30 22:25:35 +0100739 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
740 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
Forest Bond5449c682009-04-25 10:30:44 -0400741
Malcolm Priestley2dd76672014-08-30 22:25:35 +0100742 return buf->duration_a;
Joe Perches547f1cf2013-03-18 10:45:01 -0700743 } //if (byFBOption == AUTO_FB_NONE)
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700744 } else if (byPktType == PK_TYPE_11A) {
Joe Perches547f1cf2013-03-18 10:45:01 -0700745 if ((byFBOption != AUTO_FB_NONE)) {
Malcolm Priestley9c62c7a2014-08-30 22:25:37 +0100746 /* Auto Fallback */
747 struct vnt_tx_datahead_a_fb *buf = pTxDataHead;
Malcolm Priestley429a2472014-08-20 22:30:29 +0100748 /* Get SignalField, ServiceField & Length */
749 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
Malcolm Priestley9c62c7a2014-08-30 22:25:37 +0100750 byPktType, &buf->a);
Malcolm Priestley429a2472014-08-20 22:30:29 +0100751
Malcolm Priestley9c62c7a2014-08-30 22:25:37 +0100752 /* Get Duration and TimeStampOff */
753 buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
754 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
755 buf->duration_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
756 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
757 buf->duration_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
758 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
759 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
760 return buf->duration;
Joe Perches547f1cf2013-03-18 10:45:01 -0700761 } else {
Malcolm Priestley9ce842a2014-08-30 22:25:36 +0100762 struct vnt_tx_datahead_ab *buf = pTxDataHead;
Malcolm Priestley429a2472014-08-20 22:30:29 +0100763 /* Get SignalField, ServiceField & Length */
764 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
Malcolm Priestley9ce842a2014-08-30 22:25:36 +0100765 byPktType, &buf->ab);
Forest Bond5449c682009-04-25 10:30:44 -0400766
Malcolm Priestley9ce842a2014-08-30 22:25:36 +0100767 /* Get Duration and TimeStampOff */
768 buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
769 wCurrentRate, bNeedAck, uFragIdx,
770 cbLastFragmentSize, uMACfragNum,
771 byFBOption));
Forest Bond5449c682009-04-25 10:30:44 -0400772
Malcolm Priestley9ce842a2014-08-30 22:25:36 +0100773 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
774 return buf->duration;
Joe Perches547f1cf2013-03-18 10:45:01 -0700775 }
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700776 } else {
Malcolm Priestley9ce842a2014-08-30 22:25:36 +0100777 struct vnt_tx_datahead_ab *buf = pTxDataHead;
Malcolm Priestley429a2472014-08-20 22:30:29 +0100778 /* Get SignalField, ServiceField & Length */
779 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
Malcolm Priestley9ce842a2014-08-30 22:25:36 +0100780 byPktType, &buf->ab);
781 /* Get Duration and TimeStampOff */
782 buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType,
783 wCurrentRate, bNeedAck, uFragIdx,
784 cbLastFragmentSize, uMACfragNum,
785 byFBOption));
786 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
787 return buf->duration;
Joe Perches547f1cf2013-03-18 10:45:01 -0700788 }
789 return 0;
Forest Bond5449c682009-04-25 10:30:44 -0400790}
791
Forest Bond5449c682009-04-25 10:30:44 -0400792static
Charles Clément6b35b7b2010-05-07 12:30:19 -0700793void
Joe Perches547f1cf2013-03-18 10:45:01 -0700794s_vFillRTSHead(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100795 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700796 unsigned char byPktType,
797 void *pvRTS,
798 unsigned int cbFrameLength,
799 bool bNeedAck,
800 bool bDisCRC,
801 PSEthernetHeader psEthHeader,
802 unsigned short wCurrentRate,
803 unsigned char byFBOption
804)
Forest Bond5449c682009-04-25 10:30:44 -0400805{
Joe Perches547f1cf2013-03-18 10:45:01 -0700806 unsigned int uRTSFrameLen = 20;
Forest Bond5449c682009-04-25 10:30:44 -0400807
Joe Perches547f1cf2013-03-18 10:45:01 -0700808 if (pvRTS == NULL)
809 return;
Forest Bond5449c682009-04-25 10:30:44 -0400810
Joe Perches547f1cf2013-03-18 10:45:01 -0700811 if (bDisCRC) {
812 // When CRCDIS bit is on, H/W forgot to generate FCS for RTS frame,
813 // in this case we need to decrease its length by 4.
814 uRTSFrameLen -= 4;
815 }
Forest Bond5449c682009-04-25 10:30:44 -0400816
Joe Perches547f1cf2013-03-18 10:45:01 -0700817 // Note: So far RTSHead dosen't appear in ATIM & Beacom DMA, so we don't need to take them into account.
818 // Otherwise, we need to modify codes for them.
819 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
820 if (byFBOption == AUTO_FB_NONE) {
Malcolm Priestley17434f02014-08-30 22:25:41 +0100821 struct vnt_rts_g *buf = pvRTS;
Malcolm Priestley429a2472014-08-20 22:30:29 +0100822 /* Get SignalField, ServiceField & Length */
823 vnt_get_phy_field(pDevice, uRTSFrameLen,
824 pDevice->byTopCCKBasicRate,
Malcolm Priestley17434f02014-08-30 22:25:41 +0100825 PK_TYPE_11B, &buf->b);
Malcolm Priestley429a2472014-08-20 22:30:29 +0100826
827 vnt_get_phy_field(pDevice, uRTSFrameLen,
828 pDevice->byTopOFDMBasicRate,
Malcolm Priestley17434f02014-08-30 22:25:41 +0100829 byPktType, &buf->a);
830 /* Get Duration */
831 buf->duration_bb =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100832 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
833 cbFrameLength, PK_TYPE_11B,
834 pDevice->byTopCCKBasicRate,
835 bNeedAck, byFBOption);
Malcolm Priestley17434f02014-08-30 22:25:41 +0100836 buf->duration_aa =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100837 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
838 cbFrameLength, byPktType,
839 wCurrentRate, bNeedAck,
840 byFBOption);
Malcolm Priestley17434f02014-08-30 22:25:41 +0100841 buf->duration_ba =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100842 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
843 cbFrameLength, byPktType,
844 wCurrentRate, bNeedAck,
845 byFBOption);
Forest Bond5449c682009-04-25 10:30:44 -0400846
Malcolm Priestley17434f02014-08-30 22:25:41 +0100847 buf->data.duration = buf->duration_aa;
Malcolm Priestley52c41302014-08-30 22:25:39 +0100848 /* Get RTS Frame body */
Malcolm Priestley17434f02014-08-30 22:25:41 +0100849 buf->data.frame_control =
Malcolm Priestley52c41302014-08-30 22:25:39 +0100850 cpu_to_le16(IEEE80211_FTYPE_CTL |
851 IEEE80211_STYPE_RTS);
852
853
Malcolm Priestleya9873672014-08-30 22:25:49 +0100854 if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) ||
855 (pDevice->op_mode == NL80211_IFTYPE_AP)) {
Aya Mahfouz2359b5c2014-10-11 02:42:45 +0200856 ether_addr_copy(buf->data.ra,
857 psEthHeader->abyDstAddr);
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700858 } else {
Aya Mahfouz2359b5c2014-10-11 02:42:45 +0200859 ether_addr_copy(buf->data.ra,
860 pDevice->abyBSSID);
Joe Perches547f1cf2013-03-18 10:45:01 -0700861 }
Malcolm Priestleya9873672014-08-30 22:25:49 +0100862 if (pDevice->op_mode == NL80211_IFTYPE_AP)
Aya Mahfouz2359b5c2014-10-11 02:42:45 +0200863 ether_addr_copy(buf->data.ta,
864 pDevice->abyBSSID);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300865 else
Aya Mahfouz2359b5c2014-10-11 02:42:45 +0200866 ether_addr_copy(buf->data.ta,
867 psEthHeader->abySrcAddr);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300868
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700869 } else {
Malcolm Priestley9587b092014-08-30 22:25:42 +0100870 struct vnt_rts_g_fb *buf = pvRTS;
Malcolm Priestley429a2472014-08-20 22:30:29 +0100871 /* Get SignalField, ServiceField & Length */
872 vnt_get_phy_field(pDevice, uRTSFrameLen,
873 pDevice->byTopCCKBasicRate,
Malcolm Priestley9587b092014-08-30 22:25:42 +0100874 PK_TYPE_11B, &buf->b);
Forest Bond5449c682009-04-25 10:30:44 -0400875
Malcolm Priestley429a2472014-08-20 22:30:29 +0100876 vnt_get_phy_field(pDevice, uRTSFrameLen,
877 pDevice->byTopOFDMBasicRate,
Malcolm Priestley9587b092014-08-30 22:25:42 +0100878 byPktType, &buf->a);
879 /* Get Duration */
880 buf->duration_bb =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100881 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
882 cbFrameLength, PK_TYPE_11B,
883 pDevice->byTopCCKBasicRate,
884 bNeedAck, byFBOption);
Malcolm Priestley9587b092014-08-30 22:25:42 +0100885 buf->duration_aa =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100886 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
887 cbFrameLength, byPktType,
888 wCurrentRate, bNeedAck,
889 byFBOption);
Malcolm Priestley9587b092014-08-30 22:25:42 +0100890 buf->duration_ba =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100891 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
892 cbFrameLength, byPktType,
893 wCurrentRate, bNeedAck,
894 byFBOption);
Malcolm Priestley9587b092014-08-30 22:25:42 +0100895 buf->rts_duration_ba_f0 =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100896 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0,
897 cbFrameLength, byPktType,
898 wCurrentRate, bNeedAck,
899 byFBOption);
Malcolm Priestley9587b092014-08-30 22:25:42 +0100900 buf->rts_duration_aa_f0 =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100901 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
902 cbFrameLength, byPktType,
903 wCurrentRate, bNeedAck,
904 byFBOption);
Malcolm Priestley9587b092014-08-30 22:25:42 +0100905 buf->rts_duration_ba_f1 =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100906 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1,
907 cbFrameLength, byPktType,
908 wCurrentRate, bNeedAck,
909 byFBOption);
Malcolm Priestley9587b092014-08-30 22:25:42 +0100910 buf->rts_duration_aa_f1 =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100911 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
912 cbFrameLength, byPktType,
913 wCurrentRate, bNeedAck,
914 byFBOption);
Malcolm Priestley9587b092014-08-30 22:25:42 +0100915 buf->data.duration = buf->duration_aa;
Malcolm Priestley52c41302014-08-30 22:25:39 +0100916 /* Get RTS Frame body */
Malcolm Priestley9587b092014-08-30 22:25:42 +0100917 buf->data.frame_control =
Malcolm Priestley52c41302014-08-30 22:25:39 +0100918 cpu_to_le16(IEEE80211_FTYPE_CTL |
919 IEEE80211_STYPE_RTS);
920
Forest Bond5449c682009-04-25 10:30:44 -0400921
Malcolm Priestleya9873672014-08-30 22:25:49 +0100922 if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) ||
923 (pDevice->op_mode == NL80211_IFTYPE_AP)) {
Aya Mahfouz2359b5c2014-10-11 02:42:45 +0200924 ether_addr_copy(buf->data.ra,
925 psEthHeader->abyDstAddr);
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700926 } else {
Aya Mahfouz2359b5c2014-10-11 02:42:45 +0200927 ether_addr_copy(buf->data.ra,
928 pDevice->abyBSSID);
Joe Perches547f1cf2013-03-18 10:45:01 -0700929 }
Forest Bond5449c682009-04-25 10:30:44 -0400930
Malcolm Priestleya9873672014-08-30 22:25:49 +0100931 if (pDevice->op_mode == NL80211_IFTYPE_AP)
Aya Mahfouz2359b5c2014-10-11 02:42:45 +0200932 ether_addr_copy(buf->data.ta,
933 pDevice->abyBSSID);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300934 else
Aya Mahfouz2359b5c2014-10-11 02:42:45 +0200935 ether_addr_copy(buf->data.ta,
936 psEthHeader->abySrcAddr);
Forest Bond5449c682009-04-25 10:30:44 -0400937
Joe Perches547f1cf2013-03-18 10:45:01 -0700938 } // if (byFBOption == AUTO_FB_NONE)
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700939 } else if (byPktType == PK_TYPE_11A) {
Joe Perches547f1cf2013-03-18 10:45:01 -0700940 if (byFBOption == AUTO_FB_NONE) {
Malcolm Priestleye21eb1c2014-08-30 22:25:43 +0100941 struct vnt_rts_ab *buf = pvRTS;
Malcolm Priestley429a2472014-08-20 22:30:29 +0100942 /* Get SignalField, ServiceField & Length */
943 vnt_get_phy_field(pDevice, uRTSFrameLen,
944 pDevice->byTopOFDMBasicRate,
Malcolm Priestleye21eb1c2014-08-30 22:25:43 +0100945 byPktType, &buf->ab);
946 /* Get Duration */
947 buf->duration =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100948 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
949 cbFrameLength, byPktType,
950 wCurrentRate, bNeedAck,
951 byFBOption);
Malcolm Priestleye21eb1c2014-08-30 22:25:43 +0100952 buf->data.duration = buf->duration;
Malcolm Priestley52c41302014-08-30 22:25:39 +0100953 /* Get RTS Frame body */
Malcolm Priestleye21eb1c2014-08-30 22:25:43 +0100954 buf->data.frame_control =
Malcolm Priestley52c41302014-08-30 22:25:39 +0100955 cpu_to_le16(IEEE80211_FTYPE_CTL |
956 IEEE80211_STYPE_RTS);
957
Forest Bond5449c682009-04-25 10:30:44 -0400958
Malcolm Priestleya9873672014-08-30 22:25:49 +0100959 if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) ||
960 (pDevice->op_mode == NL80211_IFTYPE_AP)) {
Aya Mahfouz2359b5c2014-10-11 02:42:45 +0200961 ether_addr_copy(buf->data.ra,
962 psEthHeader->abyDstAddr);
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700963 } else {
Aya Mahfouz2359b5c2014-10-11 02:42:45 +0200964 ether_addr_copy(buf->data.ra,
965 pDevice->abyBSSID);
Joe Perches547f1cf2013-03-18 10:45:01 -0700966 }
Forest Bond5449c682009-04-25 10:30:44 -0400967
Malcolm Priestleya9873672014-08-30 22:25:49 +0100968 if (pDevice->op_mode == NL80211_IFTYPE_AP)
Aya Mahfouz2359b5c2014-10-11 02:42:45 +0200969 ether_addr_copy(buf->data.ta,
970 pDevice->abyBSSID);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300971 else
Aya Mahfouz2359b5c2014-10-11 02:42:45 +0200972 ether_addr_copy(buf->data.ta,
973 psEthHeader->abySrcAddr);
Forest Bond5449c682009-04-25 10:30:44 -0400974
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700975 } else {
Malcolm Priestley8e448042014-08-30 22:25:44 +0100976 struct vnt_rts_a_fb *buf = pvRTS;
Malcolm Priestley429a2472014-08-20 22:30:29 +0100977 /* Get SignalField, ServiceField & Length */
978 vnt_get_phy_field(pDevice, uRTSFrameLen,
979 pDevice->byTopOFDMBasicRate,
Malcolm Priestley8e448042014-08-30 22:25:44 +0100980 byPktType, &buf->a);
981 /* Get Duration */
982 buf->duration =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100983 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
984 cbFrameLength, byPktType,
985 wCurrentRate, bNeedAck,
986 byFBOption);
Malcolm Priestley8e448042014-08-30 22:25:44 +0100987 buf->rts_duration_f0 =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100988 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
989 cbFrameLength, byPktType,
990 wCurrentRate, bNeedAck,
991 byFBOption);
Malcolm Priestley8e448042014-08-30 22:25:44 +0100992 buf->rts_duration_f1 =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100993 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
994 cbFrameLength, byPktType,
995 wCurrentRate, bNeedAck,
996 byFBOption);
Malcolm Priestley8e448042014-08-30 22:25:44 +0100997 buf->data.duration = buf->duration;
Malcolm Priestley52c41302014-08-30 22:25:39 +0100998 /* Get RTS Frame body */
Malcolm Priestley8e448042014-08-30 22:25:44 +0100999 buf->data.frame_control =
Malcolm Priestley52c41302014-08-30 22:25:39 +01001000 cpu_to_le16(IEEE80211_FTYPE_CTL |
1001 IEEE80211_STYPE_RTS);
1002
Malcolm Priestleya9873672014-08-30 22:25:49 +01001003 if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) ||
1004 (pDevice->op_mode == NL80211_IFTYPE_AP)) {
Aya Mahfouz2359b5c2014-10-11 02:42:45 +02001005 ether_addr_copy(buf->data.ra,
1006 psEthHeader->abyDstAddr);
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001007 } else {
Aya Mahfouz2359b5c2014-10-11 02:42:45 +02001008 ether_addr_copy(buf->data.ra,
1009 pDevice->abyBSSID);
Joe Perches547f1cf2013-03-18 10:45:01 -07001010 }
Malcolm Priestleya9873672014-08-30 22:25:49 +01001011 if (pDevice->op_mode == NL80211_IFTYPE_AP)
Aya Mahfouz2359b5c2014-10-11 02:42:45 +02001012 ether_addr_copy(buf->data.ta,
1013 pDevice->abyBSSID);
Guido Martínezbc5cf652014-04-19 16:45:00 -03001014 else
Aya Mahfouz2359b5c2014-10-11 02:42:45 +02001015 ether_addr_copy(buf->data.ta,
1016 psEthHeader->abySrcAddr);
Joe Perches547f1cf2013-03-18 10:45:01 -07001017 }
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001018 } else if (byPktType == PK_TYPE_11B) {
Malcolm Priestleye21eb1c2014-08-30 22:25:43 +01001019 struct vnt_rts_ab *buf = pvRTS;
Malcolm Priestley429a2472014-08-20 22:30:29 +01001020 /* Get SignalField, ServiceField & Length */
1021 vnt_get_phy_field(pDevice, uRTSFrameLen,
1022 pDevice->byTopCCKBasicRate,
Malcolm Priestleye21eb1c2014-08-30 22:25:43 +01001023 PK_TYPE_11B, &buf->ab);
1024 /* Get Duration */
1025 buf->duration =
Malcolm Priestley96372bd2014-08-30 22:25:48 +01001026 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength,
1027 byPktType, wCurrentRate, bNeedAck,
1028 byFBOption);
1029
Malcolm Priestleye21eb1c2014-08-30 22:25:43 +01001030 buf->data.duration = buf->duration;
Malcolm Priestley52c41302014-08-30 22:25:39 +01001031 /* Get RTS Frame body */
Malcolm Priestleye21eb1c2014-08-30 22:25:43 +01001032 buf->data.frame_control =
Malcolm Priestley52c41302014-08-30 22:25:39 +01001033 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
Forest Bond5449c682009-04-25 10:30:44 -04001034
Malcolm Priestleya9873672014-08-30 22:25:49 +01001035 if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) ||
1036 (pDevice->op_mode == NL80211_IFTYPE_AP)) {
Aya Mahfouz2359b5c2014-10-11 02:42:45 +02001037 ether_addr_copy(buf->data.ra,
1038 psEthHeader->abyDstAddr);
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001039 } else {
Aya Mahfouz2359b5c2014-10-11 02:42:45 +02001040 ether_addr_copy(buf->data.ra, pDevice->abyBSSID);
Joe Perches547f1cf2013-03-18 10:45:01 -07001041 }
Forest Bond5449c682009-04-25 10:30:44 -04001042
Malcolm Priestleya9873672014-08-30 22:25:49 +01001043 if (pDevice->op_mode == NL80211_IFTYPE_AP)
Aya Mahfouz2359b5c2014-10-11 02:42:45 +02001044 ether_addr_copy(buf->data.ta, pDevice->abyBSSID);
Guido Martínezbc5cf652014-04-19 16:45:00 -03001045 else
Aya Mahfouz2359b5c2014-10-11 02:42:45 +02001046 ether_addr_copy(buf->data.ta,
1047 psEthHeader->abySrcAddr);
Joe Perches547f1cf2013-03-18 10:45:01 -07001048 }
Forest Bond5449c682009-04-25 10:30:44 -04001049}
1050
1051static
Charles Clément6b35b7b2010-05-07 12:30:19 -07001052void
Joe Perches547f1cf2013-03-18 10:45:01 -07001053s_vFillCTSHead(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +01001054 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -07001055 unsigned int uDMAIdx,
1056 unsigned char byPktType,
1057 void *pvCTS,
1058 unsigned int cbFrameLength,
1059 bool bNeedAck,
1060 bool bDisCRC,
1061 unsigned short wCurrentRate,
1062 unsigned char byFBOption
1063)
Forest Bond5449c682009-04-25 10:30:44 -04001064{
Joe Perches547f1cf2013-03-18 10:45:01 -07001065 unsigned int uCTSFrameLen = 14;
Forest Bond5449c682009-04-25 10:30:44 -04001066
Guido Martínezbc5cf652014-04-19 16:45:00 -03001067 if (pvCTS == NULL)
Joe Perches547f1cf2013-03-18 10:45:01 -07001068 return;
Forest Bond5449c682009-04-25 10:30:44 -04001069
Joe Perches547f1cf2013-03-18 10:45:01 -07001070 if (bDisCRC) {
1071 // When CRCDIS bit is on, H/W forgot to generate FCS for CTS frame,
1072 // in this case we need to decrease its length by 4.
1073 uCTSFrameLen -= 4;
1074 }
Forest Bond5449c682009-04-25 10:30:44 -04001075
Joe Perches547f1cf2013-03-18 10:45:01 -07001076 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
1077 if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) {
1078 // Auto Fall back
Malcolm Priestleydb1afd12014-08-30 22:25:46 +01001079 struct vnt_cts_fb *buf = pvCTS;
Malcolm Priestley429a2472014-08-20 22:30:29 +01001080 /* Get SignalField, ServiceField & Length */
1081 vnt_get_phy_field(pDevice, uCTSFrameLen,
1082 pDevice->byTopCCKBasicRate,
Malcolm Priestleydb1afd12014-08-30 22:25:46 +01001083 PK_TYPE_11B, &buf->b);
Forest Bond5449c682009-04-25 10:30:44 -04001084
Malcolm Priestley96372bd2014-08-30 22:25:48 +01001085 buf->duration_ba =
1086 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
1087 cbFrameLength, byPktType,
1088 wCurrentRate, bNeedAck,
1089 byFBOption);
1090
Malcolm Priestleydb1afd12014-08-30 22:25:46 +01001091 /* Get CTSDuration_ba_f0 */
Malcolm Priestley96372bd2014-08-30 22:25:48 +01001092 buf->cts_duration_ba_f0 =
1093 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0,
1094 cbFrameLength, byPktType,
1095 wCurrentRate, bNeedAck,
1096 byFBOption);
Malcolm Priestleydb1afd12014-08-30 22:25:46 +01001097
Malcolm Priestley96372bd2014-08-30 22:25:48 +01001098 /* Get CTSDuration_ba_f1 */
1099 buf->cts_duration_ba_f1 =
1100 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1,
1101 cbFrameLength, byPktType,
1102 wCurrentRate, bNeedAck,
1103 byFBOption);
Malcolm Priestley0864db12014-08-30 22:25:40 +01001104
Malcolm Priestleydb1afd12014-08-30 22:25:46 +01001105 /* Get CTS Frame body */
1106 buf->data.duration = buf->duration_ba;
1107
1108 buf->data.frame_control =
Malcolm Priestley0864db12014-08-30 22:25:40 +01001109 cpu_to_le16(IEEE80211_FTYPE_CTL |
1110 IEEE80211_STYPE_CTS);
1111
Malcolm Priestleydb1afd12014-08-30 22:25:46 +01001112 buf->reserved2 = 0x0;
Forest Bond5449c682009-04-25 10:30:44 -04001113
Aya Mahfouz2359b5c2014-10-11 02:42:45 +02001114 ether_addr_copy(buf->data.ra,
1115 pDevice->abyCurrentNetAddr);
Joe Perches547f1cf2013-03-18 10:45:01 -07001116 } else { //if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA)
Malcolm Priestleyf5172b02014-08-30 22:25:45 +01001117 struct vnt_cts *buf = pvCTS;
Malcolm Priestley429a2472014-08-20 22:30:29 +01001118 /* Get SignalField, ServiceField & Length */
1119 vnt_get_phy_field(pDevice, uCTSFrameLen,
1120 pDevice->byTopCCKBasicRate,
Malcolm Priestleyf5172b02014-08-30 22:25:45 +01001121 PK_TYPE_11B, &buf->b);
Malcolm Priestley429a2472014-08-20 22:30:29 +01001122
Malcolm Priestleyf5172b02014-08-30 22:25:45 +01001123 /* Get CTSDuration_ba */
1124 buf->duration_ba =
Malcolm Priestley96372bd2014-08-30 22:25:48 +01001125 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
1126 cbFrameLength, byPktType,
1127 wCurrentRate, bNeedAck,
1128 byFBOption);
Forest Bond5449c682009-04-25 10:30:44 -04001129
Malcolm Priestleyf5172b02014-08-30 22:25:45 +01001130 /* Get CTS Frame body */
1131 buf->data.duration = buf->duration_ba;
Malcolm Priestley0864db12014-08-30 22:25:40 +01001132
Malcolm Priestleyf5172b02014-08-30 22:25:45 +01001133 buf->data.frame_control =
Malcolm Priestley0864db12014-08-30 22:25:40 +01001134 cpu_to_le16(IEEE80211_FTYPE_CTL |
1135 IEEE80211_STYPE_CTS);
1136
Malcolm Priestleyf5172b02014-08-30 22:25:45 +01001137 buf->reserved2 = 0x0;
Aya Mahfouz2359b5c2014-10-11 02:42:45 +02001138 ether_addr_copy(buf->data.ra,
1139 pDevice->abyCurrentNetAddr);
Joe Perches547f1cf2013-03-18 10:45:01 -07001140 }
1141 }
Forest Bond5449c682009-04-25 10:30:44 -04001142}
1143
Forest Bond5449c682009-04-25 10:30:44 -04001144/*+
1145 *
1146 * Description:
1147 * Generate FIFO control for MAC & Baseband controller
1148 *
1149 * Parameters:
1150 * In:
Gilles Espinassef77f13e2010-03-29 15:41:47 +02001151 * pDevice - Pointer to adapter
Forest Bond5449c682009-04-25 10:30:44 -04001152 * pTxDataHead - Transmit Data Buffer
1153 * pTxBufHead - pTxBufHead
1154 * pvRrvTime - pvRrvTime
1155 * pvRTS - RTS Buffer
1156 * pCTS - CTS Buffer
1157 * cbFrameSize - Transmit Data Length (Hdr+Payload+FCS)
1158 * bNeedACK - If need ACK
1159 * uDescIdx - Desc Index
1160 * Out:
1161 * none
1162 *
1163 * Return Value: none
1164 *
Joe Perches547f1cf2013-03-18 10:45:01 -07001165 -*/
Charles Clémentb6e95cd2010-06-02 09:52:01 -07001166// unsigned int cbFrameSize,//Hdr+Payload+FCS
Forest Bond5449c682009-04-25 10:30:44 -04001167static
Charles Clément6b35b7b2010-05-07 12:30:19 -07001168void
Joe Perches547f1cf2013-03-18 10:45:01 -07001169s_vGenerateTxParameter(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +01001170 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -07001171 unsigned char byPktType,
1172 void *pTxBufHead,
1173 void *pvRrvTime,
1174 void *pvRTS,
1175 void *pvCTS,
1176 unsigned int cbFrameSize,
1177 bool bNeedACK,
1178 unsigned int uDMAIdx,
1179 PSEthernetHeader psEthHeader,
1180 unsigned short wCurrentRate
1181)
Forest Bond5449c682009-04-25 10:30:44 -04001182{
Joe Perches547f1cf2013-03-18 10:45:01 -07001183 unsigned int cbMACHdLen = WLAN_HDR_ADDR3_LEN; //24
1184 unsigned short wFifoCtl;
1185 bool bDisCRC = false;
1186 unsigned char byFBOption = AUTO_FB_NONE;
Forest Bond5449c682009-04-25 10:30:44 -04001187
Joe Perches547f1cf2013-03-18 10:45:01 -07001188 PSTxBufHead pFifoHead = (PSTxBufHead)pTxBufHead;
Guillaume Clement6b711272014-07-25 01:06:16 +02001189
Joe Perches547f1cf2013-03-18 10:45:01 -07001190 pFifoHead->wReserved = wCurrentRate;
1191 wFifoCtl = pFifoHead->wFIFOCtl;
Forest Bond5449c682009-04-25 10:30:44 -04001192
Guido Martínezbc5cf652014-04-19 16:45:00 -03001193 if (wFifoCtl & FIFOCTL_CRCDIS)
Joe Perches547f1cf2013-03-18 10:45:01 -07001194 bDisCRC = true;
Forest Bond5449c682009-04-25 10:30:44 -04001195
Guido Martínezbc5cf652014-04-19 16:45:00 -03001196 if (wFifoCtl & FIFOCTL_AUTO_FB_0)
Joe Perches547f1cf2013-03-18 10:45:01 -07001197 byFBOption = AUTO_FB_0;
Guido Martínezbc5cf652014-04-19 16:45:00 -03001198 else if (wFifoCtl & FIFOCTL_AUTO_FB_1)
Joe Perches547f1cf2013-03-18 10:45:01 -07001199 byFBOption = AUTO_FB_1;
Forest Bond5449c682009-04-25 10:30:44 -04001200
Joe Perches547f1cf2013-03-18 10:45:01 -07001201 if (pDevice->bLongHeader)
1202 cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
Forest Bond5449c682009-04-25 10:30:44 -04001203
Malcolm Priestleyc00a3782014-08-30 22:25:32 +01001204 if (!pvRrvTime)
1205 return;
1206
Joe Perches547f1cf2013-03-18 10:45:01 -07001207 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
Joe Perches547f1cf2013-03-18 10:45:01 -07001208 if (pvRTS != NULL) { //RTS_need
Malcolm Priestleyc00a3782014-08-30 22:25:32 +01001209 /* Fill RsvTime */
1210 struct vnt_rrv_time_rts *buf = pvRrvTime;
Guillaume Clement6b711272014-07-25 01:06:16 +02001211
Malcolm Priestleyc00a3782014-08-30 22:25:32 +01001212 buf->rts_rrv_time_aa = s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
1213 buf->rts_rrv_time_ba = s_uGetRTSCTSRsvTime(pDevice, 1, byPktType, cbFrameSize, wCurrentRate);
1214 buf->rts_rrv_time_bb = s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
1215 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
1216 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
1217
Joe Perches547f1cf2013-03-18 10:45:01 -07001218 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001219 } else {//RTS_needless, PCF mode
Malcolm Priestleyc00a3782014-08-30 22:25:32 +01001220 struct vnt_rrv_time_cts *buf = pvRrvTime;
Forest Bond5449c682009-04-25 10:30:44 -04001221
Malcolm Priestleyc00a3782014-08-30 22:25:32 +01001222 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
1223 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
1224 buf->cts_rrv_time_ba = s_uGetRTSCTSRsvTime(pDevice, 3, byPktType, cbFrameSize, wCurrentRate);
Forest Bond5449c682009-04-25 10:30:44 -04001225
Joe Perches547f1cf2013-03-18 10:45:01 -07001226 //Fill CTS
1227 s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
1228 }
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001229 } else if (byPktType == PK_TYPE_11A) {
Joe Perches547f1cf2013-03-18 10:45:01 -07001230 if (pvRTS != NULL) {//RTS_need, non PCF mode
Malcolm Priestleyc00a3782014-08-30 22:25:32 +01001231 struct vnt_rrv_time_ab *buf = pvRrvTime;
Guillaume Clement6b711272014-07-25 01:06:16 +02001232
Malcolm Priestleyc00a3782014-08-30 22:25:32 +01001233 buf->rts_rrv_time = s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
1234 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
1235
Joe Perches547f1cf2013-03-18 10:45:01 -07001236 //Fill RTS
1237 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001238 } else if (pvRTS == NULL) {//RTS_needless, non PCF mode
Malcolm Priestleyc00a3782014-08-30 22:25:32 +01001239 struct vnt_rrv_time_ab *buf = pvRrvTime;
Guillaume Clement6b711272014-07-25 01:06:16 +02001240
Malcolm Priestleyc00a3782014-08-30 22:25:32 +01001241 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK);
Joe Perches547f1cf2013-03-18 10:45:01 -07001242 }
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001243 } else if (byPktType == PK_TYPE_11B) {
Joe Perches547f1cf2013-03-18 10:45:01 -07001244 if ((pvRTS != NULL)) {//RTS_need, non PCF mode
Malcolm Priestleyc00a3782014-08-30 22:25:32 +01001245 struct vnt_rrv_time_ab *buf = pvRrvTime;
Guillaume Clement6b711272014-07-25 01:06:16 +02001246
Malcolm Priestleyc00a3782014-08-30 22:25:32 +01001247 buf->rts_rrv_time = s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
1248 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
1249
Joe Perches547f1cf2013-03-18 10:45:01 -07001250 //Fill RTS
1251 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001252 } else { //RTS_needless, non PCF mode
Malcolm Priestleyc00a3782014-08-30 22:25:32 +01001253 struct vnt_rrv_time_ab *buf = pvRrvTime;
Guillaume Clement6b711272014-07-25 01:06:16 +02001254
Malcolm Priestleyc00a3782014-08-30 22:25:32 +01001255 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
Joe Perches547f1cf2013-03-18 10:45:01 -07001256 }
1257 }
Forest Bond5449c682009-04-25 10:30:44 -04001258}
Guido Martínez4e8a7e52014-04-19 16:44:59 -03001259
Forest Bond5449c682009-04-25 10:30:44 -04001260static
Charles Clément6b35b7b2010-05-07 12:30:19 -07001261void
Forest Bond5449c682009-04-25 10:30:44 -04001262s_vFillFragParameter(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +01001263 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -07001264 unsigned char *pbyBuffer,
1265 unsigned int uTxType,
1266 void *pvtdCurr,
1267 unsigned short wFragType,
1268 unsigned int cbReqCount
1269)
Forest Bond5449c682009-04-25 10:30:44 -04001270{
Joe Perches547f1cf2013-03-18 10:45:01 -07001271 PSTxBufHead pTxBufHead = (PSTxBufHead) pbyBuffer;
Forest Bond5449c682009-04-25 10:30:44 -04001272
Joe Perches547f1cf2013-03-18 10:45:01 -07001273 if (uTxType == TYPE_SYNCDMA) {
Joe Perches547f1cf2013-03-18 10:45:01 -07001274 PSTxSyncDesc ptdCurr = (PSTxSyncDesc)pvtdCurr;
Forest Bond5449c682009-04-25 10:30:44 -04001275
Joe Perches547f1cf2013-03-18 10:45:01 -07001276 //Set FIFOCtl & TimeStamp in TxSyncDesc
1277 ptdCurr->m_wFIFOCtl = pTxBufHead->wFIFOCtl;
1278 ptdCurr->m_wTimeStamp = pTxBufHead->wTimeStamp;
1279 //Set TSR1 & ReqCount in TxDescHead
1280 ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount));
Guido Martínezbc5cf652014-04-19 16:45:00 -03001281 if (wFragType == FRAGCTL_ENDFRAG) //Last Fragmentation
Joe Perches547f1cf2013-03-18 10:45:01 -07001282 ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU);
Guido Martínezbc5cf652014-04-19 16:45:00 -03001283 else
Joe Perches547f1cf2013-03-18 10:45:01 -07001284 ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP);
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001285 } else {
Joe Perches547f1cf2013-03-18 10:45:01 -07001286 PSTxDesc ptdCurr = (PSTxDesc)pvtdCurr;
1287 //Set TSR1 & ReqCount in TxDescHead
1288 ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount));
Guido Martínezbc5cf652014-04-19 16:45:00 -03001289 if (wFragType == FRAGCTL_ENDFRAG) //Last Fragmentation
Joe Perches547f1cf2013-03-18 10:45:01 -07001290 ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU);
Guido Martínezbc5cf652014-04-19 16:45:00 -03001291 else
Joe Perches547f1cf2013-03-18 10:45:01 -07001292 ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP);
Joe Perches547f1cf2013-03-18 10:45:01 -07001293 }
Forest Bond5449c682009-04-25 10:30:44 -04001294
Joe Perches547f1cf2013-03-18 10:45:01 -07001295 pTxBufHead->wFragCtl |= (unsigned short)wFragType;//0x0001; //0000 0000 0000 0001
Forest Bond5449c682009-04-25 10:30:44 -04001296}
1297
Charles Clémentfe4f34b2010-06-25 10:48:53 -07001298static unsigned int
Malcolm Priestleycf76dc42014-08-10 15:46:59 +01001299s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
1300 unsigned char *pbyTxBufferAddr, unsigned int cbFrameBodySize,
1301 unsigned int uDMAIdx, PSTxDesc pHeadTD,
1302 PSEthernetHeader psEthHeader, unsigned char *pPacket,
1303 bool bNeedEncrypt, PSKeyItem pTransmitKey,
1304 unsigned int uNodeIndex, unsigned int *puMACfragNum)
Forest Bond5449c682009-04-25 10:30:44 -04001305{
Joe Perches547f1cf2013-03-18 10:45:01 -07001306 unsigned int cbMACHdLen;
1307 unsigned int cbFrameSize;
1308 unsigned int cbFragmentSize; //Hdr+(IV)+payoad+(MIC)+(ICV)+FCS
1309 unsigned int cbFragPayloadSize;
1310 unsigned int cbLastFragmentSize; //Hdr+(IV)+payoad+(MIC)+(ICV)+FCS
1311 unsigned int cbLastFragPayloadSize;
1312 unsigned int uFragIdx;
1313 unsigned char *pbyPayloadHead;
1314 unsigned char *pbyIVHead;
1315 unsigned char *pbyMacHdr;
1316 unsigned short wFragType; //00:Non-Frag, 01:Start, 10:Mid, 11:Last
Malcolm Priestleya479ffc2014-08-30 22:25:38 +01001317 __le16 uDuration;
Joe Perches547f1cf2013-03-18 10:45:01 -07001318 unsigned char *pbyBuffer;
Joe Perches547f1cf2013-03-18 10:45:01 -07001319 unsigned int cbIVlen = 0;
1320 unsigned int cbICVlen = 0;
1321 unsigned int cbMIClen = 0;
1322 unsigned int cbFCSlen = 4;
1323 unsigned int cb802_1_H_len = 0;
1324 unsigned int uLength = 0;
1325 unsigned int uTmpLen = 0;
Joe Perches547f1cf2013-03-18 10:45:01 -07001326 unsigned int cbMICHDR = 0;
Malcolm Priestley12ca22b2014-03-06 22:44:25 +00001327 u32 dwMICKey0, dwMICKey1;
1328 u32 dwMIC_Priority;
Malcolm Priestleyd0daef32014-03-06 22:44:23 +00001329 u32 *pdwMIC_L;
1330 u32 *pdwMIC_R;
Malcolm Priestley12ca22b2014-03-06 22:44:25 +00001331 u32 dwSafeMIC_L, dwSafeMIC_R; /* Fix "Last Frag Size" < "MIC length". */
Joe Perches547f1cf2013-03-18 10:45:01 -07001332 bool bMIC2Frag = false;
1333 unsigned int uMICFragLen = 0;
1334 unsigned int uMACfragNum = 1;
1335 unsigned int uPadding = 0;
1336 unsigned int cbReqCount = 0;
Forest Bond5449c682009-04-25 10:30:44 -04001337
Joe Perches547f1cf2013-03-18 10:45:01 -07001338 bool bNeedACK;
1339 bool bRTS;
1340 bool bIsAdhoc;
1341 unsigned char *pbyType;
1342 PSTxDesc ptdCurr;
1343 PSTxBufHead psTxBufHd = (PSTxBufHead) pbyTxBufferAddr;
Joe Perches547f1cf2013-03-18 10:45:01 -07001344 unsigned int cbHeaderLength = 0;
1345 void *pvRrvTime;
Malcolm Priestley11a72e52014-08-09 20:15:56 +01001346 struct vnt_mic_hdr *pMICHDR;
Joe Perches547f1cf2013-03-18 10:45:01 -07001347 void *pvRTS;
1348 void *pvCTS;
1349 void *pvTxDataHd;
1350 unsigned short wTxBufSize; // FFinfo size
1351 unsigned int uTotalCopyLength = 0;
1352 unsigned char byFBOption = AUTO_FB_NONE;
1353 bool bIsWEP256 = false;
1354 PSMgmtObject pMgmt = pDevice->pMgmt;
Forest Bond5449c682009-04-25 10:30:44 -04001355
Joe Perches547f1cf2013-03-18 10:45:01 -07001356 pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
Forest Bond5449c682009-04-25 10:30:44 -04001357
Malcolm Priestleya9873672014-08-30 22:25:49 +01001358 if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) ||
1359 (pDevice->op_mode == NL80211_IFTYPE_AP)) {
Joe Perches547f1cf2013-03-18 10:45:01 -07001360 if (is_multicast_ether_addr(&(psEthHeader->abyDstAddr[0])))
1361 bNeedACK = false;
1362 else
1363 bNeedACK = true;
1364 bIsAdhoc = true;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001365 } else {
Joe Perches547f1cf2013-03-18 10:45:01 -07001366 // MSDUs in Infra mode always need ACK
1367 bNeedACK = true;
1368 bIsAdhoc = false;
1369 }
Forest Bond5449c682009-04-25 10:30:44 -04001370
Joe Perches547f1cf2013-03-18 10:45:01 -07001371 if (pDevice->bLongHeader)
1372 cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
1373 else
1374 cbMACHdLen = WLAN_HDR_ADDR3_LEN;
Forest Bond5449c682009-04-25 10:30:44 -04001375
Joe Perches547f1cf2013-03-18 10:45:01 -07001376 if ((bNeedEncrypt == true) && (pTransmitKey != NULL)) {
1377 if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
1378 cbIVlen = 4;
1379 cbICVlen = 4;
Guido Martínezbc5cf652014-04-19 16:45:00 -03001380 if (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN)
Joe Perches547f1cf2013-03-18 10:45:01 -07001381 bIsWEP256 = true;
Joe Perches547f1cf2013-03-18 10:45:01 -07001382 }
1383 if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
1384 cbIVlen = 8;//IV+ExtIV
1385 cbMIClen = 8;
1386 cbICVlen = 4;
1387 }
1388 if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) {
1389 cbIVlen = 8;//RSN Header
1390 cbICVlen = 8;//MIC
Malcolm Priestley11a72e52014-08-09 20:15:56 +01001391 cbMICHDR = sizeof(struct vnt_mic_hdr);
Joe Perches547f1cf2013-03-18 10:45:01 -07001392 }
1393 if (pDevice->byLocalID > REV_ID_VT3253_A1) {
1394 //MAC Header should be padding 0 to DW alignment.
1395 uPadding = 4 - (cbMACHdLen%4);
1396 uPadding %= 4;
1397 }
1398 }
Forest Bond5449c682009-04-25 10:30:44 -04001399
Joe Perches547f1cf2013-03-18 10:45:01 -07001400 cbFrameSize = cbMACHdLen + cbIVlen + (cbFrameBodySize + cbMIClen) + cbICVlen + cbFCSlen;
Forest Bond5449c682009-04-25 10:30:44 -04001401
Joe Perches547f1cf2013-03-18 10:45:01 -07001402 if ((bNeedACK == false) ||
1403 (cbFrameSize < pDevice->wRTSThreshold) ||
1404 ((cbFrameSize >= pDevice->wFragmentationThreshold) && (pDevice->wFragmentationThreshold <= pDevice->wRTSThreshold))
1405) {
1406 bRTS = false;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001407 } else {
Joe Perches547f1cf2013-03-18 10:45:01 -07001408 bRTS = true;
1409 psTxBufHd->wFIFOCtl |= (FIFOCTL_RTS | FIFOCTL_LRETRY);
1410 }
1411 //
1412 // Use for AUTO FALL BACK
1413 //
Guido Martínezbc5cf652014-04-19 16:45:00 -03001414 if (psTxBufHd->wFIFOCtl & FIFOCTL_AUTO_FB_0)
Joe Perches547f1cf2013-03-18 10:45:01 -07001415 byFBOption = AUTO_FB_0;
Guido Martínezbc5cf652014-04-19 16:45:00 -03001416 else if (psTxBufHd->wFIFOCtl & FIFOCTL_AUTO_FB_1)
Joe Perches547f1cf2013-03-18 10:45:01 -07001417 byFBOption = AUTO_FB_1;
Forest Bond5449c682009-04-25 10:30:44 -04001418
Joe Perches547f1cf2013-03-18 10:45:01 -07001419 //////////////////////////////////////////////////////
1420 //Set RrvTime/RTS/CTS Buffer
1421 wTxBufSize = sizeof(STxBufHead);
1422 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
Forest Bond5449c682009-04-25 10:30:44 -04001423
Joe Perches547f1cf2013-03-18 10:45:01 -07001424 if (byFBOption == AUTO_FB_NONE) {
1425 if (bRTS == true) {//RTS_need
Malcolm Priestleya9e6a2d2014-08-30 22:25:27 +01001426 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1427 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
Malcolm Priestley17434f02014-08-30 22:25:41 +01001428 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
Joe Perches547f1cf2013-03-18 10:45:01 -07001429 pvCTS = NULL;
Malcolm Priestley17434f02014-08-30 22:25:41 +01001430 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1431 cbMICHDR + sizeof(struct vnt_rts_g));
Malcolm Priestley72edb7e2014-08-30 22:25:34 +01001432 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
Malcolm Priestley17434f02014-08-30 22:25:41 +01001433 cbMICHDR + sizeof(struct vnt_rts_g) +
1434 sizeof(struct vnt_tx_datahead_g);
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001435 } else { //RTS_needless
Malcolm Priestleyd66a5a72014-08-30 22:25:28 +01001436 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1437 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
Joe Perches547f1cf2013-03-18 10:45:01 -07001438 pvRTS = NULL;
Malcolm Priestleyf5172b02014-08-30 22:25:45 +01001439 pvCTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1440 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1441 sizeof(struct vnt_rrv_time_cts) + cbMICHDR + sizeof(struct vnt_cts));
Malcolm Priestley72edb7e2014-08-30 22:25:34 +01001442 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
Malcolm Priestleyf5172b02014-08-30 22:25:45 +01001443 cbMICHDR + sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
Joe Perches547f1cf2013-03-18 10:45:01 -07001444 }
1445 } else {
1446 // Auto Fall Back
1447 if (bRTS == true) {//RTS_need
Malcolm Priestleya9e6a2d2014-08-30 22:25:27 +01001448 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1449 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
Malcolm Priestley9587b092014-08-30 22:25:42 +01001450 pvRTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
Joe Perches547f1cf2013-03-18 10:45:01 -07001451 pvCTS = NULL;
Malcolm Priestley9587b092014-08-30 22:25:42 +01001452 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1453 cbMICHDR + sizeof(struct vnt_rts_g_fb));
Malcolm Priestley2dd76672014-08-30 22:25:35 +01001454 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
Malcolm Priestley9587b092014-08-30 22:25:42 +01001455 cbMICHDR + sizeof(struct vnt_rts_g_fb) + sizeof(struct vnt_tx_datahead_g_fb);
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001456 } else { //RTS_needless
Malcolm Priestleyd66a5a72014-08-30 22:25:28 +01001457 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1458 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
Joe Perches547f1cf2013-03-18 10:45:01 -07001459 pvRTS = NULL;
Malcolm Priestleydb1afd12014-08-30 22:25:46 +01001460 pvCTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1461 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1462 cbMICHDR + sizeof(struct vnt_cts_fb));
Malcolm Priestley2dd76672014-08-30 22:25:35 +01001463 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
Malcolm Priestleydb1afd12014-08-30 22:25:46 +01001464 cbMICHDR + sizeof(struct vnt_cts_fb) + sizeof(struct vnt_tx_datahead_g_fb);
Joe Perches547f1cf2013-03-18 10:45:01 -07001465 }
1466 } // Auto Fall Back
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001467 } else {//802.11a/b packet
Forest Bond5449c682009-04-25 10:30:44 -04001468
Joe Perches547f1cf2013-03-18 10:45:01 -07001469 if (byFBOption == AUTO_FB_NONE) {
1470 if (bRTS == true) {
Malcolm Priestleyf6a634c2014-08-30 22:25:29 +01001471 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1472 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
Malcolm Priestleye21eb1c2014-08-30 22:25:43 +01001473 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
Joe Perches547f1cf2013-03-18 10:45:01 -07001474 pvCTS = NULL;
Malcolm Priestley9ce842a2014-08-30 22:25:36 +01001475 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
Malcolm Priestleye21eb1c2014-08-30 22:25:43 +01001476 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_ab));
Malcolm Priestley9ce842a2014-08-30 22:25:36 +01001477 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
Malcolm Priestleye21eb1c2014-08-30 22:25:43 +01001478 cbMICHDR + sizeof(struct vnt_rts_ab) + sizeof(struct vnt_tx_datahead_ab);
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001479 } else { //RTS_needless, need MICHDR
Malcolm Priestleyf6a634c2014-08-30 22:25:29 +01001480 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1481 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
Joe Perches547f1cf2013-03-18 10:45:01 -07001482 pvRTS = NULL;
1483 pvCTS = NULL;
Malcolm Priestley9ce842a2014-08-30 22:25:36 +01001484 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1485 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1486 cbMICHDR + sizeof(struct vnt_tx_datahead_ab);
Joe Perches547f1cf2013-03-18 10:45:01 -07001487 }
1488 } else {
1489 // Auto Fall Back
1490 if (bRTS == true) {//RTS_need
Malcolm Priestleyf6a634c2014-08-30 22:25:29 +01001491 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1492 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
Malcolm Priestley8e448042014-08-30 22:25:44 +01001493 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
Joe Perches547f1cf2013-03-18 10:45:01 -07001494 pvCTS = NULL;
Malcolm Priestley8e448042014-08-30 22:25:44 +01001495 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1496 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_a_fb));
Malcolm Priestley9c62c7a2014-08-30 22:25:37 +01001497 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
Malcolm Priestley8e448042014-08-30 22:25:44 +01001498 cbMICHDR + sizeof(struct vnt_rts_a_fb) + sizeof(struct vnt_tx_datahead_a_fb);
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001499 } else { //RTS_needless
Malcolm Priestleyf6a634c2014-08-30 22:25:29 +01001500 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1501 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
Joe Perches547f1cf2013-03-18 10:45:01 -07001502 pvRTS = NULL;
1503 pvCTS = NULL;
Malcolm Priestley9c62c7a2014-08-30 22:25:37 +01001504 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1505 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1506 cbMICHDR + sizeof(struct vnt_tx_datahead_a_fb);
Joe Perches547f1cf2013-03-18 10:45:01 -07001507 }
1508 } // Auto Fall Back
1509 }
1510 memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize));
Forest Bond5449c682009-04-25 10:30:44 -04001511
1512//////////////////////////////////////////////////////////////////
Joe Perches547f1cf2013-03-18 10:45:01 -07001513 if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
1514 if (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
Malcolm Priestley12ca22b2014-03-06 22:44:25 +00001515 dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]);
1516 dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]);
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001517 } else if ((pTransmitKey->dwKeyIndex & AUTHENTICATOR_KEY) != 0) {
Malcolm Priestley12ca22b2014-03-06 22:44:25 +00001518 dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]);
1519 dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]);
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001520 } else {
Malcolm Priestley12ca22b2014-03-06 22:44:25 +00001521 dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[24]);
1522 dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[28]);
Joe Perches547f1cf2013-03-18 10:45:01 -07001523 }
1524 // DO Software Michael
1525 MIC_vInit(dwMICKey0, dwMICKey1);
1526 MIC_vAppend((unsigned char *)&(psEthHeader->abyDstAddr[0]), 12);
1527 dwMIC_Priority = 0;
1528 MIC_vAppend((unsigned char *)&dwMIC_Priority, 4);
Joe Perches48caf5a2014-08-17 09:17:04 -07001529 pr_debug("MIC KEY: %X, %X\n", dwMICKey0, dwMICKey1);
Joe Perches547f1cf2013-03-18 10:45:01 -07001530 }
Forest Bond5449c682009-04-25 10:30:44 -04001531
1532///////////////////////////////////////////////////////////////////
1533
Joe Perches547f1cf2013-03-18 10:45:01 -07001534 pbyMacHdr = (unsigned char *)(pbyTxBufferAddr + cbHeaderLength);
1535 pbyPayloadHead = (unsigned char *)(pbyMacHdr + cbMACHdLen + uPadding + cbIVlen);
1536 pbyIVHead = (unsigned char *)(pbyMacHdr + cbMACHdLen + uPadding);
Forest Bond5449c682009-04-25 10:30:44 -04001537
Joe Perches547f1cf2013-03-18 10:45:01 -07001538 if ((cbFrameSize > pDevice->wFragmentationThreshold) && (bNeedACK == true) && (bIsWEP256 == false)) {
1539 // Fragmentation
1540 // FragThreshold = Fragment size(Hdr+(IV)+fragment payload+(MIC)+(ICV)+FCS)
1541 cbFragmentSize = pDevice->wFragmentationThreshold;
1542 cbFragPayloadSize = cbFragmentSize - cbMACHdLen - cbIVlen - cbICVlen - cbFCSlen;
1543 //FragNum = (FrameSize-(Hdr+FCS))/(Fragment Size -(Hrd+FCS)))
1544 uMACfragNum = (unsigned short) ((cbFrameBodySize + cbMIClen) / cbFragPayloadSize);
1545 cbLastFragPayloadSize = (cbFrameBodySize + cbMIClen) % cbFragPayloadSize;
Guido Martínezbc5cf652014-04-19 16:45:00 -03001546 if (cbLastFragPayloadSize == 0)
Joe Perches547f1cf2013-03-18 10:45:01 -07001547 cbLastFragPayloadSize = cbFragPayloadSize;
Guido Martínezbc5cf652014-04-19 16:45:00 -03001548 else
Joe Perches547f1cf2013-03-18 10:45:01 -07001549 uMACfragNum++;
Guido Martínezbc5cf652014-04-19 16:45:00 -03001550
Joe Perches547f1cf2013-03-18 10:45:01 -07001551 //[Hdr+(IV)+last fragment payload+(MIC)+(ICV)+FCS]
1552 cbLastFragmentSize = cbMACHdLen + cbLastFragPayloadSize + cbIVlen + cbICVlen + cbFCSlen;
Forest Bond5449c682009-04-25 10:30:44 -04001553
Joe Perches547f1cf2013-03-18 10:45:01 -07001554 for (uFragIdx = 0; uFragIdx < uMACfragNum; uFragIdx++) {
1555 if (uFragIdx == 0) {
1556 //=========================
1557 // Start Fragmentation
1558 //=========================
Joe Perches48caf5a2014-08-17 09:17:04 -07001559 pr_debug("Start Fragmentation...\n");
Joe Perches547f1cf2013-03-18 10:45:01 -07001560 wFragType = FRAGCTL_STAFRAG;
Forest Bond5449c682009-04-25 10:30:44 -04001561
Joe Perches547f1cf2013-03-18 10:45:01 -07001562 //Fill FIFO,RrvTime,RTS,and CTS
1563 s_vGenerateTxParameter(pDevice, byPktType, (void *)psTxBufHd, pvRrvTime, pvRTS, pvCTS,
1564 cbFragmentSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate);
1565 //Fill DataHead
1566 uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFragmentSize, uDMAIdx, bNeedACK,
1567 uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption, pDevice->wCurrentRate);
1568 // Generate TX MAC Header
Malcolm Priestleya479ffc2014-08-30 22:25:38 +01001569 vGenerateMACHeader(pDevice, pbyMacHdr, uDuration, psEthHeader, bNeedEncrypt,
Joe Perches547f1cf2013-03-18 10:45:01 -07001570 wFragType, uDMAIdx, uFragIdx);
Forest Bond5449c682009-04-25 10:30:44 -04001571
Joe Perches547f1cf2013-03-18 10:45:01 -07001572 if (bNeedEncrypt == true) {
1573 //Fill TXKEY
1574 s_vFillTxKey(pDevice, (unsigned char *)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey,
1575 pbyMacHdr, (unsigned short)cbFragPayloadSize, (unsigned char *)pMICHDR);
1576 //Fill IV(ExtIV,RSNHDR)
1577 if (pDevice->bEnableHostWEP) {
1578 pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
1579 pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0;
1580 }
1581 }
Forest Bond5449c682009-04-25 10:30:44 -04001582
Joe Perches547f1cf2013-03-18 10:45:01 -07001583 // 802.1H
1584 if (ntohs(psEthHeader->wType) > ETH_DATA_LEN) {
1585 if ((psEthHeader->wType == TYPE_PKT_IPX) ||
1586 (psEthHeader->wType == cpu_to_le16(0xF380))) {
1587 memcpy((unsigned char *)(pbyPayloadHead), &pDevice->abySNAP_Bridgetunnel[0], 6);
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001588 } else {
Joe Perches547f1cf2013-03-18 10:45:01 -07001589 memcpy((unsigned char *)(pbyPayloadHead), &pDevice->abySNAP_RFC1042[0], 6);
1590 }
1591 pbyType = (unsigned char *)(pbyPayloadHead + 6);
1592 memcpy(pbyType, &(psEthHeader->wType), sizeof(unsigned short));
1593 cb802_1_H_len = 8;
1594 }
Forest Bond5449c682009-04-25 10:30:44 -04001595
Joe Perches547f1cf2013-03-18 10:45:01 -07001596 cbReqCount = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cbFragPayloadSize;
1597 //---------------------------
1598 // S/W or H/W Encryption
1599 //---------------------------
Joe Perches547f1cf2013-03-18 10:45:01 -07001600 pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf;
Forest Bond5449c682009-04-25 10:30:44 -04001601
Joe Perches547f1cf2013-03-18 10:45:01 -07001602 uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cb802_1_H_len;
1603 //copy TxBufferHeader + MacHeader to desc
1604 memcpy(pbyBuffer, (void *)psTxBufHd, uLength);
Forest Bond5449c682009-04-25 10:30:44 -04001605
Joe Perches547f1cf2013-03-18 10:45:01 -07001606 // Copy the Packet into a tx Buffer
1607 memcpy((pbyBuffer + uLength), (pPacket + 14), (cbFragPayloadSize - cb802_1_H_len));
Forest Bond5449c682009-04-25 10:30:44 -04001608
Joe Perches547f1cf2013-03-18 10:45:01 -07001609 uTotalCopyLength += cbFragPayloadSize - cb802_1_H_len;
Forest Bond5449c682009-04-25 10:30:44 -04001610
Joe Perches547f1cf2013-03-18 10:45:01 -07001611 if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
Joe Perches48caf5a2014-08-17 09:17:04 -07001612 pr_debug("Start MIC: %d\n",
1613 cbFragPayloadSize);
Joe Perches547f1cf2013-03-18 10:45:01 -07001614 MIC_vAppend((pbyBuffer + uLength - cb802_1_H_len), cbFragPayloadSize);
Forest Bond5449c682009-04-25 10:30:44 -04001615
Joe Perches547f1cf2013-03-18 10:45:01 -07001616 }
Forest Bond5449c682009-04-25 10:30:44 -04001617
Joe Perches547f1cf2013-03-18 10:45:01 -07001618 //---------------------------
1619 // S/W Encryption
1620 //---------------------------
1621 if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) {
1622 if (bNeedEncrypt) {
1623 s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength - cb802_1_H_len), (unsigned short)cbFragPayloadSize);
1624 cbReqCount += cbICVlen;
1625 }
1626 }
Forest Bond5449c682009-04-25 10:30:44 -04001627
Joe Perches547f1cf2013-03-18 10:45:01 -07001628 ptdCurr = (PSTxDesc)pHeadTD;
1629 //--------------------
1630 //1.Set TSR1 & ReqCount in TxDescHead
1631 //2.Set FragCtl in TxBufferHead
1632 //3.Set Frame Control
1633 //4.Set Sequence Control
1634 //5.Get S/W generate FCS
1635 //--------------------
1636 s_vFillFragParameter(pDevice, pbyBuffer, uDMAIdx, (void *)ptdCurr, wFragType, cbReqCount);
Forest Bond5449c682009-04-25 10:30:44 -04001637
Joe Perches547f1cf2013-03-18 10:45:01 -07001638 ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding;
1639 ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength;
1640 ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma;
1641 ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma);
1642 pDevice->iTDUsed[uDMAIdx]++;
1643 pHeadTD = ptdCurr->next;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001644 } else if (uFragIdx == (uMACfragNum-1)) {
Joe Perches547f1cf2013-03-18 10:45:01 -07001645 //=========================
1646 // Last Fragmentation
1647 //=========================
Joe Perches48caf5a2014-08-17 09:17:04 -07001648 pr_debug("Last Fragmentation...\n");
Forest Bond5449c682009-04-25 10:30:44 -04001649
Joe Perches547f1cf2013-03-18 10:45:01 -07001650 wFragType = FRAGCTL_ENDFRAG;
Forest Bond5449c682009-04-25 10:30:44 -04001651
Joe Perches547f1cf2013-03-18 10:45:01 -07001652 //Fill FIFO,RrvTime,RTS,and CTS
1653 s_vGenerateTxParameter(pDevice, byPktType, (void *)psTxBufHd, pvRrvTime, pvRTS, pvCTS,
1654 cbLastFragmentSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate);
1655 //Fill DataHead
1656 uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbLastFragmentSize, uDMAIdx, bNeedACK,
1657 uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption, pDevice->wCurrentRate);
Forest Bond5449c682009-04-25 10:30:44 -04001658
Joe Perches547f1cf2013-03-18 10:45:01 -07001659 // Generate TX MAC Header
Malcolm Priestleya479ffc2014-08-30 22:25:38 +01001660 vGenerateMACHeader(pDevice, pbyMacHdr, uDuration, psEthHeader, bNeedEncrypt,
Joe Perches547f1cf2013-03-18 10:45:01 -07001661 wFragType, uDMAIdx, uFragIdx);
Forest Bond5449c682009-04-25 10:30:44 -04001662
Joe Perches547f1cf2013-03-18 10:45:01 -07001663 if (bNeedEncrypt == true) {
1664 //Fill TXKEY
1665 s_vFillTxKey(pDevice, (unsigned char *)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey,
1666 pbyMacHdr, (unsigned short)cbLastFragPayloadSize, (unsigned char *)pMICHDR);
Forest Bond5449c682009-04-25 10:30:44 -04001667
Joe Perches547f1cf2013-03-18 10:45:01 -07001668 if (pDevice->bEnableHostWEP) {
1669 pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
1670 pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0;
1671 }
Forest Bond5449c682009-04-25 10:30:44 -04001672
Joe Perches547f1cf2013-03-18 10:45:01 -07001673 }
Forest Bond5449c682009-04-25 10:30:44 -04001674
Joe Perches547f1cf2013-03-18 10:45:01 -07001675 cbReqCount = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cbLastFragPayloadSize;
1676 //---------------------------
1677 // S/W or H/W Encryption
1678 //---------------------------
Forest Bond5449c682009-04-25 10:30:44 -04001679
Joe Perches547f1cf2013-03-18 10:45:01 -07001680 pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf;
Forest Bond5449c682009-04-25 10:30:44 -04001681
Joe Perches547f1cf2013-03-18 10:45:01 -07001682 uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen;
Forest Bond5449c682009-04-25 10:30:44 -04001683
Joe Perches547f1cf2013-03-18 10:45:01 -07001684 //copy TxBufferHeader + MacHeader to desc
1685 memcpy(pbyBuffer, (void *)psTxBufHd, uLength);
Forest Bond5449c682009-04-25 10:30:44 -04001686
Joe Perches547f1cf2013-03-18 10:45:01 -07001687 // Copy the Packet into a tx Buffer
1688 if (bMIC2Frag == false) {
Joe Perches547f1cf2013-03-18 10:45:01 -07001689 memcpy((pbyBuffer + uLength),
1690 (pPacket + 14 + uTotalCopyLength),
1691 (cbLastFragPayloadSize - cbMIClen)
1692);
1693 //TODO check uTmpLen !
1694 uTmpLen = cbLastFragPayloadSize - cbMIClen;
Forest Bond5449c682009-04-25 10:30:44 -04001695
Joe Perches547f1cf2013-03-18 10:45:01 -07001696 }
1697 if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
Joe Perches48caf5a2014-08-17 09:17:04 -07001698 pr_debug("LAST: uMICFragLen:%d, cbLastFragPayloadSize:%d, uTmpLen:%d\n",
1699 uMICFragLen,
1700 cbLastFragPayloadSize,
1701 uTmpLen);
Forest Bond5449c682009-04-25 10:30:44 -04001702
Joe Perches547f1cf2013-03-18 10:45:01 -07001703 if (bMIC2Frag == false) {
1704 if (uTmpLen != 0)
1705 MIC_vAppend((pbyBuffer + uLength), uTmpLen);
Malcolm Priestleyd0daef32014-03-06 22:44:23 +00001706 pdwMIC_L = (u32 *)(pbyBuffer + uLength + uTmpLen);
1707 pdwMIC_R = (u32 *)(pbyBuffer + uLength + uTmpLen + 4);
Joe Perches547f1cf2013-03-18 10:45:01 -07001708 MIC_vGetMIC(pdwMIC_L, pdwMIC_R);
Joe Perches48caf5a2014-08-17 09:17:04 -07001709 pr_debug("Last MIC:%X, %X\n",
1710 *pdwMIC_L, *pdwMIC_R);
Joe Perches547f1cf2013-03-18 10:45:01 -07001711 } else {
1712 if (uMICFragLen >= 4) {
1713 memcpy((pbyBuffer + uLength), ((unsigned char *)&dwSafeMIC_R + (uMICFragLen - 4)),
1714 (cbMIClen - uMICFragLen));
Joe Perches48caf5a2014-08-17 09:17:04 -07001715 pr_debug("LAST: uMICFragLen >= 4: %X, %d\n",
1716 *(unsigned char *)((unsigned char *)&dwSafeMIC_R + (uMICFragLen - 4)),
1717 (cbMIClen - uMICFragLen));
Forest Bond5449c682009-04-25 10:30:44 -04001718
Joe Perches547f1cf2013-03-18 10:45:01 -07001719 } else {
1720 memcpy((pbyBuffer + uLength), ((unsigned char *)&dwSafeMIC_L + uMICFragLen),
1721 (4 - uMICFragLen));
1722 memcpy((pbyBuffer + uLength + (4 - uMICFragLen)), &dwSafeMIC_R, 4);
Joe Perches48caf5a2014-08-17 09:17:04 -07001723 pr_debug("LAST: uMICFragLen < 4: %X, %d\n",
1724 *(unsigned char *)((unsigned char *)&dwSafeMIC_R + uMICFragLen - 4),
1725 (cbMIClen - uMICFragLen));
Joe Perches547f1cf2013-03-18 10:45:01 -07001726 }
Joe Perches547f1cf2013-03-18 10:45:01 -07001727 }
1728 MIC_vUnInit();
1729 } else {
1730 ASSERT(uTmpLen == (cbLastFragPayloadSize - cbMIClen));
1731 }
Forest Bond5449c682009-04-25 10:30:44 -04001732
Joe Perches547f1cf2013-03-18 10:45:01 -07001733 //---------------------------
1734 // S/W Encryption
1735 //---------------------------
1736 if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) {
1737 if (bNeedEncrypt) {
1738 s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength), (unsigned short)cbLastFragPayloadSize);
1739 cbReqCount += cbICVlen;
1740 }
1741 }
Forest Bond5449c682009-04-25 10:30:44 -04001742
Joe Perches547f1cf2013-03-18 10:45:01 -07001743 ptdCurr = (PSTxDesc)pHeadTD;
Forest Bond5449c682009-04-25 10:30:44 -04001744
Joe Perches547f1cf2013-03-18 10:45:01 -07001745 //--------------------
1746 //1.Set TSR1 & ReqCount in TxDescHead
1747 //2.Set FragCtl in TxBufferHead
1748 //3.Set Frame Control
1749 //4.Set Sequence Control
1750 //5.Get S/W generate FCS
1751 //--------------------
Forest Bond5449c682009-04-25 10:30:44 -04001752
Joe Perches547f1cf2013-03-18 10:45:01 -07001753 s_vFillFragParameter(pDevice, pbyBuffer, uDMAIdx, (void *)ptdCurr, wFragType, cbReqCount);
Forest Bond5449c682009-04-25 10:30:44 -04001754
Joe Perches547f1cf2013-03-18 10:45:01 -07001755 ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding;
1756 ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength;
1757 ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma;
1758 ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma);
1759 pDevice->iTDUsed[uDMAIdx]++;
1760 pHeadTD = ptdCurr->next;
Forest Bond5449c682009-04-25 10:30:44 -04001761
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001762 } else {
Joe Perches547f1cf2013-03-18 10:45:01 -07001763 //=========================
1764 // Middle Fragmentation
1765 //=========================
Joe Perches48caf5a2014-08-17 09:17:04 -07001766 pr_debug("Middle Fragmentation...\n");
Forest Bond5449c682009-04-25 10:30:44 -04001767
Joe Perches547f1cf2013-03-18 10:45:01 -07001768 wFragType = FRAGCTL_MIDFRAG;
Forest Bond5449c682009-04-25 10:30:44 -04001769
Joe Perches547f1cf2013-03-18 10:45:01 -07001770 //Fill FIFO,RrvTime,RTS,and CTS
1771 s_vGenerateTxParameter(pDevice, byPktType, (void *)psTxBufHd, pvRrvTime, pvRTS, pvCTS,
1772 cbFragmentSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate);
1773 //Fill DataHead
1774 uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFragmentSize, uDMAIdx, bNeedACK,
1775 uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption, pDevice->wCurrentRate);
Forest Bond5449c682009-04-25 10:30:44 -04001776
Joe Perches547f1cf2013-03-18 10:45:01 -07001777 // Generate TX MAC Header
Malcolm Priestleya479ffc2014-08-30 22:25:38 +01001778 vGenerateMACHeader(pDevice, pbyMacHdr, uDuration, psEthHeader, bNeedEncrypt,
Joe Perches547f1cf2013-03-18 10:45:01 -07001779 wFragType, uDMAIdx, uFragIdx);
Forest Bond5449c682009-04-25 10:30:44 -04001780
Joe Perches547f1cf2013-03-18 10:45:01 -07001781 if (bNeedEncrypt == true) {
1782 //Fill TXKEY
1783 s_vFillTxKey(pDevice, (unsigned char *)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey,
1784 pbyMacHdr, (unsigned short)cbFragPayloadSize, (unsigned char *)pMICHDR);
Forest Bond5449c682009-04-25 10:30:44 -04001785
Joe Perches547f1cf2013-03-18 10:45:01 -07001786 if (pDevice->bEnableHostWEP) {
1787 pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
1788 pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0;
1789 }
1790 }
Forest Bond5449c682009-04-25 10:30:44 -04001791
Joe Perches547f1cf2013-03-18 10:45:01 -07001792 cbReqCount = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cbFragPayloadSize;
1793 //---------------------------
1794 // S/W or H/W Encryption
1795 //---------------------------
Forest Bond5449c682009-04-25 10:30:44 -04001796
Joe Perches547f1cf2013-03-18 10:45:01 -07001797 pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf;
Joe Perches547f1cf2013-03-18 10:45:01 -07001798 uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen;
Forest Bond5449c682009-04-25 10:30:44 -04001799
Joe Perches547f1cf2013-03-18 10:45:01 -07001800 //copy TxBufferHeader + MacHeader to desc
1801 memcpy(pbyBuffer, (void *)psTxBufHd, uLength);
Forest Bond5449c682009-04-25 10:30:44 -04001802
Joe Perches547f1cf2013-03-18 10:45:01 -07001803 // Copy the Packet into a tx Buffer
1804 memcpy((pbyBuffer + uLength),
1805 (pPacket + 14 + uTotalCopyLength),
1806 cbFragPayloadSize
1807);
1808 uTmpLen = cbFragPayloadSize;
Forest Bond5449c682009-04-25 10:30:44 -04001809
Joe Perches547f1cf2013-03-18 10:45:01 -07001810 uTotalCopyLength += uTmpLen;
Forest Bond5449c682009-04-25 10:30:44 -04001811
Joe Perches547f1cf2013-03-18 10:45:01 -07001812 if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
Joe Perches547f1cf2013-03-18 10:45:01 -07001813 MIC_vAppend((pbyBuffer + uLength), uTmpLen);
Forest Bond5449c682009-04-25 10:30:44 -04001814
Joe Perches547f1cf2013-03-18 10:45:01 -07001815 if (uTmpLen < cbFragPayloadSize) {
1816 bMIC2Frag = true;
1817 uMICFragLen = cbFragPayloadSize - uTmpLen;
1818 ASSERT(uMICFragLen < cbMIClen);
Forest Bond5449c682009-04-25 10:30:44 -04001819
Malcolm Priestleyd0daef32014-03-06 22:44:23 +00001820 pdwMIC_L = (u32 *)(pbyBuffer + uLength + uTmpLen);
1821 pdwMIC_R = (u32 *)(pbyBuffer + uLength + uTmpLen + 4);
Joe Perches547f1cf2013-03-18 10:45:01 -07001822 MIC_vGetMIC(pdwMIC_L, pdwMIC_R);
1823 dwSafeMIC_L = *pdwMIC_L;
1824 dwSafeMIC_R = *pdwMIC_R;
Forest Bond5449c682009-04-25 10:30:44 -04001825
Joe Perches48caf5a2014-08-17 09:17:04 -07001826 pr_debug("MIDDLE: uMICFragLen:%d, cbFragPayloadSize:%d, uTmpLen:%d\n",
1827 uMICFragLen,
1828 cbFragPayloadSize,
1829 uTmpLen);
1830 pr_debug("Fill MIC in Middle frag [%d]\n",
1831 uMICFragLen);
1832 pr_debug("Get MIC:%X, %X\n",
1833 *pdwMIC_L, *pdwMIC_R);
Joe Perches547f1cf2013-03-18 10:45:01 -07001834 }
Joe Perches48caf5a2014-08-17 09:17:04 -07001835 pr_debug("Middle frag len: %d\n",
1836 uTmpLen);
Forest Bond5449c682009-04-25 10:30:44 -04001837
Joe Perches547f1cf2013-03-18 10:45:01 -07001838 } else {
1839 ASSERT(uTmpLen == (cbFragPayloadSize));
1840 }
Forest Bond5449c682009-04-25 10:30:44 -04001841
Joe Perches547f1cf2013-03-18 10:45:01 -07001842 if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) {
1843 if (bNeedEncrypt) {
1844 s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength), (unsigned short)cbFragPayloadSize);
1845 cbReqCount += cbICVlen;
1846 }
1847 }
Forest Bond5449c682009-04-25 10:30:44 -04001848
Joe Perches547f1cf2013-03-18 10:45:01 -07001849 ptdCurr = (PSTxDesc)pHeadTD;
Forest Bond5449c682009-04-25 10:30:44 -04001850
Joe Perches547f1cf2013-03-18 10:45:01 -07001851 //--------------------
1852 //1.Set TSR1 & ReqCount in TxDescHead
1853 //2.Set FragCtl in TxBufferHead
1854 //3.Set Frame Control
1855 //4.Set Sequence Control
1856 //5.Get S/W generate FCS
1857 //--------------------
Forest Bond5449c682009-04-25 10:30:44 -04001858
Joe Perches547f1cf2013-03-18 10:45:01 -07001859 s_vFillFragParameter(pDevice, pbyBuffer, uDMAIdx, (void *)ptdCurr, wFragType, cbReqCount);
Forest Bond5449c682009-04-25 10:30:44 -04001860
Joe Perches547f1cf2013-03-18 10:45:01 -07001861 ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding;
1862 ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength;
1863 ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma;
1864 ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma);
1865 pDevice->iTDUsed[uDMAIdx]++;
1866 pHeadTD = ptdCurr->next;
1867 }
1868 } // for (uMACfragNum)
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001869 } else {
Joe Perches547f1cf2013-03-18 10:45:01 -07001870 //=========================
1871 // No Fragmentation
1872 //=========================
Joe Perches547f1cf2013-03-18 10:45:01 -07001873 wFragType = FRAGCTL_NONFRAG;
Forest Bond5449c682009-04-25 10:30:44 -04001874
Joe Perches547f1cf2013-03-18 10:45:01 -07001875 //Set FragCtl in TxBufferHead
1876 psTxBufHd->wFragCtl |= (unsigned short)wFragType;
Forest Bond5449c682009-04-25 10:30:44 -04001877
Joe Perches547f1cf2013-03-18 10:45:01 -07001878 //Fill FIFO,RrvTime,RTS,and CTS
1879 s_vGenerateTxParameter(pDevice, byPktType, (void *)psTxBufHd, pvRrvTime, pvRTS, pvCTS,
1880 cbFrameSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate);
1881 //Fill DataHead
1882 uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,
1883 0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate);
Forest Bond5449c682009-04-25 10:30:44 -04001884
Joe Perches547f1cf2013-03-18 10:45:01 -07001885 // Generate TX MAC Header
Malcolm Priestleya479ffc2014-08-30 22:25:38 +01001886 vGenerateMACHeader(pDevice, pbyMacHdr, uDuration, psEthHeader, bNeedEncrypt,
Joe Perches547f1cf2013-03-18 10:45:01 -07001887 wFragType, uDMAIdx, 0);
Forest Bond5449c682009-04-25 10:30:44 -04001888
Joe Perches547f1cf2013-03-18 10:45:01 -07001889 if (bNeedEncrypt == true) {
1890 //Fill TXKEY
1891 s_vFillTxKey(pDevice, (unsigned char *)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey,
1892 pbyMacHdr, (unsigned short)cbFrameBodySize, (unsigned char *)pMICHDR);
Forest Bond5449c682009-04-25 10:30:44 -04001893
Joe Perches547f1cf2013-03-18 10:45:01 -07001894 if (pDevice->bEnableHostWEP) {
1895 pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
1896 pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0;
1897 }
1898 }
Forest Bond5449c682009-04-25 10:30:44 -04001899
Joe Perches547f1cf2013-03-18 10:45:01 -07001900 // 802.1H
1901 if (ntohs(psEthHeader->wType) > ETH_DATA_LEN) {
1902 if ((psEthHeader->wType == TYPE_PKT_IPX) ||
1903 (psEthHeader->wType == cpu_to_le16(0xF380))) {
1904 memcpy((unsigned char *)(pbyPayloadHead), &pDevice->abySNAP_Bridgetunnel[0], 6);
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001905 } else {
Joe Perches547f1cf2013-03-18 10:45:01 -07001906 memcpy((unsigned char *)(pbyPayloadHead), &pDevice->abySNAP_RFC1042[0], 6);
1907 }
1908 pbyType = (unsigned char *)(pbyPayloadHead + 6);
1909 memcpy(pbyType, &(psEthHeader->wType), sizeof(unsigned short));
1910 cb802_1_H_len = 8;
1911 }
Forest Bond5449c682009-04-25 10:30:44 -04001912
Joe Perches547f1cf2013-03-18 10:45:01 -07001913 cbReqCount = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + (cbFrameBodySize + cbMIClen);
1914 //---------------------------
1915 // S/W or H/W Encryption
1916 //---------------------------
Joe Perches547f1cf2013-03-18 10:45:01 -07001917 pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf;
Joe Perches547f1cf2013-03-18 10:45:01 -07001918 uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cb802_1_H_len;
Forest Bond5449c682009-04-25 10:30:44 -04001919
Joe Perches547f1cf2013-03-18 10:45:01 -07001920 //copy TxBufferHeader + MacHeader to desc
1921 memcpy(pbyBuffer, (void *)psTxBufHd, uLength);
Forest Bond5449c682009-04-25 10:30:44 -04001922
Joe Perches547f1cf2013-03-18 10:45:01 -07001923 // Copy the Packet into a tx Buffer
1924 memcpy((pbyBuffer + uLength),
1925 (pPacket + 14),
1926 cbFrameBodySize - cb802_1_H_len
1927);
Forest Bond5449c682009-04-25 10:30:44 -04001928
Joe Perches547f1cf2013-03-18 10:45:01 -07001929 if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
Joe Perches48caf5a2014-08-17 09:17:04 -07001930 pr_debug("Length:%d, %d\n",
1931 cbFrameBodySize - cb802_1_H_len, uLength);
Forest Bond5449c682009-04-25 10:30:44 -04001932
Joe Perches547f1cf2013-03-18 10:45:01 -07001933 MIC_vAppend((pbyBuffer + uLength - cb802_1_H_len), cbFrameBodySize);
Forest Bond5449c682009-04-25 10:30:44 -04001934
Malcolm Priestleyd0daef32014-03-06 22:44:23 +00001935 pdwMIC_L = (u32 *)(pbyBuffer + uLength - cb802_1_H_len + cbFrameBodySize);
1936 pdwMIC_R = (u32 *)(pbyBuffer + uLength - cb802_1_H_len + cbFrameBodySize + 4);
Forest Bond5449c682009-04-25 10:30:44 -04001937
Joe Perches547f1cf2013-03-18 10:45:01 -07001938 MIC_vGetMIC(pdwMIC_L, pdwMIC_R);
1939 MIC_vUnInit();
Forest Bond5449c682009-04-25 10:30:44 -04001940
Joe Perches547f1cf2013-03-18 10:45:01 -07001941 if (pDevice->bTxMICFail == true) {
1942 *pdwMIC_L = 0;
1943 *pdwMIC_R = 0;
1944 pDevice->bTxMICFail = false;
1945 }
Forest Bond5449c682009-04-25 10:30:44 -04001946
Joe Perches48caf5a2014-08-17 09:17:04 -07001947 pr_debug("uLength: %d, %d\n", uLength, cbFrameBodySize);
1948 pr_debug("cbReqCount:%d, %d, %d, %d\n",
1949 cbReqCount, cbHeaderLength, uPadding, cbIVlen);
1950 pr_debug("MIC:%x, %x\n", *pdwMIC_L, *pdwMIC_R);
Forest Bond5449c682009-04-25 10:30:44 -04001951
Joe Perches547f1cf2013-03-18 10:45:01 -07001952 }
Forest Bond5449c682009-04-25 10:30:44 -04001953
Joe Perches547f1cf2013-03-18 10:45:01 -07001954 if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) {
1955 if (bNeedEncrypt) {
1956 s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength - cb802_1_H_len),
1957 (unsigned short)(cbFrameBodySize + cbMIClen));
1958 cbReqCount += cbICVlen;
1959 }
1960 }
Forest Bond5449c682009-04-25 10:30:44 -04001961
Joe Perches547f1cf2013-03-18 10:45:01 -07001962 ptdCurr = (PSTxDesc)pHeadTD;
Forest Bond5449c682009-04-25 10:30:44 -04001963
Joe Perches547f1cf2013-03-18 10:45:01 -07001964 ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding;
1965 ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength;
1966 ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma;
1967 ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma);
1968 //Set TSR1 & ReqCount in TxDescHead
1969 ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU);
1970 ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount));
Forest Bond5449c682009-04-25 10:30:44 -04001971
Joe Perches547f1cf2013-03-18 10:45:01 -07001972 pDevice->iTDUsed[uDMAIdx]++;
Forest Bond5449c682009-04-25 10:30:44 -04001973
Joe Perches547f1cf2013-03-18 10:45:01 -07001974 }
1975 *puMACfragNum = uMACfragNum;
Guido Martínez4e8a7e52014-04-19 16:44:59 -03001976
Joe Perches547f1cf2013-03-18 10:45:01 -07001977 return cbHeaderLength;
Forest Bond5449c682009-04-25 10:30:44 -04001978}
1979
Charles Clément6b35b7b2010-05-07 12:30:19 -07001980void
Malcolm Priestleycf76dc42014-08-10 15:46:59 +01001981vGenerateFIFOHeader(struct vnt_private *pDevice, unsigned char byPktType,
1982 unsigned char *pbyTxBufferAddr, bool bNeedEncrypt,
1983 unsigned int cbPayloadSize, unsigned int uDMAIdx,
Joe Perches547f1cf2013-03-18 10:45:01 -07001984 PSTxDesc pHeadTD, PSEthernetHeader psEthHeader, unsigned char *pPacket,
1985 PSKeyItem pTransmitKey, unsigned int uNodeIndex, unsigned int *puMACfragNum,
1986 unsigned int *pcbHeaderSize)
Forest Bond5449c682009-04-25 10:30:44 -04001987{
Joe Perches547f1cf2013-03-18 10:45:01 -07001988 unsigned int wTxBufSize; // FFinfo size
1989 bool bNeedACK;
1990 bool bIsAdhoc;
1991 unsigned short cbMacHdLen;
1992 PSTxBufHead pTxBufHead = (PSTxBufHead) pbyTxBufferAddr;
Forest Bond5449c682009-04-25 10:30:44 -04001993
Joe Perches547f1cf2013-03-18 10:45:01 -07001994 wTxBufSize = sizeof(STxBufHead);
Forest Bond5449c682009-04-25 10:30:44 -04001995
Joe Perches547f1cf2013-03-18 10:45:01 -07001996 memset(pTxBufHead, 0, wTxBufSize);
1997 //Set FIFOCTL_NEEDACK
Forest Bond5449c682009-04-25 10:30:44 -04001998
Malcolm Priestleya9873672014-08-30 22:25:49 +01001999 if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) ||
2000 (pDevice->op_mode == NL80211_IFTYPE_AP)) {
Joe Perches547f1cf2013-03-18 10:45:01 -07002001 if (is_multicast_ether_addr(&(psEthHeader->abyDstAddr[0]))) {
2002 bNeedACK = false;
2003 pTxBufHead->wFIFOCtl = pTxBufHead->wFIFOCtl & (~FIFOCTL_NEEDACK);
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002004 } else {
Joe Perches547f1cf2013-03-18 10:45:01 -07002005 bNeedACK = true;
2006 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
2007 }
2008 bIsAdhoc = true;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002009 } else {
Joe Perches547f1cf2013-03-18 10:45:01 -07002010 // MSDUs in Infra mode always need ACK
2011 bNeedACK = true;
2012 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
2013 bIsAdhoc = false;
2014 }
Forest Bond5449c682009-04-25 10:30:44 -04002015
Joe Perches547f1cf2013-03-18 10:45:01 -07002016 pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN;
2017 pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us);
Forest Bond5449c682009-04-25 10:30:44 -04002018
Joe Perches547f1cf2013-03-18 10:45:01 -07002019 //Set FIFOCTL_LHEAD
2020 if (pDevice->bLongHeader)
2021 pTxBufHead->wFIFOCtl |= FIFOCTL_LHEAD;
Forest Bond5449c682009-04-25 10:30:44 -04002022
Joe Perches547f1cf2013-03-18 10:45:01 -07002023 //Set FIFOCTL_GENINT
Forest Bond5449c682009-04-25 10:30:44 -04002024
Joe Perches547f1cf2013-03-18 10:45:01 -07002025 pTxBufHead->wFIFOCtl |= FIFOCTL_GENINT;
Forest Bond5449c682009-04-25 10:30:44 -04002026
Joe Perches547f1cf2013-03-18 10:45:01 -07002027 //Set FIFOCTL_ISDMA0
Guido Martínezbc5cf652014-04-19 16:45:00 -03002028 if (TYPE_TXDMA0 == uDMAIdx)
Joe Perches547f1cf2013-03-18 10:45:01 -07002029 pTxBufHead->wFIFOCtl |= FIFOCTL_ISDMA0;
Forest Bond5449c682009-04-25 10:30:44 -04002030
Joe Perches547f1cf2013-03-18 10:45:01 -07002031 //Set FRAGCTL_MACHDCNT
Guido Martínezbc5cf652014-04-19 16:45:00 -03002032 if (pDevice->bLongHeader)
Joe Perches547f1cf2013-03-18 10:45:01 -07002033 cbMacHdLen = WLAN_HDR_ADDR3_LEN + 6;
Guido Martínezbc5cf652014-04-19 16:45:00 -03002034 else
Joe Perches547f1cf2013-03-18 10:45:01 -07002035 cbMacHdLen = WLAN_HDR_ADDR3_LEN;
Guido Martínezbc5cf652014-04-19 16:45:00 -03002036
Joe Perches547f1cf2013-03-18 10:45:01 -07002037 pTxBufHead->wFragCtl |= cpu_to_le16((unsigned short)(cbMacHdLen << 10));
Forest Bond5449c682009-04-25 10:30:44 -04002038
Joe Perches547f1cf2013-03-18 10:45:01 -07002039 //Set packet type
Guido Martínezbc5cf652014-04-19 16:45:00 -03002040 if (byPktType == PK_TYPE_11A) //0000 0000 0000 0000
Joe Perches547f1cf2013-03-18 10:45:01 -07002041 ;
Guido Martínezbc5cf652014-04-19 16:45:00 -03002042 else if (byPktType == PK_TYPE_11B) //0000 0001 0000 0000
Joe Perches547f1cf2013-03-18 10:45:01 -07002043 pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
Guido Martínezbc5cf652014-04-19 16:45:00 -03002044 else if (byPktType == PK_TYPE_11GB) //0000 0010 0000 0000
Joe Perches547f1cf2013-03-18 10:45:01 -07002045 pTxBufHead->wFIFOCtl |= FIFOCTL_11GB;
Guido Martínezbc5cf652014-04-19 16:45:00 -03002046 else if (byPktType == PK_TYPE_11GA) //0000 0011 0000 0000
Joe Perches547f1cf2013-03-18 10:45:01 -07002047 pTxBufHead->wFIFOCtl |= FIFOCTL_11GA;
Guido Martínezbc5cf652014-04-19 16:45:00 -03002048
Joe Perches547f1cf2013-03-18 10:45:01 -07002049 //Set FIFOCTL_GrpAckPolicy
Guido Martínezbc5cf652014-04-19 16:45:00 -03002050 if (pDevice->bGrpAckPolicy == true) //0000 0100 0000 0000
Joe Perches547f1cf2013-03-18 10:45:01 -07002051 pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK;
Forest Bond5449c682009-04-25 10:30:44 -04002052
Joe Perches547f1cf2013-03-18 10:45:01 -07002053 //Set Auto Fallback Ctl
2054 if (pDevice->wCurrentRate >= RATE_18M) {
Guido Martínezbc5cf652014-04-19 16:45:00 -03002055 if (pDevice->byAutoFBCtrl == AUTO_FB_0)
Joe Perches547f1cf2013-03-18 10:45:01 -07002056 pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_0;
Guido Martínezbc5cf652014-04-19 16:45:00 -03002057 else if (pDevice->byAutoFBCtrl == AUTO_FB_1)
Joe Perches547f1cf2013-03-18 10:45:01 -07002058 pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_1;
Joe Perches547f1cf2013-03-18 10:45:01 -07002059 }
Forest Bond5449c682009-04-25 10:30:44 -04002060
Joe Perches547f1cf2013-03-18 10:45:01 -07002061 //Set FRAGCTL_WEPTYP
2062 pDevice->bAES = false;
Forest Bond5449c682009-04-25 10:30:44 -04002063
Joe Perches547f1cf2013-03-18 10:45:01 -07002064 //Set FRAGCTL_WEPTYP
2065 if (pDevice->byLocalID > REV_ID_VT3253_A1) {
2066 if ((bNeedEncrypt) && (pTransmitKey != NULL)) { //WEP enabled
2067 if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
2068 pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002069 } else if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { //WEP40 or WEP104
Joe Perches547f1cf2013-03-18 10:45:01 -07002070 if (pTransmitKey->uKeyLength != WLAN_WEP232_KEYLEN)
2071 pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002072 } else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { //CCMP
Joe Perches547f1cf2013-03-18 10:45:01 -07002073 pTxBufHead->wFragCtl |= FRAGCTL_AES;
2074 }
2075 }
2076 }
Forest Bond5449c682009-04-25 10:30:44 -04002077
Forest Bond5449c682009-04-25 10:30:44 -04002078 RFbSetPower(pDevice, pDevice->wCurrentRate, pDevice->byCurrentCh);
Malcolm Priestley281a19d2014-08-17 20:42:27 +01002079
Joe Perches547f1cf2013-03-18 10:45:01 -07002080 pTxBufHead->byTxPower = pDevice->byCurPwr;
Forest Bond5449c682009-04-25 10:30:44 -04002081
Joe Perches547f1cf2013-03-18 10:45:01 -07002082 *pcbHeaderSize = s_cbFillTxBufHead(pDevice, byPktType, pbyTxBufferAddr, cbPayloadSize,
2083 uDMAIdx, pHeadTD, psEthHeader, pPacket, bNeedEncrypt,
2084 pTransmitKey, uNodeIndex, puMACfragNum);
Forest Bond5449c682009-04-25 10:30:44 -04002085}
2086
Forest Bond5449c682009-04-25 10:30:44 -04002087/*+
2088 *
2089 * Description:
2090 * Translate 802.3 to 802.11 header
2091 *
2092 * Parameters:
2093 * In:
Gilles Espinassef77f13e2010-03-29 15:41:47 +02002094 * pDevice - Pointer to adapter
Forest Bond5449c682009-04-25 10:30:44 -04002095 * dwTxBufferAddr - Transmit Buffer
2096 * pPacket - Packet from upper layer
2097 * cbPacketSize - Transmit Data Length
2098 * Out:
2099 * pcbHeadSize - Header size of MAC&Baseband control and 802.11 Header
2100 * pcbAppendPayload - size of append payload for 802.1H translation
2101 *
2102 * Return Value: none
2103 *
Joe Perches547f1cf2013-03-18 10:45:01 -07002104 -*/
Forest Bond5449c682009-04-25 10:30:44 -04002105
Charles Clément6b35b7b2010-05-07 12:30:19 -07002106void
Joe Perches547f1cf2013-03-18 10:45:01 -07002107vGenerateMACHeader(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +01002108 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -07002109 unsigned char *pbyBufferAddr,
Malcolm Priestleya479ffc2014-08-30 22:25:38 +01002110 __le16 wDuration,
Joe Perches547f1cf2013-03-18 10:45:01 -07002111 PSEthernetHeader psEthHeader,
2112 bool bNeedEncrypt,
2113 unsigned short wFragType,
2114 unsigned int uDMAIdx,
2115 unsigned int uFragIdx
2116)
Forest Bond5449c682009-04-25 10:30:44 -04002117{
Joe Perches547f1cf2013-03-18 10:45:01 -07002118 PS802_11Header pMACHeader = (PS802_11Header)pbyBufferAddr;
Forest Bond5449c682009-04-25 10:30:44 -04002119
Guido Martínez4e8a7e52014-04-19 16:44:59 -03002120 memset(pMACHeader, 0, (sizeof(S802_11Header)));
Forest Bond5449c682009-04-25 10:30:44 -04002121
Guido Martínezbc5cf652014-04-19 16:45:00 -03002122 if (uDMAIdx == TYPE_ATIMDMA)
Joe Perches547f1cf2013-03-18 10:45:01 -07002123 pMACHeader->wFrameCtl = TYPE_802_11_ATIM;
Guido Martínezbc5cf652014-04-19 16:45:00 -03002124 else
Joe Perches547f1cf2013-03-18 10:45:01 -07002125 pMACHeader->wFrameCtl = TYPE_802_11_DATA;
Forest Bond5449c682009-04-25 10:30:44 -04002126
Malcolm Priestleya9873672014-08-30 22:25:49 +01002127 if (pDevice->op_mode == NL80211_IFTYPE_AP) {
Aya Mahfouz2359b5c2014-10-11 02:42:45 +02002128 ether_addr_copy(&(pMACHeader->abyAddr1[0]),
2129 &(psEthHeader->abyDstAddr[0]));
2130 ether_addr_copy(&(pMACHeader->abyAddr2[0]),
2131 &(pDevice->abyBSSID[0]));
2132 ether_addr_copy(&(pMACHeader->abyAddr3[0]),
2133 &(psEthHeader->abySrcAddr[0]));
Joe Perches547f1cf2013-03-18 10:45:01 -07002134 pMACHeader->wFrameCtl |= FC_FROMDS;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002135 } else {
Malcolm Priestleya9873672014-08-30 22:25:49 +01002136 if (pDevice->op_mode == NL80211_IFTYPE_ADHOC) {
Aya Mahfouz2359b5c2014-10-11 02:42:45 +02002137 ether_addr_copy(&(pMACHeader->abyAddr1[0]),
2138 &(psEthHeader->abyDstAddr[0]));
2139 ether_addr_copy(&(pMACHeader->abyAddr2[0]),
2140 &(psEthHeader->abySrcAddr[0]));
2141 ether_addr_copy(&(pMACHeader->abyAddr3[0]),
2142 &(pDevice->abyBSSID[0]));
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002143 } else {
Aya Mahfouz2359b5c2014-10-11 02:42:45 +02002144 ether_addr_copy(&(pMACHeader->abyAddr3[0]),
2145 &(psEthHeader->abyDstAddr[0]));
2146 ether_addr_copy(&(pMACHeader->abyAddr2[0]),
2147 &(psEthHeader->abySrcAddr[0]));
2148 ether_addr_copy(&(pMACHeader->abyAddr1[0]),
2149 &(pDevice->abyBSSID[0]));
Joe Perches547f1cf2013-03-18 10:45:01 -07002150 pMACHeader->wFrameCtl |= FC_TODS;
2151 }
2152 }
Forest Bond5449c682009-04-25 10:30:44 -04002153
Joe Perches547f1cf2013-03-18 10:45:01 -07002154 if (bNeedEncrypt)
2155 pMACHeader->wFrameCtl |= cpu_to_le16((unsigned short)WLAN_SET_FC_ISWEP(1));
Forest Bond5449c682009-04-25 10:30:44 -04002156
Malcolm Priestleya479ffc2014-08-30 22:25:38 +01002157 pMACHeader->wDurationID = le16_to_cpu(wDuration);
Forest Bond5449c682009-04-25 10:30:44 -04002158
Joe Perches547f1cf2013-03-18 10:45:01 -07002159 if (pDevice->bLongHeader) {
2160 PWLAN_80211HDR_A4 pMACA4Header = (PWLAN_80211HDR_A4) pbyBufferAddr;
Guillaume Clement6b711272014-07-25 01:06:16 +02002161
Joe Perches547f1cf2013-03-18 10:45:01 -07002162 pMACHeader->wFrameCtl |= (FC_TODS | FC_FROMDS);
2163 memcpy(pMACA4Header->abyAddr4, pDevice->abyBSSID, WLAN_ADDR_LEN);
2164 }
2165 pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4);
Forest Bond5449c682009-04-25 10:30:44 -04002166
Joe Perches547f1cf2013-03-18 10:45:01 -07002167 //Set FragNumber in Sequence Control
2168 pMACHeader->wSeqCtl |= cpu_to_le16((unsigned short)uFragIdx);
Forest Bond5449c682009-04-25 10:30:44 -04002169
Joe Perches547f1cf2013-03-18 10:45:01 -07002170 if ((wFragType == FRAGCTL_ENDFRAG) || (wFragType == FRAGCTL_NONFRAG)) {
2171 pDevice->wSeqCounter++;
2172 if (pDevice->wSeqCounter > 0x0fff)
2173 pDevice->wSeqCounter = 0;
2174 }
Forest Bond5449c682009-04-25 10:30:44 -04002175
Guido Martínezbc5cf652014-04-19 16:45:00 -03002176 if ((wFragType == FRAGCTL_STAFRAG) || (wFragType == FRAGCTL_MIDFRAG)) //StartFrag or MidFrag
Joe Perches547f1cf2013-03-18 10:45:01 -07002177 pMACHeader->wFrameCtl |= FC_MOREFRAG;
Forest Bond5449c682009-04-25 10:30:44 -04002178}
2179
Malcolm Priestleycf76dc42014-08-10 15:46:59 +01002180CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice, PSTxMgmtPacket pPacket)
Guillaume Clement84b50762014-07-25 01:06:18 +02002181{
Joe Perches547f1cf2013-03-18 10:45:01 -07002182 PSTxDesc pFrstTD;
2183 unsigned char byPktType;
2184 unsigned char *pbyTxBufferAddr;
2185 void *pvRTS;
Malcolm Priestleyf5172b02014-08-30 22:25:45 +01002186 struct vnt_cts *pCTS;
Joe Perches547f1cf2013-03-18 10:45:01 -07002187 void *pvTxDataHd;
2188 unsigned int uDuration;
2189 unsigned int cbReqCount;
2190 PS802_11Header pMACHeader;
2191 unsigned int cbHeaderSize;
2192 unsigned int cbFrameBodySize;
2193 bool bNeedACK;
2194 bool bIsPSPOLL = false;
2195 PSTxBufHead pTxBufHead;
2196 unsigned int cbFrameSize;
2197 unsigned int cbIVlen = 0;
2198 unsigned int cbICVlen = 0;
2199 unsigned int cbMIClen = 0;
2200 unsigned int cbFCSlen = 4;
2201 unsigned int uPadding = 0;
2202 unsigned short wTxBufSize;
2203 unsigned int cbMacHdLen;
2204 SEthernetHeader sEthHeader;
2205 void *pvRrvTime;
2206 void *pMICHDR;
2207 PSMgmtObject pMgmt = pDevice->pMgmt;
2208 unsigned short wCurrentRate = RATE_1M;
Forest Bond5449c682009-04-25 10:30:44 -04002209
Guido Martínezbc5cf652014-04-19 16:45:00 -03002210 if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0)
Joe Perches547f1cf2013-03-18 10:45:01 -07002211 return CMD_STATUS_RESOURCES;
Forest Bond5449c682009-04-25 10:30:44 -04002212
Joe Perches547f1cf2013-03-18 10:45:01 -07002213 pFrstTD = pDevice->apCurrTD[TYPE_TXDMA0];
2214 pbyTxBufferAddr = (unsigned char *)pFrstTD->pTDInfo->buf;
2215 cbFrameBodySize = pPacket->cbPayloadLen;
2216 pTxBufHead = (PSTxBufHead) pbyTxBufferAddr;
2217 wTxBufSize = sizeof(STxBufHead);
2218 memset(pTxBufHead, 0, wTxBufSize);
Forest Bond5449c682009-04-25 10:30:44 -04002219
Joe Perches547f1cf2013-03-18 10:45:01 -07002220 if (pDevice->eCurrentPHYType == PHY_TYPE_11A) {
2221 wCurrentRate = RATE_6M;
2222 byPktType = PK_TYPE_11A;
2223 } else {
2224 wCurrentRate = RATE_1M;
2225 byPktType = PK_TYPE_11B;
2226 }
Forest Bond5449c682009-04-25 10:30:44 -04002227
Joe Perches547f1cf2013-03-18 10:45:01 -07002228 // SetPower will cause error power TX state for OFDM Date packet in TX buffer.
2229 // 2004.11.11 Kyle -- Using OFDM power to tx MngPkt will decrease the connection capability.
2230 // And cmd timer will wait data pkt TX finish before scanning so it's OK
2231 // to set power here.
Guido Martínezbc5cf652014-04-19 16:45:00 -03002232 if (pDevice->pMgmt->eScanState != WMAC_NO_SCANNING)
Forest Bond5449c682009-04-25 10:30:44 -04002233 RFbSetPower(pDevice, wCurrentRate, pDevice->byCurrentCh);
Guido Martínezbc5cf652014-04-19 16:45:00 -03002234 else
Joe Perches547f1cf2013-03-18 10:45:01 -07002235 RFbSetPower(pDevice, wCurrentRate, pMgmt->uCurrChannel);
Guido Martínezbc5cf652014-04-19 16:45:00 -03002236
Joe Perches547f1cf2013-03-18 10:45:01 -07002237 pTxBufHead->byTxPower = pDevice->byCurPwr;
2238 //+++++++++++++++++++++ Patch VT3253 A1 performance +++++++++++++++++++++++++++
2239 if (pDevice->byFOETuning) {
2240 if ((pPacket->p80211Header->sA3.wFrameCtl & TYPE_DATE_NULL) == TYPE_DATE_NULL) {
2241 wCurrentRate = RATE_24M;
2242 byPktType = PK_TYPE_11GA;
2243 }
2244 }
Forest Bond5449c682009-04-25 10:30:44 -04002245
Joe Perches547f1cf2013-03-18 10:45:01 -07002246 //Set packet type
2247 if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000
2248 pTxBufHead->wFIFOCtl = 0;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002249 } else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000
Joe Perches547f1cf2013-03-18 10:45:01 -07002250 pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002251 } else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000
Joe Perches547f1cf2013-03-18 10:45:01 -07002252 pTxBufHead->wFIFOCtl |= FIFOCTL_11GB;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002253 } else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000
Joe Perches547f1cf2013-03-18 10:45:01 -07002254 pTxBufHead->wFIFOCtl |= FIFOCTL_11GA;
2255 }
Forest Bond5449c682009-04-25 10:30:44 -04002256
Joe Perches547f1cf2013-03-18 10:45:01 -07002257 pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN;
2258 pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
Forest Bond5449c682009-04-25 10:30:44 -04002259
Joe Perches547f1cf2013-03-18 10:45:01 -07002260 if (is_multicast_ether_addr(&(pPacket->p80211Header->sA3.abyAddr1[0])))
2261 bNeedACK = false;
2262 else {
2263 bNeedACK = true;
2264 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
Teodora Baluta88cc8502013-11-10 17:12:45 +02002265 }
Forest Bond5449c682009-04-25 10:30:44 -04002266
Joe Perches547f1cf2013-03-18 10:45:01 -07002267 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) ||
2268 (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) {
Joe Perches547f1cf2013-03-18 10:45:01 -07002269 pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY;
Joe Perches547f1cf2013-03-18 10:45:01 -07002270 }
Forest Bond5449c682009-04-25 10:30:44 -04002271
Joe Perches547f1cf2013-03-18 10:45:01 -07002272 pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0);
Forest Bond5449c682009-04-25 10:30:44 -04002273
Joe Perches547f1cf2013-03-18 10:45:01 -07002274 if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) {
2275 bIsPSPOLL = true;
2276 cbMacHdLen = WLAN_HDR_ADDR2_LEN;
2277 } else {
2278 cbMacHdLen = WLAN_HDR_ADDR3_LEN;
2279 }
Forest Bond5449c682009-04-25 10:30:44 -04002280
Joe Perches547f1cf2013-03-18 10:45:01 -07002281 //Set FRAGCTL_MACHDCNT
2282 pTxBufHead->wFragCtl |= cpu_to_le16((unsigned short)(cbMacHdLen << 10));
Forest Bond5449c682009-04-25 10:30:44 -04002283
Joe Perches547f1cf2013-03-18 10:45:01 -07002284 // Notes:
2285 // Although spec says MMPDU can be fragmented; In most cases,
2286 // no one will send a MMPDU under fragmentation. With RTS may occur.
2287 pDevice->bAES = false; //Set FRAGCTL_WEPTYP
Forest Bond5449c682009-04-25 10:30:44 -04002288
Joe Perches547f1cf2013-03-18 10:45:01 -07002289 if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) {
2290 if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) {
2291 cbIVlen = 4;
2292 cbICVlen = 4;
2293 pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002294 } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
Joe Perches547f1cf2013-03-18 10:45:01 -07002295 cbIVlen = 8;//IV+ExtIV
2296 cbMIClen = 8;
2297 cbICVlen = 4;
2298 pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
2299 //We need to get seed here for filling TxKey entry.
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002300 } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
Joe Perches547f1cf2013-03-18 10:45:01 -07002301 cbIVlen = 8;//RSN Header
2302 cbICVlen = 8;//MIC
2303 pTxBufHead->wFragCtl |= FRAGCTL_AES;
2304 pDevice->bAES = true;
2305 }
2306 //MAC Header should be padding 0 to DW alignment.
2307 uPadding = 4 - (cbMacHdLen%4);
2308 uPadding %= 4;
2309 }
Forest Bond5449c682009-04-25 10:30:44 -04002310
Joe Perches547f1cf2013-03-18 10:45:01 -07002311 cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen;
Forest Bond5449c682009-04-25 10:30:44 -04002312
Joe Perches547f1cf2013-03-18 10:45:01 -07002313 //Set FIFOCTL_GrpAckPolicy
Guido Martínezbc5cf652014-04-19 16:45:00 -03002314 if (pDevice->bGrpAckPolicy == true) //0000 0100 0000 0000
Joe Perches547f1cf2013-03-18 10:45:01 -07002315 pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK;
Guido Martínezbc5cf652014-04-19 16:45:00 -03002316
Joe Perches547f1cf2013-03-18 10:45:01 -07002317 //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter()
Forest Bond5449c682009-04-25 10:30:44 -04002318
Joe Perches547f1cf2013-03-18 10:45:01 -07002319 //Set RrvTime/RTS/CTS Buffer
2320 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
Malcolm Priestleyd66a5a72014-08-30 22:25:28 +01002321 pvRrvTime = (void *) (pbyTxBufferAddr + wTxBufSize);
Joe Perches547f1cf2013-03-18 10:45:01 -07002322 pMICHDR = NULL;
2323 pvRTS = NULL;
Malcolm Priestleyf5172b02014-08-30 22:25:45 +01002324 pCTS = (struct vnt_cts *)(pbyTxBufferAddr + wTxBufSize +
Malcolm Priestleyd66a5a72014-08-30 22:25:28 +01002325 sizeof(struct vnt_rrv_time_cts));
Malcolm Priestley72edb7e2014-08-30 22:25:34 +01002326 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
Malcolm Priestleyf5172b02014-08-30 22:25:45 +01002327 sizeof(struct vnt_rrv_time_cts) + sizeof(struct vnt_cts));
Malcolm Priestleyd66a5a72014-08-30 22:25:28 +01002328 cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
Malcolm Priestleyf5172b02014-08-30 22:25:45 +01002329 sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002330 } else { // 802.11a/b packet
Malcolm Priestleyf6a634c2014-08-30 22:25:29 +01002331 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
Joe Perches547f1cf2013-03-18 10:45:01 -07002332 pMICHDR = NULL;
2333 pvRTS = NULL;
2334 pCTS = NULL;
Malcolm Priestley9ce842a2014-08-30 22:25:36 +01002335 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
2336 sizeof(struct vnt_rrv_time_ab));
2337 cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
2338 sizeof(struct vnt_tx_datahead_ab);
Joe Perches547f1cf2013-03-18 10:45:01 -07002339 }
Forest Bond5449c682009-04-25 10:30:44 -04002340
Joe Perches547f1cf2013-03-18 10:45:01 -07002341 memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderSize - wTxBufSize));
Forest Bond5449c682009-04-25 10:30:44 -04002342
Aya Mahfouz2359b5c2014-10-11 02:42:45 +02002343 ether_addr_copy(&(sEthHeader.abyDstAddr[0]),
2344 &(pPacket->p80211Header->sA3.abyAddr1[0]));
2345 ether_addr_copy(&(sEthHeader.abySrcAddr[0]),
2346 &(pPacket->p80211Header->sA3.abyAddr2[0]));
Joe Perches547f1cf2013-03-18 10:45:01 -07002347 //=========================
2348 // No Fragmentation
2349 //=========================
2350 pTxBufHead->wFragCtl |= (unsigned short)FRAGCTL_NONFRAG;
Forest Bond5449c682009-04-25 10:30:44 -04002351
Joe Perches547f1cf2013-03-18 10:45:01 -07002352 //Fill FIFO,RrvTime,RTS,and CTS
2353 s_vGenerateTxParameter(pDevice, byPktType, pbyTxBufferAddr, pvRrvTime, pvRTS, pCTS,
2354 cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader, wCurrentRate);
Forest Bond5449c682009-04-25 10:30:44 -04002355
Joe Perches547f1cf2013-03-18 10:45:01 -07002356 //Fill DataHead
2357 uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK,
2358 0, 0, 1, AUTO_FB_NONE, wCurrentRate);
Forest Bond5449c682009-04-25 10:30:44 -04002359
Joe Perches547f1cf2013-03-18 10:45:01 -07002360 pMACHeader = (PS802_11Header) (pbyTxBufferAddr + cbHeaderSize);
Forest Bond5449c682009-04-25 10:30:44 -04002361
Joe Perches547f1cf2013-03-18 10:45:01 -07002362 cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + cbFrameBodySize;
Forest Bond5449c682009-04-25 10:30:44 -04002363
Joe Perches547f1cf2013-03-18 10:45:01 -07002364 if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) {
2365 unsigned char *pbyIVHead;
2366 unsigned char *pbyPayloadHead;
2367 unsigned char *pbyBSSID;
2368 PSKeyItem pTransmitKey = NULL;
Forest Bond5449c682009-04-25 10:30:44 -04002369
Joe Perches547f1cf2013-03-18 10:45:01 -07002370 pbyIVHead = (unsigned char *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding);
2371 pbyPayloadHead = (unsigned char *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding + cbIVlen);
Forest Bond5449c682009-04-25 10:30:44 -04002372
Joe Perches547f1cf2013-03-18 10:45:01 -07002373 //Fill TXKEY
2374 //Kyle: Need fix: TKIP and AES did't encrypt Mnt Packet.
2375 //s_vFillTxKey(pDevice, (unsigned char *)pTxBufHead->adwTxKey, NULL);
Forest Bond5449c682009-04-25 10:30:44 -04002376
Joe Perches547f1cf2013-03-18 10:45:01 -07002377 //Fill IV(ExtIV,RSNHDR)
2378 //s_vFillPrePayload(pDevice, pbyIVHead, NULL);
2379 //---------------------------
2380 // S/W or H/W Encryption
2381 //---------------------------
Joe Perches547f1cf2013-03-18 10:45:01 -07002382 do {
Malcolm Priestleya9873672014-08-30 22:25:49 +01002383 if ((pDevice->op_mode == NL80211_IFTYPE_STATION) &&
Joe Perches547f1cf2013-03-18 10:45:01 -07002384 (pDevice->bLinkPass == true)) {
2385 pbyBSSID = pDevice->abyBSSID;
2386 // get pairwise key
2387 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == false) {
2388 // get group key
2389 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == true) {
Joe Perches48caf5a2014-08-17 09:17:04 -07002390 pr_debug("Get GTK\n");
Joe Perches547f1cf2013-03-18 10:45:01 -07002391 break;
2392 }
2393 } else {
Joe Perches48caf5a2014-08-17 09:17:04 -07002394 pr_debug("Get PTK\n");
Joe Perches547f1cf2013-03-18 10:45:01 -07002395 break;
2396 }
2397 }
2398 // get group key
2399 pbyBSSID = pDevice->abyBroadcastAddr;
2400 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) {
2401 pTransmitKey = NULL;
Joe Perches48caf5a2014-08-17 09:17:04 -07002402 pr_debug("KEY is NULL. OP Mode[%d]\n",
Malcolm Priestleya9873672014-08-30 22:25:49 +01002403 pDevice->op_mode);
Joe Perches547f1cf2013-03-18 10:45:01 -07002404 } else {
Joe Perches48caf5a2014-08-17 09:17:04 -07002405 pr_debug("Get GTK\n");
Joe Perches547f1cf2013-03-18 10:45:01 -07002406 }
2407 } while (false);
2408 //Fill TXKEY
2409 s_vFillTxKey(pDevice, (unsigned char *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
2410 (unsigned char *)pMACHeader, (unsigned short)cbFrameBodySize, NULL);
Forest Bond5449c682009-04-25 10:30:44 -04002411
Joe Perches547f1cf2013-03-18 10:45:01 -07002412 memcpy(pMACHeader, pPacket->p80211Header, cbMacHdLen);
2413 memcpy(pbyPayloadHead, ((unsigned char *)(pPacket->p80211Header) + cbMacHdLen),
2414 cbFrameBodySize);
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002415 } else {
Joe Perches547f1cf2013-03-18 10:45:01 -07002416 // Copy the Packet into a tx Buffer
2417 memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen);
2418 }
Forest Bond5449c682009-04-25 10:30:44 -04002419
Joe Perches547f1cf2013-03-18 10:45:01 -07002420 pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4);
2421 pDevice->wSeqCounter++;
2422 if (pDevice->wSeqCounter > 0x0fff)
2423 pDevice->wSeqCounter = 0;
Forest Bond5449c682009-04-25 10:30:44 -04002424
Joe Perches547f1cf2013-03-18 10:45:01 -07002425 if (bIsPSPOLL) {
2426 // The MAC will automatically replace the Duration-field of MAC header by Duration-field
2427 // of FIFO control header.
2428 // This will cause AID-field of PS-POLL packet to be incorrect (Because PS-POLL's AID field is
2429 // in the same place of other packet's Duration-field).
2430 // And it will cause Cisco-AP to issue Disassociation-packet
2431 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
Malcolm Priestley72edb7e2014-08-30 22:25:34 +01002432 ((struct vnt_tx_datahead_g *)pvTxDataHd)->duration_a = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
2433 ((struct vnt_tx_datahead_g *)pvTxDataHd)->duration_b = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
Joe Perches547f1cf2013-03-18 10:45:01 -07002434 } else {
Malcolm Priestley9ce842a2014-08-30 22:25:36 +01002435 ((struct vnt_tx_datahead_ab *)pvTxDataHd)->duration = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
Joe Perches547f1cf2013-03-18 10:45:01 -07002436 }
2437 }
Forest Bond5449c682009-04-25 10:30:44 -04002438
Joe Perches547f1cf2013-03-18 10:45:01 -07002439 // first TD is the only TD
2440 //Set TSR1 & ReqCount in TxDescHead
2441 pFrstTD->m_td1TD1.byTCR = (TCR_STP | TCR_EDP | EDMSDU);
2442 pFrstTD->pTDInfo->skb_dma = pFrstTD->pTDInfo->buf_dma;
2443 pFrstTD->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount));
2444 pFrstTD->buff_addr = cpu_to_le32(pFrstTD->pTDInfo->skb_dma);
2445 pFrstTD->pTDInfo->byFlags = 0;
Forest Bond5449c682009-04-25 10:30:44 -04002446
Joe Perches547f1cf2013-03-18 10:45:01 -07002447 if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) {
2448 // Disable PS
2449 MACbPSWakeup(pDevice->PortOffset);
2450 }
2451 pDevice->bPWBitOn = false;
Forest Bond5449c682009-04-25 10:30:44 -04002452
Joe Perches547f1cf2013-03-18 10:45:01 -07002453 wmb();
2454 pFrstTD->m_td0TD0.f1Owner = OWNED_BY_NIC;
2455 wmb();
Forest Bond5449c682009-04-25 10:30:44 -04002456
Joe Perches547f1cf2013-03-18 10:45:01 -07002457 pDevice->iTDUsed[TYPE_TXDMA0]++;
Forest Bond5449c682009-04-25 10:30:44 -04002458
Guido Martínezbc5cf652014-04-19 16:45:00 -03002459 if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 1)
Joe Perches48caf5a2014-08-17 09:17:04 -07002460 pr_debug(" available td0 <= 1\n");
Forest Bond5449c682009-04-25 10:30:44 -04002461
Joe Perches547f1cf2013-03-18 10:45:01 -07002462 pDevice->apCurrTD[TYPE_TXDMA0] = pFrstTD->next;
Forest Bond5449c682009-04-25 10:30:44 -04002463
Joe Perches547f1cf2013-03-18 10:45:01 -07002464 pDevice->nTxDataTimeCout = 0; //2008-8-21 chester <add> for send null packet
Forest Bond5449c682009-04-25 10:30:44 -04002465
Joe Perches547f1cf2013-03-18 10:45:01 -07002466 // Poll Transmit the adapter
2467 MACvTransmit0(pDevice->PortOffset);
Forest Bond5449c682009-04-25 10:30:44 -04002468
Joe Perches547f1cf2013-03-18 10:45:01 -07002469 return CMD_STATUS_PENDING;
Forest Bond5449c682009-04-25 10:30:44 -04002470}
2471
Malcolm Priestleycf76dc42014-08-10 15:46:59 +01002472CMD_STATUS csBeacon_xmit(struct vnt_private *pDevice, PSTxMgmtPacket pPacket)
Guillaume Clement84b50762014-07-25 01:06:18 +02002473{
Joe Perches547f1cf2013-03-18 10:45:01 -07002474 unsigned char byPktType;
2475 unsigned char *pbyBuffer = (unsigned char *)pDevice->tx_beacon_bufs;
2476 unsigned int cbFrameSize = pPacket->cbMPDULen + WLAN_FCS_LEN;
2477 unsigned int cbHeaderSize = 0;
Malcolm Priestley96417232014-08-22 22:35:11 +01002478 struct vnt_tx_short_buf_head *short_head =
2479 (struct vnt_tx_short_buf_head *)pbyBuffer;
Joe Perches547f1cf2013-03-18 10:45:01 -07002480 PS802_11Header pMACHeader;
2481 unsigned short wCurrentRate;
Forest Bond5449c682009-04-25 10:30:44 -04002482
Malcolm Priestley96417232014-08-22 22:35:11 +01002483 memset(short_head, 0, sizeof(*short_head));
Forest Bond5449c682009-04-25 10:30:44 -04002484
Joe Perches547f1cf2013-03-18 10:45:01 -07002485 if (pDevice->eCurrentPHYType == PHY_TYPE_11A) {
2486 wCurrentRate = RATE_6M;
2487 byPktType = PK_TYPE_11A;
2488 } else {
2489 wCurrentRate = RATE_2M;
2490 byPktType = PK_TYPE_11B;
2491 }
Forest Bond5449c682009-04-25 10:30:44 -04002492
Joe Perches547f1cf2013-03-18 10:45:01 -07002493 //Set Preamble type always long
2494 pDevice->byPreambleType = PREAMBLE_LONG;
Forest Bond5449c682009-04-25 10:30:44 -04002495
Malcolm Priestley96417232014-08-22 22:35:11 +01002496 /* Set FIFOCTL_GENINT */
2497 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
Forest Bond5449c682009-04-25 10:30:44 -04002498
Malcolm Priestley96417232014-08-22 22:35:11 +01002499 /* Set packet type & Get Duration */
Joe Perches547f1cf2013-03-18 10:45:01 -07002500 if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000
Malcolm Priestley96417232014-08-22 22:35:11 +01002501 short_head->duration =
2502 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A,
2503 cbFrameSize, byPktType, wCurrentRate, false,
2504 0, 0, 1, AUTO_FB_NONE));
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002505 } else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000
Malcolm Priestley96417232014-08-22 22:35:11 +01002506 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B);
2507
2508 short_head->duration =
2509 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B,
2510 cbFrameSize, byPktType, wCurrentRate, false,
2511 0, 0, 1, AUTO_FB_NONE));
Joe Perches547f1cf2013-03-18 10:45:01 -07002512 }
Forest Bond5449c682009-04-25 10:30:44 -04002513
Malcolm Priestley429a2472014-08-20 22:30:29 +01002514 vnt_get_phy_field(pDevice, cbFrameSize,
Malcolm Priestley96417232014-08-22 22:35:11 +01002515 wCurrentRate, byPktType, &short_head->ab);
Malcolm Priestley429a2472014-08-20 22:30:29 +01002516
Malcolm Priestley96417232014-08-22 22:35:11 +01002517 /* Get TimeStampOff */
Malcolm Priestleyd6b95c02014-08-30 22:25:33 +01002518 short_head->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
Malcolm Priestley96417232014-08-22 22:35:11 +01002519 cbHeaderSize = sizeof(struct vnt_tx_short_buf_head);
Forest Bond5449c682009-04-25 10:30:44 -04002520
Joe Perches547f1cf2013-03-18 10:45:01 -07002521 //Generate Beacon Header
2522 pMACHeader = (PS802_11Header)(pbyBuffer + cbHeaderSize);
2523 memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen);
Forest Bond5449c682009-04-25 10:30:44 -04002524
Joe Perches547f1cf2013-03-18 10:45:01 -07002525 pMACHeader->wDurationID = 0;
2526 pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4);
2527 pDevice->wSeqCounter++;
2528 if (pDevice->wSeqCounter > 0x0fff)
2529 pDevice->wSeqCounter = 0;
Forest Bond5449c682009-04-25 10:30:44 -04002530
Joe Perches547f1cf2013-03-18 10:45:01 -07002531 // Set Beacon buffer length
2532 pDevice->wBCNBufLen = pPacket->cbMPDULen + cbHeaderSize;
Forest Bond5449c682009-04-25 10:30:44 -04002533
Joe Perches547f1cf2013-03-18 10:45:01 -07002534 MACvSetCurrBCNTxDescAddr(pDevice->PortOffset, (pDevice->tx_beacon_dma));
Forest Bond5449c682009-04-25 10:30:44 -04002535
Joe Perches547f1cf2013-03-18 10:45:01 -07002536 MACvSetCurrBCNLength(pDevice->PortOffset, pDevice->wBCNBufLen);
2537 // Set auto Transmit on
2538 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
2539 // Poll Transmit the adapter
2540 MACvTransmitBCN(pDevice->PortOffset);
Forest Bond5449c682009-04-25 10:30:44 -04002541
Joe Perches547f1cf2013-03-18 10:45:01 -07002542 return CMD_STATUS_PENDING;
Forest Bond5449c682009-04-25 10:30:44 -04002543}
2544
Charles Clémentb6e95cd2010-06-02 09:52:01 -07002545unsigned int
Joe Perches547f1cf2013-03-18 10:45:01 -07002546cbGetFragCount(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +01002547 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -07002548 PSKeyItem pTransmitKey,
2549 unsigned int cbFrameBodySize,
2550 PSEthernetHeader psEthHeader
2551)
Forest Bond5449c682009-04-25 10:30:44 -04002552{
Joe Perches547f1cf2013-03-18 10:45:01 -07002553 unsigned int cbMACHdLen;
2554 unsigned int cbFrameSize;
2555 unsigned int cbFragmentSize; //Hdr+(IV)+payoad+(MIC)+(ICV)+FCS
2556 unsigned int cbFragPayloadSize;
2557 unsigned int cbLastFragPayloadSize;
2558 unsigned int cbIVlen = 0;
2559 unsigned int cbICVlen = 0;
2560 unsigned int cbMIClen = 0;
2561 unsigned int cbFCSlen = 4;
2562 unsigned int uMACfragNum = 1;
2563 bool bNeedACK;
Forest Bond5449c682009-04-25 10:30:44 -04002564
Malcolm Priestleya9873672014-08-30 22:25:49 +01002565 if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) ||
2566 (pDevice->op_mode == NL80211_IFTYPE_AP)) {
Joe Perches547f1cf2013-03-18 10:45:01 -07002567 if (is_multicast_ether_addr(&(psEthHeader->abyDstAddr[0])))
2568 bNeedACK = false;
2569 else
2570 bNeedACK = true;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002571 } else {
Joe Perches547f1cf2013-03-18 10:45:01 -07002572 // MSDUs in Infra mode always need ACK
2573 bNeedACK = true;
2574 }
Forest Bond5449c682009-04-25 10:30:44 -04002575
Joe Perches547f1cf2013-03-18 10:45:01 -07002576 if (pDevice->bLongHeader)
2577 cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
2578 else
2579 cbMACHdLen = WLAN_HDR_ADDR3_LEN;
Forest Bond5449c682009-04-25 10:30:44 -04002580
Joe Perches547f1cf2013-03-18 10:45:01 -07002581 if (pDevice->bEncryptionEnable == true) {
Joe Perches547f1cf2013-03-18 10:45:01 -07002582 if (pTransmitKey == NULL) {
2583 if ((pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) ||
2584 (pDevice->pMgmt->eAuthenMode < WMAC_AUTH_WPA)) {
2585 cbIVlen = 4;
2586 cbICVlen = 4;
2587 } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
2588 cbIVlen = 8;//IV+ExtIV
2589 cbMIClen = 8;
2590 cbICVlen = 4;
2591 } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
2592 cbIVlen = 8;//RSN Header
2593 cbICVlen = 8;//MIC
2594 }
2595 } else if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
2596 cbIVlen = 4;
2597 cbICVlen = 4;
2598 } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
2599 cbIVlen = 8;//IV+ExtIV
2600 cbMIClen = 8;
2601 cbICVlen = 4;
2602 } else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) {
2603 cbIVlen = 8;//RSN Header
2604 cbICVlen = 8;//MIC
2605 }
2606 }
Forest Bond5449c682009-04-25 10:30:44 -04002607
Joe Perches547f1cf2013-03-18 10:45:01 -07002608 cbFrameSize = cbMACHdLen + cbIVlen + (cbFrameBodySize + cbMIClen) + cbICVlen + cbFCSlen;
Forest Bond5449c682009-04-25 10:30:44 -04002609
Joe Perches547f1cf2013-03-18 10:45:01 -07002610 if ((cbFrameSize > pDevice->wFragmentationThreshold) && (bNeedACK == true)) {
2611 // Fragmentation
2612 cbFragmentSize = pDevice->wFragmentationThreshold;
2613 cbFragPayloadSize = cbFragmentSize - cbMACHdLen - cbIVlen - cbICVlen - cbFCSlen;
2614 uMACfragNum = (unsigned short) ((cbFrameBodySize + cbMIClen) / cbFragPayloadSize);
2615 cbLastFragPayloadSize = (cbFrameBodySize + cbMIClen) % cbFragPayloadSize;
Guido Martínezbc5cf652014-04-19 16:45:00 -03002616 if (cbLastFragPayloadSize == 0)
Joe Perches547f1cf2013-03-18 10:45:01 -07002617 cbLastFragPayloadSize = cbFragPayloadSize;
Guido Martínezbc5cf652014-04-19 16:45:00 -03002618 else
Joe Perches547f1cf2013-03-18 10:45:01 -07002619 uMACfragNum++;
Joe Perches547f1cf2013-03-18 10:45:01 -07002620 }
2621 return uMACfragNum;
Forest Bond5449c682009-04-25 10:30:44 -04002622}
2623
Malcolm Priestleycf76dc42014-08-10 15:46:59 +01002624void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb,
2625 unsigned char *pbMPDU, unsigned int cbMPDULen)
2626{
Joe Perches547f1cf2013-03-18 10:45:01 -07002627 PSTxDesc pFrstTD;
2628 unsigned char byPktType;
2629 unsigned char *pbyTxBufferAddr;
2630 void *pvRTS;
2631 void *pvCTS;
2632 void *pvTxDataHd;
2633 unsigned int uDuration;
2634 unsigned int cbReqCount;
2635 PS802_11Header pMACHeader;
2636 unsigned int cbHeaderSize;
2637 unsigned int cbFrameBodySize;
2638 bool bNeedACK;
2639 bool bIsPSPOLL = false;
2640 PSTxBufHead pTxBufHead;
2641 unsigned int cbFrameSize;
2642 unsigned int cbIVlen = 0;
2643 unsigned int cbICVlen = 0;
2644 unsigned int cbMIClen = 0;
2645 unsigned int cbFCSlen = 4;
2646 unsigned int uPadding = 0;
2647 unsigned int cbMICHDR = 0;
2648 unsigned int uLength = 0;
Malcolm Priestley12ca22b2014-03-06 22:44:25 +00002649 u32 dwMICKey0, dwMICKey1;
2650 u32 dwMIC_Priority;
Malcolm Priestleyd0daef32014-03-06 22:44:23 +00002651 u32 *pdwMIC_L;
2652 u32 *pdwMIC_R;
Joe Perches547f1cf2013-03-18 10:45:01 -07002653 unsigned short wTxBufSize;
2654 unsigned int cbMacHdLen;
2655 SEthernetHeader sEthHeader;
2656 void *pvRrvTime;
2657 void *pMICHDR;
2658 PSMgmtObject pMgmt = pDevice->pMgmt;
2659 unsigned short wCurrentRate = RATE_1M;
2660 PUWLAN_80211HDR p80211Header;
2661 unsigned int uNodeIndex = 0;
2662 bool bNodeExist = false;
2663 SKeyItem STempKey;
2664 PSKeyItem pTransmitKey = NULL;
2665 unsigned char *pbyIVHead;
2666 unsigned char *pbyPayloadHead;
2667 unsigned char *pbyMacHdr;
Forest Bond5449c682009-04-25 10:30:44 -04002668
Joe Perches547f1cf2013-03-18 10:45:01 -07002669 unsigned int cbExtSuppRate = 0;
Forest Bond5449c682009-04-25 10:30:44 -04002670
Joe Perches547f1cf2013-03-18 10:45:01 -07002671 pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
Forest Bond5449c682009-04-25 10:30:44 -04002672
Guido Martínezbc5cf652014-04-19 16:45:00 -03002673 if (cbMPDULen <= WLAN_HDR_ADDR3_LEN)
Joe Perches547f1cf2013-03-18 10:45:01 -07002674 cbFrameBodySize = 0;
Guido Martínezbc5cf652014-04-19 16:45:00 -03002675 else
Joe Perches547f1cf2013-03-18 10:45:01 -07002676 cbFrameBodySize = cbMPDULen - WLAN_HDR_ADDR3_LEN;
Guido Martínezbc5cf652014-04-19 16:45:00 -03002677
Joe Perches547f1cf2013-03-18 10:45:01 -07002678 p80211Header = (PUWLAN_80211HDR)pbMPDU;
Forest Bond5449c682009-04-25 10:30:44 -04002679
Joe Perches547f1cf2013-03-18 10:45:01 -07002680 pFrstTD = pDevice->apCurrTD[TYPE_TXDMA0];
2681 pbyTxBufferAddr = (unsigned char *)pFrstTD->pTDInfo->buf;
2682 pTxBufHead = (PSTxBufHead) pbyTxBufferAddr;
2683 wTxBufSize = sizeof(STxBufHead);
2684 memset(pTxBufHead, 0, wTxBufSize);
Forest Bond5449c682009-04-25 10:30:44 -04002685
Joe Perches547f1cf2013-03-18 10:45:01 -07002686 if (pDevice->eCurrentPHYType == PHY_TYPE_11A) {
2687 wCurrentRate = RATE_6M;
2688 byPktType = PK_TYPE_11A;
2689 } else {
2690 wCurrentRate = RATE_1M;
2691 byPktType = PK_TYPE_11B;
2692 }
Forest Bond5449c682009-04-25 10:30:44 -04002693
Joe Perches547f1cf2013-03-18 10:45:01 -07002694 // SetPower will cause error power TX state for OFDM Date packet in TX buffer.
2695 // 2004.11.11 Kyle -- Using OFDM power to tx MngPkt will decrease the connection capability.
2696 // And cmd timer will wait data pkt TX to finish before scanning so it's OK
2697 // to set power here.
Guido Martínezbc5cf652014-04-19 16:45:00 -03002698 if (pDevice->pMgmt->eScanState != WMAC_NO_SCANNING)
Joe Perches547f1cf2013-03-18 10:45:01 -07002699 RFbSetPower(pDevice, wCurrentRate, pDevice->byCurrentCh);
Guido Martínezbc5cf652014-04-19 16:45:00 -03002700 else
Joe Perches547f1cf2013-03-18 10:45:01 -07002701 RFbSetPower(pDevice, wCurrentRate, pMgmt->uCurrChannel);
Guido Martínezbc5cf652014-04-19 16:45:00 -03002702
Joe Perches547f1cf2013-03-18 10:45:01 -07002703 pTxBufHead->byTxPower = pDevice->byCurPwr;
Forest Bond5449c682009-04-25 10:30:44 -04002704
Joe Perches547f1cf2013-03-18 10:45:01 -07002705 //+++++++++++++++++++++ Patch VT3253 A1 performance +++++++++++++++++++++++++++
2706 if (pDevice->byFOETuning) {
2707 if ((p80211Header->sA3.wFrameCtl & TYPE_DATE_NULL) == TYPE_DATE_NULL) {
2708 wCurrentRate = RATE_24M;
2709 byPktType = PK_TYPE_11GA;
2710 }
2711 }
Forest Bond5449c682009-04-25 10:30:44 -04002712
Joe Perches48caf5a2014-08-17 09:17:04 -07002713 pr_debug("vDMA0_tx_80211: p80211Header->sA3.wFrameCtl = %x\n",
2714 p80211Header->sA3.wFrameCtl);
Forest Bond5449c682009-04-25 10:30:44 -04002715
Joe Perches547f1cf2013-03-18 10:45:01 -07002716 //Set packet type
2717 if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000
2718 pTxBufHead->wFIFOCtl = 0;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002719 } else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000
Joe Perches547f1cf2013-03-18 10:45:01 -07002720 pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002721 } else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000
Joe Perches547f1cf2013-03-18 10:45:01 -07002722 pTxBufHead->wFIFOCtl |= FIFOCTL_11GB;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002723 } else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000
Joe Perches547f1cf2013-03-18 10:45:01 -07002724 pTxBufHead->wFIFOCtl |= FIFOCTL_11GA;
2725 }
Forest Bond5449c682009-04-25 10:30:44 -04002726
Joe Perches547f1cf2013-03-18 10:45:01 -07002727 pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN;
2728 pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
Forest Bond5449c682009-04-25 10:30:44 -04002729
Joe Perches547f1cf2013-03-18 10:45:01 -07002730 if (is_multicast_ether_addr(&(p80211Header->sA3.abyAddr1[0]))) {
2731 bNeedACK = false;
2732 if (pDevice->bEnableHostWEP) {
2733 uNodeIndex = 0;
2734 bNodeExist = true;
2735 }
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002736 } else {
Joe Perches547f1cf2013-03-18 10:45:01 -07002737 if (pDevice->bEnableHostWEP) {
2738 if (BSSDBbIsSTAInNodeDB(pDevice->pMgmt, (unsigned char *)(p80211Header->sA3.abyAddr1), &uNodeIndex))
2739 bNodeExist = true;
2740 }
2741 bNeedACK = true;
2742 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
Teodora Baluta88cc8502013-11-10 17:12:45 +02002743 }
Forest Bond5449c682009-04-25 10:30:44 -04002744
Joe Perches547f1cf2013-03-18 10:45:01 -07002745 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) ||
2746 (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) {
Joe Perches547f1cf2013-03-18 10:45:01 -07002747 pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY;
Joe Perches547f1cf2013-03-18 10:45:01 -07002748 }
Forest Bond5449c682009-04-25 10:30:44 -04002749
Joe Perches547f1cf2013-03-18 10:45:01 -07002750 pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0);
Forest Bond5449c682009-04-25 10:30:44 -04002751
Joe Perches547f1cf2013-03-18 10:45:01 -07002752 if ((p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) {
2753 bIsPSPOLL = true;
2754 cbMacHdLen = WLAN_HDR_ADDR2_LEN;
2755 } else {
2756 cbMacHdLen = WLAN_HDR_ADDR3_LEN;
2757 }
Forest Bond5449c682009-04-25 10:30:44 -04002758
Joe Perches547f1cf2013-03-18 10:45:01 -07002759 // hostapd deamon ext support rate patch
2760 if (WLAN_GET_FC_FSTYPE(p80211Header->sA4.wFrameCtl) == WLAN_FSTYPE_ASSOCRESP) {
Guido Martínezbc5cf652014-04-19 16:45:00 -03002761 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len != 0)
Joe Perches547f1cf2013-03-18 10:45:01 -07002762 cbExtSuppRate += ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN;
Forest Bond5449c682009-04-25 10:30:44 -04002763
Guido Martínezbc5cf652014-04-19 16:45:00 -03002764 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len != 0)
Joe Perches547f1cf2013-03-18 10:45:01 -07002765 cbExtSuppRate += ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
Forest Bond5449c682009-04-25 10:30:44 -04002766
Guido Martínezbc5cf652014-04-19 16:45:00 -03002767 if (cbExtSuppRate > 0)
Joe Perches547f1cf2013-03-18 10:45:01 -07002768 cbFrameBodySize = WLAN_ASSOCRESP_OFF_SUPP_RATES;
Joe Perches547f1cf2013-03-18 10:45:01 -07002769 }
Forest Bond5449c682009-04-25 10:30:44 -04002770
Joe Perches547f1cf2013-03-18 10:45:01 -07002771 //Set FRAGCTL_MACHDCNT
2772 pTxBufHead->wFragCtl |= cpu_to_le16((unsigned short)cbMacHdLen << 10);
Forest Bond5449c682009-04-25 10:30:44 -04002773
Joe Perches547f1cf2013-03-18 10:45:01 -07002774 // Notes:
2775 // Although spec says MMPDU can be fragmented; In most cases,
2776 // no one will send a MMPDU under fragmentation. With RTS may occur.
2777 pDevice->bAES = false; //Set FRAGCTL_WEPTYP
Forest Bond5449c682009-04-25 10:30:44 -04002778
Joe Perches547f1cf2013-03-18 10:45:01 -07002779 if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) {
2780 if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) {
2781 cbIVlen = 4;
2782 cbICVlen = 4;
2783 pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002784 } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
Joe Perches547f1cf2013-03-18 10:45:01 -07002785 cbIVlen = 8;//IV+ExtIV
2786 cbMIClen = 8;
2787 cbICVlen = 4;
2788 pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
2789 //We need to get seed here for filling TxKey entry.
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002790 } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
Joe Perches547f1cf2013-03-18 10:45:01 -07002791 cbIVlen = 8;//RSN Header
2792 cbICVlen = 8;//MIC
Malcolm Priestley11a72e52014-08-09 20:15:56 +01002793 cbMICHDR = sizeof(struct vnt_mic_hdr);
Joe Perches547f1cf2013-03-18 10:45:01 -07002794 pTxBufHead->wFragCtl |= FRAGCTL_AES;
2795 pDevice->bAES = true;
2796 }
2797 //MAC Header should be padding 0 to DW alignment.
2798 uPadding = 4 - (cbMacHdLen%4);
2799 uPadding %= 4;
2800 }
Forest Bond5449c682009-04-25 10:30:44 -04002801
Joe Perches547f1cf2013-03-18 10:45:01 -07002802 cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen + cbExtSuppRate;
Forest Bond5449c682009-04-25 10:30:44 -04002803
Joe Perches547f1cf2013-03-18 10:45:01 -07002804 //Set FIFOCTL_GrpAckPolicy
Guido Martínezbc5cf652014-04-19 16:45:00 -03002805 if (pDevice->bGrpAckPolicy == true) //0000 0100 0000 0000
Joe Perches547f1cf2013-03-18 10:45:01 -07002806 pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK;
Guido Martínezbc5cf652014-04-19 16:45:00 -03002807
Joe Perches547f1cf2013-03-18 10:45:01 -07002808 //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter()
Forest Bond5449c682009-04-25 10:30:44 -04002809
Joe Perches547f1cf2013-03-18 10:45:01 -07002810 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
Forest Bond5449c682009-04-25 10:30:44 -04002811
Malcolm Priestleyd66a5a72014-08-30 22:25:28 +01002812 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
2813 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize +
2814 sizeof(struct vnt_rrv_time_cts));
Joe Perches547f1cf2013-03-18 10:45:01 -07002815 pvRTS = NULL;
Malcolm Priestleyf5172b02014-08-30 22:25:45 +01002816 pvCTS = (struct vnt_cts *)(pbyTxBufferAddr + wTxBufSize +
Malcolm Priestleyd66a5a72014-08-30 22:25:28 +01002817 sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
Malcolm Priestley72edb7e2014-08-30 22:25:34 +01002818 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
Malcolm Priestleyf5172b02014-08-30 22:25:45 +01002819 sizeof(struct vnt_rrv_time_cts) + cbMICHDR + sizeof(struct vnt_cts));
Malcolm Priestleyd66a5a72014-08-30 22:25:28 +01002820 cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
Malcolm Priestleyf5172b02014-08-30 22:25:45 +01002821 cbMICHDR + sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
Forest Bond5449c682009-04-25 10:30:44 -04002822
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002823 } else {//802.11a/b packet
Forest Bond5449c682009-04-25 10:30:44 -04002824
Malcolm Priestleyf6a634c2014-08-30 22:25:29 +01002825 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
2826 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr +
2827 wTxBufSize + sizeof(struct vnt_rrv_time_ab));
Joe Perches547f1cf2013-03-18 10:45:01 -07002828 pvRTS = NULL;
2829 pvCTS = NULL;
Malcolm Priestley9ce842a2014-08-30 22:25:36 +01002830 pvTxDataHd = (void *)(pbyTxBufferAddr +
Malcolm Priestleyf6a634c2014-08-30 22:25:29 +01002831 wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
2832 cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
Malcolm Priestley9ce842a2014-08-30 22:25:36 +01002833 cbMICHDR + sizeof(struct vnt_tx_datahead_ab);
Forest Bond5449c682009-04-25 10:30:44 -04002834
Joe Perches547f1cf2013-03-18 10:45:01 -07002835 }
Forest Bond5449c682009-04-25 10:30:44 -04002836
Joe Perches547f1cf2013-03-18 10:45:01 -07002837 memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderSize - wTxBufSize));
Aya Mahfouz2359b5c2014-10-11 02:42:45 +02002838 ether_addr_copy(&(sEthHeader.abyDstAddr[0]),
2839 &(p80211Header->sA3.abyAddr1[0]));
2840 ether_addr_copy(&(sEthHeader.abySrcAddr[0]),
2841 &(p80211Header->sA3.abyAddr2[0]));
Joe Perches547f1cf2013-03-18 10:45:01 -07002842 //=========================
2843 // No Fragmentation
2844 //=========================
2845 pTxBufHead->wFragCtl |= (unsigned short)FRAGCTL_NONFRAG;
Forest Bond5449c682009-04-25 10:30:44 -04002846
Joe Perches547f1cf2013-03-18 10:45:01 -07002847 //Fill FIFO,RrvTime,RTS,and CTS
2848 s_vGenerateTxParameter(pDevice, byPktType, pbyTxBufferAddr, pvRrvTime, pvRTS, pvCTS,
2849 cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader, wCurrentRate);
Forest Bond5449c682009-04-25 10:30:44 -04002850
Joe Perches547f1cf2013-03-18 10:45:01 -07002851 //Fill DataHead
2852 uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK,
2853 0, 0, 1, AUTO_FB_NONE, wCurrentRate);
Forest Bond5449c682009-04-25 10:30:44 -04002854
Joe Perches547f1cf2013-03-18 10:45:01 -07002855 pMACHeader = (PS802_11Header) (pbyTxBufferAddr + cbHeaderSize);
Forest Bond5449c682009-04-25 10:30:44 -04002856
Joe Perches547f1cf2013-03-18 10:45:01 -07002857 cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + (cbFrameBodySize + cbMIClen) + cbExtSuppRate;
Forest Bond5449c682009-04-25 10:30:44 -04002858
Joe Perches547f1cf2013-03-18 10:45:01 -07002859 pbyMacHdr = (unsigned char *)(pbyTxBufferAddr + cbHeaderSize);
2860 pbyPayloadHead = (unsigned char *)(pbyMacHdr + cbMacHdLen + uPadding + cbIVlen);
2861 pbyIVHead = (unsigned char *)(pbyMacHdr + cbMacHdLen + uPadding);
Forest Bond5449c682009-04-25 10:30:44 -04002862
Joe Perches547f1cf2013-03-18 10:45:01 -07002863 // Copy the Packet into a tx Buffer
2864 memcpy(pbyMacHdr, pbMPDU, cbMacHdLen);
Forest Bond5449c682009-04-25 10:30:44 -04002865
Joe Perches547f1cf2013-03-18 10:45:01 -07002866 // version set to 0, patch for hostapd deamon
2867 pMACHeader->wFrameCtl &= cpu_to_le16(0xfffc);
2868 memcpy(pbyPayloadHead, (pbMPDU + cbMacHdLen), cbFrameBodySize);
Forest Bond5449c682009-04-25 10:30:44 -04002869
Joe Perches547f1cf2013-03-18 10:45:01 -07002870 // replace support rate, patch for hostapd deamon(only support 11M)
2871 if (WLAN_GET_FC_FSTYPE(p80211Header->sA4.wFrameCtl) == WLAN_FSTYPE_ASSOCRESP) {
2872 if (cbExtSuppRate != 0) {
2873 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len != 0)
2874 memcpy((pbyPayloadHead + cbFrameBodySize),
2875 pMgmt->abyCurrSuppRates,
2876 ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN
2877);
2878 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len != 0)
2879 memcpy((pbyPayloadHead + cbFrameBodySize) + ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN,
2880 pMgmt->abyCurrExtSuppRates,
2881 ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len + WLAN_IEHDR_LEN
2882);
2883 }
2884 }
Forest Bond5449c682009-04-25 10:30:44 -04002885
Joe Perches547f1cf2013-03-18 10:45:01 -07002886 // Set wep
2887 if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) {
Joe Perches547f1cf2013-03-18 10:45:01 -07002888 if (pDevice->bEnableHostWEP) {
2889 pTransmitKey = &STempKey;
2890 pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
2891 pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
2892 pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
2893 pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
2894 pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
2895 memcpy(pTransmitKey->abyKey,
2896 &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
2897 pTransmitKey->uKeyLength
2898);
2899 }
Forest Bond5449c682009-04-25 10:30:44 -04002900
Joe Perches547f1cf2013-03-18 10:45:01 -07002901 if ((pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
Malcolm Priestley12ca22b2014-03-06 22:44:25 +00002902 dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]);
2903 dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]);
Forest Bond5449c682009-04-25 10:30:44 -04002904
Joe Perches547f1cf2013-03-18 10:45:01 -07002905 // DO Software Michael
2906 MIC_vInit(dwMICKey0, dwMICKey1);
2907 MIC_vAppend((unsigned char *)&(sEthHeader.abyDstAddr[0]), 12);
2908 dwMIC_Priority = 0;
2909 MIC_vAppend((unsigned char *)&dwMIC_Priority, 4);
Joe Perches48caf5a2014-08-17 09:17:04 -07002910 pr_debug("DMA0_tx_8021:MIC KEY: %X, %X\n",
2911 dwMICKey0, dwMICKey1);
Forest Bond5449c682009-04-25 10:30:44 -04002912
Joe Perches547f1cf2013-03-18 10:45:01 -07002913 uLength = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen;
Forest Bond5449c682009-04-25 10:30:44 -04002914
Joe Perches547f1cf2013-03-18 10:45:01 -07002915 MIC_vAppend((pbyTxBufferAddr + uLength), cbFrameBodySize);
Forest Bond5449c682009-04-25 10:30:44 -04002916
Malcolm Priestleyd0daef32014-03-06 22:44:23 +00002917 pdwMIC_L = (u32 *)(pbyTxBufferAddr + uLength + cbFrameBodySize);
2918 pdwMIC_R = (u32 *)(pbyTxBufferAddr + uLength + cbFrameBodySize + 4);
Forest Bond5449c682009-04-25 10:30:44 -04002919
Joe Perches547f1cf2013-03-18 10:45:01 -07002920 MIC_vGetMIC(pdwMIC_L, pdwMIC_R);
2921 MIC_vUnInit();
Forest Bond5449c682009-04-25 10:30:44 -04002922
Joe Perches547f1cf2013-03-18 10:45:01 -07002923 if (pDevice->bTxMICFail == true) {
2924 *pdwMIC_L = 0;
2925 *pdwMIC_R = 0;
2926 pDevice->bTxMICFail = false;
2927 }
Forest Bond5449c682009-04-25 10:30:44 -04002928
Joe Perches48caf5a2014-08-17 09:17:04 -07002929 pr_debug("uLength: %d, %d\n", uLength, cbFrameBodySize);
2930 pr_debug("cbReqCount:%d, %d, %d, %d\n",
2931 cbReqCount, cbHeaderSize, uPadding, cbIVlen);
2932 pr_debug("MIC:%x, %x\n", *pdwMIC_L, *pdwMIC_R);
Forest Bond5449c682009-04-25 10:30:44 -04002933
Joe Perches547f1cf2013-03-18 10:45:01 -07002934 }
Forest Bond5449c682009-04-25 10:30:44 -04002935
Joe Perches547f1cf2013-03-18 10:45:01 -07002936 s_vFillTxKey(pDevice, (unsigned char *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
2937 pbyMacHdr, (unsigned short)cbFrameBodySize, (unsigned char *)pMICHDR);
Forest Bond5449c682009-04-25 10:30:44 -04002938
Joe Perches547f1cf2013-03-18 10:45:01 -07002939 if (pDevice->bEnableHostWEP) {
2940 pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
2941 pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0;
2942 }
Forest Bond5449c682009-04-25 10:30:44 -04002943
Guido Martínezbc5cf652014-04-19 16:45:00 -03002944 if ((pDevice->byLocalID <= REV_ID_VT3253_A1))
Joe Perches547f1cf2013-03-18 10:45:01 -07002945 s_vSWencryption(pDevice, pTransmitKey, pbyPayloadHead, (unsigned short)(cbFrameBodySize + cbMIClen));
Joe Perches547f1cf2013-03-18 10:45:01 -07002946 }
Forest Bond5449c682009-04-25 10:30:44 -04002947
Joe Perches547f1cf2013-03-18 10:45:01 -07002948 pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4);
2949 pDevice->wSeqCounter++;
2950 if (pDevice->wSeqCounter > 0x0fff)
2951 pDevice->wSeqCounter = 0;
Forest Bond5449c682009-04-25 10:30:44 -04002952
Joe Perches547f1cf2013-03-18 10:45:01 -07002953 if (bIsPSPOLL) {
2954 // The MAC will automatically replace the Duration-field of MAC header by Duration-field
2955 // of FIFO control header.
2956 // This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is
2957 // in the same place of other packet's Duration-field).
2958 // And it will cause Cisco-AP to issue Disassociation-packet
2959 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
Malcolm Priestley72edb7e2014-08-30 22:25:34 +01002960 ((struct vnt_tx_datahead_g *)pvTxDataHd)->duration_a = cpu_to_le16(p80211Header->sA2.wDurationID);
2961 ((struct vnt_tx_datahead_g *)pvTxDataHd)->duration_b = cpu_to_le16(p80211Header->sA2.wDurationID);
Joe Perches547f1cf2013-03-18 10:45:01 -07002962 } else {
Malcolm Priestley9ce842a2014-08-30 22:25:36 +01002963 ((struct vnt_tx_datahead_ab *)pvTxDataHd)->duration = cpu_to_le16(p80211Header->sA2.wDurationID);
Joe Perches547f1cf2013-03-18 10:45:01 -07002964 }
2965 }
Forest Bond5449c682009-04-25 10:30:44 -04002966
Joe Perches547f1cf2013-03-18 10:45:01 -07002967 // first TD is the only TD
2968 //Set TSR1 & ReqCount in TxDescHead
2969 pFrstTD->pTDInfo->skb = skb;
2970 pFrstTD->m_td1TD1.byTCR = (TCR_STP | TCR_EDP | EDMSDU);
2971 pFrstTD->pTDInfo->skb_dma = pFrstTD->pTDInfo->buf_dma;
2972 pFrstTD->m_td1TD1.wReqCount = cpu_to_le16(cbReqCount);
2973 pFrstTD->buff_addr = cpu_to_le32(pFrstTD->pTDInfo->skb_dma);
2974 pFrstTD->pTDInfo->byFlags = 0;
2975 pFrstTD->pTDInfo->byFlags |= TD_FLAGS_PRIV_SKB;
Forest Bond5449c682009-04-25 10:30:44 -04002976
Joe Perches547f1cf2013-03-18 10:45:01 -07002977 if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) {
2978 // Disable PS
2979 MACbPSWakeup(pDevice->PortOffset);
2980 }
2981 pDevice->bPWBitOn = false;
Forest Bond5449c682009-04-25 10:30:44 -04002982
Joe Perches547f1cf2013-03-18 10:45:01 -07002983 wmb();
2984 pFrstTD->m_td0TD0.f1Owner = OWNED_BY_NIC;
2985 wmb();
Forest Bond5449c682009-04-25 10:30:44 -04002986
Joe Perches547f1cf2013-03-18 10:45:01 -07002987 pDevice->iTDUsed[TYPE_TXDMA0]++;
Forest Bond5449c682009-04-25 10:30:44 -04002988
Guido Martínezbc5cf652014-04-19 16:45:00 -03002989 if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 1)
Joe Perches48caf5a2014-08-17 09:17:04 -07002990 pr_debug(" available td0 <= 1\n");
Forest Bond5449c682009-04-25 10:30:44 -04002991
Joe Perches547f1cf2013-03-18 10:45:01 -07002992 pDevice->apCurrTD[TYPE_TXDMA0] = pFrstTD->next;
Forest Bond5449c682009-04-25 10:30:44 -04002993
Joe Perches547f1cf2013-03-18 10:45:01 -07002994 // Poll Transmit the adapter
2995 MACvTransmit0(pDevice->PortOffset);
Forest Bond5449c682009-04-25 10:30:44 -04002996}