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