2 *************************************************************************
4 * 5F., No.36, Taiyuan St., Jhubei City,
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
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. *
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. *
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. *
25 *************************************************************************
35 -------- ---------- ----------------------------------------------
38 #include "../rt_config.h"
41 VOID STARxEAPOLFrameIndicate(
43 IN MAC_TABLE_ENTRY *pEntry,
45 IN UCHAR FromWhichBSSID)
47 PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
48 PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
52 #ifdef WPA_SUPPLICANT_SUPPORT
53 if (pAd->StaCfg.WpaSupplicantUP)
55 // All EAPoL frames have to pass to upper layer (ex. WPA_SUPPLICANT daemon)
56 // TBD : process fragmented EAPol frames
58 // In 802.1x mode, if the received frame is EAP-SUCCESS packet, turn on the PortSecured variable
59 if ( pAd->StaCfg.IEEE8021X == TRUE &&
60 (EAP_CODE_SUCCESS == WpaCheckEapCode(pAd, pRxBlk->pData, pRxBlk->DataSize, LENGTH_802_1_H)))
66 DBGPRINT_RAW(RT_DEBUG_TRACE, ("Receive EAP-SUCCESS Packet\n"));
67 //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
68 STA_PORT_SECURED(pAd);
70 if (pAd->StaCfg.IEEE8021x_required_keys == FALSE)
72 idx = pAd->StaCfg.DesireSharedKeyId;
73 CipherAlg = pAd->StaCfg.DesireSharedKey[idx].CipherAlg;
74 Key = pAd->StaCfg.DesireSharedKey[idx].Key;
76 if (pAd->StaCfg.DesireSharedKey[idx].KeyLen > 0)
79 MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[BSSID_WCID];
81 // Set key material and cipherAlg to Asic
82 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
84 // Assign group key info
85 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
87 // Assign pairwise key info
88 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, pEntry);
90 pAd->IndicateMediaState = NdisMediaStateConnected;
91 pAd->ExtraInfo = GENERAL_LINK_UP;
92 #endif // RTMP_MAC_PCI //
93 // For Preventing ShardKey Table is cleared by remove key procedure.
94 pAd->SharedKey[BSS0][idx].CipherAlg = CipherAlg;
95 pAd->SharedKey[BSS0][idx].KeyLen = pAd->StaCfg.DesireSharedKey[idx].KeyLen;
96 NdisMoveMemory(pAd->SharedKey[BSS0][idx].Key,
97 pAd->StaCfg.DesireSharedKey[idx].Key,
98 pAd->StaCfg.DesireSharedKey[idx].KeyLen);
103 Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
108 #endif // WPA_SUPPLICANT_SUPPORT //
110 // Special DATA frame that has to pass to MLME
111 // 1. Cisco Aironet frames for CCX2. We need pass it to MLME for special process
112 // 2. EAPOL handshaking frames when driver supplicant enabled, pass to MLME for special process
114 pTmpBuf = pRxBlk->pData - LENGTH_802_11;
115 NdisMoveMemory(pTmpBuf, pRxBlk->pHeader, LENGTH_802_11);
116 REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->WirelessCliID, pTmpBuf, pRxBlk->DataSize + LENGTH_802_11, pRxWI->RSSI0, pRxWI->RSSI1, pRxWI->RSSI2, pRxD->PlcpSignal);
117 DBGPRINT_RAW(RT_DEBUG_TRACE, ("!!! report EAPOL/AIRONET DATA to MLME (len=%d) !!!\n", pRxBlk->DataSize));
121 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
126 VOID STARxDataFrameAnnounce(
127 IN PRTMP_ADAPTER pAd,
128 IN MAC_TABLE_ENTRY *pEntry,
130 IN UCHAR FromWhichBSSID)
134 if (!RTMPCheckWPAframe(pAd, pEntry, pRxBlk->pData, pRxBlk->DataSize, FromWhichBSSID))
138 // drop all non-EAP DATA frame before
139 // this client's Port-Access-Control is secured
140 if (pRxBlk->pHeader->FC.Wep)
142 // unsupported cipher suite
143 if (pAd->StaCfg.WepStatus == Ndis802_11EncryptionDisabled)
146 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
152 // encryption in-use but receive a non-EAPOL clear text frame, drop it
153 if ((pAd->StaCfg.WepStatus != Ndis802_11EncryptionDisabled) &&
154 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
157 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
162 RX_BLK_CLEAR_FLAG(pRxBlk, fRX_EAP);
165 if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_ARALINK))
167 // Normal legacy, AMPDU or AMSDU
168 CmmRxnonRalinkFrameIndicate(pAd, pRxBlk, FromWhichBSSID);
174 CmmRxRalinkFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
176 #ifdef QOS_DLS_SUPPORT
177 RX_BLK_CLEAR_FLAG(pRxBlk, fRX_DLS);
178 #endif // QOS_DLS_SUPPORT //
182 RX_BLK_SET_FLAG(pRxBlk, fRX_EAP);
183 #ifdef DOT11_N_SUPPORT
184 if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU) && (pAd->CommonCfg.bDisableReordering == 0))
186 Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID);
189 #endif // DOT11_N_SUPPORT //
191 // Determin the destination of the EAP frame
192 // to WPA state machine or upper layer
193 STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
199 // For TKIP frame, calculate the MIC value
200 BOOLEAN STACheckTkipMICValue(
201 IN PRTMP_ADAPTER pAd,
202 IN MAC_TABLE_ENTRY *pEntry,
205 PHEADER_802_11 pHeader = pRxBlk->pHeader;
206 UCHAR *pData = pRxBlk->pData;
207 USHORT DataSize = pRxBlk->DataSize;
208 UCHAR UserPriority = pRxBlk->UserPriority;
212 pWpaKey = &pAd->SharedKey[BSS0][pRxBlk->pRxWI->KeyIndex];
214 pDA = pHeader->Addr1;
215 if (RX_BLK_TEST_FLAG(pRxBlk, fRX_INFRA))
217 pSA = pHeader->Addr3;
221 pSA = pHeader->Addr2;
224 if (RTMPTkipCompareMICValue(pAd,
232 DBGPRINT_RAW(RT_DEBUG_ERROR,("Rx MIC Value error 2\n"));
234 #ifdef WPA_SUPPLICANT_SUPPORT
235 if (pAd->StaCfg.WpaSupplicantUP)
237 WpaSendMicFailureToWpaSupplicant(pAd, (pWpaKey->Type == PAIRWISEKEY) ? TRUE : FALSE);
240 #endif // WPA_SUPPLICANT_SUPPORT //
242 RTMPReportMicError(pAd, pWpaKey);
246 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
255 // All Rx routines use RX_BLK structure to hande rx events
256 // It is very important to build pRxBlk attributes
257 // 1. pHeader pointer to 802.11 Header
258 // 2. pData pointer to payload including LLC (just skip Header)
259 // 3. set payload size including LLC to DataSize
260 // 4. set some flags with RX_BLK_SET_FLAG()
262 VOID STAHandleRxDataFrame(
263 IN PRTMP_ADAPTER pAd,
266 PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
267 PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
268 PHEADER_802_11 pHeader = pRxBlk->pHeader;
269 PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
270 BOOLEAN bFragment = FALSE;
271 MAC_TABLE_ENTRY *pEntry = NULL;
272 UCHAR FromWhichBSSID = BSS0;
273 UCHAR UserPriority = 0;
276 // before LINK UP, all DATA frames are rejected
277 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
280 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
284 #ifdef QOS_DLS_SUPPORT
285 //if ((pHeader->FC.FrDs == 0) && (pHeader->FC.ToDs == 0))
286 if (RTMPRcvFrameDLSCheck(pAd, pHeader, pRxWI->MPDUtotalByteCount, pRxD))
290 #endif // QOS_DLS_SUPPORT //
292 // Drop not my BSS frames
293 if (pRxD->MyBss == 0)
297 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
302 pAd->RalinkCounters.RxCountSinceLastNULL++;
303 if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable && (pHeader->FC.SubType & 0x08))
306 DBGPRINT(RT_DEBUG_INFO,("bAPSDCapable\n"));
309 pData = (PUCHAR)pHeader + LENGTH_802_11;
310 if ((*pData >> 4) & 0x01)
312 DBGPRINT(RT_DEBUG_INFO,("RxDone- Rcv EOSP frame, driver may fall into sleep\n"));
313 pAd->CommonCfg.bInServicePeriod = FALSE;
315 // Force driver to fall into sleep mode when rcv EOSP frame
316 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
318 USHORT TbttNumToNextWakeUp;
319 USHORT NextDtim = pAd->StaCfg.DtimPeriod;
322 NdisGetSystemUpTime(&Now);
323 NextDtim -= (USHORT)(Now - pAd->StaCfg.LastBeaconRxTime)/pAd->CommonCfg.BeaconPeriod;
325 TbttNumToNextWakeUp = pAd->StaCfg.DefaultListenCount;
326 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim))
327 TbttNumToNextWakeUp = NextDtim;
329 RTMP_SET_PSM_BIT(pAd, PWR_SAVE);
330 // if WMM-APSD is failed, try to disable following line
331 AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
335 if ((pHeader->FC.MoreData) && (pAd->CommonCfg.bInServicePeriod))
337 DBGPRINT(RT_DEBUG_TRACE,("Sending another trigger frame when More Data bit is set to 1\n"));
341 // Drop NULL, CF-ACK(no data), CF-POLL(no data), and CF-ACK+CF-POLL(no data) data frame
342 if ((pHeader->FC.SubType & 0x04)) // bit 2 : no DATA
345 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
349 // Drop not my BSS frame (we can not only check the MyBss bit in RxD)
350 #ifdef QOS_DLS_SUPPORT
351 if (!pAd->CommonCfg.bDLSCapable)
353 #endif // QOS_DLS_SUPPORT //
356 // Infrastructure mode, check address 2 for BSSID
357 if (!RTMPEqualMemory(&pHeader->Addr2, &pAd->CommonCfg.Bssid, 6))
359 // Receive frame not my BSSID
361 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
365 else // Ad-Hoc mode or Not associated
367 // Ad-Hoc mode, check address 3 for BSSID
368 if (!RTMPEqualMemory(&pHeader->Addr3, &pAd->CommonCfg.Bssid, 6))
370 // Receive frame not my BSSID
372 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
376 #ifdef QOS_DLS_SUPPORT
378 #endif // QOS_DLS_SUPPORT //
383 if (pRxWI->WirelessCliID < MAX_LEN_OF_MAC_TABLE)
385 pEntry = &pAd->MacTab.Content[pRxWI->WirelessCliID];
390 // 1. release packet if infra mode
391 // 2. new a pEntry if ad-hoc mode
392 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
399 RX_BLK_SET_FLAG(pRxBlk, fRX_INFRA);
400 #ifdef QOS_DLS_SUPPORT
401 if ((pHeader->FC.FrDs == 0) && (pHeader->FC.ToDs == 0))
402 RX_BLK_SET_FLAG(pRxBlk, fRX_DLS);
404 #endif // QOS_DLS_SUPPORT //
405 ASSERT(pRxWI->WirelessCliID == BSSID_WCID);
408 // check Atheros Client
409 if ((pEntry->bIAmBadAtheros == FALSE) && (pRxD->AMPDU == 1) && (pHeader->FC.Retry ))
411 pEntry->bIAmBadAtheros = TRUE;
412 pAd->CommonCfg.IOTestParm.bCurrentAtheros = TRUE;
413 pAd->CommonCfg.IOTestParm.bLastAtheros = TRUE;
414 if (!STA_AES_ON(pAd))
416 AsicUpdateProtect(pAd, 8, ALLN_SETPROTECT, TRUE, FALSE);
421 pRxBlk->pData = (UCHAR *)pHeader;
424 // update RxBlk->pData, DataSize
425 // 802.11 Header, QOS, HTC, Hw Padding
428 // 1. skip 802.11 HEADER
430 pRxBlk->pData += LENGTH_802_11;
431 pRxBlk->DataSize -= LENGTH_802_11;
435 if (pHeader->FC.SubType & 0x08)
437 RX_BLK_SET_FLAG(pRxBlk, fRX_QOS);
438 UserPriority = *(pRxBlk->pData) & 0x0f;
439 // bit 7 in QoS Control field signals the HT A-MSDU format
440 if ((*pRxBlk->pData) & 0x80)
442 RX_BLK_SET_FLAG(pRxBlk, fRX_AMSDU);
445 // skip QOS contorl field
447 pRxBlk->DataSize -=2;
449 pRxBlk->UserPriority = UserPriority;
451 /* check if need to resend PS Poll when received packet with MoreData = 1 */
452 if ((pAd->StaCfg.Psm == PWR_SAVE) && (pHeader->FC.MoreData == 1))
454 if ((((UserPriority == 0) || (UserPriority == 3)) &&
455 pAd->CommonCfg.bAPSDAC_BE == 0) ||
456 (((UserPriority == 1) || (UserPriority == 2)) &&
457 pAd->CommonCfg.bAPSDAC_BK == 0) ||
458 (((UserPriority == 4) || (UserPriority == 5)) &&
459 pAd->CommonCfg.bAPSDAC_VI == 0) ||
460 (((UserPriority == 6) || (UserPriority == 7)) &&
461 pAd->CommonCfg.bAPSDAC_VO == 0))
463 /* non-UAPSD delivery-enabled AC */
464 RTMP_PS_POLL_ENQUEUE(pAd);
468 // 3. Order bit: A-Ralink or HTC+
469 if (pHeader->FC.Order)
471 #ifdef AGGREGATION_SUPPORT
472 if ((pRxWI->PHYMODE <= MODE_OFDM) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)))
474 RX_BLK_SET_FLAG(pRxBlk, fRX_ARALINK);
477 #endif // AGGREGATION_SUPPORT //
479 #ifdef DOT11_N_SUPPORT
480 RX_BLK_SET_FLAG(pRxBlk, fRX_HTC);
481 // skip HTC contorl field
483 pRxBlk->DataSize -= 4;
484 #endif // DOT11_N_SUPPORT //
488 // 4. skip HW padding
491 // just move pData pointer
492 // because DataSize excluding HW padding
493 RX_BLK_SET_FLAG(pRxBlk, fRX_PAD);
497 #ifdef DOT11_N_SUPPORT
500 RX_BLK_SET_FLAG(pRxBlk, fRX_AMPDU);
502 #endif // DOT11_N_SUPPORT //
506 // Case I Process Broadcast & Multicast data frame
508 if (pRxD->Bcast || pRxD->Mcast)
510 INC_COUNTER64(pAd->WlanCounters.MulticastReceivedFrameCount);
512 // Drop Mcast/Bcast frame with fragment bit on
513 if (pHeader->FC.MoreFrag)
516 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
520 // Filter out Bcast frame which AP relayed for us
521 if (pHeader->FC.FrDs && MAC_ADDR_EQUAL(pHeader->Addr3, pAd->CurrentAddress))
524 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
528 Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
533 pAd->LastRxRate = (USHORT)((pRxWI->MCS) + (pRxWI->BW <<7) + (pRxWI->ShortGI <<8)+ (pRxWI->PHYMODE <<14)) ;
536 #ifdef QOS_DLS_SUPPORT
537 if (RX_BLK_TEST_FLAG(pRxBlk, fRX_DLS))
539 MAC_TABLE_ENTRY *pDlsEntry = NULL;
541 pDlsEntry = DlsEntryTableLookupByWcid(pAd, pRxWI->WirelessCliID, pHeader->Addr2, TRUE);
543 Update_Rssi_Sample(pAd, &pDlsEntry->RssiSample, pRxWI);
546 #endif // QOS_DLS_SUPPORT //
549 pEntry = MacTableLookup(pAd, pHeader->Addr2);
551 Update_Rssi_Sample(pAd, &pEntry->RssiSample, pRxWI);
555 Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI);
557 pAd->StaCfg.LastSNR0 = (UCHAR)(pRxWI->SNR0);
558 pAd->StaCfg.LastSNR1 = (UCHAR)(pRxWI->SNR1);
560 pAd->RalinkCounters.OneSecRxOkDataCnt++;
563 if (!((pHeader->Frag == 0) && (pHeader->FC.MoreFrag == 0)))
565 // re-assemble the fragmented packets
566 // return complete frame (pRxPacket) or NULL
568 pRxPacket = RTMPDeFragmentDataFrame(pAd, pRxBlk);
573 pEntry = &pAd->MacTab.Content[pRxWI->WirelessCliID];
575 // process complete frame
576 if (bFragment && (pRxD->Decrypted) && (pEntry->WepStatus == Ndis802_11Encryption2Enabled))
579 pRxBlk->DataSize -= 8;
581 // For TKIP frame, calculate the MIC value
582 if (STACheckTkipMICValue(pAd, pEntry, pRxBlk) == FALSE)
588 STARxDataFrameAnnounce(pAd, pEntry, pRxBlk, FromWhichBSSID);
594 // because RTMPDeFragmentDataFrame() will release rx packet,
595 // if packet is fragmented
602 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
605 VOID STAHandleRxMgmtFrame(
606 IN PRTMP_ADAPTER pAd,
609 PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
610 PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
611 PHEADER_802_11 pHeader = pRxBlk->pHeader;
612 PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
618 /* check if need to resend PS Poll when received packet with MoreData = 1 */
619 if ((pAd->StaCfg.Psm == PWR_SAVE) && (pHeader->FC.MoreData == 1))
621 /* for UAPSD, all management frames will be VO priority */
622 if (pAd->CommonCfg.bAPSDAC_VO == 0)
624 /* non-UAPSD delivery-enabled AC */
625 RTMP_PS_POLL_ENQUEUE(pAd);
629 /* TODO: if MoreData == 0, station can go to sleep */
632 // We should collect RSSI not only U2M data but also my beacon
633 if ((pHeader->FC.SubType == SUBTYPE_BEACON) && (MAC_ADDR_EQUAL(&pAd->CommonCfg.Bssid, &pHeader->Addr2))
634 && (pAd->RxAnt.EvaluatePeriod == 0))
636 Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI);
638 pAd->StaCfg.LastSNR0 = (UCHAR)(pRxWI->SNR0);
639 pAd->StaCfg.LastSNR1 = (UCHAR)(pRxWI->SNR1);
643 #ifdef ANT_DIVERSITY_SUPPORT
644 // collect rssi information for antenna diversity
645 if ((pAd->NicConfig2.field.AntDiversity) &&
646 (pAd->CommonCfg.bRxAntDiversity != ANT_DIVERSITY_DISABLE))
648 if ((pRxD->U2M) || ((pHeader->FC.SubType == SUBTYPE_BEACON) && (MAC_ADDR_EQUAL(&pAd->CommonCfg.Bssid, &pHeader->Addr2))))
650 COLLECT_RX_ANTENNA_AVERAGE_RSSI(pAd, ConvertToRssi(pAd, (UCHAR)pRxWI->RSSI0, RSSI_0), 0); //Note: RSSI2 not used on RT73
651 pAd->StaCfg.NumOfAvgRssiSample ++;
654 #endif // ANT_DIVERSITY_SUPPORT //
657 // First check the size, it MUST not exceed the mlme queue size
658 if (pRxWI->MPDUtotalByteCount > MGMT_DMA_BUFFER_SIZE)
660 DBGPRINT_ERR(("STAHandleRxMgmtFrame: frame too large, size = %d \n", pRxWI->MPDUtotalByteCount));
664 REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->WirelessCliID, pHeader, pRxWI->MPDUtotalByteCount,
665 pRxWI->RSSI0, pRxWI->RSSI1, pRxWI->RSSI2, pRxD->PlcpSignal);
668 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_SUCCESS);
671 VOID STAHandleRxControlFrame(
672 IN PRTMP_ADAPTER pAd,
675 #ifdef DOT11_N_SUPPORT
676 PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
677 #endif // DOT11_N_SUPPORT //
678 PHEADER_802_11 pHeader = pRxBlk->pHeader;
679 PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
681 switch (pHeader->FC.SubType)
683 case SUBTYPE_BLOCK_ACK_REQ:
684 #ifdef DOT11_N_SUPPORT
686 CntlEnqueueForRecv(pAd, pRxWI->WirelessCliID, (pRxWI->MPDUtotalByteCount), (PFRAME_BA_REQ)pHeader);
689 #endif // DOT11_N_SUPPORT //
690 case SUBTYPE_BLOCK_ACK:
696 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
701 ========================================================================
704 Process RxDone interrupt, running in DPC level
707 pAd Pointer to our adapter
712 IRQL = DISPATCH_LEVEL
715 This routine has to maintain Rx ring read pointer.
716 Need to consider QOS DATA format when converting to 802.3
717 ========================================================================
719 BOOLEAN STARxDoneInterruptHandle(
720 IN PRTMP_ADAPTER pAd,
724 UINT32 RxProcessed, RxPending;
725 BOOLEAN bReschedule = FALSE;
726 RT28XX_RXD_STRUC *pRxD;
729 PNDIS_PACKET pRxPacket;
730 PHEADER_802_11 pHeader;
733 RxProcessed = RxPending = 0;
735 // process whole rx ring
739 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF |
740 fRTMP_ADAPTER_RESET_IN_PROGRESS |
741 fRTMP_ADAPTER_HALT_IN_PROGRESS |
742 fRTMP_ADAPTER_NIC_NOT_EXIST) ||
743 !RTMP_TEST_FLAG(pAd,fRTMP_ADAPTER_START_UP))
749 if (RxProcessed++ > MAX_RX_PROCESS_CNT)
751 // need to reschedule rx handle
755 #endif // RTMP_MAC_PCI //
757 RxProcessed ++; // test
759 // 1. allocate a new data packet into rx ring to replace received packet
760 // then processing the received packet
761 // 2. the callee must take charge of release of packet
762 // 3. As far as driver is concerned ,
763 // the rx packet must
764 // a. be indicated to upper layer or
765 // b. be released if it is discarded
766 pRxPacket = GetPacketFromRxRing(pAd, &(RxCell.RxD), &bReschedule, &RxPending);
767 if (pRxPacket == NULL)
769 // no more packet to process
773 // get rx ring descriptor
774 pRxD = &(RxCell.RxD);
775 // get rx data buffer
776 pData = GET_OS_PKT_DATAPTR(pRxPacket);
777 pRxWI = (PRXWI_STRUC) pData;
778 pHeader = (PHEADER_802_11) (pData+RXWI_SIZE) ;
781 RTMPFrameEndianChange(pAd, (PUCHAR)pHeader, DIR_READ, TRUE);
782 RTMPWIEndianChange((PUCHAR)pRxWI, TYPE_RXWI);
786 RxCell.pRxWI = pRxWI;
787 RxCell.pHeader = pHeader;
788 RxCell.pRxPacket = pRxPacket;
789 RxCell.pData = (UCHAR *) pHeader;
790 RxCell.DataSize = pRxWI->MPDUtotalByteCount;
793 // Increase Total receive byte counter after real data received no mater any error or not
794 pAd->RalinkCounters.ReceivedByteCount += pRxWI->MPDUtotalByteCount;
795 pAd->RalinkCounters.OneSecReceivedByteCount += pRxWI->MPDUtotalByteCount;
796 pAd->RalinkCounters.RxCount ++;
798 INC_COUNTER64(pAd->WlanCounters.ReceivedFragmentCount);
800 if (pRxWI->MPDUtotalByteCount < 14)
801 Status = NDIS_STATUS_FAILURE;
805 send_monitor_packets(pAd, &RxCell);
809 /* STARxDoneInterruptHandle() is called in rtusb_bulk.c */
813 pAd->ate.RxCntPerSec++;
814 ATESampleRssi(pAd, pRxWI);
815 #ifdef RALINK_28xx_QA
816 if (pAd->ate.bQARxStart == TRUE)
818 /* (*pRxD) has been swapped in GetPacketFromRxRing() */
819 ATE_QA_Statistics(pAd, pRxWI, pRxD, pHeader);
821 #endif // RALINK_28xx_QA //
822 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_SUCCESS);
825 #endif // RALINK_ATE //
827 // Check for all RxD errors
828 Status = RTMPCheckRxError(pAd, pHeader, pRxWI, pRxD);
830 // Handle the received frame
831 if (Status == NDIS_STATUS_SUCCESS)
833 switch (pHeader->FC.Type)
835 // CASE I, receive a DATA frame
838 // process DATA frame
839 STAHandleRxDataFrame(pAd, &RxCell);
842 // CASE II, receive a MGMT frame
845 STAHandleRxMgmtFrame(pAd, &RxCell);
848 // CASE III. receive a CNTL frame
851 STAHandleRxControlFrame(pAd, &RxCell);
854 // discard other type
856 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
862 pAd->Counters8023.RxErrors++;
863 // discard this frame
864 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
872 ========================================================================
876 pAd Pointer to our adapter
878 IRQL = DISPATCH_LEVEL
880 ========================================================================
882 VOID RTMPHandleTwakeupInterrupt(
883 IN PRTMP_ADAPTER pAd)
885 AsicForceWakeup(pAd, FALSE);
889 ========================================================================
891 Early checking and OS-depened parsing for Tx packet send to our STA driver.
894 NDIS_HANDLE MiniportAdapterContext Pointer refer to the device handle, i.e., the pAd.
895 PPNDIS_PACKET ppPacketArray The packet array need to do transmission.
896 UINT NumberOfPackets Number of packet in packet array.
902 This function do early checking and classification for send-out packet.
903 You only can put OS-depened & STA related code in here.
904 ========================================================================
907 IN NDIS_HANDLE MiniportAdapterContext,
908 IN PPNDIS_PACKET ppPacketArray,
909 IN UINT NumberOfPackets)
912 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) MiniportAdapterContext;
913 PNDIS_PACKET pPacket;
914 BOOLEAN allowToSend = FALSE;
917 for (Index = 0; Index < NumberOfPackets; Index++)
919 pPacket = ppPacketArray[Index];
924 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
925 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) ||
926 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
928 // Drop send request since hardware is in reset state
931 else if (!INFRA_ON(pAd) && !ADHOC_ON(pAd))
933 // Drop send request since there are no physical connection yet
938 // Record that orignal packet source is from NDIS layer,so that
939 // later on driver knows how to release this NDIS PACKET
940 #ifdef QOS_DLS_SUPPORT
941 MAC_TABLE_ENTRY *pEntry;
942 PUCHAR pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
944 pEntry = MacTableLookup(pAd, pSrcBufVA);
945 if (pEntry && (pEntry->ValidAsDls == TRUE))
947 RTMP_SET_PACKET_WCID(pPacket, pEntry->Aid);
950 #endif // QOS_DLS_SUPPORT //
951 RTMP_SET_PACKET_WCID(pPacket, 0); // this field is useless when in STA mode
952 RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
953 NDIS_SET_PACKET_STATUS(pPacket, NDIS_STATUS_PENDING);
954 pAd->RalinkCounters.PendingNdisPacketCount++;
960 if (allowToSend == TRUE)
961 STASendPacket(pAd, pPacket);
963 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
966 // Dequeue outgoing frames from TxSwQueue[] and process it
967 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
973 ========================================================================
975 This routine is used to do packet parsing and classification for Tx packet
976 to STA device, and it will en-queue packets to our TxSwQueue depends on AC
980 pAd Pointer to our adapter
981 pPacket Pointer to send packet
984 NDIS_STATUS_SUCCESS If succes to queue the packet into TxSwQueue.
985 NDIS_STATUS_FAILURE If failed to do en-queue.
988 You only can put OS-indepened & STA related code in here.
989 ========================================================================
991 NDIS_STATUS STASendPacket(
992 IN PRTMP_ADAPTER pAd,
993 IN PNDIS_PACKET pPacket)
995 PACKET_INFO PacketInfo;
1001 UCHAR QueIdx, UserPriority;
1002 MAC_TABLE_ENTRY *pEntry = NULL;
1003 unsigned int IrqFlags;
1007 // Prepare packet information structure for buffer descriptor
1008 // chained within a single NDIS packet.
1009 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
1011 if (pSrcBufVA == NULL)
1013 DBGPRINT(RT_DEBUG_ERROR,("STASendPacket --> pSrcBufVA == NULL !!!SrcBufLen=%x\n",SrcBufLen));
1014 // Resourece is low, system did not allocate virtual address
1015 // return NDIS_STATUS_FAILURE directly to upper layer
1016 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
1017 return NDIS_STATUS_FAILURE;
1023 DBGPRINT(RT_DEBUG_ERROR,("STASendPacket --> Ndis Packet buffer error !!!\n"));
1024 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
1025 return (NDIS_STATUS_FAILURE);
1028 // In HT rate adhoc mode, A-MPDU is often used. So need to lookup BA Table and MAC Entry.
1029 // Note multicast packets in adhoc also use BSSID_WCID index.
1033 #ifdef QOS_DLS_SUPPORT
1036 tmpWcid = RTMP_GET_PACKET_WCID(pPacket);
1037 if (VALID_WCID(tmpWcid) &&
1038 (pAd->MacTab.Content[tmpWcid].ValidAsDls== TRUE))
1040 pEntry = &pAd->MacTab.Content[tmpWcid];
1041 Rate = pAd->MacTab.Content[tmpWcid].CurrTxRate;
1044 #endif // QOS_DLS_SUPPORT //
1046 pEntry = &pAd->MacTab.Content[BSSID_WCID];
1047 RTMP_SET_PACKET_WCID(pPacket, BSSID_WCID);
1048 Rate = pAd->CommonCfg.TxRate;
1051 else if (ADHOC_ON(pAd))
1053 if (*pSrcBufVA & 0x01)
1055 RTMP_SET_PACKET_WCID(pPacket, MCAST_WCID);
1056 pEntry = &pAd->MacTab.Content[MCAST_WCID];
1060 pEntry = MacTableLookup(pAd, pSrcBufVA);
1062 Rate = pAd->CommonCfg.TxRate;
1068 DBGPRINT(RT_DEBUG_ERROR,("STASendPacket->Cannot find pEntry(%2x:%2x:%2x:%2x:%2x:%2x) in MacTab!\n", PRINT_MAC(pSrcBufVA)));
1069 // Resourece is low, system did not allocate virtual address
1070 // return NDIS_STATUS_FAILURE directly to upper layer
1071 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
1072 return NDIS_STATUS_FAILURE;
1078 RTMP_SET_PACKET_WCID(pPacket, (UCHAR)pEntry->Aid);
1082 // Check the Ethernet Frame type of this packet, and set the RTMP_SET_PACKET_SPECIFIC flags.
1083 // Here we set the PACKET_SPECIFIC flags(LLC, VLAN, DHCP/ARP, EAPOL).
1084 RTMPCheckEtherType(pAd, pPacket);
1089 // WPA 802.1x secured port control - drop all non-802.1x frame before port secured
1091 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
1092 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
1093 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
1094 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
1095 #ifdef WPA_SUPPLICANT_SUPPORT
1096 || (pAd->StaCfg.IEEE8021X == TRUE)
1097 #endif // WPA_SUPPLICANT_SUPPORT //
1099 && ((pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED) || (pAd->StaCfg.MicErrCnt >= 2))
1100 && (RTMP_GET_PACKET_EAPOL(pPacket)== FALSE)
1103 DBGPRINT(RT_DEBUG_TRACE,("STASendPacket --> Drop packet before port secured !!!\n"));
1104 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
1106 return (NDIS_STATUS_FAILURE);
1110 // STEP 1. Decide number of fragments required to deliver this MSDU.
1111 // The estimation here is not very accurate because difficult to
1112 // take encryption overhead into consideration here. The result
1113 // "NumberOfFrag" is then just used to pre-check if enough free
1114 // TXD are available to hold this MSDU.
1117 if (*pSrcBufVA & 0x01) // fragmentation not allowed on multicast & broadcast
1119 else if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED))
1120 NumberOfFrag = 1; // Aggregation overwhelms fragmentation
1121 else if (CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_AMSDU_INUSED))
1122 NumberOfFrag = 1; // Aggregation overwhelms fragmentation
1123 #ifdef DOT11_N_SUPPORT
1124 else if ((pAd->StaCfg.HTPhyMode.field.MODE == MODE_HTMIX) || (pAd->StaCfg.HTPhyMode.field.MODE == MODE_HTGREENFIELD))
1125 NumberOfFrag = 1; // MIMO RATE overwhelms fragmentation
1126 #endif // DOT11_N_SUPPORT //
1129 // The calculated "NumberOfFrag" is a rough estimation because of various
1130 // encryption/encapsulation overhead not taken into consideration. This number is just
1131 // used to make sure enough free TXD are available before fragmentation takes place.
1132 // In case the actual required number of fragments of an NDIS packet
1133 // excceeds "NumberOfFrag"caculated here and not enough free TXD available, the
1134 // last fragment (i.e. last MPDU) will be dropped in RTMPHardTransmit() due to out of
1135 // resource, and the NDIS packet will be indicated NDIS_STATUS_FAILURE. This should
1136 // rarely happen and the penalty is just like a TX RETRY fail. Affordable.
1138 AllowFragSize = (pAd->CommonCfg.FragmentThreshold) - LENGTH_802_11 - LENGTH_CRC;
1139 NumberOfFrag = ((PacketInfo.TotalPacketLength - LENGTH_802_3 + LENGTH_802_1_H) / AllowFragSize) + 1;
1140 // To get accurate number of fragmentation, Minus 1 if the size just match to allowable fragment size
1141 if (((PacketInfo.TotalPacketLength - LENGTH_802_3 + LENGTH_802_1_H) % AllowFragSize) == 0)
1147 // Save fragment number to Ndis packet reserved field
1148 RTMP_SET_PACKET_FRAGMENTS(pPacket, NumberOfFrag);
1151 // STEP 2. Check the requirement of RTS:
1152 // If multiple fragment required, RTS is required only for the first fragment
1153 // if the fragment size large than RTS threshold
1154 // For RT28xx, Let ASIC send RTS/CTS
1155 // RTMP_SET_PACKET_RTS(pPacket, 0);
1156 if (NumberOfFrag > 1)
1157 RTSRequired = (pAd->CommonCfg.FragmentThreshold > pAd->CommonCfg.RtsThreshold) ? 1 : 0;
1159 RTSRequired = (PacketInfo.TotalPacketLength > pAd->CommonCfg.RtsThreshold) ? 1 : 0;
1161 // Save RTS requirement to Ndis packet reserved field
1162 RTMP_SET_PACKET_RTS(pPacket, RTSRequired);
1163 RTMP_SET_PACKET_TXRATE(pPacket, pAd->CommonCfg.TxRate);
1166 // STEP 3. Traffic classification. outcome = <UserPriority, QueIdx>
1170 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
1171 CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE))
1174 UCHAR LlcSnapLen = 0, Byte0, Byte1;
1177 // get Ethernet protocol field
1178 Protocol = (USHORT)((pSrcBufVA[12] << 8) + pSrcBufVA[13]);
1179 if (Protocol <= 1500)
1181 // get Ethernet protocol field from LLC/SNAP
1182 if (Sniff2BytesFromNdisBuffer(PacketInfo.pFirstBuffer, LENGTH_802_3 + 6, &Byte0, &Byte1) != NDIS_STATUS_SUCCESS)
1185 Protocol = (USHORT)((Byte0 << 8) + Byte1);
1189 // always AC_BE for non-IP packet
1190 if (Protocol != 0x0800)
1194 if (Sniff2BytesFromNdisBuffer(PacketInfo.pFirstBuffer, LENGTH_802_3 + LlcSnapLen, &Byte0, &Byte1) != NDIS_STATUS_SUCCESS)
1197 // return AC_BE if packet is not IPv4
1198 if ((Byte0 & 0xf0) != 0x40)
1202 UserPriority = (Byte1 & 0xe0) >> 5;
1203 QueIdx = MapUserPriorityToAccessCategory[UserPriority];
1205 // TODO: have to check ACM bit. apply TSPEC if ACM is ON
1206 // TODO: downgrade UP & QueIdx before passing ACM
1208 Under WMM ACM control, we dont need to check the bit;
1209 Or when a TSPEC is built for VO but we will change to issue
1210 BA session for BE here, so we will not use BA to send VO packets.
1212 if (pAd->CommonCfg.APEdcaParm.bACM[QueIdx])
1220 RTMP_SET_PACKET_UP(pPacket, UserPriority);
1224 // Make sure SendTxWait queue resource won't be used by other threads
1225 RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
1226 if (pAd->TxSwQueue[QueIdx].Number >= MAX_PACKETS_IN_QUEUE)
1228 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
1230 StopNetIfQueue(pAd, QueIdx, pPacket);
1231 #endif // BLOCK_NET_IF //
1232 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
1234 return NDIS_STATUS_FAILURE;
1238 InsertTailQueueAc(pAd, pEntry, &pAd->TxSwQueue[QueIdx], PACKET_TO_QUEUE_ENTRY(pPacket));
1240 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
1242 #ifdef DOT11_N_SUPPORT
1243 if ((pAd->CommonCfg.BACapability.field.AutoBA == TRUE)&&
1246 //PMAC_TABLE_ENTRY pMacEntry = &pAd->MacTab.Content[BSSID_WCID];
1247 if (((pEntry->TXBAbitmap & (1<<UserPriority)) == 0) &&
1248 ((pEntry->BADeclineBitmap & (1<<UserPriority)) == 0) &&
1249 (pEntry->PortSecured == WPA_802_1X_PORT_SECURED)
1250 // For IOT compatibility, if
1251 // 1. It is Ralink chip or
1252 // 2. It is OPEN or AES mode,
1253 // then BA session can be bulit.
1254 && ((pEntry->ValidAsCLI && pAd->MlmeAux.APRalinkIe != 0x0) ||
1255 (pEntry->WepStatus != Ndis802_11WEPEnabled && pEntry->WepStatus != Ndis802_11Encryption2Enabled))
1258 BAOriSessionSetUp(pAd, pEntry, UserPriority, 0, 10, FALSE);
1261 #endif // DOT11_N_SUPPORT //
1263 pAd->RalinkCounters.OneSecOsTxCount[QueIdx]++; // TODO: for debug only. to be removed
1264 return NDIS_STATUS_SUCCESS;
1269 ========================================================================
1271 Routine Description:
1272 This subroutine will scan through releative ring descriptor to find
1273 out avaliable free ring descriptor and compare with request size.
1276 pAd Pointer to our adapter
1277 QueIdx Selected TX Ring
1280 NDIS_STATUS_FAILURE Not enough free descriptor
1281 NDIS_STATUS_SUCCESS Enough free descriptor
1283 IRQL = PASSIVE_LEVEL
1284 IRQL = DISPATCH_LEVEL
1288 ========================================================================
1291 NDIS_STATUS RTMPFreeTXDRequest(
1292 IN PRTMP_ADAPTER pAd,
1294 IN UCHAR NumberRequired,
1295 IN PUCHAR FreeNumberIs)
1297 ULONG FreeNumber = 0;
1298 NDIS_STATUS Status = NDIS_STATUS_FAILURE;
1307 if (pAd->TxRing[QueIdx].TxSwFreeIdx > pAd->TxRing[QueIdx].TxCpuIdx)
1308 FreeNumber = pAd->TxRing[QueIdx].TxSwFreeIdx - pAd->TxRing[QueIdx].TxCpuIdx - 1;
1310 FreeNumber = pAd->TxRing[QueIdx].TxSwFreeIdx + TX_RING_SIZE - pAd->TxRing[QueIdx].TxCpuIdx - 1;
1312 if (FreeNumber >= NumberRequired)
1313 Status = NDIS_STATUS_SUCCESS;
1317 if (pAd->MgmtRing.TxSwFreeIdx > pAd->MgmtRing.TxCpuIdx)
1318 FreeNumber = pAd->MgmtRing.TxSwFreeIdx - pAd->MgmtRing.TxCpuIdx - 1;
1320 FreeNumber = pAd->MgmtRing.TxSwFreeIdx + MGMT_RING_SIZE - pAd->MgmtRing.TxCpuIdx - 1;
1322 if (FreeNumber >= NumberRequired)
1323 Status = NDIS_STATUS_SUCCESS;
1327 DBGPRINT(RT_DEBUG_ERROR,("RTMPFreeTXDRequest::Invalid QueIdx(=%d)\n", QueIdx));
1330 *FreeNumberIs = (UCHAR)FreeNumber;
1334 #endif // RTMP_MAC_PCI //
1338 VOID RTMPSendDisassociationFrame(
1339 IN PRTMP_ADAPTER pAd)
1343 VOID RTMPSendNullFrame(
1344 IN PRTMP_ADAPTER pAd,
1346 IN BOOLEAN bQosNull)
1348 UCHAR NullFrame[48];
1350 PHEADER_802_11 pHeader_802_11;
1358 #endif // RALINK_ATE //
1360 // WPA 802.1x secured port control
1361 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
1362 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
1363 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
1364 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
1365 #ifdef WPA_SUPPLICANT_SUPPORT
1366 || (pAd->StaCfg.IEEE8021X == TRUE)
1369 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
1374 NdisZeroMemory(NullFrame, 48);
1375 Length = sizeof(HEADER_802_11);
1377 pHeader_802_11 = (PHEADER_802_11) NullFrame;
1379 pHeader_802_11->FC.Type = BTYPE_DATA;
1380 pHeader_802_11->FC.SubType = SUBTYPE_NULL_FUNC;
1381 pHeader_802_11->FC.ToDs = 1;
1382 COPY_MAC_ADDR(pHeader_802_11->Addr1, pAd->CommonCfg.Bssid);
1383 COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
1384 COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid);
1386 if (pAd->CommonCfg.bAPSDForcePowerSave)
1388 pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
1392 pHeader_802_11->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE) ? 1: 0;
1394 pHeader_802_11->Duration = pAd->CommonCfg.Dsifs + RTMPCalcDuration(pAd, TxRate, 14);
1397 pHeader_802_11->Sequence = pAd->Sequence;
1399 // Prepare QosNull function frame
1402 pHeader_802_11->FC.SubType = SUBTYPE_QOS_NULL;
1404 // copy QOS control bytes
1405 NullFrame[Length] = 0;
1406 NullFrame[Length+1] = 0;
1407 Length += 2;// if pad with 2 bytes for alignment, APSD will fail
1410 HAL_KickOutNullFrameTx(pAd, 0, NullFrame, Length);
1414 // IRQL = DISPATCH_LEVEL
1415 VOID RTMPSendRTSFrame(
1416 IN PRTMP_ADAPTER pAd,
1418 IN unsigned int NextMpduSize,
1421 IN USHORT AckDuration,
1429 // --------------------------------------------------------
1430 // FIND ENCRYPT KEY AND DECIDE CIPHER ALGORITHM
1431 // Find the WPA key, either Group or Pairwise Key
1432 // LEAP + TKIP also use WPA key.
1433 // --------------------------------------------------------
1434 // Decide WEP bit and cipher suite to be used. Same cipher suite should be used for whole fragment burst
1435 // In Cisco CCX 2.0 Leap Authentication
1436 // WepStatus is Ndis802_11Encryption1Enabled but the key will use PairwiseKey
1437 // Instead of the SharedKey, SharedKey Length may be Zero.
1438 VOID STAFindCipherAlgorithm(
1439 IN PRTMP_ADAPTER pAd,
1442 NDIS_802_11_ENCRYPTION_STATUS Cipher; // To indicate cipher used for this packet
1443 UCHAR CipherAlg = CIPHER_NONE; // cipher alogrithm
1444 UCHAR KeyIdx = 0xff;
1446 PCIPHER_KEY pKey = NULL;
1448 pSrcBufVA = GET_OS_PKT_DATAPTR(pTxBlk->pPacket);
1452 if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd)))
1453 Cipher = pAd->StaCfg.GroupCipher; // Cipher for Multicast or Broadcast
1455 Cipher = pAd->StaCfg.PairCipher; // Cipher for Unicast
1457 if (RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket))
1459 ASSERT(pAd->SharedKey[BSS0][0].CipherAlg <= CIPHER_CKIP128);
1461 // 4-way handshaking frame must be clear
1462 if (!(TX_BLK_TEST_FLAG(pTxBlk, fTX_bClearEAPFrame)) && (pAd->SharedKey[BSS0][0].CipherAlg) &&
1463 (pAd->SharedKey[BSS0][0].KeyLen))
1465 CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
1469 else if (Cipher == Ndis802_11Encryption1Enabled)
1471 KeyIdx = pAd->StaCfg.DefaultKeyId;
1473 else if ((Cipher == Ndis802_11Encryption2Enabled) ||
1474 (Cipher == Ndis802_11Encryption3Enabled))
1476 if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd))) // multicast
1477 KeyIdx = pAd->StaCfg.DefaultKeyId;
1478 else if (pAd->SharedKey[BSS0][0].KeyLen)
1481 KeyIdx = pAd->StaCfg.DefaultKeyId;
1485 CipherAlg = CIPHER_NONE;
1486 else if ((Cipher == Ndis802_11EncryptionDisabled) || (pAd->SharedKey[BSS0][KeyIdx].KeyLen == 0))
1487 CipherAlg = CIPHER_NONE;
1488 #ifdef WPA_SUPPLICANT_SUPPORT
1489 else if ( pAd->StaCfg.WpaSupplicantUP &&
1490 (Cipher == Ndis802_11Encryption1Enabled) &&
1491 (pAd->StaCfg.IEEE8021X == TRUE) &&
1492 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
1493 CipherAlg = CIPHER_NONE;
1494 #endif // WPA_SUPPLICANT_SUPPORT //
1497 //Header_802_11.FC.Wep = 1;
1498 CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
1499 pKey = &pAd->SharedKey[BSS0][KeyIdx];
1503 pTxBlk->CipherAlg = CipherAlg;
1504 pTxBlk->pKey = pKey;
1508 VOID STABuildCommon802_11Header(
1509 IN PRTMP_ADAPTER pAd,
1513 HEADER_802_11 *pHeader_802_11;
1514 #ifdef QOS_DLS_SUPPORT
1515 BOOLEAN bDLSFrame = FALSE;
1516 INT DlsEntryIndex = 0;
1517 #endif // QOS_DLS_SUPPORT //
1520 // MAKE A COMMON 802.11 HEADER
1523 // normal wlan header size : 24 octets
1524 pTxBlk->MpduHeaderLen = sizeof(HEADER_802_11);
1526 pHeader_802_11 = (HEADER_802_11 *) &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
1528 NdisZeroMemory(pHeader_802_11, sizeof(HEADER_802_11));
1530 pHeader_802_11->FC.FrDs = 0;
1531 pHeader_802_11->FC.Type = BTYPE_DATA;
1532 pHeader_802_11->FC.SubType = ((TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) ? SUBTYPE_QDATA : SUBTYPE_DATA);
1534 #ifdef QOS_DLS_SUPPORT
1537 // Check if the frame can be sent through DLS direct link interface
1538 // If packet can be sent through DLS, then force aggregation disable. (Hard to determine peer STA's capability)
1539 DlsEntryIndex = RTMPCheckDLSFrame(pAd, pTxBlk->pSrcBufHeader);
1540 if (DlsEntryIndex >= 0)
1545 #endif // QOS_DLS_SUPPORT //
1547 if (pTxBlk->pMacEntry)
1549 if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bForceNonQoS))
1551 pHeader_802_11->Sequence = pTxBlk->pMacEntry->NonQosDataSeq;
1552 pTxBlk->pMacEntry->NonQosDataSeq = (pTxBlk->pMacEntry->NonQosDataSeq+1) & MAXSEQ;
1557 pHeader_802_11->Sequence = pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority];
1558 pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority] = (pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority]+1) & MAXSEQ;
1564 pHeader_802_11->Sequence = pAd->Sequence;
1565 pAd->Sequence = (pAd->Sequence+1) & MAXSEQ; // next sequence
1568 pHeader_802_11->Frag = 0;
1570 pHeader_802_11->FC.MoreData = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData);
1575 #ifdef QOS_DLS_SUPPORT
1578 COPY_MAC_ADDR(pHeader_802_11->Addr1, pTxBlk->pSrcBufHeader);
1579 COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
1580 COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid);
1581 pHeader_802_11->FC.ToDs = 0;
1584 #endif // QOS_DLS_SUPPORT //
1586 COPY_MAC_ADDR(pHeader_802_11->Addr1, pAd->CommonCfg.Bssid);
1587 COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
1588 COPY_MAC_ADDR(pHeader_802_11->Addr3, pTxBlk->pSrcBufHeader);
1589 pHeader_802_11->FC.ToDs = 1;
1592 else if (ADHOC_ON(pAd))
1594 COPY_MAC_ADDR(pHeader_802_11->Addr1, pTxBlk->pSrcBufHeader);
1595 COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
1596 COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid);
1597 pHeader_802_11->FC.ToDs = 0;
1601 if (pTxBlk->CipherAlg != CIPHER_NONE)
1602 pHeader_802_11->FC.Wep = 1;
1604 // -----------------------------------------------------------------
1605 // STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later.
1606 // -----------------------------------------------------------------
1607 if (pAd->CommonCfg.bAPSDForcePowerSave)
1608 pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
1610 pHeader_802_11->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
1613 #ifdef DOT11_N_SUPPORT
1614 VOID STABuildCache802_11Header(
1615 IN RTMP_ADAPTER *pAd,
1619 MAC_TABLE_ENTRY *pMacEntry;
1620 PHEADER_802_11 pHeader80211;
1622 pHeader80211 = (PHEADER_802_11)pHeader;
1623 pMacEntry = pTxBlk->pMacEntry;
1626 // Update the cached 802.11 HEADER
1629 // normal wlan header size : 24 octets
1630 pTxBlk->MpduHeaderLen = sizeof(HEADER_802_11);
1633 pHeader80211->FC.MoreData = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData);
1636 pHeader80211->Sequence = pMacEntry->TxSeq[pTxBlk->UserPriority];
1637 pMacEntry->TxSeq[pTxBlk->UserPriority] = (pMacEntry->TxSeq[pTxBlk->UserPriority]+1) & MAXSEQ;
1640 // Check if the frame can be sent through DLS direct link interface
1641 // If packet can be sent through DLS, then force aggregation disable. (Hard to determine peer STA's capability)
1642 #ifdef QOS_DLS_SUPPORT
1643 BOOLEAN bDLSFrame = FALSE;
1644 INT DlsEntryIndex = 0;
1646 DlsEntryIndex = RTMPCheckDLSFrame(pAd, pTxBlk->pSrcBufHeader);
1647 if (DlsEntryIndex >= 0)
1651 #endif // QOS_DLS_SUPPORT //
1653 // The addr3 of normal packet send from DS is Dest Mac address.
1654 #ifdef QOS_DLS_SUPPORT
1657 COPY_MAC_ADDR(pHeader80211->Addr1, pTxBlk->pSrcBufHeader);
1658 COPY_MAC_ADDR(pHeader80211->Addr3, pAd->CommonCfg.Bssid);
1659 pHeader80211->FC.ToDs = 0;
1662 #endif // QOS_DLS_SUPPORT //
1664 COPY_MAC_ADDR(pHeader80211->Addr3, pAd->CommonCfg.Bssid);
1666 COPY_MAC_ADDR(pHeader80211->Addr3, pTxBlk->pSrcBufHeader);
1669 // -----------------------------------------------------------------
1670 // STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later.
1671 // -----------------------------------------------------------------
1672 if (pAd->CommonCfg.bAPSDForcePowerSave)
1673 pHeader80211->FC.PwrMgmt = PWR_SAVE;
1675 pHeader80211->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
1677 #endif // DOT11_N_SUPPORT //
1679 static inline PUCHAR STA_Build_ARalink_Frame_Header(
1680 IN RTMP_ADAPTER *pAd,
1683 PUCHAR pHeaderBufPtr;
1684 HEADER_802_11 *pHeader_802_11;
1685 PNDIS_PACKET pNextPacket;
1687 PQUEUE_ENTRY pQEntry;
1689 STAFindCipherAlgorithm(pAd, pTxBlk);
1690 STABuildCommon802_11Header(pAd, pTxBlk);
1693 pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
1694 pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
1696 // steal "order" bit to mark "aggregation"
1697 pHeader_802_11->FC.Order = 1;
1699 // skip common header
1700 pHeaderBufPtr += pTxBlk->MpduHeaderLen;
1702 if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM))
1705 // build QOS Control bytes
1707 *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
1709 *(pHeaderBufPtr+1) = 0;
1711 pTxBlk->MpduHeaderLen += 2;
1714 // padding at front of LLC header. LLC header should at 4-bytes aligment.
1715 pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
1716 pHeaderBufPtr = (PUCHAR)ROUND_UP(pHeaderBufPtr, 4);
1717 pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
1719 // For RA Aggregation,
1720 // put the 2nd MSDU length(extra 2-byte field) after QOS_CONTROL in little endian format
1721 pQEntry = pTxBlk->TxPacketList.Head;
1722 pNextPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
1723 nextBufLen = GET_OS_PKT_LEN(pNextPacket);
1724 if (RTMP_GET_PACKET_VLAN(pNextPacket))
1725 nextBufLen -= LENGTH_802_1Q;
1727 *pHeaderBufPtr = (UCHAR)nextBufLen & 0xff;
1728 *(pHeaderBufPtr+1) = (UCHAR)(nextBufLen >> 8);
1731 pTxBlk->MpduHeaderLen += 2;
1733 return pHeaderBufPtr;
1737 #ifdef DOT11_N_SUPPORT
1738 static inline PUCHAR STA_Build_AMSDU_Frame_Header(
1739 IN RTMP_ADAPTER *pAd,
1742 PUCHAR pHeaderBufPtr;//, pSaveBufPtr;
1743 HEADER_802_11 *pHeader_802_11;
1746 STAFindCipherAlgorithm(pAd, pTxBlk);
1747 STABuildCommon802_11Header(pAd, pTxBlk);
1749 pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
1750 pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
1752 // skip common header
1753 pHeaderBufPtr += pTxBlk->MpduHeaderLen;
1756 // build QOS Control bytes
1758 *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
1763 *pHeaderBufPtr |= 0x80;
1765 *(pHeaderBufPtr+1) = 0;
1767 pTxBlk->MpduHeaderLen += 2;
1769 //pSaveBufPtr = pHeaderBufPtr;
1772 // padding at front of LLC header
1773 // LLC header should locate at 4-octets aligment
1775 // @@@ MpduHeaderLen excluding padding @@@
1777 pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
1778 pHeaderBufPtr = (PUCHAR) ROUND_UP(pHeaderBufPtr, 4);
1779 pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
1781 return pHeaderBufPtr;
1786 VOID STA_AMPDU_Frame_Tx(
1787 IN PRTMP_ADAPTER pAd,
1790 HEADER_802_11 *pHeader_802_11;
1791 PUCHAR pHeaderBufPtr;
1793 MAC_TABLE_ENTRY *pMacEntry;
1795 PQUEUE_ENTRY pQEntry;
1799 while(pTxBlk->TxPacketList.Head)
1801 pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
1802 pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
1803 if ( RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
1805 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
1809 bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
1811 pMacEntry = pTxBlk->pMacEntry;
1812 if (pMacEntry->isCached)
1814 // NOTE: Please make sure the size of pMacEntry->CachedBuf[] is smaller than pTxBlk->HeaderBuf[]!!!!
1815 NdisMoveMemory((PUCHAR)&pTxBlk->HeaderBuf[TXINFO_SIZE], (PUCHAR)&pMacEntry->CachedBuf[0], TXWI_SIZE + sizeof(HEADER_802_11));
1816 pHeaderBufPtr = (PUCHAR)(&pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE]);
1817 STABuildCache802_11Header(pAd, pTxBlk, pHeaderBufPtr);
1821 STAFindCipherAlgorithm(pAd, pTxBlk);
1822 STABuildCommon802_11Header(pAd, pTxBlk);
1824 pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
1828 pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
1830 // skip common header
1831 pHeaderBufPtr += pTxBlk->MpduHeaderLen;
1834 // build QOS Control bytes
1836 *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
1837 *(pHeaderBufPtr+1) = 0;
1839 pTxBlk->MpduHeaderLen += 2;
1843 // HTC control filed following QoS field
1845 if ((pAd->CommonCfg.bRdg == TRUE) && CLIENT_STATUS_TEST_FLAG(pTxBlk->pMacEntry, fCLIENT_STATUS_RDG_CAPABLE))
1847 if (pMacEntry->isCached == FALSE)
1850 pHeader_802_11->FC.Order = 1;
1852 NdisZeroMemory(pHeaderBufPtr, 4);
1853 *(pHeaderBufPtr+3) |= 0x80;
1856 pTxBlk->MpduHeaderLen += 4;
1859 //pTxBlk->MpduHeaderLen = pHeaderBufPtr - pTxBlk->HeaderBuf - TXWI_SIZE - TXINFO_SIZE;
1860 ASSERT(pTxBlk->MpduHeaderLen >= 24);
1862 // skip 802.3 header
1863 pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
1864 pTxBlk->SrcBufLen -= LENGTH_802_3;
1869 pTxBlk->pSrcBufData += LENGTH_802_1Q;
1870 pTxBlk->SrcBufLen -= LENGTH_802_1Q;
1874 // padding at front of LLC header
1875 // LLC header should locate at 4-octets aligment
1877 // @@@ MpduHeaderLen excluding padding @@@
1879 pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
1880 pHeaderBufPtr = (PUCHAR) ROUND_UP(pHeaderBufPtr, 4);
1881 pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
1886 // Insert LLC-SNAP encapsulation - 8 octets
1888 EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData-2, pTxBlk->pExtraLlcSnapEncap);
1889 if (pTxBlk->pExtraLlcSnapEncap)
1891 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
1893 // get 2 octets (TypeofLen)
1894 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
1896 pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
1901 if (pMacEntry->isCached)
1903 RTMPWriteTxWI_Cache(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
1907 RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
1909 NdisZeroMemory((PUCHAR)(&pMacEntry->CachedBuf[0]), sizeof(pMacEntry->CachedBuf));
1910 NdisMoveMemory((PUCHAR)(&pMacEntry->CachedBuf[0]), (PUCHAR)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), (pHeaderBufPtr - (PUCHAR)(&pTxBlk->HeaderBuf[TXINFO_SIZE])));
1911 pMacEntry->isCached = TRUE;
1914 // calculate Transmitted AMPDU count and ByteCount
1916 pAd->RalinkCounters.TransmittedMPDUsInAMPDUCount.u.LowPart ++;
1917 pAd->RalinkCounters.TransmittedOctetsInAMPDUCount.QuadPart += pTxBlk->SrcBufLen;
1920 //FreeNumber = GET_TXRING_FREENO(pAd, QueIdx);
1922 HAL_WriteTxResource(pAd, pTxBlk, TRUE, &FreeNumber);
1927 if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
1928 HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
1930 pAd->RalinkCounters.KickTxCount++;
1931 pAd->RalinkCounters.OneSecTxDoneCount++;
1937 VOID STA_AMSDU_Frame_Tx(
1938 IN PRTMP_ADAPTER pAd,
1941 PUCHAR pHeaderBufPtr;
1943 USHORT subFramePayloadLen = 0; // AMSDU Subframe length without AMSDU-Header / Padding.
1944 USHORT totalMPDUSize=0;
1945 UCHAR *subFrameHeader;
1947 USHORT FirstTx = 0, LastTxIdx = 0;
1950 PQUEUE_ENTRY pQEntry;
1955 ASSERT((pTxBlk->TxPacketList.Number > 1));
1957 while(pTxBlk->TxPacketList.Head)
1959 pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
1960 pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
1961 if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
1963 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
1967 bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
1969 // skip 802.3 header
1970 pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
1971 pTxBlk->SrcBufLen -= LENGTH_802_3;
1976 pTxBlk->pSrcBufData += LENGTH_802_1Q;
1977 pTxBlk->SrcBufLen -= LENGTH_802_1Q;
1982 pHeaderBufPtr = STA_Build_AMSDU_Frame_Header(pAd, pTxBlk);
1984 // NOTE: TxWI->MPDUtotalByteCount will be updated after final frame was handled.
1985 RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
1989 pHeaderBufPtr = &pTxBlk->HeaderBuf[0];
1990 padding = ROUND_UP(LENGTH_AMSDU_SUBFRAMEHEAD + subFramePayloadLen, 4) - (LENGTH_AMSDU_SUBFRAMEHEAD + subFramePayloadLen);
1991 NdisZeroMemory(pHeaderBufPtr, padding + LENGTH_AMSDU_SUBFRAMEHEAD);
1992 pHeaderBufPtr += padding;
1993 pTxBlk->MpduHeaderLen = padding;
1998 // DA(6)+SA(6)+Length(2) + LLC/SNAP Encap
2000 subFrameHeader = pHeaderBufPtr;
2001 subFramePayloadLen = pTxBlk->SrcBufLen;
2003 NdisMoveMemory(subFrameHeader, pTxBlk->pSrcBufHeader, 12);
2006 pHeaderBufPtr += LENGTH_AMSDU_SUBFRAMEHEAD;
2007 pTxBlk->MpduHeaderLen += LENGTH_AMSDU_SUBFRAMEHEAD;
2011 // Insert LLC-SNAP encapsulation - 8 octets
2013 EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData-2, pTxBlk->pExtraLlcSnapEncap);
2015 subFramePayloadLen = pTxBlk->SrcBufLen;
2017 if (pTxBlk->pExtraLlcSnapEncap)
2019 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
2021 // get 2 octets (TypeofLen)
2022 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
2024 pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
2025 subFramePayloadLen += LENGTH_802_1_H;
2028 // update subFrame Length field
2029 subFrameHeader[12] = (subFramePayloadLen & 0xFF00) >> 8;
2030 subFrameHeader[13] = subFramePayloadLen & 0xFF;
2032 totalMPDUSize += pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
2035 FirstTx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
2037 LastTxIdx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
2041 pAd->RalinkCounters.KickTxCount++;
2042 pAd->RalinkCounters.OneSecTxDoneCount++;
2044 // calculate Transmitted AMSDU Count and ByteCount
2046 pAd->RalinkCounters.TransmittedAMSDUCount.u.LowPart ++;
2047 pAd->RalinkCounters.TransmittedOctetsInAMSDU.QuadPart += totalMPDUSize;
2052 HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, FirstTx);
2053 HAL_LastTxIdx(pAd, pTxBlk->QueIdx, LastTxIdx);
2058 if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
2059 HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
2061 #endif // DOT11_N_SUPPORT //
2063 VOID STA_Legacy_Frame_Tx(
2064 IN PRTMP_ADAPTER pAd,
2067 HEADER_802_11 *pHeader_802_11;
2068 PUCHAR pHeaderBufPtr;
2071 PQUEUE_ENTRY pQEntry;
2076 pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
2077 pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
2078 if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
2080 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
2084 if (pTxBlk->TxFrameType == TX_MCAST_FRAME)
2086 INC_COUNTER64(pAd->WlanCounters.MulticastTransmittedFrameCount);
2089 if (RTMP_GET_PACKET_RTS(pTxBlk->pPacket))
2090 TX_BLK_SET_FLAG(pTxBlk, fTX_bRtsRequired);
2092 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bRtsRequired);
2094 bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
2096 if (pTxBlk->TxRate < pAd->CommonCfg.MinTxRate)
2097 pTxBlk->TxRate = pAd->CommonCfg.MinTxRate;
2099 STAFindCipherAlgorithm(pAd, pTxBlk);
2100 STABuildCommon802_11Header(pAd, pTxBlk);
2103 // skip 802.3 header
2104 pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
2105 pTxBlk->SrcBufLen -= LENGTH_802_3;
2110 pTxBlk->pSrcBufData += LENGTH_802_1Q;
2111 pTxBlk->SrcBufLen -= LENGTH_802_1Q;
2114 pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
2115 pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
2117 // skip common header
2118 pHeaderBufPtr += pTxBlk->MpduHeaderLen;
2120 if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM))
2123 // build QOS Control bytes
2125 *(pHeaderBufPtr) = ((pTxBlk->UserPriority & 0x0F) | (pAd->CommonCfg.AckPolicy[pTxBlk->QueIdx]<<5));
2126 *(pHeaderBufPtr+1) = 0;
2128 pTxBlk->MpduHeaderLen += 2;
2131 // The remaining content of MPDU header should locate at 4-octets aligment
2132 pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
2133 pHeaderBufPtr = (PUCHAR) ROUND_UP(pHeaderBufPtr, 4);
2134 pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
2139 // Insert LLC-SNAP encapsulation - 8 octets
2142 // if original Ethernet frame contains no LLC/SNAP,
2143 // then an extra LLC/SNAP encap is required
2145 EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(pTxBlk->pSrcBufHeader, pTxBlk->pExtraLlcSnapEncap);
2146 if (pTxBlk->pExtraLlcSnapEncap)
2150 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
2153 vlan_size = (bVLANPkt) ? LENGTH_802_1Q : 0;
2154 // get 2 octets (TypeofLen)
2155 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufHeader+12+vlan_size, 2);
2157 pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
2164 // use Wcid as Key Index
2167 RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
2169 //FreeNumber = GET_TXRING_FREENO(pAd, QueIdx);
2171 HAL_WriteTxResource(pAd, pTxBlk, TRUE, &FreeNumber);
2173 pAd->RalinkCounters.KickTxCount++;
2174 pAd->RalinkCounters.OneSecTxDoneCount++;
2179 if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
2180 HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
2184 VOID STA_ARalink_Frame_Tx(
2185 IN PRTMP_ADAPTER pAd,
2188 PUCHAR pHeaderBufPtr;
2190 USHORT totalMPDUSize=0;
2191 USHORT FirstTx, LastTxIdx;
2194 PQUEUE_ENTRY pQEntry;
2199 ASSERT((pTxBlk->TxPacketList.Number== 2));
2202 FirstTx = LastTxIdx = 0; // Is it ok init they as 0?
2203 while(pTxBlk->TxPacketList.Head)
2205 pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
2206 pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
2208 if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
2210 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
2214 bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
2216 // skip 802.3 header
2217 pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
2218 pTxBlk->SrcBufLen -= LENGTH_802_3;
2223 pTxBlk->pSrcBufData += LENGTH_802_1Q;
2224 pTxBlk->SrcBufLen -= LENGTH_802_1Q;
2228 { // For first frame, we need to create the 802.11 header + padding(optional) + RA-AGG-LEN + SNAP Header
2230 pHeaderBufPtr = STA_Build_ARalink_Frame_Header(pAd, pTxBlk);
2232 // It's ok write the TxWI here, because the TxWI->MPDUtotalByteCount
2233 // will be updated after final frame was handled.
2234 RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
2238 // Insert LLC-SNAP encapsulation - 8 octets
2240 EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData-2, pTxBlk->pExtraLlcSnapEncap);
2242 if (pTxBlk->pExtraLlcSnapEncap)
2244 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
2246 // get 2 octets (TypeofLen)
2247 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
2249 pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
2253 { // For second aggregated frame, we need create the 802.3 header to headerBuf, because PCI will copy it to SDPtr0.
2255 pHeaderBufPtr = &pTxBlk->HeaderBuf[0];
2256 pTxBlk->MpduHeaderLen = 0;
2258 // A-Ralink sub-sequent frame header is the same as 802.3 header.
2259 // DA(6)+SA(6)+FrameType(2)
2260 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufHeader, 12);
2261 pHeaderBufPtr += 12;
2262 // get 2 octets (TypeofLen)
2263 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
2265 pTxBlk->MpduHeaderLen = LENGTH_ARALINK_SUBFRAMEHEAD;
2268 totalMPDUSize += pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
2270 //FreeNumber = GET_TXRING_FREENO(pAd, QueIdx);
2272 FirstTx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
2274 LastTxIdx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
2278 pAd->RalinkCounters.OneSecTxAggregationCount++;
2279 pAd->RalinkCounters.KickTxCount++;
2280 pAd->RalinkCounters.OneSecTxDoneCount++;
2284 HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, FirstTx);
2285 HAL_LastTxIdx(pAd, pTxBlk->QueIdx, LastTxIdx);
2290 if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
2291 HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
2296 VOID STA_Fragment_Frame_Tx(
2297 IN RTMP_ADAPTER *pAd,
2300 HEADER_802_11 *pHeader_802_11;
2301 PUCHAR pHeaderBufPtr;
2304 PACKET_INFO PacketInfo;
2305 USHORT EncryptionOverhead = 0;
2306 UINT32 FreeMpduSize, SrcRemainingBytes;
2310 PQUEUE_ENTRY pQEntry;
2311 HTTRANSMIT_SETTING *pTransmit;
2316 pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
2317 pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
2318 if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
2320 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
2324 ASSERT(TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag));
2325 bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
2327 STAFindCipherAlgorithm(pAd, pTxBlk);
2328 STABuildCommon802_11Header(pAd, pTxBlk);
2330 if (pTxBlk->CipherAlg == CIPHER_TKIP)
2332 pTxBlk->pPacket = duplicate_pkt_with_TKIP_MIC(pAd, pTxBlk->pPacket);
2333 if (pTxBlk->pPacket == NULL)
2335 RTMP_QueryPacketInfo(pTxBlk->pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen);
2338 // skip 802.3 header
2339 pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
2340 pTxBlk->SrcBufLen -= LENGTH_802_3;
2346 pTxBlk->pSrcBufData += LENGTH_802_1Q;
2347 pTxBlk->SrcBufLen -= LENGTH_802_1Q;
2350 pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
2351 pHeader_802_11 = (HEADER_802_11 *)pHeaderBufPtr;
2354 // skip common header
2355 pHeaderBufPtr += pTxBlk->MpduHeaderLen;
2357 if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM))
2360 // build QOS Control bytes
2362 *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
2364 *(pHeaderBufPtr+1) = 0;
2366 pTxBlk->MpduHeaderLen += 2;
2370 // padding at front of LLC header
2371 // LLC header should locate at 4-octets aligment
2373 pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
2374 pHeaderBufPtr = (PUCHAR) ROUND_UP(pHeaderBufPtr, 4);
2375 pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
2380 // Insert LLC-SNAP encapsulation - 8 octets
2383 // if original Ethernet frame contains no LLC/SNAP,
2384 // then an extra LLC/SNAP encap is required
2386 EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(pTxBlk->pSrcBufHeader, pTxBlk->pExtraLlcSnapEncap);
2387 if (pTxBlk->pExtraLlcSnapEncap)
2391 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
2394 vlan_size = (bVLANPkt) ? LENGTH_802_1Q : 0;
2395 // get 2 octets (TypeofLen)
2396 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufHeader+12+vlan_size, 2);
2398 pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
2402 // If TKIP is used and fragmentation is required. Driver has to
2403 // append TKIP MIC at tail of the scatter buffer
2404 // MAC ASIC will only perform IV/EIV/ICV insertion but no TKIP MIC
2405 if (pTxBlk->CipherAlg == CIPHER_TKIP)
2407 RTMPCalculateMICValue(pAd, pTxBlk->pPacket, pTxBlk->pExtraLlcSnapEncap, pTxBlk->pKey, 0);
2409 // NOTE: DON'T refer the skb->len directly after following copy. Becasue the length is not adjust
2410 // to correct lenght, refer to pTxBlk->SrcBufLen for the packet length in following progress.
2411 NdisMoveMemory(pTxBlk->pSrcBufData + pTxBlk->SrcBufLen, &pAd->PrivateInfo.Tx.MIC[0], 8);
2412 //skb_put((RTPKT_TO_OSPKT(pTxBlk->pPacket))->tail, 8);
2413 pTxBlk->SrcBufLen += 8;
2414 pTxBlk->TotalFrameLen += 8;
2415 pTxBlk->CipherAlg = CIPHER_TKIP_NO_MIC;
2419 // calcuate the overhead bytes that encryption algorithm may add. This
2420 // affects the calculate of "duration" field
2422 if ((pTxBlk->CipherAlg == CIPHER_WEP64) || (pTxBlk->CipherAlg == CIPHER_WEP128))
2423 EncryptionOverhead = 8; //WEP: IV[4] + ICV[4];
2424 else if (pTxBlk->CipherAlg == CIPHER_TKIP_NO_MIC)
2425 EncryptionOverhead = 12;//TKIP: IV[4] + EIV[4] + ICV[4], MIC will be added to TotalPacketLength
2426 else if (pTxBlk->CipherAlg == CIPHER_TKIP)
2427 EncryptionOverhead = 20;//TKIP: IV[4] + EIV[4] + ICV[4] + MIC[8]
2428 else if (pTxBlk->CipherAlg == CIPHER_AES)
2429 EncryptionOverhead = 16; // AES: IV[4] + EIV[4] + MIC[8]
2431 EncryptionOverhead = 0;
2433 pTransmit = pTxBlk->pTransmit;
2434 // Decide the TX rate
2435 if (pTransmit->field.MODE == MODE_CCK)
2436 pTxBlk->TxRate = pTransmit->field.MCS;
2437 else if (pTransmit->field.MODE == MODE_OFDM)
2438 pTxBlk->TxRate = pTransmit->field.MCS + RATE_FIRST_OFDM_RATE;
2440 pTxBlk->TxRate = RATE_6_5;
2442 // decide how much time an ACK/CTS frame will consume in the air
2443 if (pTxBlk->TxRate <= RATE_LAST_OFDM_RATE)
2444 AckDuration = RTMPCalcDuration(pAd, pAd->CommonCfg.ExpectedACKRate[pTxBlk->TxRate], 14);
2446 AckDuration = RTMPCalcDuration(pAd, RATE_6_5, 14);
2448 // Init the total payload length of this frame.
2449 SrcRemainingBytes = pTxBlk->SrcBufLen;
2451 pTxBlk->TotalFragNum = 0xff;
2455 FreeMpduSize = pAd->CommonCfg.FragmentThreshold - LENGTH_CRC;
2457 FreeMpduSize -= pTxBlk->MpduHeaderLen;
2459 if (SrcRemainingBytes <= FreeMpduSize)
2460 { // this is the last or only fragment
2462 pTxBlk->SrcBufLen = SrcRemainingBytes;
2464 pHeader_802_11->FC.MoreFrag = 0;
2465 pHeader_802_11->Duration = pAd->CommonCfg.Dsifs + AckDuration;
2467 // Indicate the lower layer that this's the last fragment.
2468 pTxBlk->TotalFragNum = fragNum;
2471 { // more fragment is required
2473 pTxBlk->SrcBufLen = FreeMpduSize;
2475 NextMpduSize = min(((UINT)SrcRemainingBytes - pTxBlk->SrcBufLen), ((UINT)pAd->CommonCfg.FragmentThreshold));
2476 pHeader_802_11->FC.MoreFrag = 1;
2477 pHeader_802_11->Duration = (3 * pAd->CommonCfg.Dsifs) + (2 * AckDuration) + RTMPCalcDuration(pAd, pTxBlk->TxRate, NextMpduSize + EncryptionOverhead);
2481 pTxBlk->FrameGap = IFS_HTTXOP;
2483 pTxBlk->FrameGap = IFS_SIFS;
2485 RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
2487 HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, &FreeNumber);
2489 pAd->RalinkCounters.KickTxCount++;
2490 pAd->RalinkCounters.OneSecTxDoneCount++;
2492 // Update the frame number, remaining size of the NDIS packet payload.
2494 // space for 802.11 header.
2495 if (fragNum == 0 && pTxBlk->pExtraLlcSnapEncap)
2496 pTxBlk->MpduHeaderLen -= LENGTH_802_1_H;
2499 SrcRemainingBytes -= pTxBlk->SrcBufLen;
2500 pTxBlk->pSrcBufData += pTxBlk->SrcBufLen;
2502 pHeader_802_11->Frag++; // increase Frag #
2504 }while(SrcRemainingBytes > 0);
2509 if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
2510 HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
2514 #define RELEASE_FRAMES_OF_TXBLK(_pAd, _pTxBlk, _pQEntry, _Status) \
2515 while(_pTxBlk->TxPacketList.Head) \
2517 _pQEntry = RemoveHeadQueue(&_pTxBlk->TxPacketList); \
2518 RELEASE_NDIS_PACKET(_pAd, QUEUE_ENTRY_TO_PACKET(_pQEntry), _Status); \
2523 ========================================================================
2525 Routine Description:
2526 Copy frame from waiting queue into relative ring buffer and set
2527 appropriate ASIC register to kick hardware encryption before really
2531 pAd Pointer to our adapter
2532 PNDIS_PACKET Pointer to outgoing Ndis frame
2533 NumberOfFrag Number of fragment required
2538 IRQL = DISPATCH_LEVEL
2542 ========================================================================
2544 NDIS_STATUS STAHardTransmit(
2545 IN PRTMP_ADAPTER pAd,
2549 NDIS_PACKET *pPacket;
2550 PQUEUE_ENTRY pQEntry;
2552 // ---------------------------------------------
2553 // STEP 0. DO SANITY CHECK AND SOME EARLY PREPARATION.
2554 // ---------------------------------------------
2556 ASSERT(pTxBlk->TxPacketList.Number);
2557 if (pTxBlk->TxPacketList.Head == NULL)
2559 DBGPRINT(RT_DEBUG_ERROR, ("pTxBlk->TotalFrameNum == %ld!\n", pTxBlk->TxPacketList.Number));
2560 return NDIS_STATUS_FAILURE;
2563 pPacket = QUEUE_ENTRY_TO_PACKET(pTxBlk->TxPacketList.Head);
2566 // ------------------------------------------------------------------
2567 // STEP 1. WAKE UP PHY
2568 // outgoing frame always wakeup PHY to prevent frame lost and
2569 // turn off PSM bit to improve performance
2570 // ------------------------------------------------------------------
2571 // not to change PSM bit, just send this frame out?
2572 if ((pAd->StaCfg.Psm == PWR_SAVE) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
2574 DBGPRINT_RAW(RT_DEBUG_INFO, ("AsicForceWakeup At HardTx\n"));
2576 AsicForceWakeup(pAd, TRUE);
2577 #endif // RTMP_MAC_PCI //
2580 // It should not change PSM bit, when APSD turn on.
2581 if ((!(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable) && (pAd->CommonCfg.bAPSDForcePowerSave == FALSE))
2582 || (RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket))
2583 || (RTMP_GET_PACKET_WAI(pTxBlk->pPacket)))
2585 if ((pAd->StaCfg.Psm == PWR_SAVE) &&
2586 (pAd->StaCfg.WindowsPowerMode == Ndis802_11PowerModeFast_PSP))
2587 RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE);
2590 switch (pTxBlk->TxFrameType)
2592 #ifdef DOT11_N_SUPPORT
2593 case TX_AMPDU_FRAME:
2594 STA_AMPDU_Frame_Tx(pAd, pTxBlk);
2596 case TX_AMSDU_FRAME:
2597 STA_AMSDU_Frame_Tx(pAd, pTxBlk);
2599 #endif // DOT11_N_SUPPORT //
2600 case TX_LEGACY_FRAME:
2601 STA_Legacy_Frame_Tx(pAd, pTxBlk);
2603 case TX_MCAST_FRAME:
2604 STA_Legacy_Frame_Tx(pAd, pTxBlk);
2606 case TX_RALINK_FRAME:
2607 STA_ARalink_Frame_Tx(pAd, pTxBlk);
2610 STA_Fragment_Frame_Tx(pAd, pTxBlk);
2614 // It should not happened!
2615 DBGPRINT(RT_DEBUG_ERROR, ("Send a pacekt was not classified!! It should not happen!\n"));
2616 while(pTxBlk->TxPacketList.Number)
2618 pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
2619 pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
2621 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
2627 return (NDIS_STATUS_SUCCESS);
2631 ULONG HashBytesPolynomial(UCHAR *value, unsigned int len)
2633 unsigned char *word = value;
2634 unsigned int ret = 0;
2637 for(i=0; i < len; i++)
2640 ret ^=(unsigned int) (word[i]) << mod;
2641 ret ^=(unsigned int) (word[i]) >> (32 - mod);
2646 VOID Sta_Announce_or_Forward_802_3_Packet(
2647 IN PRTMP_ADAPTER pAd,
2648 IN PNDIS_PACKET pPacket,
2649 IN UCHAR FromWhichBSSID)
2654 announce_802_3_packet(pAd, pPacket);
2659 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);