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