]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/staging/rt2860/sta/rtmp_data.c
Staging: rt28x0: remove typedefs (part three)
[net-next-2.6.git] / drivers / staging / rt2860 / sta / rtmp_data.c
CommitLineData
91980990
GKH
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 rtmp_data.c
29
30 Abstract:
31 Data path subroutines
32
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
91980990
GKH
36*/
37#include "../rt_config.h"
38
62eb734b
BZ
39void STARxEAPOLFrameIndicate(struct rt_rtmp_adapter *pAd,
40 struct rt_mac_table_entry *pEntry,
41 struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
91980990 42{
0f65bec1 43 PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
62eb734b 44 struct rt_rxwi * pRxWI = pRxBlk->pRxWI;
51126deb 45 u8 *pTmpBuf;
91980990 46
0f65bec1 47 if (pAd->StaCfg.WpaSupplicantUP) {
8281958b
BZ
48 /* All EAPoL frames have to pass to upper layer (ex. WPA_SUPPLICANT daemon) */
49 /* TBD : process fragmented EAPol frames */
91980990 50 {
8281958b 51 /* In 802.1x mode, if the received frame is EAP-SUCCESS packet, turn on the PortSecured variable */
0f65bec1
BZ
52 if (pAd->StaCfg.IEEE8021X == TRUE &&
53 (EAP_CODE_SUCCESS ==
54 WpaCheckEapCode(pAd, pRxBlk->pData,
55 pRxBlk->DataSize,
56 LENGTH_802_1_H))) {
51126deb
BZ
57 u8 *Key;
58 u8 CipherAlg;
0f65bec1
BZ
59 int idx = 0;
60
61 DBGPRINT_RAW(RT_DEBUG_TRACE,
62 ("Receive EAP-SUCCESS Packet\n"));
8281958b 63 /*pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */
91980990
GKH
64 STA_PORT_SECURED(pAd);
65
0f65bec1
BZ
66 if (pAd->StaCfg.IEEE8021x_required_keys ==
67 FALSE) {
68 idx = pAd->StaCfg.DesireSharedKeyId;
69 CipherAlg =
70 pAd->StaCfg.DesireSharedKey[idx].
71 CipherAlg;
72 Key =
73 pAd->StaCfg.DesireSharedKey[idx].
74 Key;
75
76 if (pAd->StaCfg.DesireSharedKey[idx].
77 KeyLen > 0) {
ca97b838 78#ifdef RTMP_MAC_PCI
62eb734b 79 struct rt_mac_table_entry *pEntry =
0f65bec1
BZ
80 &pAd->MacTab.
81 Content[BSSID_WCID];
91980990 82
8281958b 83 /* Set key material and cipherAlg to Asic */
0f65bec1
BZ
84 AsicAddSharedKeyEntry(pAd, BSS0,
85 idx,
86 CipherAlg,
87 Key, NULL,
88 NULL);
91980990 89
8281958b 90 /* Assign group key info */
0f65bec1
BZ
91 RTMPAddWcidAttributeEntry(pAd,
92 BSS0,
93 idx,
94 CipherAlg,
95 NULL);
91980990 96
8281958b 97 /* Assign pairwise key info */
0f65bec1
BZ
98 RTMPAddWcidAttributeEntry(pAd,
99 BSS0,
100 idx,
101 CipherAlg,
102 pEntry);
103
104 pAd->IndicateMediaState =
105 NdisMediaStateConnected;
106 pAd->ExtraInfo =
107 GENERAL_LINK_UP;
8281958b 108#endif /* RTMP_MAC_PCI // */
ca97b838 109#ifdef RTMP_MAC_USB
0f65bec1
BZ
110 union {
111 char buf[sizeof
62eb734b 112 (struct rt_ndis_802_11_wep)
0f65bec1
BZ
113 +
114 MAX_LEN_OF_KEY
115 - 1];
62eb734b 116 struct rt_ndis_802_11_wep keyinfo;
0f65bec1
BZ
117 }
118 WepKey;
5f5d2df8
BZ
119 int len;
120
0f65bec1
BZ
121 NdisZeroMemory(&WepKey,
122 sizeof(WepKey));
123 len =
124 pAd->StaCfg.
125 DesireSharedKey[idx].KeyLen;
126
127 NdisMoveMemory(WepKey.keyinfo.
128 KeyMaterial,
129 pAd->StaCfg.
130 DesireSharedKey
131 [idx].Key,
132 pAd->StaCfg.
133 DesireSharedKey
134 [idx].KeyLen);
135
136 WepKey.keyinfo.KeyIndex =
137 0x80000000 + idx;
5f5d2df8 138 WepKey.keyinfo.KeyLength = len;
0f65bec1
BZ
139 pAd->SharedKey[BSS0][idx].
140 KeyLen =
51126deb 141 (u8)(len <= 5 ? 5 : 13);
0f65bec1
BZ
142
143 pAd->IndicateMediaState =
144 NdisMediaStateConnected;
145 pAd->ExtraInfo =
146 GENERAL_LINK_UP;
8281958b 147 /* need to enqueue cmd to thread */
0f65bec1
BZ
148 RTUSBEnqueueCmdFromNdis(pAd,
149 OID_802_11_ADD_WEP,
150 TRUE,
151 &WepKey,
152 sizeof
153 (WepKey.
154 keyinfo)
155 + len -
156 1);
8281958b
BZ
157#endif /* RTMP_MAC_USB // */
158 /* For Preventing ShardKey Table is cleared by remove key procedure. */
0f65bec1
BZ
159 pAd->SharedKey[BSS0][idx].
160 CipherAlg = CipherAlg;
161 pAd->SharedKey[BSS0][idx].
162 KeyLen =
163 pAd->StaCfg.
164 DesireSharedKey[idx].KeyLen;
165 NdisMoveMemory(pAd->
166 SharedKey[BSS0]
167 [idx].Key,
168 pAd->StaCfg.
169 DesireSharedKey
170 [idx].Key,
171 pAd->StaCfg.
172 DesireSharedKey
173 [idx].KeyLen);
174 }
91980990
GKH
175 }
176 }
177
178 Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
179 return;
180 }
0f65bec1 181 } else {
8281958b
BZ
182 /* Special DATA frame that has to pass to MLME */
183 /* 1. Cisco Aironet frames for CCX2. We need pass it to MLME for special process */
184 /* 2. EAPOL handshaking frames when driver supplicant enabled, pass to MLME for special process */
91980990
GKH
185 {
186 pTmpBuf = pRxBlk->pData - LENGTH_802_11;
187 NdisMoveMemory(pTmpBuf, pRxBlk->pHeader, LENGTH_802_11);
0f65bec1
BZ
188 REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->WirelessCliID,
189 pTmpBuf,
190 pRxBlk->DataSize +
191 LENGTH_802_11, pRxWI->RSSI0,
192 pRxWI->RSSI1, pRxWI->RSSI2,
193 pRxD->PlcpSignal);
194 DBGPRINT_RAW(RT_DEBUG_TRACE,
195 ("!!! report EAPOL/AIRONET DATA to MLME (len=%d) !!!\n",
196 pRxBlk->DataSize));
91980990
GKH
197 }
198 }
199
200 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
201 return;
202
203}
204
62eb734b
BZ
205void STARxDataFrameAnnounce(struct rt_rtmp_adapter *pAd,
206 struct rt_mac_table_entry *pEntry,
207 struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
91980990
GKH
208{
209
8281958b 210 /* non-EAP frame */
0f65bec1
BZ
211 if (!RTMPCheckWPAframe
212 (pAd, pEntry, pRxBlk->pData, pRxBlk->DataSize, FromWhichBSSID)) {
ca97b838 213
91980990 214 {
8281958b
BZ
215 /* drop all non-EAP DATA frame before */
216 /* this client's Port-Access-Control is secured */
0f65bec1 217 if (pRxBlk->pHeader->FC.Wep) {
8281958b 218 /* unsupported cipher suite */
0f65bec1
BZ
219 if (pAd->StaCfg.WepStatus ==
220 Ndis802_11EncryptionDisabled) {
8281958b 221 /* release packet */
0f65bec1
BZ
222 RELEASE_NDIS_PACKET(pAd,
223 pRxBlk->pRxPacket,
224 NDIS_STATUS_FAILURE);
91980990
GKH
225 return;
226 }
0f65bec1 227 } else {
8281958b 228 /* encryption in-use but receive a non-EAPOL clear text frame, drop it */
0f65bec1
BZ
229 if ((pAd->StaCfg.WepStatus !=
230 Ndis802_11EncryptionDisabled)
231 && (pAd->StaCfg.PortSecured ==
232 WPA_802_1X_PORT_NOT_SECURED)) {
8281958b 233 /* release packet */
0f65bec1
BZ
234 RELEASE_NDIS_PACKET(pAd,
235 pRxBlk->pRxPacket,
236 NDIS_STATUS_FAILURE);
91980990
GKH
237 return;
238 }
239 }
240 }
241 RX_BLK_CLEAR_FLAG(pRxBlk, fRX_EAP);
0f65bec1 242 if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_ARALINK)) {
8281958b 243 /* Normal legacy, AMPDU or AMSDU */
0f65bec1
BZ
244 CmmRxnonRalinkFrameIndicate(pAd, pRxBlk,
245 FromWhichBSSID);
91980990 246
0f65bec1 247 } else {
8281958b 248 /* ARALINK */
0f65bec1
BZ
249 CmmRxRalinkFrameIndicate(pAd, pEntry, pRxBlk,
250 FromWhichBSSID);
91980990 251 }
0f65bec1 252 } else {
91980990 253 RX_BLK_SET_FLAG(pRxBlk, fRX_EAP);
1623267a 254
0f65bec1
BZ
255 if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU)
256 && (pAd->CommonCfg.bDisableReordering == 0)) {
91980990 257 Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID);
0f65bec1 258 } else {
8281958b
BZ
259 /* Determin the destination of the EAP frame */
260 /* to WPA state machine or upper layer */
0f65bec1
BZ
261 STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk,
262 FromWhichBSSID);
91980990
GKH
263 }
264 }
265}
266
8281958b 267/* For TKIP frame, calculate the MIC value */
62eb734b
BZ
268BOOLEAN STACheckTkipMICValue(struct rt_rtmp_adapter *pAd,
269 struct rt_mac_table_entry *pEntry, struct rt_rx_blk *pRxBlk)
91980990 270{
62eb734b 271 struct rt_header_802_11 * pHeader = pRxBlk->pHeader;
51126deb
BZ
272 u8 *pData = pRxBlk->pData;
273 u16 DataSize = pRxBlk->DataSize;
274 u8 UserPriority = pRxBlk->UserPriority;
62eb734b 275 struct rt_cipher_key *pWpaKey;
51126deb 276 u8 *pDA, *pSA;
91980990
GKH
277
278 pWpaKey = &pAd->SharedKey[BSS0][pRxBlk->pRxWI->KeyIndex];
279
280 pDA = pHeader->Addr1;
0f65bec1 281 if (RX_BLK_TEST_FLAG(pRxBlk, fRX_INFRA)) {
91980990 282 pSA = pHeader->Addr3;
0f65bec1 283 } else {
91980990
GKH
284 pSA = pHeader->Addr2;
285 }
286
287 if (RTMPTkipCompareMICValue(pAd,
0f65bec1
BZ
288 pData,
289 pDA,
290 pSA,
291 pWpaKey->RxMic,
292 UserPriority, DataSize) == FALSE) {
293 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Rx MIC Value error 2\n"));
294
295 if (pAd->StaCfg.WpaSupplicantUP) {
296 WpaSendMicFailureToWpaSupplicant(pAd,
297 (pWpaKey->Type ==
298 PAIRWISEKEY) ? TRUE :
299 FALSE);
300 } else {
91980990
GKH
301 RTMPReportMicError(pAd, pWpaKey);
302 }
303
8281958b 304 /* release packet */
0f65bec1
BZ
305 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket,
306 NDIS_STATUS_FAILURE);
91980990
GKH
307 return FALSE;
308 }
309
310 return TRUE;
311}
312
8281958b 313/* */
62eb734b 314/* All Rx routines use struct rt_rx_blk structure to hande rx events */
8281958b
BZ
315/* It is very important to build pRxBlk attributes */
316/* 1. pHeader pointer to 802.11 Header */
317/* 2. pData pointer to payload including LLC (just skip Header) */
318/* 3. set payload size including LLC to DataSize */
319/* 4. set some flags with RX_BLK_SET_FLAG() */
320/* */
62eb734b 321void STAHandleRxDataFrame(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk)
91980990 322{
0f65bec1 323 PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
62eb734b
BZ
324 struct rt_rxwi * pRxWI = pRxBlk->pRxWI;
325 struct rt_header_802_11 * pHeader = pRxBlk->pHeader;
8a10a546 326 void *pRxPacket = pRxBlk->pRxPacket;
0f65bec1 327 BOOLEAN bFragment = FALSE;
62eb734b 328 struct rt_mac_table_entry *pEntry = NULL;
51126deb
BZ
329 u8 FromWhichBSSID = BSS0;
330 u8 UserPriority = 0;
91980990
GKH
331
332 {
8281958b 333 /* before LINK UP, all DATA frames are rejected */
0f65bec1 334 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) {
8281958b 335 /* release packet */
0f65bec1
BZ
336 RELEASE_NDIS_PACKET(pAd, pRxPacket,
337 NDIS_STATUS_FAILURE);
91980990
GKH
338 return;
339 }
8281958b 340 /* Drop not my BSS frames */
0f65bec1 341 if (pRxD->MyBss == 0) {
91980990 342 {
8281958b 343 /* release packet */
0f65bec1
BZ
344 RELEASE_NDIS_PACKET(pAd, pRxPacket,
345 NDIS_STATUS_FAILURE);
91980990
GKH
346 return;
347 }
348 }
349
350 pAd->RalinkCounters.RxCountSinceLastNULL++;
0f65bec1
BZ
351 if (pAd->CommonCfg.bAPSDCapable
352 && pAd->CommonCfg.APEdcaParm.bAPSDCapable
353 && (pHeader->FC.SubType & 0x08)) {
51126deb 354 u8 *pData;
0f65bec1 355 DBGPRINT(RT_DEBUG_INFO, ("bAPSDCapable\n"));
91980990 356
8281958b 357 /* Qos bit 4 */
51126deb 358 pData = (u8 *)pHeader + LENGTH_802_11;
0f65bec1
BZ
359 if ((*pData >> 4) & 0x01) {
360 DBGPRINT(RT_DEBUG_INFO,
361 ("RxDone- Rcv EOSP frame, driver may fall into sleep\n"));
91980990
GKH
362 pAd->CommonCfg.bInServicePeriod = FALSE;
363
8281958b 364 /* Force driver to fall into sleep mode when rcv EOSP frame */
0f65bec1 365 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) {
51126deb
BZ
366 u16 TbttNumToNextWakeUp;
367 u16 NextDtim =
0f65bec1 368 pAd->StaCfg.DtimPeriod;
51126deb 369 unsigned long Now;
91980990
GKH
370
371 NdisGetSystemUpTime(&Now);
0f65bec1 372 NextDtim -=
51126deb 373 (u16)(Now -
0f65bec1
BZ
374 pAd->StaCfg.
375 LastBeaconRxTime) /
376 pAd->CommonCfg.BeaconPeriod;
377
378 TbttNumToNextWakeUp =
379 pAd->StaCfg.DefaultListenCount;
380 if (OPSTATUS_TEST_FLAG
381 (pAd, fOP_STATUS_RECEIVE_DTIM)
382 && (TbttNumToNextWakeUp > NextDtim))
91980990
GKH
383 TbttNumToNextWakeUp = NextDtim;
384
ca97b838 385 RTMP_SET_PSM_BIT(pAd, PWR_SAVE);
8281958b 386 /* if WMM-APSD is failed, try to disable following line */
0f65bec1
BZ
387 AsicSleepThenAutoWakeup(pAd,
388 TbttNumToNextWakeUp);
91980990
GKH
389 }
390 }
391
0f65bec1
BZ
392 if ((pHeader->FC.MoreData)
393 && (pAd->CommonCfg.bInServicePeriod)) {
394 DBGPRINT(RT_DEBUG_TRACE,
395 ("Sending another trigger frame when More Data bit is set to 1\n"));
91980990
GKH
396 }
397 }
8281958b
BZ
398 /* Drop NULL, CF-ACK(no data), CF-POLL(no data), and CF-ACK+CF-POLL(no data) data frame */
399 if ((pHeader->FC.SubType & 0x04)) /* bit 2 : no DATA */
91980990 400 {
8281958b 401 /* release packet */
0f65bec1
BZ
402 RELEASE_NDIS_PACKET(pAd, pRxPacket,
403 NDIS_STATUS_FAILURE);
91980990
GKH
404 return;
405 }
8281958b 406 /* Drop not my BSS frame (we can not only check the MyBss bit in RxD) */
91980990 407
0f65bec1 408 if (INFRA_ON(pAd)) {
8281958b 409 /* Infrastructure mode, check address 2 for BSSID */
0f65bec1
BZ
410 if (!RTMPEqualMemory
411 (&pHeader->Addr2, &pAd->CommonCfg.Bssid, 6)) {
8281958b
BZ
412 /* Receive frame not my BSSID */
413 /* release packet */
0f65bec1
BZ
414 RELEASE_NDIS_PACKET(pAd, pRxPacket,
415 NDIS_STATUS_FAILURE);
91980990
GKH
416 return;
417 }
8281958b 418 } else /* Ad-Hoc mode or Not associated */
91980990 419 {
8281958b 420 /* Ad-Hoc mode, check address 3 for BSSID */
0f65bec1
BZ
421 if (!RTMPEqualMemory
422 (&pHeader->Addr3, &pAd->CommonCfg.Bssid, 6)) {
8281958b
BZ
423 /* Receive frame not my BSSID */
424 /* release packet */
0f65bec1
BZ
425 RELEASE_NDIS_PACKET(pAd, pRxPacket,
426 NDIS_STATUS_FAILURE);
91980990
GKH
427 return;
428 }
429 }
91980990 430
8281958b
BZ
431 /* */
432 /* find pEntry */
433 /* */
0f65bec1 434 if (pRxWI->WirelessCliID < MAX_LEN_OF_MAC_TABLE) {
91980990 435 pEntry = &pAd->MacTab.Content[pRxWI->WirelessCliID];
0f65bec1 436 } else {
8281958b
BZ
437 /* 1. release packet if infra mode */
438 /* 2. new a pEntry if ad-hoc mode */
0f65bec1
BZ
439 RELEASE_NDIS_PACKET(pAd, pRxPacket,
440 NDIS_STATUS_FAILURE);
91980990
GKH
441 return;
442 }
443
8281958b 444 /* infra or ad-hoc */
0f65bec1 445 if (INFRA_ON(pAd)) {
91980990 446 RX_BLK_SET_FLAG(pRxBlk, fRX_INFRA);
91980990
GKH
447 ASSERT(pRxWI->WirelessCliID == BSSID_WCID);
448 }
8281958b 449 /* check Atheros Client */
0f65bec1
BZ
450 if ((pEntry->bIAmBadAtheros == FALSE) && (pRxD->AMPDU == 1)
451 && (pHeader->FC.Retry)) {
91980990
GKH
452 pEntry->bIAmBadAtheros = TRUE;
453 pAd->CommonCfg.IOTestParm.bCurrentAtheros = TRUE;
454 pAd->CommonCfg.IOTestParm.bLastAtheros = TRUE;
0f65bec1
BZ
455 if (!STA_AES_ON(pAd)) {
456 AsicUpdateProtect(pAd, 8, ALLN_SETPROTECT, TRUE,
457 FALSE);
91980990
GKH
458 }
459 }
460 }
461
51126deb 462 pRxBlk->pData = (u8 *) pHeader;
91980990 463
8281958b
BZ
464 /* */
465 /* update RxBlk->pData, DataSize */
466 /* 802.11 Header, QOS, HTC, Hw Padding */
467 /* */
91980990 468
8281958b 469 /* 1. skip 802.11 HEADER */
91980990
GKH
470 {
471 pRxBlk->pData += LENGTH_802_11;
472 pRxBlk->DataSize -= LENGTH_802_11;
473 }
474
8281958b 475 /* 2. QOS */
0f65bec1 476 if (pHeader->FC.SubType & 0x08) {
91980990
GKH
477 RX_BLK_SET_FLAG(pRxBlk, fRX_QOS);
478 UserPriority = *(pRxBlk->pData) & 0x0f;
8281958b 479 /* bit 7 in QoS Control field signals the HT A-MSDU format */
0f65bec1 480 if ((*pRxBlk->pData) & 0x80) {
91980990
GKH
481 RX_BLK_SET_FLAG(pRxBlk, fRX_AMSDU);
482 }
8281958b 483 /* skip QOS contorl field */
91980990 484 pRxBlk->pData += 2;
0f65bec1 485 pRxBlk->DataSize -= 2;
91980990
GKH
486 }
487 pRxBlk->UserPriority = UserPriority;
488
ca97b838 489 /* check if need to resend PS Poll when received packet with MoreData = 1 */
0f65bec1 490 if ((pAd->StaCfg.Psm == PWR_SAVE) && (pHeader->FC.MoreData == 1)) {
ca97b838 491 if ((((UserPriority == 0) || (UserPriority == 3)) &&
0f65bec1
BZ
492 pAd->CommonCfg.bAPSDAC_BE == 0) ||
493 (((UserPriority == 1) || (UserPriority == 2)) &&
494 pAd->CommonCfg.bAPSDAC_BK == 0) ||
495 (((UserPriority == 4) || (UserPriority == 5)) &&
496 pAd->CommonCfg.bAPSDAC_VI == 0) ||
497 (((UserPriority == 6) || (UserPriority == 7)) &&
498 pAd->CommonCfg.bAPSDAC_VO == 0)) {
ca97b838
BZ
499 /* non-UAPSD delivery-enabled AC */
500 RTMP_PS_POLL_ENQUEUE(pAd);
501 }
502 }
8281958b 503 /* 3. Order bit: A-Ralink or HTC+ */
0f65bec1 504 if (pHeader->FC.Order) {
91980990 505#ifdef AGGREGATION_SUPPORT
0f65bec1
BZ
506 if ((pRxWI->PHYMODE <= MODE_OFDM)
507 && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)))
91980990
GKH
508 {
509 RX_BLK_SET_FLAG(pRxBlk, fRX_ARALINK);
0f65bec1 510 } else
8281958b 511#endif /* AGGREGATION_SUPPORT // */
91980990 512 {
91980990 513 RX_BLK_SET_FLAG(pRxBlk, fRX_HTC);
8281958b 514 /* skip HTC contorl field */
91980990
GKH
515 pRxBlk->pData += 4;
516 pRxBlk->DataSize -= 4;
91980990
GKH
517 }
518 }
8281958b 519 /* 4. skip HW padding */
0f65bec1 520 if (pRxD->L2PAD) {
8281958b
BZ
521 /* just move pData pointer */
522 /* because DataSize excluding HW padding */
91980990
GKH
523 RX_BLK_SET_FLAG(pRxBlk, fRX_PAD);
524 pRxBlk->pData += 2;
525 }
526
0f65bec1 527 if (pRxD->BA) {
91980990
GKH
528 RX_BLK_SET_FLAG(pRxBlk, fRX_AMPDU);
529 }
8281958b
BZ
530 /* */
531 /* Case I Process Broadcast & Multicast data frame */
532 /* */
0f65bec1 533 if (pRxD->Bcast || pRxD->Mcast) {
91980990
GKH
534 INC_COUNTER64(pAd->WlanCounters.MulticastReceivedFrameCount);
535
8281958b 536 /* Drop Mcast/Bcast frame with fragment bit on */
0f65bec1 537 if (pHeader->FC.MoreFrag) {
8281958b 538 /* release packet */
0f65bec1
BZ
539 RELEASE_NDIS_PACKET(pAd, pRxPacket,
540 NDIS_STATUS_FAILURE);
91980990
GKH
541 return;
542 }
8281958b 543 /* Filter out Bcast frame which AP relayed for us */
0f65bec1
BZ
544 if (pHeader->FC.FrDs
545 && MAC_ADDR_EQUAL(pHeader->Addr3, pAd->CurrentAddress)) {
8281958b 546 /* release packet */
0f65bec1
BZ
547 RELEASE_NDIS_PACKET(pAd, pRxPacket,
548 NDIS_STATUS_FAILURE);
91980990
GKH
549 return;
550 }
551
552 Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
553 return;
0f65bec1
BZ
554 } else if (pRxD->U2M) {
555 pAd->LastRxRate =
51126deb 556 (u16)((pRxWI->MCS) + (pRxWI->BW << 7) +
0f65bec1 557 (pRxWI->ShortGI << 8) + (pRxWI->PHYMODE << 14));
91980990 558
0f65bec1 559 if (ADHOC_ON(pAd)) {
91980990
GKH
560 pEntry = MacTableLookup(pAd, pHeader->Addr2);
561 if (pEntry)
0f65bec1
BZ
562 Update_Rssi_Sample(pAd, &pEntry->RssiSample,
563 pRxWI);
91980990
GKH
564 }
565
91980990
GKH
566 Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI);
567
51126deb
BZ
568 pAd->StaCfg.LastSNR0 = (u8)(pRxWI->SNR0);
569 pAd->StaCfg.LastSNR1 = (u8)(pRxWI->SNR1);
91980990
GKH
570
571 pAd->RalinkCounters.OneSecRxOkDataCnt++;
572
0f65bec1 573 if (!((pHeader->Frag == 0) && (pHeader->FC.MoreFrag == 0))) {
8281958b
BZ
574 /* re-assemble the fragmented packets */
575 /* return complete frame (pRxPacket) or NULL */
0f65bec1
BZ
576 bFragment = TRUE;
577 pRxPacket = RTMPDeFragmentDataFrame(pAd, pRxBlk);
578 }
91980990 579
0f65bec1 580 if (pRxPacket) {
91980990
GKH
581 pEntry = &pAd->MacTab.Content[pRxWI->WirelessCliID];
582
8281958b 583 /* process complete frame */
0f65bec1
BZ
584 if (bFragment && (pRxD->Decrypted)
585 && (pEntry->WepStatus ==
586 Ndis802_11Encryption2Enabled)) {
8281958b 587 /* Minus MIC length */
91980990
GKH
588 pRxBlk->DataSize -= 8;
589
8281958b 590 /* For TKIP frame, calculate the MIC value */
0f65bec1
BZ
591 if (STACheckTkipMICValue(pAd, pEntry, pRxBlk) ==
592 FALSE) {
593 return;
594 }
595 }
91980990 596
0f65bec1
BZ
597 STARxDataFrameAnnounce(pAd, pEntry, pRxBlk,
598 FromWhichBSSID);
599 return;
600 } else {
8281958b
BZ
601 /* just return */
602 /* because RTMPDeFragmentDataFrame() will release rx packet, */
603 /* if packet is fragmented */
91980990 604 return;
0f65bec1 605 }
91980990
GKH
606 }
607
608 ASSERT(0);
8281958b 609 /* release packet */
91980990
GKH
610 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
611}
612
62eb734b 613void STAHandleRxMgmtFrame(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk)
91980990 614{
0f65bec1 615 PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
62eb734b
BZ
616 struct rt_rxwi * pRxWI = pRxBlk->pRxWI;
617 struct rt_header_802_11 * pHeader = pRxBlk->pHeader;
8a10a546 618 void *pRxPacket = pRxBlk->pRxPacket;
91980990 619
0f65bec1 620 do {
ca97b838
BZ
621
622 /* check if need to resend PS Poll when received packet with MoreData = 1 */
0f65bec1
BZ
623 if ((pAd->StaCfg.Psm == PWR_SAVE)
624 && (pHeader->FC.MoreData == 1)) {
ca97b838 625 /* for UAPSD, all management frames will be VO priority */
0f65bec1 626 if (pAd->CommonCfg.bAPSDAC_VO == 0) {
ca97b838
BZ
627 /* non-UAPSD delivery-enabled AC */
628 RTMP_PS_POLL_ENQUEUE(pAd);
629 }
630 }
631
632 /* TODO: if MoreData == 0, station can go to sleep */
633
8281958b 634 /* We should collect RSSI not only U2M data but also my beacon */
0f65bec1
BZ
635 if ((pHeader->FC.SubType == SUBTYPE_BEACON)
636 && (MAC_ADDR_EQUAL(&pAd->CommonCfg.Bssid, &pHeader->Addr2))
637 && (pAd->RxAnt.EvaluatePeriod == 0)) {
91980990
GKH
638 Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI);
639
51126deb
BZ
640 pAd->StaCfg.LastSNR0 = (u8)(pRxWI->SNR0);
641 pAd->StaCfg.LastSNR1 = (u8)(pRxWI->SNR1);
91980990
GKH
642 }
643
8281958b 644 /* First check the size, it MUST not exceed the mlme queue size */
0f65bec1 645 if (pRxWI->MPDUtotalByteCount > MGMT_DMA_BUFFER_SIZE) {
91980990
GKH
646 DBGPRINT_ERR(("STAHandleRxMgmtFrame: frame too large, size = %d \n", pRxWI->MPDUtotalByteCount));
647 break;
648 }
649
0f65bec1
BZ
650 REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->WirelessCliID, pHeader,
651 pRxWI->MPDUtotalByteCount,
652 pRxWI->RSSI0, pRxWI->RSSI1,
653 pRxWI->RSSI2, pRxD->PlcpSignal);
91980990
GKH
654 } while (FALSE);
655
656 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_SUCCESS);
657}
658
62eb734b 659void STAHandleRxControlFrame(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk)
91980990 660{
62eb734b
BZ
661 struct rt_rxwi * pRxWI = pRxBlk->pRxWI;
662 struct rt_header_802_11 * pHeader = pRxBlk->pHeader;
8a10a546 663 void *pRxPacket = pRxBlk->pRxPacket;
0f65bec1
BZ
664
665 switch (pHeader->FC.SubType) {
666 case SUBTYPE_BLOCK_ACK_REQ:
667 {
668 CntlEnqueueForRecv(pAd, pRxWI->WirelessCliID,
669 (pRxWI->MPDUtotalByteCount),
62eb734b 670 (struct rt_frame_ba_req *) pHeader);
0f65bec1
BZ
671 }
672 break;
673 case SUBTYPE_BLOCK_ACK:
674 case SUBTYPE_ACK:
675 default:
676 break;
91980990
GKH
677 }
678
679 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
680}
681
91980990
GKH
682/*
683 ========================================================================
684
685 Routine Description:
686 Process RxDone interrupt, running in DPC level
687
688 Arguments:
689 pAd Pointer to our adapter
690
691 Return Value:
692 None
693
694 IRQL = DISPATCH_LEVEL
695
696 Note:
697 This routine has to maintain Rx ring read pointer.
698 Need to consider QOS DATA format when converting to 802.3
699 ========================================================================
700*/
62eb734b 701BOOLEAN STARxDoneInterruptHandle(struct rt_rtmp_adapter *pAd, IN BOOLEAN argc)
91980990 702{
51126deb
BZ
703 int Status;
704 u32 RxProcessed, RxPending;
0f65bec1 705 BOOLEAN bReschedule = FALSE;
62eb734b 706 PRT28XX_RXD_STRUC pRxD;
51126deb 707 u8 *pData;
62eb734b 708 struct rt_rxwi * pRxWI;
8a10a546 709 void *pRxPacket;
62eb734b
BZ
710 struct rt_header_802_11 * pHeader;
711 struct rt_rx_blk RxCell;
91980990
GKH
712
713 RxProcessed = RxPending = 0;
714
8281958b 715 /* process whole rx ring */
0f65bec1 716 while (1) {
91980990
GKH
717
718 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF |
0f65bec1
BZ
719 fRTMP_ADAPTER_RESET_IN_PROGRESS |
720 fRTMP_ADAPTER_HALT_IN_PROGRESS |
721 fRTMP_ADAPTER_NIC_NOT_EXIST) ||
722 !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)) {
91980990
GKH
723 break;
724 }
ca97b838 725#ifdef RTMP_MAC_PCI
0f65bec1 726 if (RxProcessed++ > MAX_RX_PROCESS_CNT) {
8281958b 727 /* need to reschedule rx handle */
91980990
GKH
728 bReschedule = TRUE;
729 break;
730 }
8281958b 731#endif /* RTMP_MAC_PCI // */
91980990 732
8281958b 733 RxProcessed++; /* test */
91980990 734
8281958b
BZ
735 /* 1. allocate a new data packet into rx ring to replace received packet */
736 /* then processing the received packet */
737 /* 2. the callee must take charge of release of packet */
738 /* 3. As far as driver is concerned , */
739 /* the rx packet must */
740 /* a. be indicated to upper layer or */
741 /* b. be released if it is discarded */
0f65bec1
BZ
742 pRxPacket =
743 GetPacketFromRxRing(pAd, &(RxCell.RxD), &bReschedule,
744 &RxPending);
745 if (pRxPacket == NULL) {
8281958b 746 /* no more packet to process */
91980990
GKH
747 break;
748 }
8281958b 749 /* get rx ring descriptor */
91980990 750 pRxD = &(RxCell.RxD);
8281958b 751 /* get rx data buffer */
0f65bec1 752 pData = GET_OS_PKT_DATAPTR(pRxPacket);
62eb734b
BZ
753 pRxWI = (struct rt_rxwi *) pData;
754 pHeader = (struct rt_header_802_11 *) (pData + RXWI_SIZE);
91980990 755
8281958b 756 /* build RxCell */
91980990
GKH
757 RxCell.pRxWI = pRxWI;
758 RxCell.pHeader = pHeader;
759 RxCell.pRxPacket = pRxPacket;
51126deb 760 RxCell.pData = (u8 *) pHeader;
91980990
GKH
761 RxCell.DataSize = pRxWI->MPDUtotalByteCount;
762 RxCell.Flags = 0;
763
8281958b 764 /* Increase Total receive byte counter after real data received no mater any error or not */
0f65bec1
BZ
765 pAd->RalinkCounters.ReceivedByteCount +=
766 pRxWI->MPDUtotalByteCount;
767 pAd->RalinkCounters.OneSecReceivedByteCount +=
768 pRxWI->MPDUtotalByteCount;
769 pAd->RalinkCounters.RxCount++;
91980990
GKH
770
771 INC_COUNTER64(pAd->WlanCounters.ReceivedFragmentCount);
772
773 if (pRxWI->MPDUtotalByteCount < 14)
774 Status = NDIS_STATUS_FAILURE;
775
0f65bec1
BZ
776 if (MONITOR_ON(pAd)) {
777 send_monitor_packets(pAd, &RxCell);
91980990
GKH
778 break;
779 }
ca97b838
BZ
780
781 /* STARxDoneInterruptHandle() is called in rtusb_bulk.c */
91980990 782
8281958b 783 /* Check for all RxD errors */
91980990
GKH
784 Status = RTMPCheckRxError(pAd, pHeader, pRxWI, pRxD);
785
8281958b 786 /* Handle the received frame */
0f65bec1
BZ
787 if (Status == NDIS_STATUS_SUCCESS) {
788 switch (pHeader->FC.Type) {
8281958b 789 /* CASE I, receive a DATA frame */
0f65bec1 790 case BTYPE_DATA:
91980990 791 {
8281958b 792 /* process DATA frame */
91980990
GKH
793 STAHandleRxDataFrame(pAd, &RxCell);
794 }
795 break;
8281958b 796 /* CASE II, receive a MGMT frame */
0f65bec1 797 case BTYPE_MGMT:
91980990
GKH
798 {
799 STAHandleRxMgmtFrame(pAd, &RxCell);
800 }
801 break;
8281958b 802 /* CASE III. receive a CNTL frame */
0f65bec1 803 case BTYPE_CNTL:
91980990
GKH
804 {
805 STAHandleRxControlFrame(pAd, &RxCell);
806 }
807 break;
8281958b 808 /* discard other type */
0f65bec1
BZ
809 default:
810 RELEASE_NDIS_PACKET(pAd, pRxPacket,
811 NDIS_STATUS_FAILURE);
812 break;
91980990 813 }
0f65bec1 814 } else {
91980990 815 pAd->Counters8023.RxErrors++;
8281958b 816 /* discard this frame */
0f65bec1
BZ
817 RELEASE_NDIS_PACKET(pAd, pRxPacket,
818 NDIS_STATUS_FAILURE);
91980990
GKH
819 }
820 }
821
822 return bReschedule;
823}
824
825/*
826 ========================================================================
827
828 Routine Description:
829 Arguments:
830 pAd Pointer to our adapter
831
832 IRQL = DISPATCH_LEVEL
833
834 ========================================================================
835*/
62eb734b 836void RTMPHandleTwakeupInterrupt(struct rt_rtmp_adapter *pAd)
91980990 837{
5f5d2df8 838 AsicForceWakeup(pAd, FALSE);
91980990
GKH
839}
840
841/*
842========================================================================
843Routine Description:
844 Early checking and OS-depened parsing for Tx packet send to our STA driver.
845
846Arguments:
8a10a546
BZ
847 void * MiniportAdapterContext Pointer refer to the device handle, i.e., the pAd.
848 void ** ppPacketArray The packet array need to do transmission.
51126deb 849 u32 NumberOfPackets Number of packet in packet array.
91980990
GKH
850
851Return Value:
852 NONE
853
854Note:
855 This function do early checking and classification for send-out packet.
856 You only can put OS-depened & STA related code in here.
857========================================================================
858*/
8a10a546
BZ
859void STASendPackets(void *MiniportAdapterContext,
860 void **ppPacketArray, u32 NumberOfPackets)
91980990 861{
51126deb 862 u32 Index;
62eb734b 863 struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)MiniportAdapterContext;
8a10a546 864 void *pPacket;
0f65bec1 865 BOOLEAN allowToSend = FALSE;
91980990 866
0f65bec1 867 for (Index = 0; Index < NumberOfPackets; Index++) {
91980990
GKH
868 pPacket = ppPacketArray[Index];
869
0f65bec1
BZ
870 do {
871 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)
872 || RTMP_TEST_FLAG(pAd,
873 fRTMP_ADAPTER_HALT_IN_PROGRESS)
874 || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) {
8281958b 875 /* Drop send request since hardware is in reset state */
0f65bec1
BZ
876 break;
877 } else if (!INFRA_ON(pAd) && !ADHOC_ON(pAd)) {
8281958b 878 /* Drop send request since there are no physical connection yet */
0f65bec1
BZ
879 break;
880 } else {
8281958b
BZ
881 /* Record that orignal packet source is from NDIS layer,so that */
882 /* later on driver knows how to release this NDIS PACKET */
883 RTMP_SET_PACKET_WCID(pPacket, 0); /* this field is useless when in STA mode */
91980990 884 RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
0f65bec1
BZ
885 NDIS_SET_PACKET_STATUS(pPacket,
886 NDIS_STATUS_PENDING);
91980990
GKH
887 pAd->RalinkCounters.PendingNdisPacketCount++;
888
889 allowToSend = TRUE;
890 }
0f65bec1 891 } while (FALSE);
91980990
GKH
892
893 if (allowToSend == TRUE)
894 STASendPacket(pAd, pPacket);
895 else
896 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
897 }
898
8281958b 899 /* Dequeue outgoing frames from TxSwQueue[] and process it */
91980990
GKH
900 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
901
902}
903
91980990
GKH
904/*
905========================================================================
906Routine Description:
907 This routine is used to do packet parsing and classification for Tx packet
908 to STA device, and it will en-queue packets to our TxSwQueue depends on AC
909 class.
910
911Arguments:
912 pAd Pointer to our adapter
913 pPacket Pointer to send packet
914
915Return Value:
916 NDIS_STATUS_SUCCESS If succes to queue the packet into TxSwQueue.
917 NDIS_STATUS_FAILURE If failed to do en-queue.
918
919Note:
920 You only can put OS-indepened & STA related code in here.
921========================================================================
922*/
62eb734b 923int STASendPacket(struct rt_rtmp_adapter *pAd, void *pPacket)
91980990 924{
62eb734b 925 struct rt_packet_info PacketInfo;
51126deb
BZ
926 u8 *pSrcBufVA;
927 u32 SrcBufLen;
928 u32 AllowFragSize;
929 u8 NumberOfFrag;
930 u8 RTSRequired;
931 u8 QueIdx, UserPriority;
62eb734b 932 struct rt_mac_table_entry *pEntry = NULL;
0f65bec1 933 unsigned int IrqFlags;
51126deb
BZ
934 u8 FlgIsIP = 0;
935 u8 Rate;
91980990 936
8281958b
BZ
937 /* Prepare packet information structure for buffer descriptor */
938 /* chained within a single NDIS packet. */
91980990
GKH
939 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
940
0f65bec1
BZ
941 if (pSrcBufVA == NULL) {
942 DBGPRINT(RT_DEBUG_ERROR,
943 ("STASendPacket --> pSrcBufVA == NULL !!!SrcBufLen=%x\n",
944 SrcBufLen));
8281958b
BZ
945 /* Resourece is low, system did not allocate virtual address */
946 /* return NDIS_STATUS_FAILURE directly to upper layer */
91980990
GKH
947 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
948 return NDIS_STATUS_FAILURE;
949 }
950
0f65bec1
BZ
951 if (SrcBufLen < 14) {
952 DBGPRINT(RT_DEBUG_ERROR,
953 ("STASendPacket --> Ndis Packet buffer error !!!\n"));
91980990
GKH
954 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
955 return (NDIS_STATUS_FAILURE);
956 }
8281958b
BZ
957 /* In HT rate adhoc mode, A-MPDU is often used. So need to lookup BA Table and MAC Entry. */
958 /* Note multicast packets in adhoc also use BSSID_WCID index. */
91980990 959 {
0f65bec1 960 if (INFRA_ON(pAd)) {
91980990 961 {
0f65bec1
BZ
962 pEntry = &pAd->MacTab.Content[BSSID_WCID];
963 RTMP_SET_PACKET_WCID(pPacket, BSSID_WCID);
964 Rate = pAd->CommonCfg.TxRate;
965 }
966 } else if (ADHOC_ON(pAd)) {
967 if (*pSrcBufVA & 0x01) {
91980990
GKH
968 RTMP_SET_PACKET_WCID(pPacket, MCAST_WCID);
969 pEntry = &pAd->MacTab.Content[MCAST_WCID];
0f65bec1 970 } else {
91980990
GKH
971 pEntry = MacTableLookup(pAd, pSrcBufVA);
972 }
973 Rate = pAd->CommonCfg.TxRate;
974 }
975 }
976
0f65bec1
BZ
977 if (!pEntry) {
978 DBGPRINT(RT_DEBUG_ERROR,
979 ("STASendPacket->Cannot find pEntry(%2x:%2x:%2x:%2x:%2x:%2x) in MacTab!\n",
980 PRINT_MAC(pSrcBufVA)));
8281958b
BZ
981 /* Resourece is low, system did not allocate virtual address */
982 /* return NDIS_STATUS_FAILURE directly to upper layer */
91980990
GKH
983 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
984 return NDIS_STATUS_FAILURE;
985 }
986
987 if (ADHOC_ON(pAd)
0f65bec1 988 ) {
51126deb 989 RTMP_SET_PACKET_WCID(pPacket, (u8)pEntry->Aid);
91980990 990 }
8281958b
BZ
991 /* */
992 /* Check the Ethernet Frame type of this packet, and set the RTMP_SET_PACKET_SPECIFIC flags. */
993 /* Here we set the PACKET_SPECIFIC flags(LLC, VLAN, DHCP/ARP, EAPOL). */
91980990
GKH
994 RTMPCheckEtherType(pAd, pPacket);
995
8281958b
BZ
996 /* */
997 /* WPA 802.1x secured port control - drop all non-802.1x frame before port secured */
998 /* */
91980990 999 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
0f65bec1
BZ
1000 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
1001 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
1002 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
1003 || (pAd->StaCfg.IEEE8021X == TRUE)
1004 )
1005 && ((pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED)
1006 || (pAd->StaCfg.MicErrCnt >= 2))
1007 && (RTMP_GET_PACKET_EAPOL(pPacket) == FALSE)
1008 ) {
1009 DBGPRINT(RT_DEBUG_TRACE,
1010 ("STASendPacket --> Drop packet before port secured !!!\n"));
91980990
GKH
1011 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
1012
1013 return (NDIS_STATUS_FAILURE);
1014 }
1015
8281958b
BZ
1016 /* STEP 1. Decide number of fragments required to deliver this MSDU. */
1017 /* The estimation here is not very accurate because difficult to */
1018 /* take encryption overhead into consideration here. The result */
1019 /* "NumberOfFrag" is then just used to pre-check if enough free */
1020 /* TXD are available to hold this MSDU. */
91980990 1021
8281958b 1022 if (*pSrcBufVA & 0x01) /* fragmentation not allowed on multicast & broadcast */
91980990
GKH
1023 NumberOfFrag = 1;
1024 else if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED))
8281958b 1025 NumberOfFrag = 1; /* Aggregation overwhelms fragmentation */
91980990 1026 else if (CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_AMSDU_INUSED))
8281958b 1027 NumberOfFrag = 1; /* Aggregation overwhelms fragmentation */
0f65bec1
BZ
1028 else if ((pAd->StaCfg.HTPhyMode.field.MODE == MODE_HTMIX)
1029 || (pAd->StaCfg.HTPhyMode.field.MODE == MODE_HTGREENFIELD))
8281958b 1030 NumberOfFrag = 1; /* MIMO RATE overwhelms fragmentation */
0f65bec1 1031 else {
8281958b
BZ
1032 /* The calculated "NumberOfFrag" is a rough estimation because of various */
1033 /* encryption/encapsulation overhead not taken into consideration. This number is just */
1034 /* used to make sure enough free TXD are available before fragmentation takes place. */
1035 /* In case the actual required number of fragments of an NDIS packet */
1036 /* excceeds "NumberOfFrag"caculated here and not enough free TXD available, the */
1037 /* last fragment (i.e. last MPDU) will be dropped in RTMPHardTransmit() due to out of */
1038 /* resource, and the NDIS packet will be indicated NDIS_STATUS_FAILURE. This should */
1039 /* rarely happen and the penalty is just like a TX RETRY fail. Affordable. */
91980990 1040
0f65bec1
BZ
1041 AllowFragSize =
1042 (pAd->CommonCfg.FragmentThreshold) - LENGTH_802_11 -
1043 LENGTH_CRC;
1044 NumberOfFrag =
1045 ((PacketInfo.TotalPacketLength - LENGTH_802_3 +
1046 LENGTH_802_1_H) / AllowFragSize) + 1;
8281958b 1047 /* To get accurate number of fragmentation, Minus 1 if the size just match to allowable fragment size */
0f65bec1
BZ
1048 if (((PacketInfo.TotalPacketLength - LENGTH_802_3 +
1049 LENGTH_802_1_H) % AllowFragSize) == 0) {
91980990
GKH
1050 NumberOfFrag--;
1051 }
1052 }
1053
8281958b 1054 /* Save fragment number to Ndis packet reserved field */
91980990
GKH
1055 RTMP_SET_PACKET_FRAGMENTS(pPacket, NumberOfFrag);
1056
8281958b
BZ
1057 /* STEP 2. Check the requirement of RTS: */
1058 /* If multiple fragment required, RTS is required only for the first fragment */
1059 /* if the fragment size large than RTS threshold */
1060 /* For RT28xx, Let ASIC send RTS/CTS */
1061/* RTMP_SET_PACKET_RTS(pPacket, 0); */
ca97b838 1062 if (NumberOfFrag > 1)
0f65bec1
BZ
1063 RTSRequired =
1064 (pAd->CommonCfg.FragmentThreshold >
1065 pAd->CommonCfg.RtsThreshold) ? 1 : 0;
ca97b838 1066 else
0f65bec1
BZ
1067 RTSRequired =
1068 (PacketInfo.TotalPacketLength >
1069 pAd->CommonCfg.RtsThreshold) ? 1 : 0;
ca97b838 1070
8281958b 1071 /* Save RTS requirement to Ndis packet reserved field */
ca97b838 1072 RTMP_SET_PACKET_RTS(pPacket, RTSRequired);
91980990
GKH
1073 RTMP_SET_PACKET_TXRATE(pPacket, pAd->CommonCfg.TxRate);
1074
8281958b
BZ
1075 /* */
1076 /* STEP 3. Traffic classification. outcome = <UserPriority, QueIdx> */
1077 /* */
91980990 1078 UserPriority = 0;
0f65bec1 1079 QueIdx = QID_AC_BE;
5f5d2df8 1080 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
0f65bec1 1081 CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE)) {
51126deb
BZ
1082 u16 Protocol;
1083 u8 LlcSnapLen = 0, Byte0, Byte1;
0f65bec1 1084 do {
8281958b 1085 /* get Ethernet protocol field */
0f65bec1 1086 Protocol =
51126deb 1087 (u16)((pSrcBufVA[12] << 8) + pSrcBufVA[13]);
0f65bec1 1088 if (Protocol <= 1500) {
8281958b 1089 /* get Ethernet protocol field from LLC/SNAP */
0f65bec1
BZ
1090 if (Sniff2BytesFromNdisBuffer
1091 (PacketInfo.pFirstBuffer, LENGTH_802_3 + 6,
1092 &Byte0, &Byte1) != NDIS_STATUS_SUCCESS)
91980990
GKH
1093 break;
1094
51126deb 1095 Protocol = (u16)((Byte0 << 8) + Byte1);
91980990
GKH
1096 LlcSnapLen = 8;
1097 }
8281958b 1098 /* always AC_BE for non-IP packet */
91980990
GKH
1099 if (Protocol != 0x0800)
1100 break;
1101
8281958b 1102 /* get IP header */
0f65bec1
BZ
1103 if (Sniff2BytesFromNdisBuffer
1104 (PacketInfo.pFirstBuffer, LENGTH_802_3 + LlcSnapLen,
1105 &Byte0, &Byte1) != NDIS_STATUS_SUCCESS)
91980990
GKH
1106 break;
1107
8281958b 1108 /* return AC_BE if packet is not IPv4 */
91980990
GKH
1109 if ((Byte0 & 0xf0) != 0x40)
1110 break;
1111
1112 FlgIsIP = 1;
1113 UserPriority = (Byte1 & 0xe0) >> 5;
1114 QueIdx = MapUserPriorityToAccessCategory[UserPriority];
1115
8281958b
BZ
1116 /* TODO: have to check ACM bit. apply TSPEC if ACM is ON */
1117 /* TODO: downgrade UP & QueIdx before passing ACM */
ca97b838 1118 /*
0f65bec1
BZ
1119 Under WMM ACM control, we dont need to check the bit;
1120 Or when a TSPEC is built for VO but we will change to issue
1121 BA session for BE here, so we will not use BA to send VO packets.
1122 */
1123 if (pAd->CommonCfg.APEdcaParm.bACM[QueIdx]) {
91980990 1124 UserPriority = 0;
0f65bec1 1125 QueIdx = QID_AC_BE;
91980990
GKH
1126 }
1127 } while (FALSE);
1128 }
1129
1130 RTMP_SET_PACKET_UP(pPacket, UserPriority);
1131
8281958b 1132 /* Make sure SendTxWait queue resource won't be used by other threads */
91980990 1133 RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
0f65bec1 1134 if (pAd->TxSwQueue[QueIdx].Number >= MAX_PACKETS_IN_QUEUE) {
91980990 1135 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
91980990
GKH
1136 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
1137
1138 return NDIS_STATUS_FAILURE;
0f65bec1
BZ
1139 } else {
1140 InsertTailQueueAc(pAd, pEntry, &pAd->TxSwQueue[QueIdx],
1141 PACKET_TO_QUEUE_ENTRY(pPacket));
91980990
GKH
1142 }
1143 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
1144
0f65bec1
BZ
1145 if ((pAd->CommonCfg.BACapability.field.AutoBA == TRUE) &&
1146 IS_HT_STA(pEntry)) {
62eb734b 1147 /*struct rt_mac_table_entry *pMacEntry = &pAd->MacTab.Content[BSSID_WCID]; */
0f65bec1
BZ
1148 if (((pEntry->TXBAbitmap & (1 << UserPriority)) == 0) &&
1149 ((pEntry->BADeclineBitmap & (1 << UserPriority)) == 0) &&
1150 (pEntry->PortSecured == WPA_802_1X_PORT_SECURED)
8281958b
BZ
1151 /* For IOT compatibility, if */
1152 /* 1. It is Ralink chip or */
1153 /* 2. It is OPEN or AES mode, */
1154 /* then BA session can be bulit. */
0f65bec1
BZ
1155 && ((pEntry->ValidAsCLI && pAd->MlmeAux.APRalinkIe != 0x0)
1156 || (pEntry->WepStatus != Ndis802_11WEPEnabled
1157 && pEntry->WepStatus !=
1158 Ndis802_11Encryption2Enabled))
1159 ) {
1160 BAOriSessionSetUp(pAd, pEntry, UserPriority, 0, 10,
1161 FALSE);
91980990
GKH
1162 }
1163 }
91980990 1164
8281958b 1165 pAd->RalinkCounters.OneSecOsTxCount[QueIdx]++; /* TODO: for debug only. to be removed */
91980990
GKH
1166 return NDIS_STATUS_SUCCESS;
1167}
1168
91980990
GKH
1169/*
1170 ========================================================================
1171
1172 Routine Description:
1173 This subroutine will scan through releative ring descriptor to find
1174 out avaliable free ring descriptor and compare with request size.
1175
1176 Arguments:
1177 pAd Pointer to our adapter
1178 QueIdx Selected TX Ring
1179
1180 Return Value:
1181 NDIS_STATUS_FAILURE Not enough free descriptor
1182 NDIS_STATUS_SUCCESS Enough free descriptor
1183
1184 IRQL = PASSIVE_LEVEL
1185 IRQL = DISPATCH_LEVEL
1186
1187 Note:
1188
1189 ========================================================================
1190*/
ca97b838 1191#ifdef RTMP_MAC_PCI
62eb734b 1192int RTMPFreeTXDRequest(struct rt_rtmp_adapter *pAd,
51126deb
BZ
1193 u8 QueIdx,
1194 u8 NumberRequired, u8 *FreeNumberIs)
91980990 1195{
51126deb
BZ
1196 unsigned long FreeNumber = 0;
1197 int Status = NDIS_STATUS_FAILURE;
0f65bec1
BZ
1198
1199 switch (QueIdx) {
1200 case QID_AC_BK:
1201 case QID_AC_BE:
1202 case QID_AC_VI:
1203 case QID_AC_VO:
1204 if (pAd->TxRing[QueIdx].TxSwFreeIdx >
1205 pAd->TxRing[QueIdx].TxCpuIdx)
1206 FreeNumber =
1207 pAd->TxRing[QueIdx].TxSwFreeIdx -
1208 pAd->TxRing[QueIdx].TxCpuIdx - 1;
1209 else
1210 FreeNumber =
1211 pAd->TxRing[QueIdx].TxSwFreeIdx + TX_RING_SIZE -
1212 pAd->TxRing[QueIdx].TxCpuIdx - 1;
1213
1214 if (FreeNumber >= NumberRequired)
1215 Status = NDIS_STATUS_SUCCESS;
1216 break;
1217
1218 case QID_MGMT:
1219 if (pAd->MgmtRing.TxSwFreeIdx > pAd->MgmtRing.TxCpuIdx)
1220 FreeNumber =
1221 pAd->MgmtRing.TxSwFreeIdx - pAd->MgmtRing.TxCpuIdx -
1222 1;
1223 else
1224 FreeNumber =
1225 pAd->MgmtRing.TxSwFreeIdx + MGMT_RING_SIZE -
1226 pAd->MgmtRing.TxCpuIdx - 1;
1227
1228 if (FreeNumber >= NumberRequired)
1229 Status = NDIS_STATUS_SUCCESS;
1230 break;
1231
1232 default:
1233 DBGPRINT(RT_DEBUG_ERROR,
1234 ("RTMPFreeTXDRequest::Invalid QueIdx(=%d)\n", QueIdx));
1235 break;
ca97b838 1236 }
51126deb 1237 *FreeNumberIs = (u8)FreeNumber;
ca97b838
BZ
1238
1239 return (Status);
1240}
8281958b 1241#endif /* RTMP_MAC_PCI // */
ca97b838
BZ
1242#ifdef RTMP_MAC_USB
1243/*
1244 Actually, this function used to check if the TxHardware Queue still has frame need to send.
1245 If no frame need to send, go to sleep, else, still wake up.
1246*/
62eb734b 1247int RTMPFreeTXDRequest(struct rt_rtmp_adapter *pAd,
51126deb
BZ
1248 u8 QueIdx,
1249 u8 NumberRequired, u8 *FreeNumberIs)
ca97b838 1250{
51126deb
BZ
1251 /*unsigned long FreeNumber = 0; */
1252 int Status = NDIS_STATUS_FAILURE;
0f65bec1 1253 unsigned long IrqFlags;
62eb734b 1254 struct rt_ht_tx_context *pHTTXContext;
0f65bec1
BZ
1255
1256 switch (QueIdx) {
1257 case QID_AC_BK:
1258 case QID_AC_BE:
1259 case QID_AC_VI:
1260 case QID_AC_VO:
1261 {
1262 pHTTXContext = &pAd->TxContext[QueIdx];
1263 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx],
1264 IrqFlags);
1265 if ((pHTTXContext->CurWritePosition !=
1266 pHTTXContext->ENextBulkOutPosition)
1267 || (pHTTXContext->IRPPending == TRUE)) {
5f5d2df8 1268 Status = NDIS_STATUS_FAILURE;
0f65bec1 1269 } else {
5f5d2df8 1270 Status = NDIS_STATUS_SUCCESS;
0f65bec1
BZ
1271 }
1272 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx],
1273 IrqFlags);
1274 }
1275 break;
1276 case QID_MGMT:
1277 if (pAd->MgmtRing.TxSwFreeIdx != MGMT_RING_SIZE)
1278 Status = NDIS_STATUS_FAILURE;
1279 else
1280 Status = NDIS_STATUS_SUCCESS;
1281 break;
1282 default:
1283 DBGPRINT(RT_DEBUG_ERROR,
1284 ("RTMPFreeTXDRequest::Invalid QueIdx(=%d)\n", QueIdx));
1285 break;
91980990 1286 }
91980990
GKH
1287
1288 return (Status);
1289}
8281958b 1290#endif /* RTMP_MAC_USB // */
91980990 1291
62eb734b 1292void RTMPSendDisassociationFrame(struct rt_rtmp_adapter *pAd)
91980990
GKH
1293{
1294}
1295
62eb734b 1296void RTMPSendNullFrame(struct rt_rtmp_adapter *pAd,
51126deb 1297 u8 TxRate, IN BOOLEAN bQosNull)
91980990 1298{
51126deb
BZ
1299 u8 NullFrame[48];
1300 unsigned long Length;
62eb734b 1301 struct rt_header_802_11 * pHeader_802_11;
0f65bec1 1302
8281958b 1303 /* WPA 802.1x secured port control */
0f65bec1
BZ
1304 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
1305 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
1306 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
1307 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
1308 || (pAd->StaCfg.IEEE8021X == TRUE)
1309 ) && (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED)) {
91980990
GKH
1310 return;
1311 }
1312
1313 NdisZeroMemory(NullFrame, 48);
62eb734b 1314 Length = sizeof(struct rt_header_802_11);
91980990 1315
62eb734b 1316 pHeader_802_11 = (struct rt_header_802_11 *) NullFrame;
91980990
GKH
1317
1318 pHeader_802_11->FC.Type = BTYPE_DATA;
1319 pHeader_802_11->FC.SubType = SUBTYPE_NULL_FUNC;
1320 pHeader_802_11->FC.ToDs = 1;
1321 COPY_MAC_ADDR(pHeader_802_11->Addr1, pAd->CommonCfg.Bssid);
1322 COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
1323 COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid);
1324
0f65bec1 1325 if (pAd->CommonCfg.bAPSDForcePowerSave) {
91980990 1326 pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
0f65bec1
BZ
1327 } else {
1328 pHeader_802_11->FC.PwrMgmt =
1329 (pAd->StaCfg.Psm == PWR_SAVE) ? 1 : 0;
91980990 1330 }
0f65bec1
BZ
1331 pHeader_802_11->Duration =
1332 pAd->CommonCfg.Dsifs + RTMPCalcDuration(pAd, TxRate, 14);
91980990
GKH
1333
1334 pAd->Sequence++;
1335 pHeader_802_11->Sequence = pAd->Sequence;
1336
8281958b 1337 /* Prepare QosNull function frame */
0f65bec1 1338 if (bQosNull) {
91980990
GKH
1339 pHeader_802_11->FC.SubType = SUBTYPE_QOS_NULL;
1340
8281958b 1341 /* copy QOS control bytes */
0f65bec1
BZ
1342 NullFrame[Length] = 0;
1343 NullFrame[Length + 1] = 0;
8281958b 1344 Length += 2; /* if pad with 2 bytes for alignment, APSD will fail */
91980990
GKH
1345 }
1346
1347 HAL_KickOutNullFrameTx(pAd, 0, NullFrame, Length);
1348
1349}
1350
8281958b 1351/* IRQL = DISPATCH_LEVEL */
62eb734b 1352void RTMPSendRTSFrame(struct rt_rtmp_adapter *pAd,
51126deb 1353 u8 *pDA,
0f65bec1 1354 IN unsigned int NextMpduSize,
51126deb
BZ
1355 u8 TxRate,
1356 u8 RTSRate,
1357 u16 AckDuration, u8 QueIdx, u8 FrameGap)
91980990
GKH
1358{
1359}
1360
8281958b
BZ
1361/* -------------------------------------------------------- */
1362/* FIND ENCRYPT KEY AND DECIDE CIPHER ALGORITHM */
1363/* Find the WPA key, either Group or Pairwise Key */
1364/* LEAP + TKIP also use WPA key. */
1365/* -------------------------------------------------------- */
1366/* Decide WEP bit and cipher suite to be used. Same cipher suite should be used for whole fragment burst */
1367/* In Cisco CCX 2.0 Leap Authentication */
1368/* WepStatus is Ndis802_11Encryption1Enabled but the key will use PairwiseKey */
1369/* Instead of the SharedKey, SharedKey Length may be Zero. */
62eb734b 1370void STAFindCipherAlgorithm(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
91980990 1371{
8281958b 1372 NDIS_802_11_ENCRYPTION_STATUS Cipher; /* To indicate cipher used for this packet */
51126deb
BZ
1373 u8 CipherAlg = CIPHER_NONE; /* cipher alogrithm */
1374 u8 KeyIdx = 0xff;
1375 u8 *pSrcBufVA;
62eb734b 1376 struct rt_cipher_key *pKey = NULL;
91980990
GKH
1377
1378 pSrcBufVA = GET_OS_PKT_DATAPTR(pTxBlk->pPacket);
1379
1380 {
8281958b 1381 /* Select Cipher */
0f65bec1 1382 if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd)))
8281958b 1383 Cipher = pAd->StaCfg.GroupCipher; /* Cipher for Multicast or Broadcast */
0f65bec1 1384 else
8281958b 1385 Cipher = pAd->StaCfg.PairCipher; /* Cipher for Unicast */
91980990 1386
0f65bec1
BZ
1387 if (RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket)) {
1388 ASSERT(pAd->SharedKey[BSS0][0].CipherAlg <=
1389 CIPHER_CKIP128);
91980990 1390
8281958b 1391 /* 4-way handshaking frame must be clear */
0f65bec1
BZ
1392 if (!(TX_BLK_TEST_FLAG(pTxBlk, fTX_bClearEAPFrame))
1393 && (pAd->SharedKey[BSS0][0].CipherAlg)
1394 && (pAd->SharedKey[BSS0][0].KeyLen)) {
91980990
GKH
1395 CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
1396 KeyIdx = 0;
1397 }
0f65bec1
BZ
1398 } else if (Cipher == Ndis802_11Encryption1Enabled) {
1399 KeyIdx = pAd->StaCfg.DefaultKeyId;
1400 } else if ((Cipher == Ndis802_11Encryption2Enabled) ||
1401 (Cipher == Ndis802_11Encryption3Enabled)) {
8281958b 1402 if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd))) /* multicast */
91980990
GKH
1403 KeyIdx = pAd->StaCfg.DefaultKeyId;
1404 else if (pAd->SharedKey[BSS0][0].KeyLen)
1405 KeyIdx = 0;
1406 else
1407 KeyIdx = pAd->StaCfg.DefaultKeyId;
1408 }
1409
1410 if (KeyIdx == 0xff)
1411 CipherAlg = CIPHER_NONE;
0f65bec1
BZ
1412 else if ((Cipher == Ndis802_11EncryptionDisabled)
1413 || (pAd->SharedKey[BSS0][KeyIdx].KeyLen == 0))
91980990 1414 CipherAlg = CIPHER_NONE;
0f65bec1
BZ
1415 else if (pAd->StaCfg.WpaSupplicantUP &&
1416 (Cipher == Ndis802_11Encryption1Enabled) &&
1417 (pAd->StaCfg.IEEE8021X == TRUE) &&
1418 (pAd->StaCfg.PortSecured ==
1419 WPA_802_1X_PORT_NOT_SECURED))
1420 CipherAlg = CIPHER_NONE;
1421 else {
8281958b 1422 /*Header_802_11.FC.Wep = 1; */
91980990
GKH
1423 CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
1424 pKey = &pAd->SharedKey[BSS0][KeyIdx];
1425 }
1426 }
1427
1428 pTxBlk->CipherAlg = CipherAlg;
1429 pTxBlk->pKey = pKey;
1430}
1431
62eb734b 1432void STABuildCommon802_11Header(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
91980990 1433{
62eb734b 1434 struct rt_header_802_11 *pHeader_802_11;
91980990 1435
8281958b
BZ
1436 /* */
1437 /* MAKE A COMMON 802.11 HEADER */
1438 /* */
91980990 1439
8281958b 1440 /* normal wlan header size : 24 octets */
62eb734b 1441 pTxBlk->MpduHeaderLen = sizeof(struct rt_header_802_11);
91980990 1442
0f65bec1 1443 pHeader_802_11 =
62eb734b 1444 (struct rt_header_802_11 *) & pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
91980990 1445
62eb734b 1446 NdisZeroMemory(pHeader_802_11, sizeof(struct rt_header_802_11));
91980990
GKH
1447
1448 pHeader_802_11->FC.FrDs = 0;
1449 pHeader_802_11->FC.Type = BTYPE_DATA;
0f65bec1
BZ
1450 pHeader_802_11->FC.SubType =
1451 ((TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) ? SUBTYPE_QDATA :
1452 SUBTYPE_DATA);
1453
1454 if (pTxBlk->pMacEntry) {
1455 if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bForceNonQoS)) {
1456 pHeader_802_11->Sequence =
1457 pTxBlk->pMacEntry->NonQosDataSeq;
1458 pTxBlk->pMacEntry->NonQosDataSeq =
1459 (pTxBlk->pMacEntry->NonQosDataSeq + 1) & MAXSEQ;
1460 } else {
91980990 1461 {
0f65bec1
BZ
1462 pHeader_802_11->Sequence =
1463 pTxBlk->pMacEntry->TxSeq[pTxBlk->
1464 UserPriority];
1465 pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority] =
1466 (pTxBlk->pMacEntry->
1467 TxSeq[pTxBlk->UserPriority] + 1) & MAXSEQ;
1468 }
1469 }
1470 } else {
91980990 1471 pHeader_802_11->Sequence = pAd->Sequence;
8281958b 1472 pAd->Sequence = (pAd->Sequence + 1) & MAXSEQ; /* next sequence */
91980990
GKH
1473 }
1474
1475 pHeader_802_11->Frag = 0;
1476
1477 pHeader_802_11->FC.MoreData = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData);
1478
1479 {
0f65bec1 1480 if (INFRA_ON(pAd)) {
91980990 1481 {
0f65bec1
BZ
1482 COPY_MAC_ADDR(pHeader_802_11->Addr1,
1483 pAd->CommonCfg.Bssid);
1484 COPY_MAC_ADDR(pHeader_802_11->Addr2,
1485 pAd->CurrentAddress);
1486 COPY_MAC_ADDR(pHeader_802_11->Addr3,
1487 pTxBlk->pSrcBufHeader);
1488 pHeader_802_11->FC.ToDs = 1;
1489 }
1490 } else if (ADHOC_ON(pAd)) {
1491 COPY_MAC_ADDR(pHeader_802_11->Addr1,
1492 pTxBlk->pSrcBufHeader);
1493 COPY_MAC_ADDR(pHeader_802_11->Addr2,
1494 pAd->CurrentAddress);
1495 COPY_MAC_ADDR(pHeader_802_11->Addr3,
1496 pAd->CommonCfg.Bssid);
91980990
GKH
1497 pHeader_802_11->FC.ToDs = 0;
1498 }
1499 }
1500
1501 if (pTxBlk->CipherAlg != CIPHER_NONE)
1502 pHeader_802_11->FC.Wep = 1;
1503
8281958b
BZ
1504 /* ----------------------------------------------------------------- */
1505 /* STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later. */
1506 /* ----------------------------------------------------------------- */
91980990 1507 if (pAd->CommonCfg.bAPSDForcePowerSave)
0f65bec1 1508 pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
91980990 1509 else
0f65bec1 1510 pHeader_802_11->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
91980990
GKH
1511}
1512
62eb734b
BZ
1513void STABuildCache802_11Header(struct rt_rtmp_adapter *pAd,
1514 struct rt_tx_blk *pTxBlk, u8 * pHeader)
91980990 1515{
62eb734b
BZ
1516 struct rt_mac_table_entry *pMacEntry;
1517 struct rt_header_802_11 * pHeader80211;
91980990 1518
62eb734b 1519 pHeader80211 = (struct rt_header_802_11 *) pHeader;
91980990
GKH
1520 pMacEntry = pTxBlk->pMacEntry;
1521
8281958b
BZ
1522 /* */
1523 /* Update the cached 802.11 HEADER */
1524 /* */
91980990 1525
8281958b 1526 /* normal wlan header size : 24 octets */
62eb734b 1527 pTxBlk->MpduHeaderLen = sizeof(struct rt_header_802_11);
91980990 1528
8281958b 1529 /* More Bit */
91980990
GKH
1530 pHeader80211->FC.MoreData = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData);
1531
8281958b 1532 /* Sequence */
91980990 1533 pHeader80211->Sequence = pMacEntry->TxSeq[pTxBlk->UserPriority];
0f65bec1
BZ
1534 pMacEntry->TxSeq[pTxBlk->UserPriority] =
1535 (pMacEntry->TxSeq[pTxBlk->UserPriority] + 1) & MAXSEQ;
91980990
GKH
1536
1537 {
8281958b
BZ
1538 /* Check if the frame can be sent through DLS direct link interface */
1539 /* If packet can be sent through DLS, then force aggregation disable. (Hard to determine peer STA's capability) */
ca97b838 1540
8281958b 1541 /* The addr3 of normal packet send from DS is Dest Mac address. */
91980990 1542 if (ADHOC_ON(pAd))
0f65bec1
BZ
1543 COPY_MAC_ADDR(pHeader80211->Addr3,
1544 pAd->CommonCfg.Bssid);
91980990 1545 else
0f65bec1
BZ
1546 COPY_MAC_ADDR(pHeader80211->Addr3,
1547 pTxBlk->pSrcBufHeader);
91980990
GKH
1548 }
1549
8281958b
BZ
1550 /* ----------------------------------------------------------------- */
1551 /* STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later. */
1552 /* ----------------------------------------------------------------- */
91980990 1553 if (pAd->CommonCfg.bAPSDForcePowerSave)
0f65bec1 1554 pHeader80211->FC.PwrMgmt = PWR_SAVE;
91980990 1555 else
0f65bec1 1556 pHeader80211->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
91980990 1557}
91980990 1558
62eb734b
BZ
1559static inline u8 *STA_Build_ARalink_Frame_Header(struct rt_rtmp_adapter *pAd,
1560 struct rt_tx_blk *pTxBlk)
91980990 1561{
51126deb 1562 u8 *pHeaderBufPtr;
62eb734b 1563 struct rt_header_802_11 *pHeader_802_11;
8a10a546 1564 void *pNextPacket;
51126deb 1565 u32 nextBufLen;
62eb734b 1566 struct rt_queue_entry *pQEntry;
91980990
GKH
1567
1568 STAFindCipherAlgorithm(pAd, pTxBlk);
1569 STABuildCommon802_11Header(pAd, pTxBlk);
1570
91980990 1571 pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
62eb734b 1572 pHeader_802_11 = (struct rt_header_802_11 *) pHeaderBufPtr;
91980990 1573
8281958b 1574 /* steal "order" bit to mark "aggregation" */
91980990
GKH
1575 pHeader_802_11->FC.Order = 1;
1576
8281958b 1577 /* skip common header */
91980990
GKH
1578 pHeaderBufPtr += pTxBlk->MpduHeaderLen;
1579
0f65bec1 1580 if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) {
8281958b
BZ
1581 /* */
1582 /* build QOS Control bytes */
1583 /* */
91980990
GKH
1584 *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
1585
0f65bec1
BZ
1586 *(pHeaderBufPtr + 1) = 0;
1587 pHeaderBufPtr += 2;
91980990
GKH
1588 pTxBlk->MpduHeaderLen += 2;
1589 }
8281958b 1590 /* padding at front of LLC header. LLC header should at 4-bytes aligment. */
51126deb
BZ
1591 pTxBlk->HdrPadLen = (unsigned long)pHeaderBufPtr;
1592 pHeaderBufPtr = (u8 *)ROUND_UP(pHeaderBufPtr, 4);
1593 pTxBlk->HdrPadLen = (unsigned long)(pHeaderBufPtr - pTxBlk->HdrPadLen);
91980990 1594
8281958b 1595 /* For RA Aggregation, */
62eb734b 1596 /* put the 2nd MSDU length(extra 2-byte field) after struct rt_qos_control in little endian format */
91980990 1597 pQEntry = pTxBlk->TxPacketList.Head;
ca97b838 1598 pNextPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
91980990
GKH
1599 nextBufLen = GET_OS_PKT_LEN(pNextPacket);
1600 if (RTMP_GET_PACKET_VLAN(pNextPacket))
1601 nextBufLen -= LENGTH_802_1Q;
1602
51126deb
BZ
1603 *pHeaderBufPtr = (u8)nextBufLen & 0xff;
1604 *(pHeaderBufPtr + 1) = (u8)(nextBufLen >> 8);
91980990
GKH
1605
1606 pHeaderBufPtr += 2;
1607 pTxBlk->MpduHeaderLen += 2;
1608
1609 return pHeaderBufPtr;
1610
1611}
1612
62eb734b
BZ
1613static inline u8 *STA_Build_AMSDU_Frame_Header(struct rt_rtmp_adapter *pAd,
1614 struct rt_tx_blk *pTxBlk)
91980990 1615{
51126deb 1616 u8 *pHeaderBufPtr; /*, pSaveBufPtr; */
62eb734b 1617 struct rt_header_802_11 *pHeader_802_11;
91980990
GKH
1618
1619 STAFindCipherAlgorithm(pAd, pTxBlk);
1620 STABuildCommon802_11Header(pAd, pTxBlk);
1621
1622 pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
62eb734b 1623 pHeader_802_11 = (struct rt_header_802_11 *) pHeaderBufPtr;
91980990 1624
8281958b 1625 /* skip common header */
91980990
GKH
1626 pHeaderBufPtr += pTxBlk->MpduHeaderLen;
1627
8281958b
BZ
1628 /* */
1629 /* build QOS Control bytes */
1630 /* */
91980990
GKH
1631 *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
1632
8281958b
BZ
1633 /* */
1634 /* A-MSDU packet */
1635 /* */
91980990
GKH
1636 *pHeaderBufPtr |= 0x80;
1637
0f65bec1
BZ
1638 *(pHeaderBufPtr + 1) = 0;
1639 pHeaderBufPtr += 2;
91980990
GKH
1640 pTxBlk->MpduHeaderLen += 2;
1641
8281958b 1642 /*pSaveBufPtr = pHeaderBufPtr; */
91980990 1643
8281958b
BZ
1644 /* */
1645 /* padding at front of LLC header */
1646 /* LLC header should locate at 4-octets aligment */
1647 /* */
1648 /* @@@ MpduHeaderLen excluding padding @@@ */
1649 /* */
51126deb
BZ
1650 pTxBlk->HdrPadLen = (unsigned long)pHeaderBufPtr;
1651 pHeaderBufPtr = (u8 *)ROUND_UP(pHeaderBufPtr, 4);
1652 pTxBlk->HdrPadLen = (unsigned long)(pHeaderBufPtr - pTxBlk->HdrPadLen);
91980990
GKH
1653
1654 return pHeaderBufPtr;
1655
1656}
1657
62eb734b 1658void STA_AMPDU_Frame_Tx(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
91980990 1659{
62eb734b 1660 struct rt_header_802_11 *pHeader_802_11;
51126deb
BZ
1661 u8 *pHeaderBufPtr;
1662 u16 FreeNumber;
62eb734b 1663 struct rt_mac_table_entry *pMacEntry;
0f65bec1 1664 BOOLEAN bVLANPkt;
62eb734b 1665 struct rt_queue_entry *pQEntry;
91980990
GKH
1666
1667 ASSERT(pTxBlk);
1668
0f65bec1 1669 while (pTxBlk->TxPacketList.Head) {
91980990
GKH
1670 pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
1671 pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
0f65bec1
BZ
1672 if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) {
1673 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket,
1674 NDIS_STATUS_FAILURE);
91980990
GKH
1675 continue;
1676 }
1677
0f65bec1
BZ
1678 bVLANPkt =
1679 (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
91980990
GKH
1680
1681 pMacEntry = pTxBlk->pMacEntry;
0f65bec1 1682 if (pMacEntry->isCached) {
8281958b 1683 /* NOTE: Please make sure the size of pMacEntry->CachedBuf[] is smaller than pTxBlk->HeaderBuf[]!!!! */
51126deb 1684 NdisMoveMemory((u8 *)& pTxBlk->
0f65bec1 1685 HeaderBuf[TXINFO_SIZE],
51126deb 1686 (u8 *)& pMacEntry->CachedBuf[0],
62eb734b 1687 TXWI_SIZE + sizeof(struct rt_header_802_11));
0f65bec1 1688 pHeaderBufPtr =
51126deb 1689 (u8 *)(&pTxBlk->
0f65bec1 1690 HeaderBuf[TXINFO_SIZE + TXWI_SIZE]);
91980990 1691 STABuildCache802_11Header(pAd, pTxBlk, pHeaderBufPtr);
0f65bec1 1692 } else {
91980990
GKH
1693 STAFindCipherAlgorithm(pAd, pTxBlk);
1694 STABuildCommon802_11Header(pAd, pTxBlk);
1695
0f65bec1
BZ
1696 pHeaderBufPtr =
1697 &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
91980990
GKH
1698 }
1699
62eb734b 1700 pHeader_802_11 = (struct rt_header_802_11 *) pHeaderBufPtr;
91980990 1701
8281958b 1702 /* skip common header */
91980990
GKH
1703 pHeaderBufPtr += pTxBlk->MpduHeaderLen;
1704
8281958b
BZ
1705 /* */
1706 /* build QOS Control bytes */
1707 /* */
91980990 1708 *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
0f65bec1
BZ
1709 *(pHeaderBufPtr + 1) = 0;
1710 pHeaderBufPtr += 2;
91980990
GKH
1711 pTxBlk->MpduHeaderLen += 2;
1712
8281958b
BZ
1713 /* */
1714 /* build HTC+ */
1715 /* HTC control filed following QoS field */
1716 /* */
0f65bec1
BZ
1717 if ((pAd->CommonCfg.bRdg == TRUE)
1718 && CLIENT_STATUS_TEST_FLAG(pTxBlk->pMacEntry,
1719 fCLIENT_STATUS_RDG_CAPABLE)) {
1720 if (pMacEntry->isCached == FALSE) {
8281958b 1721 /* mark HTC bit */
91980990
GKH
1722 pHeader_802_11->FC.Order = 1;
1723
1724 NdisZeroMemory(pHeaderBufPtr, 4);
0f65bec1 1725 *(pHeaderBufPtr + 3) |= 0x80;
91980990
GKH
1726 }
1727 pHeaderBufPtr += 4;
1728 pTxBlk->MpduHeaderLen += 4;
1729 }
8281958b 1730 /*pTxBlk->MpduHeaderLen = pHeaderBufPtr - pTxBlk->HeaderBuf - TXWI_SIZE - TXINFO_SIZE; */
91980990
GKH
1731 ASSERT(pTxBlk->MpduHeaderLen >= 24);
1732
8281958b 1733 /* skip 802.3 header */
91980990 1734 pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
0f65bec1 1735 pTxBlk->SrcBufLen -= LENGTH_802_3;
91980990 1736
8281958b 1737 /* skip vlan tag */
0f65bec1
BZ
1738 if (bVLANPkt) {
1739 pTxBlk->pSrcBufData += LENGTH_802_1Q;
1740 pTxBlk->SrcBufLen -= LENGTH_802_1Q;
91980990 1741 }
8281958b
BZ
1742 /* */
1743 /* padding at front of LLC header */
1744 /* LLC header should locate at 4-octets aligment */
1745 /* */
1746 /* @@@ MpduHeaderLen excluding padding @@@ */
1747 /* */
51126deb
BZ
1748 pTxBlk->HdrPadLen = (unsigned long)pHeaderBufPtr;
1749 pHeaderBufPtr = (u8 *)ROUND_UP(pHeaderBufPtr, 4);
1750 pTxBlk->HdrPadLen = (unsigned long)(pHeaderBufPtr - pTxBlk->HdrPadLen);
91980990
GKH
1751
1752 {
1753
8281958b
BZ
1754 /* */
1755 /* Insert LLC-SNAP encapsulation - 8 octets */
1756 /* */
0f65bec1
BZ
1757 EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->
1758 pSrcBufData - 2,
1759 pTxBlk->
1760 pExtraLlcSnapEncap);
1761 if (pTxBlk->pExtraLlcSnapEncap) {
1762 NdisMoveMemory(pHeaderBufPtr,
1763 pTxBlk->pExtraLlcSnapEncap, 6);
91980990 1764 pHeaderBufPtr += 6;
8281958b 1765 /* get 2 octets (TypeofLen) */
0f65bec1
BZ
1766 NdisMoveMemory(pHeaderBufPtr,
1767 pTxBlk->pSrcBufData - 2, 2);
91980990
GKH
1768 pHeaderBufPtr += 2;
1769 pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
1770 }
1771
1772 }
1773
0f65bec1
BZ
1774 if (pMacEntry->isCached) {
1775 RTMPWriteTxWI_Cache(pAd,
62eb734b 1776 (struct rt_txwi *) (&pTxBlk->
0f65bec1
BZ
1777 HeaderBuf
1778 [TXINFO_SIZE]),
1779 pTxBlk);
1780 } else {
1781 RTMPWriteTxWI_Data(pAd,
62eb734b 1782 (struct rt_txwi *) (&pTxBlk->
0f65bec1
BZ
1783 HeaderBuf
1784 [TXINFO_SIZE]),
1785 pTxBlk);
1786
51126deb 1787 NdisZeroMemory((u8 *)(&pMacEntry->CachedBuf[0]),
0f65bec1 1788 sizeof(pMacEntry->CachedBuf));
51126deb
BZ
1789 NdisMoveMemory((u8 *)(&pMacEntry->CachedBuf[0]),
1790 (u8 *)(&pTxBlk->
0f65bec1
BZ
1791 HeaderBuf[TXINFO_SIZE]),
1792 (pHeaderBufPtr -
51126deb 1793 (u8 *)(&pTxBlk->
0f65bec1 1794 HeaderBuf[TXINFO_SIZE])));
91980990
GKH
1795 pMacEntry->isCached = TRUE;
1796 }
1797
8281958b 1798 /* calculate Transmitted AMPDU count and ByteCount */
91980990 1799 {
0f65bec1
BZ
1800 pAd->RalinkCounters.TransmittedMPDUsInAMPDUCount.u.
1801 LowPart++;
1802 pAd->RalinkCounters.TransmittedOctetsInAMPDUCount.
1803 QuadPart += pTxBlk->SrcBufLen;
91980990
GKH
1804 }
1805
8281958b 1806 /*FreeNumber = GET_TXRING_FREENO(pAd, QueIdx); */
91980990
GKH
1807
1808 HAL_WriteTxResource(pAd, pTxBlk, TRUE, &FreeNumber);
1809
8281958b
BZ
1810 /* */
1811 /* Kick out Tx */
1812 /* */
ed291e80
AM
1813 if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
1814 HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
91980990
GKH
1815
1816 pAd->RalinkCounters.KickTxCount++;
1817 pAd->RalinkCounters.OneSecTxDoneCount++;
1818 }
1819
1820}
1821
62eb734b 1822void STA_AMSDU_Frame_Tx(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
91980990 1823{
51126deb
BZ
1824 u8 *pHeaderBufPtr;
1825 u16 FreeNumber;
1826 u16 subFramePayloadLen = 0; /* AMSDU Subframe length without AMSDU-Header / Padding. */
1827 u16 totalMPDUSize = 0;
1828 u8 *subFrameHeader;
1829 u8 padding = 0;
1830 u16 FirstTx = 0, LastTxIdx = 0;
0f65bec1
BZ
1831 BOOLEAN bVLANPkt;
1832 int frameNum = 0;
62eb734b 1833 struct rt_queue_entry *pQEntry;
91980990
GKH
1834
1835 ASSERT(pTxBlk);
1836
1837 ASSERT((pTxBlk->TxPacketList.Number > 1));
1838
0f65bec1 1839 while (pTxBlk->TxPacketList.Head) {
91980990
GKH
1840 pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
1841 pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
0f65bec1
BZ
1842 if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) {
1843 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket,
1844 NDIS_STATUS_FAILURE);
91980990
GKH
1845 continue;
1846 }
1847
0f65bec1
BZ
1848 bVLANPkt =
1849 (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
91980990 1850
8281958b 1851 /* skip 802.3 header */
91980990 1852 pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
0f65bec1 1853 pTxBlk->SrcBufLen -= LENGTH_802_3;
91980990 1854
8281958b 1855 /* skip vlan tag */
0f65bec1
BZ
1856 if (bVLANPkt) {
1857 pTxBlk->pSrcBufData += LENGTH_802_1Q;
1858 pTxBlk->SrcBufLen -= LENGTH_802_1Q;
91980990
GKH
1859 }
1860
0f65bec1
BZ
1861 if (frameNum == 0) {
1862 pHeaderBufPtr =
1863 STA_Build_AMSDU_Frame_Header(pAd, pTxBlk);
91980990 1864
8281958b 1865 /* NOTE: TxWI->MPDUtotalByteCount will be updated after final frame was handled. */
0f65bec1 1866 RTMPWriteTxWI_Data(pAd,
62eb734b 1867 (struct rt_txwi *) (&pTxBlk->
0f65bec1
BZ
1868 HeaderBuf
1869 [TXINFO_SIZE]),
1870 pTxBlk);
1871 } else {
91980990 1872 pHeaderBufPtr = &pTxBlk->HeaderBuf[0];
0f65bec1
BZ
1873 padding =
1874 ROUND_UP(LENGTH_AMSDU_SUBFRAMEHEAD +
1875 subFramePayloadLen,
1876 4) - (LENGTH_AMSDU_SUBFRAMEHEAD +
1877 subFramePayloadLen);
1878 NdisZeroMemory(pHeaderBufPtr,
1879 padding + LENGTH_AMSDU_SUBFRAMEHEAD);
91980990
GKH
1880 pHeaderBufPtr += padding;
1881 pTxBlk->MpduHeaderLen = padding;
1882 }
1883
8281958b
BZ
1884 /* */
1885 /* A-MSDU subframe */
1886 /* DA(6)+SA(6)+Length(2) + LLC/SNAP Encap */
1887 /* */
91980990
GKH
1888 subFrameHeader = pHeaderBufPtr;
1889 subFramePayloadLen = pTxBlk->SrcBufLen;
1890
1891 NdisMoveMemory(subFrameHeader, pTxBlk->pSrcBufHeader, 12);
1892
91980990
GKH
1893 pHeaderBufPtr += LENGTH_AMSDU_SUBFRAMEHEAD;
1894 pTxBlk->MpduHeaderLen += LENGTH_AMSDU_SUBFRAMEHEAD;
1895
8281958b
BZ
1896 /* */
1897 /* Insert LLC-SNAP encapsulation - 8 octets */
1898 /* */
0f65bec1
BZ
1899 EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData - 2,
1900 pTxBlk->pExtraLlcSnapEncap);
91980990
GKH
1901
1902 subFramePayloadLen = pTxBlk->SrcBufLen;
1903
0f65bec1
BZ
1904 if (pTxBlk->pExtraLlcSnapEncap) {
1905 NdisMoveMemory(pHeaderBufPtr,
1906 pTxBlk->pExtraLlcSnapEncap, 6);
91980990 1907 pHeaderBufPtr += 6;
8281958b 1908 /* get 2 octets (TypeofLen) */
0f65bec1
BZ
1909 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData - 2,
1910 2);
91980990
GKH
1911 pHeaderBufPtr += 2;
1912 pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
1913 subFramePayloadLen += LENGTH_802_1_H;
1914 }
8281958b 1915 /* update subFrame Length field */
91980990
GKH
1916 subFrameHeader[12] = (subFramePayloadLen & 0xFF00) >> 8;
1917 subFrameHeader[13] = subFramePayloadLen & 0xFF;
1918
1919 totalMPDUSize += pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
1920
0f65bec1
BZ
1921 if (frameNum == 0)
1922 FirstTx =
1923 HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum,
1924 &FreeNumber);
91980990 1925 else
0f65bec1
BZ
1926 LastTxIdx =
1927 HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum,
1928 &FreeNumber);
91980990
GKH
1929
1930 frameNum++;
1931
1932 pAd->RalinkCounters.KickTxCount++;
1933 pAd->RalinkCounters.OneSecTxDoneCount++;
1934
8281958b 1935 /* calculate Transmitted AMSDU Count and ByteCount */
91980990 1936 {
0f65bec1
BZ
1937 pAd->RalinkCounters.TransmittedAMSDUCount.u.LowPart++;
1938 pAd->RalinkCounters.TransmittedOctetsInAMSDU.QuadPart +=
1939 totalMPDUSize;
91980990
GKH
1940 }
1941
1942 }
1943
1944 HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, FirstTx);
1945 HAL_LastTxIdx(pAd, pTxBlk->QueIdx, LastTxIdx);
1946
8281958b
BZ
1947 /* */
1948 /* Kick out Tx */
1949 /* */
ed291e80
AM
1950 if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
1951 HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
91980990 1952}
91980990 1953
62eb734b 1954void STA_Legacy_Frame_Tx(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
91980990 1955{
62eb734b 1956 struct rt_header_802_11 *pHeader_802_11;
51126deb
BZ
1957 u8 *pHeaderBufPtr;
1958 u16 FreeNumber;
0f65bec1 1959 BOOLEAN bVLANPkt;
62eb734b 1960 struct rt_queue_entry *pQEntry;
91980990
GKH
1961
1962 ASSERT(pTxBlk);
1963
91980990
GKH
1964 pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
1965 pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
0f65bec1 1966 if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) {
91980990
GKH
1967 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
1968 return;
1969 }
1970
0f65bec1 1971 if (pTxBlk->TxFrameType == TX_MCAST_FRAME) {
91980990
GKH
1972 INC_COUNTER64(pAd->WlanCounters.MulticastTransmittedFrameCount);
1973 }
1974
1975 if (RTMP_GET_PACKET_RTS(pTxBlk->pPacket))
1976 TX_BLK_SET_FLAG(pTxBlk, fTX_bRtsRequired);
1977 else
1978 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bRtsRequired);
1979
1980 bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
1981
1982 if (pTxBlk->TxRate < pAd->CommonCfg.MinTxRate)
1983 pTxBlk->TxRate = pAd->CommonCfg.MinTxRate;
1984
1985 STAFindCipherAlgorithm(pAd, pTxBlk);
1986 STABuildCommon802_11Header(pAd, pTxBlk);
1987
8281958b 1988 /* skip 802.3 header */
91980990 1989 pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
0f65bec1 1990 pTxBlk->SrcBufLen -= LENGTH_802_3;
91980990 1991
8281958b 1992 /* skip vlan tag */
0f65bec1
BZ
1993 if (bVLANPkt) {
1994 pTxBlk->pSrcBufData += LENGTH_802_1Q;
1995 pTxBlk->SrcBufLen -= LENGTH_802_1Q;
91980990
GKH
1996 }
1997
1998 pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
62eb734b 1999 pHeader_802_11 = (struct rt_header_802_11 *) pHeaderBufPtr;
91980990 2000
8281958b 2001 /* skip common header */
91980990
GKH
2002 pHeaderBufPtr += pTxBlk->MpduHeaderLen;
2003
0f65bec1 2004 if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) {
8281958b
BZ
2005 /* */
2006 /* build QOS Control bytes */
2007 /* */
0f65bec1
BZ
2008 *(pHeaderBufPtr) =
2009 ((pTxBlk->UserPriority & 0x0F) | (pAd->CommonCfg.
2010 AckPolicy[pTxBlk->
2011 QueIdx] << 5));
2012 *(pHeaderBufPtr + 1) = 0;
2013 pHeaderBufPtr += 2;
91980990
GKH
2014 pTxBlk->MpduHeaderLen += 2;
2015 }
8281958b 2016 /* The remaining content of MPDU header should locate at 4-octets aligment */
51126deb
BZ
2017 pTxBlk->HdrPadLen = (unsigned long)pHeaderBufPtr;
2018 pHeaderBufPtr = (u8 *)ROUND_UP(pHeaderBufPtr, 4);
2019 pTxBlk->HdrPadLen = (unsigned long)(pHeaderBufPtr - pTxBlk->HdrPadLen);
91980990
GKH
2020
2021 {
2022
8281958b
BZ
2023 /* */
2024 /* Insert LLC-SNAP encapsulation - 8 octets */
2025 /* */
2026 /* */
2027 /* if original Ethernet frame contains no LLC/SNAP, */
2028 /* then an extra LLC/SNAP encap is required */
2029 /* */
0f65bec1
BZ
2030 EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(pTxBlk->pSrcBufHeader,
2031 pTxBlk->pExtraLlcSnapEncap);
2032 if (pTxBlk->pExtraLlcSnapEncap) {
51126deb 2033 u8 vlan_size;
91980990 2034
0f65bec1
BZ
2035 NdisMoveMemory(pHeaderBufPtr,
2036 pTxBlk->pExtraLlcSnapEncap, 6);
91980990 2037 pHeaderBufPtr += 6;
8281958b 2038 /* skip vlan tag */
0f65bec1 2039 vlan_size = (bVLANPkt) ? LENGTH_802_1Q : 0;
8281958b 2040 /* get 2 octets (TypeofLen) */
0f65bec1
BZ
2041 NdisMoveMemory(pHeaderBufPtr,
2042 pTxBlk->pSrcBufHeader + 12 + vlan_size,
2043 2);
91980990
GKH
2044 pHeaderBufPtr += 2;
2045 pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
2046 }
2047
2048 }
2049
8281958b
BZ
2050 /* */
2051 /* prepare for TXWI */
2052 /* use Wcid as Key Index */
2053 /* */
91980990 2054
62eb734b 2055 RTMPWriteTxWI_Data(pAd, (struct rt_txwi *) (&pTxBlk->HeaderBuf[TXINFO_SIZE]),
0f65bec1 2056 pTxBlk);
91980990 2057
8281958b 2058 /*FreeNumber = GET_TXRING_FREENO(pAd, QueIdx); */
91980990
GKH
2059
2060 HAL_WriteTxResource(pAd, pTxBlk, TRUE, &FreeNumber);
2061
2062 pAd->RalinkCounters.KickTxCount++;
2063 pAd->RalinkCounters.OneSecTxDoneCount++;
2064
8281958b
BZ
2065 /* */
2066 /* Kick out Tx */
2067 /* */
ed291e80
AM
2068 if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
2069 HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
91980990
GKH
2070}
2071
62eb734b 2072void STA_ARalink_Frame_Tx(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
91980990 2073{
51126deb
BZ
2074 u8 *pHeaderBufPtr;
2075 u16 FreeNumber;
2076 u16 totalMPDUSize = 0;
2077 u16 FirstTx, LastTxIdx;
0f65bec1
BZ
2078 int frameNum = 0;
2079 BOOLEAN bVLANPkt;
62eb734b 2080 struct rt_queue_entry *pQEntry;
91980990
GKH
2081
2082 ASSERT(pTxBlk);
2083
0f65bec1 2084 ASSERT((pTxBlk->TxPacketList.Number == 2));
91980990 2085
8281958b 2086 FirstTx = LastTxIdx = 0; /* Is it ok init they as 0? */
0f65bec1 2087 while (pTxBlk->TxPacketList.Head) {
91980990
GKH
2088 pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
2089 pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
2090
0f65bec1
BZ
2091 if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) {
2092 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket,
2093 NDIS_STATUS_FAILURE);
91980990
GKH
2094 continue;
2095 }
2096
0f65bec1
BZ
2097 bVLANPkt =
2098 (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
91980990 2099
8281958b 2100 /* skip 802.3 header */
91980990 2101 pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
0f65bec1 2102 pTxBlk->SrcBufLen -= LENGTH_802_3;
91980990 2103
8281958b 2104 /* skip vlan tag */
0f65bec1
BZ
2105 if (bVLANPkt) {
2106 pTxBlk->pSrcBufData += LENGTH_802_1Q;
2107 pTxBlk->SrcBufLen -= LENGTH_802_1Q;
91980990
GKH
2108 }
2109
8281958b 2110 if (frameNum == 0) { /* For first frame, we need to create the 802.11 header + padding(optional) + RA-AGG-LEN + SNAP Header */
91980990 2111
0f65bec1
BZ
2112 pHeaderBufPtr =
2113 STA_Build_ARalink_Frame_Header(pAd, pTxBlk);
91980990 2114
8281958b
BZ
2115 /* It's ok write the TxWI here, because the TxWI->MPDUtotalByteCount */
2116 /* will be updated after final frame was handled. */
0f65bec1 2117 RTMPWriteTxWI_Data(pAd,
62eb734b 2118 (struct rt_txwi *) (&pTxBlk->
0f65bec1
BZ
2119 HeaderBuf
2120 [TXINFO_SIZE]),
2121 pTxBlk);
91980990 2122
8281958b
BZ
2123 /* */
2124 /* Insert LLC-SNAP encapsulation - 8 octets */
2125 /* */
0f65bec1
BZ
2126 EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->
2127 pSrcBufData - 2,
2128 pTxBlk->
2129 pExtraLlcSnapEncap);
2130
2131 if (pTxBlk->pExtraLlcSnapEncap) {
2132 NdisMoveMemory(pHeaderBufPtr,
2133 pTxBlk->pExtraLlcSnapEncap, 6);
91980990 2134 pHeaderBufPtr += 6;
8281958b 2135 /* get 2 octets (TypeofLen) */
0f65bec1
BZ
2136 NdisMoveMemory(pHeaderBufPtr,
2137 pTxBlk->pSrcBufData - 2, 2);
91980990
GKH
2138 pHeaderBufPtr += 2;
2139 pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
2140 }
8281958b 2141 } else { /* For second aggregated frame, we need create the 802.3 header to headerBuf, because PCI will copy it to SDPtr0. */
91980990
GKH
2142
2143 pHeaderBufPtr = &pTxBlk->HeaderBuf[0];
2144 pTxBlk->MpduHeaderLen = 0;
2145
8281958b
BZ
2146 /* A-Ralink sub-sequent frame header is the same as 802.3 header. */
2147 /* DA(6)+SA(6)+FrameType(2) */
0f65bec1
BZ
2148 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufHeader,
2149 12);
91980990 2150 pHeaderBufPtr += 12;
8281958b 2151 /* get 2 octets (TypeofLen) */
0f65bec1
BZ
2152 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData - 2,
2153 2);
91980990
GKH
2154 pHeaderBufPtr += 2;
2155 pTxBlk->MpduHeaderLen = LENGTH_ARALINK_SUBFRAMEHEAD;
2156 }
2157
2158 totalMPDUSize += pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
2159
8281958b 2160 /*FreeNumber = GET_TXRING_FREENO(pAd, QueIdx); */
0f65bec1
BZ
2161 if (frameNum == 0)
2162 FirstTx =
2163 HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum,
2164 &FreeNumber);
91980990 2165 else
0f65bec1
BZ
2166 LastTxIdx =
2167 HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum,
2168 &FreeNumber);
91980990
GKH
2169
2170 frameNum++;
2171
2172 pAd->RalinkCounters.OneSecTxAggregationCount++;
2173 pAd->RalinkCounters.KickTxCount++;
2174 pAd->RalinkCounters.OneSecTxDoneCount++;
2175
2176 }
2177
2178 HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, FirstTx);
2179 HAL_LastTxIdx(pAd, pTxBlk->QueIdx, LastTxIdx);
2180
8281958b
BZ
2181 /* */
2182 /* Kick out Tx */
2183 /* */
ed291e80
AM
2184 if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
2185 HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
91980990
GKH
2186
2187}
2188
62eb734b 2189void STA_Fragment_Frame_Tx(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
91980990 2190{
62eb734b 2191 struct rt_header_802_11 *pHeader_802_11;
51126deb
BZ
2192 u8 *pHeaderBufPtr;
2193 u16 FreeNumber;
2194 u8 fragNum = 0;
62eb734b 2195 struct rt_packet_info PacketInfo;
51126deb
BZ
2196 u16 EncryptionOverhead = 0;
2197 u32 FreeMpduSize, SrcRemainingBytes;
2198 u16 AckDuration;
2199 u32 NextMpduSize;
0f65bec1 2200 BOOLEAN bVLANPkt;
62eb734b 2201 struct rt_queue_entry *pQEntry;
0f65bec1 2202 HTTRANSMIT_SETTING *pTransmit;
91980990
GKH
2203
2204 ASSERT(pTxBlk);
2205
2206 pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
2207 pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
0f65bec1 2208 if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) {
91980990
GKH
2209 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
2210 return;
2211 }
2212
2213 ASSERT(TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag));
2214 bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
2215
2216 STAFindCipherAlgorithm(pAd, pTxBlk);
2217 STABuildCommon802_11Header(pAd, pTxBlk);
2218
0f65bec1
BZ
2219 if (pTxBlk->CipherAlg == CIPHER_TKIP) {
2220 pTxBlk->pPacket =
2221 duplicate_pkt_with_TKIP_MIC(pAd, pTxBlk->pPacket);
91980990
GKH
2222 if (pTxBlk->pPacket == NULL)
2223 return;
0f65bec1
BZ
2224 RTMP_QueryPacketInfo(pTxBlk->pPacket, &PacketInfo,
2225 &pTxBlk->pSrcBufHeader,
2226 &pTxBlk->SrcBufLen);
91980990 2227 }
8281958b 2228 /* skip 802.3 header */
91980990 2229 pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
0f65bec1 2230 pTxBlk->SrcBufLen -= LENGTH_802_3;
91980990 2231
8281958b 2232 /* skip vlan tag */
0f65bec1
BZ
2233 if (bVLANPkt) {
2234 pTxBlk->pSrcBufData += LENGTH_802_1Q;
2235 pTxBlk->SrcBufLen -= LENGTH_802_1Q;
91980990
GKH
2236 }
2237
2238 pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
62eb734b 2239 pHeader_802_11 = (struct rt_header_802_11 *) pHeaderBufPtr;
91980990 2240
8281958b 2241 /* skip common header */
91980990
GKH
2242 pHeaderBufPtr += pTxBlk->MpduHeaderLen;
2243
0f65bec1 2244 if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) {
8281958b
BZ
2245 /* */
2246 /* build QOS Control bytes */
2247 /* */
91980990
GKH
2248 *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
2249
0f65bec1
BZ
2250 *(pHeaderBufPtr + 1) = 0;
2251 pHeaderBufPtr += 2;
91980990
GKH
2252 pTxBlk->MpduHeaderLen += 2;
2253 }
8281958b
BZ
2254 /* */
2255 /* padding at front of LLC header */
2256 /* LLC header should locate at 4-octets aligment */
2257 /* */
51126deb
BZ
2258 pTxBlk->HdrPadLen = (unsigned long)pHeaderBufPtr;
2259 pHeaderBufPtr = (u8 *)ROUND_UP(pHeaderBufPtr, 4);
2260 pTxBlk->HdrPadLen = (unsigned long)(pHeaderBufPtr - pTxBlk->HdrPadLen);
91980990 2261
8281958b
BZ
2262 /* */
2263 /* Insert LLC-SNAP encapsulation - 8 octets */
2264 /* */
2265 /* */
2266 /* if original Ethernet frame contains no LLC/SNAP, */
2267 /* then an extra LLC/SNAP encap is required */
2268 /* */
0f65bec1
BZ
2269 EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(pTxBlk->pSrcBufHeader,
2270 pTxBlk->pExtraLlcSnapEncap);
2271 if (pTxBlk->pExtraLlcSnapEncap) {
51126deb 2272 u8 vlan_size;
91980990
GKH
2273
2274 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
2275 pHeaderBufPtr += 6;
8281958b 2276 /* skip vlan tag */
0f65bec1 2277 vlan_size = (bVLANPkt) ? LENGTH_802_1Q : 0;
8281958b 2278 /* get 2 octets (TypeofLen) */
0f65bec1
BZ
2279 NdisMoveMemory(pHeaderBufPtr,
2280 pTxBlk->pSrcBufHeader + 12 + vlan_size, 2);
91980990
GKH
2281 pHeaderBufPtr += 2;
2282 pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
2283 }
2284
8281958b
BZ
2285 /* If TKIP is used and fragmentation is required. Driver has to */
2286 /* append TKIP MIC at tail of the scatter buffer */
2287 /* MAC ASIC will only perform IV/EIV/ICV insertion but no TKIP MIC */
0f65bec1
BZ
2288 if (pTxBlk->CipherAlg == CIPHER_TKIP) {
2289 RTMPCalculateMICValue(pAd, pTxBlk->pPacket,
2290 pTxBlk->pExtraLlcSnapEncap, pTxBlk->pKey,
2291 0);
91980990 2292
8281958b
BZ
2293 /* NOTE: DON'T refer the skb->len directly after following copy. Becasue the length is not adjust */
2294 /* to correct lenght, refer to pTxBlk->SrcBufLen for the packet length in following progress. */
0f65bec1
BZ
2295 NdisMoveMemory(pTxBlk->pSrcBufData + pTxBlk->SrcBufLen,
2296 &pAd->PrivateInfo.Tx.MIC[0], 8);
8281958b 2297 /*skb_put((RTPKT_TO_OSPKT(pTxBlk->pPacket))->tail, 8); */
91980990
GKH
2298 pTxBlk->SrcBufLen += 8;
2299 pTxBlk->TotalFrameLen += 8;
2300 pTxBlk->CipherAlg = CIPHER_TKIP_NO_MIC;
2301 }
8281958b
BZ
2302 /* */
2303 /* calcuate the overhead bytes that encryption algorithm may add. This */
2304 /* affects the calculate of "duration" field */
2305 /* */
0f65bec1
BZ
2306 if ((pTxBlk->CipherAlg == CIPHER_WEP64)
2307 || (pTxBlk->CipherAlg == CIPHER_WEP128))
8281958b 2308 EncryptionOverhead = 8; /*WEP: IV[4] + ICV[4]; */
91980990 2309 else if (pTxBlk->CipherAlg == CIPHER_TKIP_NO_MIC)
8281958b 2310 EncryptionOverhead = 12; /*TKIP: IV[4] + EIV[4] + ICV[4], MIC will be added to TotalPacketLength */
91980990 2311 else if (pTxBlk->CipherAlg == CIPHER_TKIP)
8281958b 2312 EncryptionOverhead = 20; /*TKIP: IV[4] + EIV[4] + ICV[4] + MIC[8] */
91980990 2313 else if (pTxBlk->CipherAlg == CIPHER_AES)
8281958b 2314 EncryptionOverhead = 16; /* AES: IV[4] + EIV[4] + MIC[8] */
91980990
GKH
2315 else
2316 EncryptionOverhead = 0;
2317
ca97b838 2318 pTransmit = pTxBlk->pTransmit;
8281958b 2319 /* Decide the TX rate */
ca97b838
BZ
2320 if (pTransmit->field.MODE == MODE_CCK)
2321 pTxBlk->TxRate = pTransmit->field.MCS;
2322 else if (pTransmit->field.MODE == MODE_OFDM)
2323 pTxBlk->TxRate = pTransmit->field.MCS + RATE_FIRST_OFDM_RATE;
2324 else
2325 pTxBlk->TxRate = RATE_6_5;
2326
8281958b 2327 /* decide how much time an ACK/CTS frame will consume in the air */
ca97b838 2328 if (pTxBlk->TxRate <= RATE_LAST_OFDM_RATE)
0f65bec1
BZ
2329 AckDuration =
2330 RTMPCalcDuration(pAd,
2331 pAd->CommonCfg.ExpectedACKRate[pTxBlk->
2332 TxRate],
2333 14);
ca97b838
BZ
2334 else
2335 AckDuration = RTMPCalcDuration(pAd, RATE_6_5, 14);
91980990 2336
8281958b 2337 /* Init the total payload length of this frame. */
91980990
GKH
2338 SrcRemainingBytes = pTxBlk->SrcBufLen;
2339
2340 pTxBlk->TotalFragNum = 0xff;
2341
2342 do {
2343
2344 FreeMpduSize = pAd->CommonCfg.FragmentThreshold - LENGTH_CRC;
2345
2346 FreeMpduSize -= pTxBlk->MpduHeaderLen;
2347
8281958b 2348 if (SrcRemainingBytes <= FreeMpduSize) { /* this is the last or only fragment */
91980990
GKH
2349
2350 pTxBlk->SrcBufLen = SrcRemainingBytes;
2351
2352 pHeader_802_11->FC.MoreFrag = 0;
0f65bec1
BZ
2353 pHeader_802_11->Duration =
2354 pAd->CommonCfg.Dsifs + AckDuration;
91980990 2355
8281958b 2356 /* Indicate the lower layer that this's the last fragment. */
91980990 2357 pTxBlk->TotalFragNum = fragNum;
8281958b 2358 } else { /* more fragment is required */
91980990
GKH
2359
2360 pTxBlk->SrcBufLen = FreeMpduSize;
2361
0f65bec1 2362 NextMpduSize =
51126deb
BZ
2363 min(((u32)SrcRemainingBytes - pTxBlk->SrcBufLen),
2364 ((u32)pAd->CommonCfg.FragmentThreshold));
91980990 2365 pHeader_802_11->FC.MoreFrag = 1;
0f65bec1
BZ
2366 pHeader_802_11->Duration =
2367 (3 * pAd->CommonCfg.Dsifs) + (2 * AckDuration) +
2368 RTMPCalcDuration(pAd, pTxBlk->TxRate,
2369 NextMpduSize + EncryptionOverhead);
91980990
GKH
2370 }
2371
2372 if (fragNum == 0)
2373 pTxBlk->FrameGap = IFS_HTTXOP;
2374 else
2375 pTxBlk->FrameGap = IFS_SIFS;
2376
0f65bec1 2377 RTMPWriteTxWI_Data(pAd,
62eb734b 2378 (struct rt_txwi *) (&pTxBlk->
0f65bec1
BZ
2379 HeaderBuf[TXINFO_SIZE]),
2380 pTxBlk);
91980990
GKH
2381
2382 HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, &FreeNumber);
2383
2384 pAd->RalinkCounters.KickTxCount++;
2385 pAd->RalinkCounters.OneSecTxDoneCount++;
2386
8281958b 2387 /* Update the frame number, remaining size of the NDIS packet payload. */
91980990 2388
8281958b 2389 /* space for 802.11 header. */
91980990
GKH
2390 if (fragNum == 0 && pTxBlk->pExtraLlcSnapEncap)
2391 pTxBlk->MpduHeaderLen -= LENGTH_802_1_H;
2392
2393 fragNum++;
2394 SrcRemainingBytes -= pTxBlk->SrcBufLen;
2395 pTxBlk->pSrcBufData += pTxBlk->SrcBufLen;
2396
8281958b 2397 pHeader_802_11->Frag++; /* increase Frag # */
91980990 2398
0f65bec1 2399 } while (SrcRemainingBytes > 0);
91980990 2400
8281958b
BZ
2401 /* */
2402 /* Kick out Tx */
2403 /* */
ca97b838 2404 if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
0f65bec1 2405 HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
91980990
GKH
2406}
2407
91980990
GKH
2408#define RELEASE_FRAMES_OF_TXBLK(_pAd, _pTxBlk, _pQEntry, _Status) \
2409 while(_pTxBlk->TxPacketList.Head) \
2410 { \
2411 _pQEntry = RemoveHeadQueue(&_pTxBlk->TxPacketList); \
2412 RELEASE_NDIS_PACKET(_pAd, QUEUE_ENTRY_TO_PACKET(_pQEntry), _Status); \
2413 }
2414
91980990
GKH
2415/*
2416 ========================================================================
2417
2418 Routine Description:
2419 Copy frame from waiting queue into relative ring buffer and set
2420 appropriate ASIC register to kick hardware encryption before really
2421 sent out to air.
2422
2423 Arguments:
2424 pAd Pointer to our adapter
8a10a546 2425 void * Pointer to outgoing Ndis frame
91980990
GKH
2426 NumberOfFrag Number of fragment required
2427
2428 Return Value:
2429 None
2430
2431 IRQL = DISPATCH_LEVEL
2432
2433 Note:
2434
2435 ========================================================================
2436*/
62eb734b
BZ
2437int STAHardTransmit(struct rt_rtmp_adapter *pAd,
2438 struct rt_tx_blk *pTxBlk, u8 QueIdx)
91980990 2439{
8a10a546 2440 char *pPacket;
62eb734b 2441 struct rt_queue_entry *pQEntry;
91980990 2442
8281958b
BZ
2443 /* --------------------------------------------- */
2444 /* STEP 0. DO SANITY CHECK AND SOME EARLY PREPARATION. */
2445 /* --------------------------------------------- */
2446 /* */
91980990 2447 ASSERT(pTxBlk->TxPacketList.Number);
0f65bec1
BZ
2448 if (pTxBlk->TxPacketList.Head == NULL) {
2449 DBGPRINT(RT_DEBUG_ERROR,
2450 ("pTxBlk->TotalFrameNum == %ld!\n",
2451 pTxBlk->TxPacketList.Number));
91980990
GKH
2452 return NDIS_STATUS_FAILURE;
2453 }
2454
2455 pPacket = QUEUE_ENTRY_TO_PACKET(pTxBlk->TxPacketList.Head);
2456
8281958b
BZ
2457 /* ------------------------------------------------------------------ */
2458 /* STEP 1. WAKE UP PHY */
2459 /* outgoing frame always wakeup PHY to prevent frame lost and */
2460 /* turn off PSM bit to improve performance */
2461 /* ------------------------------------------------------------------ */
2462 /* not to change PSM bit, just send this frame out? */
0f65bec1
BZ
2463 if ((pAd->StaCfg.Psm == PWR_SAVE)
2464 && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) {
2465 DBGPRINT_RAW(RT_DEBUG_INFO, ("AsicForceWakeup At HardTx\n"));
ca97b838 2466#ifdef RTMP_MAC_PCI
5f5d2df8 2467 AsicForceWakeup(pAd, TRUE);
8281958b 2468#endif /* RTMP_MAC_PCI // */
ca97b838
BZ
2469#ifdef RTMP_MAC_USB
2470 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_FORCE_WAKE_UP, NULL, 0);
8281958b 2471#endif /* RTMP_MAC_USB // */
91980990 2472 }
8281958b 2473 /* It should not change PSM bit, when APSD turn on. */
0f65bec1
BZ
2474 if ((!
2475 (pAd->CommonCfg.bAPSDCapable
2476 && pAd->CommonCfg.APEdcaParm.bAPSDCapable)
2477 && (pAd->CommonCfg.bAPSDForcePowerSave == FALSE))
2478 || (RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket))
2479 || (RTMP_GET_PACKET_WAI(pTxBlk->pPacket))) {
91980990 2480 if ((pAd->StaCfg.Psm == PWR_SAVE) &&
0f65bec1
BZ
2481 (pAd->StaCfg.WindowsPowerMode ==
2482 Ndis802_11PowerModeFast_PSP))
ca97b838 2483 RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE);
91980990
GKH
2484 }
2485
0f65bec1
BZ
2486 switch (pTxBlk->TxFrameType) {
2487 case TX_AMPDU_FRAME:
2488 STA_AMPDU_Frame_Tx(pAd, pTxBlk);
2489 break;
2490 case TX_AMSDU_FRAME:
2491 STA_AMSDU_Frame_Tx(pAd, pTxBlk);
2492 break;
2493 case TX_LEGACY_FRAME:
2494 STA_Legacy_Frame_Tx(pAd, pTxBlk);
2495 break;
2496 case TX_MCAST_FRAME:
2497 STA_Legacy_Frame_Tx(pAd, pTxBlk);
2498 break;
2499 case TX_RALINK_FRAME:
2500 STA_ARalink_Frame_Tx(pAd, pTxBlk);
2501 break;
2502 case TX_FRAG_FRAME:
2503 STA_Fragment_Frame_Tx(pAd, pTxBlk);
2504 break;
2505 default:
2506 {
8281958b 2507 /* It should not happened! */
0f65bec1
BZ
2508 DBGPRINT(RT_DEBUG_ERROR,
2509 ("Send a pacekt was not classified!! It should not happen!\n"));
2510 while (pTxBlk->TxPacketList.Number) {
2511 pQEntry =
2512 RemoveHeadQueue(&pTxBlk->TxPacketList);
2513 pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
2514 if (pPacket)
2515 RELEASE_NDIS_PACKET(pAd, pPacket,
2516 NDIS_STATUS_FAILURE);
91980990 2517 }
0f65bec1
BZ
2518 }
2519 break;
91980990
GKH
2520 }
2521
2522 return (NDIS_STATUS_SUCCESS);
2523
2524}
2525
51126deb 2526unsigned long HashBytesPolynomial(u8 * value, unsigned int len)
91980990 2527{
0f65bec1
BZ
2528 unsigned char *word = value;
2529 unsigned int ret = 0;
2530 unsigned int i;
2531
2532 for (i = 0; i < len; i++) {
2533 int mod = i % 32;
2534 ret ^= (unsigned int)(word[i]) << mod;
2535 ret ^= (unsigned int)(word[i]) >> (32 - mod);
2536 }
2537 return ret;
91980990
GKH
2538}
2539
62eb734b 2540void Sta_Announce_or_Forward_802_3_Packet(struct rt_rtmp_adapter *pAd,
8a10a546 2541 void *pPacket,
51126deb 2542 u8 FromWhichBSSID)
91980990 2543{
0f65bec1 2544 if (TRUE) {
91980990 2545 announce_802_3_packet(pAd, pPacket);
0f65bec1 2546 } else {
8281958b 2547 /* release packet */
91980990
GKH
2548 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
2549 }
2550}