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