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 
28 #include "../rt_config.h"
29 
30 u8 SNAP_802_1H[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
31 u8 SNAP_BRIDGE_TUNNEL[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
32 
33 /* Add Cisco Aironet SNAP heade for CCX2 support */
34 u8 SNAP_AIRONET[] = { 0xaa, 0xaa, 0x03, 0x00, 0x40, 0x96, 0x00, 0x00 };
35 u8 CKIP_LLC_SNAP[] = { 0xaa, 0xaa, 0x03, 0x00, 0x40, 0x96, 0x00, 0x02 };
36 u8 EAPOL_LLC_SNAP[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8e };
37 u8 EAPOL[] = { 0x88, 0x8e };
38 u8 TPID[] = { 0x81, 0x00 };	/* VLAN related */
39 
40 u8 IPX[] = { 0x81, 0x37 };
41 u8 APPLE_TALK[] = { 0x80, 0xf3 };
42 
43 u8 RateIdToPlcpSignal[12] = {
44 	0, /* RATE_1 */ 1, /* RATE_2 */ 2, /* RATE_5_5 */ 3,	/* RATE_11 *//* see BBP spec */
45 	11, /* RATE_6 */ 15, /* RATE_9 */ 10, /* RATE_12 */ 14,	/* RATE_18 *//* see IEEE802.11a-1999 p.14 */
46 	9, /* RATE_24 */ 13, /* RATE_36 */ 8, /* RATE_48 */ 12 /* RATE_54 */
47 };				/* see IEEE802.11a-1999 p.14 */
48 
49 u8 OfdmSignalToRateId[16] = {
50 	RATE_54, RATE_54, RATE_54, RATE_54,	/* OFDM PLCP Signal = 0,  1,  2,  3 respectively */
51 	RATE_54, RATE_54, RATE_54, RATE_54,	/* OFDM PLCP Signal = 4,  5,  6,  7 respectively */
52 	RATE_48, RATE_24, RATE_12, RATE_6,	/* OFDM PLCP Signal = 8,  9,  10, 11 respectively */
53 	RATE_54, RATE_36, RATE_18, RATE_9,	/* OFDM PLCP Signal = 12, 13, 14, 15 respectively */
54 };
55 
56 u8 OfdmRateToRxwiMCS[12] = {
57 	0, 0, 0, 0,
58 	0, 1, 2, 3,		/* OFDM rate 6,9,12,18 = rxwi mcs 0,1,2,3 */
59 	4, 5, 6, 7,		/* OFDM rate 24,36,48,54 = rxwi mcs 4,5,6,7 */
60 };
61 
62 u8 RxwiMCSToOfdmRate[12] = {
63 	RATE_6, RATE_9, RATE_12, RATE_18,
64 	RATE_24, RATE_36, RATE_48, RATE_54,	/* OFDM rate 6,9,12,18 = rxwi mcs 0,1,2,3 */
65 	4, 5, 6, 7,		/* OFDM rate 24,36,48,54 = rxwi mcs 4,5,6,7 */
66 };
67 
68 char *MCSToMbps[] =
69     { "1Mbps", "2Mbps", "5.5Mbps", "11Mbps", "06Mbps", "09Mbps", "12Mbps",
70 "18Mbps", "24Mbps", "36Mbps", "48Mbps", "54Mbps", "MM-0", "MM-1", "MM-2", "MM-3",
71 "MM-4", "MM-5", "MM-6", "MM-7", "MM-8", "MM-9", "MM-10", "MM-11", "MM-12", "MM-13",
72 "MM-14", "MM-15", "MM-32", "ee1", "ee2", "ee3" };
73 
74 u8 default_cwmin[] =
75     { CW_MIN_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS - 1, CW_MIN_IN_BITS - 2 };
76 /*u8 default_cwmax[]={CW_MAX_IN_BITS, CW_MAX_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS-1}; */
77 u8 default_sta_aifsn[] = { 3, 7, 2, 2 };
78 
79 u8 MapUserPriorityToAccessCategory[8] =
80     { QID_AC_BE, QID_AC_BK, QID_AC_BK, QID_AC_BE, QID_AC_VI, QID_AC_VI,
81 QID_AC_VO, QID_AC_VO };
82 
83 /*
84 	========================================================================
85 
86 	Routine Description:
87 		API for MLME to transmit management frame to AP (BSS Mode)
88 	or station (IBSS Mode)
89 
90 	Arguments:
91 		pAd Pointer to our adapter
92 		pData		Pointer to the outgoing 802.11 frame
93 		Length		Size of outgoing management frame
94 
95 	Return Value:
96 		NDIS_STATUS_FAILURE
97 		NDIS_STATUS_PENDING
98 		NDIS_STATUS_SUCCESS
99 
100 	IRQL = PASSIVE_LEVEL
101 	IRQL = DISPATCH_LEVEL
102 
103 	Note:
104 
105 	========================================================================
106 */
MiniportMMRequest(struct rt_rtmp_adapter * pAd,u8 QueIdx,u8 * pData,u32 Length)107 int MiniportMMRequest(struct rt_rtmp_adapter *pAd,
108 			      u8 QueIdx, u8 *pData, u32 Length)
109 {
110 	void *pPacket;
111 	int Status = NDIS_STATUS_SUCCESS;
112 	unsigned long FreeNum;
113 	u8 rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE];	/*RTMP_HW_HDR_LEN]; */
114 #ifdef RTMP_MAC_PCI
115 	unsigned long IrqFlags = 0;
116 	u8 IrqState;
117 #endif /* RTMP_MAC_PCI // */
118 	BOOLEAN bUseDataQ = FALSE;
119 	int retryCnt = 0;
120 
121 	ASSERT(Length <= MGMT_DMA_BUFFER_SIZE);
122 
123 	if ((QueIdx & MGMT_USE_QUEUE_FLAG) == MGMT_USE_QUEUE_FLAG) {
124 		bUseDataQ = TRUE;
125 		QueIdx &= (~MGMT_USE_QUEUE_FLAG);
126 	}
127 #ifdef RTMP_MAC_PCI
128 	/* 2860C use Tx Ring */
129 	IrqState = pAd->irq_disabled;
130 	if (pAd->MACVersion == 0x28600100) {
131 		QueIdx = (bUseDataQ == TRUE ? QueIdx : 3);
132 		bUseDataQ = TRUE;
133 	}
134 	if (bUseDataQ && (!IrqState))
135 		RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
136 #endif /* RTMP_MAC_PCI // */
137 
138 	do {
139 		/* Reset is in progress, stop immediately */
140 		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
141 		    RTMP_TEST_FLAG(pAd,
142 				   fRTMP_ADAPTER_HALT_IN_PROGRESS |
143 				   fRTMP_ADAPTER_NIC_NOT_EXIST)
144 		    || !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)) {
145 			Status = NDIS_STATUS_FAILURE;
146 			break;
147 		}
148 		/* Check Free priority queue */
149 		/* Since we use PBF Queue2 for management frame.  Its corresponding DMA ring should be using TxRing. */
150 #ifdef RTMP_MAC_PCI
151 		if (bUseDataQ) {
152 			retryCnt = MAX_DATAMM_RETRY;
153 			/* free Tx(QueIdx) resources */
154 			RTMPFreeTXDUponTxDmaDone(pAd, QueIdx);
155 			FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
156 		} else
157 #endif /* RTMP_MAC_PCI // */
158 		{
159 			FreeNum = GET_MGMTRING_FREENO(pAd);
160 		}
161 
162 		if ((FreeNum > 0)) {
163 			/* We need to reserve space for rtmp hardware header. i.e., TxWI for RT2860 and TxInfo+TxWI for RT2870 */
164 			NdisZeroMemory(&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE));
165 			Status =
166 			    RTMPAllocateNdisPacket(pAd, &pPacket,
167 						   (u8 *)& rtmpHwHdr,
168 						   (TXINFO_SIZE + TXWI_SIZE),
169 						   pData, Length);
170 			if (Status != NDIS_STATUS_SUCCESS) {
171 				DBGPRINT(RT_DEBUG_WARN,
172 					 ("MiniportMMRequest (error:: can't allocate NDIS PACKET)\n"));
173 				break;
174 			}
175 			/*pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK; */
176 			/*pAd->CommonCfg.MlmeRate = RATE_2; */
177 
178 #ifdef RTMP_MAC_PCI
179 			if (bUseDataQ) {
180 				Status =
181 				    MlmeDataHardTransmit(pAd, QueIdx, pPacket);
182 				retryCnt--;
183 			} else
184 #endif /* RTMP_MAC_PCI // */
185 				Status = MlmeHardTransmit(pAd, QueIdx, pPacket);
186 			if (Status == NDIS_STATUS_SUCCESS)
187 				retryCnt = 0;
188 			else
189 				RTMPFreeNdisPacket(pAd, pPacket);
190 		} else {
191 			pAd->RalinkCounters.MgmtRingFullCount++;
192 #ifdef RTMP_MAC_PCI
193 			if (bUseDataQ) {
194 				retryCnt--;
195 				DBGPRINT(RT_DEBUG_TRACE,
196 					 ("retryCnt %d\n", retryCnt));
197 				if (retryCnt == 0) {
198 					DBGPRINT(RT_DEBUG_ERROR,
199 						 ("Qidx(%d), not enough space in DataRing, MgmtRingFullCount=%ld!\n",
200 						  QueIdx,
201 						  pAd->RalinkCounters.
202 						  MgmtRingFullCount));
203 				}
204 			}
205 #endif /* RTMP_MAC_PCI // */
206 			DBGPRINT(RT_DEBUG_ERROR,
207 				 ("Qidx(%d), not enough space in MgmtRing, MgmtRingFullCount=%ld!\n",
208 				  QueIdx,
209 				  pAd->RalinkCounters.MgmtRingFullCount));
210 		}
211 	} while (retryCnt > 0);
212 
213 #ifdef RTMP_MAC_PCI
214 	if (bUseDataQ && (!IrqState))
215 		RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
216 #endif /* RTMP_MAC_PCI // */
217 
218 	return Status;
219 }
220 
221 /*
222 	========================================================================
223 
224 	Routine Description:
225 		Copy frame from waiting queue into relative ring buffer and set
226 	appropriate ASIC register to kick hardware transmit function
227 
228 	Arguments:
229 		pAd Pointer to our adapter
230 		pBuffer 	Pointer to	memory of outgoing frame
231 		Length		Size of outgoing management frame
232 
233 	Return Value:
234 		NDIS_STATUS_FAILURE
235 		NDIS_STATUS_PENDING
236 		NDIS_STATUS_SUCCESS
237 
238 	IRQL = PASSIVE_LEVEL
239 	IRQL = DISPATCH_LEVEL
240 
241 	Note:
242 
243 	========================================================================
244 */
MlmeHardTransmit(struct rt_rtmp_adapter * pAd,u8 QueIdx,void * pPacket)245 int MlmeHardTransmit(struct rt_rtmp_adapter *pAd,
246 			     u8 QueIdx, void *pPacket)
247 {
248 	struct rt_packet_info PacketInfo;
249 	u8 *pSrcBufVA;
250 	u32 SrcBufLen;
251 	struct rt_header_802_11 * pHeader_802_11;
252 
253 	if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
254 	    ) {
255 		return NDIS_STATUS_FAILURE;
256 	}
257 
258 	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
259 	if (pSrcBufVA == NULL)
260 		return NDIS_STATUS_FAILURE;
261 
262 	pHeader_802_11 = (struct rt_header_802_11 *) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE);
263 
264 #ifdef RTMP_MAC_PCI
265 	if (pAd->MACVersion == 0x28600100)
266 		return MlmeHardTransmitTxRing(pAd, QueIdx, pPacket);
267 	else
268 #endif /* RTMP_MAC_PCI // */
269 		return MlmeHardTransmitMgmtRing(pAd, QueIdx, pPacket);
270 
271 }
272 
MlmeHardTransmitMgmtRing(struct rt_rtmp_adapter * pAd,u8 QueIdx,void * pPacket)273 int MlmeHardTransmitMgmtRing(struct rt_rtmp_adapter *pAd,
274 				     u8 QueIdx, void *pPacket)
275 {
276 	struct rt_packet_info PacketInfo;
277 	u8 *pSrcBufVA;
278 	u32 SrcBufLen;
279 	struct rt_header_802_11 * pHeader_802_11;
280 	BOOLEAN bAckRequired, bInsertTimestamp;
281 	u8 MlmeRate;
282 	struct rt_txwi * pFirstTxWI;
283 	struct rt_mac_table_entry *pMacEntry = NULL;
284 	u8 PID;
285 
286 	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
287 
288 	/* Make sure MGMT ring resource won't be used by other threads */
289 	RTMP_SEM_LOCK(&pAd->MgmtRingLock);
290 	if (pSrcBufVA == NULL) {
291 		/* The buffer shouldn't be NULL */
292 		RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
293 		return NDIS_STATUS_FAILURE;
294 	}
295 
296 	{
297 		/* outgoing frame always wakeup PHY to prevent frame lost */
298 		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
299 			AsicForceWakeup(pAd, TRUE);
300 	}
301 
302 	pFirstTxWI = (struct rt_txwi *) (pSrcBufVA + TXINFO_SIZE);
303 	pHeader_802_11 = (struct rt_header_802_11 *) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE);	/*TXWI_SIZE); */
304 
305 	if (pHeader_802_11->Addr1[0] & 0x01) {
306 		MlmeRate = pAd->CommonCfg.BasicMlmeRate;
307 	} else {
308 		MlmeRate = pAd->CommonCfg.MlmeRate;
309 	}
310 
311 	/* Verify Mlme rate for a / g bands. */
312 	if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6))	/* 11A band */
313 		MlmeRate = RATE_6;
314 
315 	if ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
316 	    (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL)) {
317 		pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1);
318 	}
319 
320 	{
321 		/* Fixed W52 with Activity scan issue in ABG_MIXED and ABGN_MIXED mode. */
322 		if (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED
323 		    || pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) {
324 			if (pAd->LatchRfRegs.Channel > 14)
325 				pAd->CommonCfg.MlmeTransmit.field.MODE = 1;
326 			else
327 				pAd->CommonCfg.MlmeTransmit.field.MODE = 0;
328 		}
329 	}
330 
331 	/* */
332 	/* Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE) */
333 	/* Snice it's been set to 0 while on MgtMacHeaderInit */
334 	/* By the way this will cause frame to be send on PWR_SAVE failed. */
335 	/* */
336 	pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE;	/* (pAd->StaCfg.Psm == PWR_SAVE); */
337 
338 	/* */
339 	/* In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame */
340 	/* Data-Null packets also pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD */
341 /*      if ((pHeader_802_11->FC.Type != BTYPE_DATA) && (pHeader_802_11->FC.Type != BTYPE_CNTL)) */
342 	{
343 		if ((pHeader_802_11->FC.SubType == SUBTYPE_ACTION) ||
344 		    ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
345 		     ((pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL) ||
346 		      (pHeader_802_11->FC.SubType == SUBTYPE_NULL_FUNC)))) {
347 			if (pAd->StaCfg.Psm == PWR_SAVE)
348 				pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
349 			else
350 				pHeader_802_11->FC.PwrMgmt =
351 				    pAd->CommonCfg.bAPSDForcePowerSave;
352 		}
353 	}
354 
355 	bInsertTimestamp = FALSE;
356 	if (pHeader_802_11->FC.Type == BTYPE_CNTL)	/* must be PS-POLL */
357 	{
358 		/*Set PM bit in ps-poll, to fix WLK 1.2  PowerSaveMode_ext failure issue. */
359 		if ((pAd->OpMode == OPMODE_STA)
360 		    && (pHeader_802_11->FC.SubType == SUBTYPE_PS_POLL)) {
361 			pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
362 		}
363 		bAckRequired = FALSE;
364 	} else			/* BTYPE_MGMT or BTYPE_DATA(must be NULL frame) */
365 	{
366 		/*pAd->Sequence++; */
367 		/*pHeader_802_11->Sequence = pAd->Sequence; */
368 
369 		if (pHeader_802_11->Addr1[0] & 0x01)	/* MULTICAST, BROADCAST */
370 		{
371 			bAckRequired = FALSE;
372 			pHeader_802_11->Duration = 0;
373 		} else {
374 			bAckRequired = TRUE;
375 			pHeader_802_11->Duration =
376 			    RTMPCalcDuration(pAd, MlmeRate, 14);
377 			if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP)
378 			    && (pHeader_802_11->FC.Type == BTYPE_MGMT)) {
379 				bInsertTimestamp = TRUE;
380 				bAckRequired = FALSE;	/* Disable ACK to prevent retry 0x1f for Probe Response */
381 			} else
382 			    if ((pHeader_802_11->FC.SubType ==
383 				 SUBTYPE_PROBE_REQ)
384 				&& (pHeader_802_11->FC.Type == BTYPE_MGMT)) {
385 				bAckRequired = FALSE;	/* Disable ACK to prevent retry 0x1f for Probe Request */
386 			}
387 		}
388 	}
389 
390 	pHeader_802_11->Sequence = pAd->Sequence++;
391 	if (pAd->Sequence > 0xfff)
392 		pAd->Sequence = 0;
393 
394 	/* Before radar detection done, mgmt frame can not be sent but probe req */
395 	/* Because we need to use probe req to trigger driver to send probe req in passive scan */
396 	if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ)
397 	    && (pAd->CommonCfg.bIEEE80211H == 1)
398 	    && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)) {
399 		DBGPRINT(RT_DEBUG_ERROR,
400 			 ("MlmeHardTransmit --> radar detect not in normal mode!\n"));
401 /*              if (!IrqState) */
402 		RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
403 		return (NDIS_STATUS_FAILURE);
404 	}
405 
406 	/* */
407 	/* fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET */
408 	/* should always has only one physical buffer, and the whole frame size equals */
409 	/* to the first scatter buffer size */
410 	/* */
411 
412 	/* Initialize TX Descriptor */
413 	/* For inter-frame gap, the number is for this frame and next frame */
414 	/* For MLME rate, we will fix as 2Mb to match other vendor's implement */
415 /*      pAd->CommonCfg.MlmeTransmit.field.MODE = 1; */
416 
417 /* management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not. */
418 	PID = PID_MGMT;
419 
420 	if (pMacEntry == NULL) {
421 		RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp,
422 			      FALSE, bAckRequired, FALSE, 0, RESERVED_WCID,
423 			      (SrcBufLen - TXINFO_SIZE - TXWI_SIZE), PID, 0,
424 			      (u8)pAd->CommonCfg.MlmeTransmit.field.MCS,
425 			      IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
426 	} else {
427 		/* dont use low rate to send QoS Null data frame */
428 		RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE,
429 			      bInsertTimestamp, FALSE, bAckRequired, FALSE,
430 			      0, pMacEntry->Aid,
431 			      (SrcBufLen - TXINFO_SIZE - TXWI_SIZE),
432 			      pMacEntry->MaxHTPhyMode.field.MCS, 0,
433 			      (u8)pMacEntry->MaxHTPhyMode.field.MCS,
434 			      IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
435 	}
436 
437 	/* Now do hardware-depened kick out. */
438 	HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen);
439 
440 	/* Make sure to release MGMT ring resource */
441 /*      if (!IrqState) */
442 	RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
443 	return NDIS_STATUS_SUCCESS;
444 }
445 
446 /********************************************************************************
447 
448 	New DeQueue Procedures.
449 
450  ********************************************************************************/
451 
452 #define DEQUEUE_LOCK(lock, bIntContext, IrqFlags) 				\
453 			do{													\
454 				if (bIntContext == FALSE)						\
455 				RTMP_IRQ_LOCK((lock), IrqFlags);		\
456 			}while(0)
457 
458 #define DEQUEUE_UNLOCK(lock, bIntContext, IrqFlags)				\
459 			do{													\
460 				if (bIntContext == FALSE)						\
461 					RTMP_IRQ_UNLOCK((lock), IrqFlags);	\
462 			}while(0)
463 
464 /*
465 	========================================================================
466 	Tx Path design algorithm:
467 		Basically, we divide the packets into four types, Broadcast/Multicast, 11N Rate(AMPDU, AMSDU, Normal), B/G Rate(ARALINK, Normal),
468 		Specific Packet Type. Following show the classification rule and policy for each kinds of packets.
469 				Classification Rule=>
470 					Multicast: (*addr1 & 0x01) == 0x01
471 					Specific : bDHCPFrame, bARPFrame, bEAPOLFrame, etc.
472 					11N Rate : If peer support HT
473 								(1).AMPDU  -- If TXBA is negotiated.
474 								(2).AMSDU  -- If AMSDU is capable for both peer and ourself.
475 											*). AMSDU can embedded in a AMPDU, but now we didn't support it.
476 								(3).Normal -- Other packets which send as 11n rate.
477 
478 					B/G Rate : If peer is b/g only.
479 								(1).ARALINK-- If both of peer/us supprot Ralink proprietary Aggregation and the TxRate is large than RATE_6
480 								(2).Normal -- Other packets which send as b/g rate.
481 					Fragment:
482 								The packet must be unicast, NOT A-RALINK, NOT A-MSDU, NOT 11n, then can consider about fragment.
483 
484 				Classified Packet Handle Rule=>
485 					Multicast:
486 								No ACK, 		//pTxBlk->bAckRequired = FALSE;
487 								No WMM, 		//pTxBlk->bWMM = FALSE;
488 								No piggyback,   //pTxBlk->bPiggyBack = FALSE;
489 								Force LowRate,  //pTxBlk->bForceLowRate = TRUE;
490 					Specific :	Basically, for specific packet, we should handle it specifically, but now all specific packets are use
491 									the same policy to handle it.
492 								Force LowRate,  //pTxBlk->bForceLowRate = TRUE;
493 
494 					11N Rate :
495 								No piggyback,	//pTxBlk->bPiggyBack = FALSE;
496 
497 								(1).AMSDU
498 									pTxBlk->bWMM = TRUE;
499 								(2).AMPDU
500 									pTxBlk->bWMM = TRUE;
501 								(3).Normal
502 
503 					B/G Rate :
504 								(1).ARALINK
505 
506 								(2).Normal
507 	========================================================================
508 */
TxPktClassification(struct rt_rtmp_adapter * pAd,void * pPacket)509 static u8 TxPktClassification(struct rt_rtmp_adapter *pAd, void *pPacket)
510 {
511 	u8 TxFrameType = TX_UNKOWN_FRAME;
512 	u8 Wcid;
513 	struct rt_mac_table_entry *pMacEntry = NULL;
514 	BOOLEAN bHTRate = FALSE;
515 
516 	Wcid = RTMP_GET_PACKET_WCID(pPacket);
517 	if (Wcid == MCAST_WCID) {	/* Handle for RA is Broadcast/Multicast Address. */
518 		return TX_MCAST_FRAME;
519 	}
520 	/* Handle for unicast packets */
521 	pMacEntry = &pAd->MacTab.Content[Wcid];
522 	if (RTMP_GET_PACKET_LOWRATE(pPacket)) {	/* It's a specific packet need to force low rate, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame */
523 		TxFrameType = TX_LEGACY_FRAME;
524 	} else if (IS_HT_RATE(pMacEntry)) {	/* it's a 11n capable packet */
525 
526 		/* Depends on HTPhyMode to check if the peer support the HTRate transmission. */
527 		/*      Currently didn't support A-MSDU embedded in A-MPDU */
528 		bHTRate = TRUE;
529 		if (RTMP_GET_PACKET_MOREDATA(pPacket)
530 		    || (pMacEntry->PsMode == PWR_SAVE))
531 			TxFrameType = TX_LEGACY_FRAME;
532 		else if ((pMacEntry->
533 			  TXBAbitmap & (1 << (RTMP_GET_PACKET_UP(pPacket)))) !=
534 			 0)
535 			return TX_AMPDU_FRAME;
536 		else if (CLIENT_STATUS_TEST_FLAG
537 			 (pMacEntry, fCLIENT_STATUS_AMSDU_INUSED))
538 			return TX_AMSDU_FRAME;
539 		else
540 			TxFrameType = TX_LEGACY_FRAME;
541 	} else {		/* it's a legacy b/g packet. */
542 		if ((CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE) && pAd->CommonCfg.bAggregationCapable) && (RTMP_GET_PACKET_TXRATE(pPacket) >= RATE_6) && (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE)))) {	/* if peer support Ralink Aggregation, we use it. */
543 			TxFrameType = TX_RALINK_FRAME;
544 		} else {
545 			TxFrameType = TX_LEGACY_FRAME;
546 		}
547 	}
548 
549 	/* Currently, our fragment only support when a unicast packet send as NOT-ARALINK, NOT-AMSDU and NOT-AMPDU. */
550 	if ((RTMP_GET_PACKET_FRAGMENTS(pPacket) > 1)
551 	    && (TxFrameType == TX_LEGACY_FRAME))
552 		TxFrameType = TX_FRAG_FRAME;
553 
554 	return TxFrameType;
555 }
556 
RTMP_FillTxBlkInfo(struct rt_rtmp_adapter * pAd,struct rt_tx_blk * pTxBlk)557 BOOLEAN RTMP_FillTxBlkInfo(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
558 {
559 	struct rt_packet_info PacketInfo;
560 	void *pPacket;
561 	struct rt_mac_table_entry *pMacEntry = NULL;
562 
563 	pPacket = pTxBlk->pPacket;
564 	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader,
565 			     &pTxBlk->SrcBufLen);
566 
567 	pTxBlk->Wcid = RTMP_GET_PACKET_WCID(pPacket);
568 	pTxBlk->apidx = RTMP_GET_PACKET_IF(pPacket);
569 	pTxBlk->UserPriority = RTMP_GET_PACKET_UP(pPacket);
570 	pTxBlk->FrameGap = IFS_HTTXOP;	/* ASIC determine Frame Gap */
571 
572 	if (RTMP_GET_PACKET_CLEAR_EAP_FRAME(pTxBlk->pPacket))
573 		TX_BLK_SET_FLAG(pTxBlk, fTX_bClearEAPFrame);
574 	else
575 		TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bClearEAPFrame);
576 
577 	/* Default to clear this flag */
578 	TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bForceNonQoS);
579 
580 	if (pTxBlk->Wcid == MCAST_WCID) {
581 		pTxBlk->pMacEntry = NULL;
582 		{
583 			pTxBlk->pTransmit =
584 			    &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
585 		}
586 
587 		TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired);	/* AckRequired = FALSE, when broadcast packet in Adhoc mode. */
588 		/*TX_BLK_SET_FLAG(pTxBlk, fTX_bForceLowRate); */
589 		TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAllowFrag);
590 		TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
591 		if (RTMP_GET_PACKET_MOREDATA(pPacket)) {
592 			TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
593 		}
594 
595 	} else {
596 		pTxBlk->pMacEntry = &pAd->MacTab.Content[pTxBlk->Wcid];
597 		pTxBlk->pTransmit = &pTxBlk->pMacEntry->HTPhyMode;
598 
599 		pMacEntry = pTxBlk->pMacEntry;
600 
601 		/* For all unicast packets, need Ack unless the Ack Policy is not set as NORMAL_ACK. */
602 		if (pAd->CommonCfg.AckPolicy[pTxBlk->QueIdx] != NORMAL_ACK)
603 			TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired);
604 		else
605 			TX_BLK_SET_FLAG(pTxBlk, fTX_bAckRequired);
606 
607 		if ((pAd->OpMode == OPMODE_STA) &&
608 		    (ADHOC_ON(pAd)) &&
609 		    (RX_FILTER_TEST_FLAG(pAd, fRX_FILTER_ACCEPT_PROMISCUOUS))) {
610 			if (pAd->CommonCfg.PSPXlink)
611 				TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired);
612 		}
613 
614 		{
615 			{
616 
617 				/* If support WMM, enable it. */
618 				if (OPSTATUS_TEST_FLAG
619 				    (pAd, fOP_STATUS_WMM_INUSED)
620 				    && CLIENT_STATUS_TEST_FLAG(pMacEntry,
621 							       fCLIENT_STATUS_WMM_CAPABLE))
622 					TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM);
623 
624 /*                              if (pAd->StaCfg.bAutoTxRateSwitch) */
625 /*                                      TX_BLK_SET_FLAG(pTxBlk, fTX_AutoRateSwitch); */
626 			}
627 		}
628 
629 		if (pTxBlk->TxFrameType == TX_LEGACY_FRAME) {
630 			if ((RTMP_GET_PACKET_LOWRATE(pPacket)) || ((pAd->OpMode == OPMODE_AP) && (pMacEntry->MaxHTPhyMode.field.MODE == MODE_CCK) && (pMacEntry->MaxHTPhyMode.field.MCS == RATE_1))) {	/* Specific packet, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame, need force low rate. */
631 				pTxBlk->pTransmit =
632 				    &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
633 
634 				/* Modify the WMM bit for ICV issue. If we have a packet with EOSP field need to set as 1, how to handle it??? */
635 				if (IS_HT_STA(pTxBlk->pMacEntry) &&
636 				    (CLIENT_STATUS_TEST_FLAG
637 				     (pMacEntry, fCLIENT_STATUS_RALINK_CHIPSET))
638 				    && ((pAd->CommonCfg.bRdg == TRUE)
639 					&& CLIENT_STATUS_TEST_FLAG(pMacEntry,
640 								   fCLIENT_STATUS_RDG_CAPABLE)))
641 				{
642 					TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
643 					TX_BLK_SET_FLAG(pTxBlk,
644 							fTX_bForceNonQoS);
645 				}
646 			}
647 
648 			if ((IS_HT_RATE(pMacEntry) == FALSE) && (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE))) {	/* Currently piggy-back only support when peer is operate in b/g mode. */
649 				TX_BLK_SET_FLAG(pTxBlk, fTX_bPiggyBack);
650 			}
651 
652 			if (RTMP_GET_PACKET_MOREDATA(pPacket)) {
653 				TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
654 			}
655 		} else if (pTxBlk->TxFrameType == TX_FRAG_FRAME) {
656 			TX_BLK_SET_FLAG(pTxBlk, fTX_bAllowFrag);
657 		}
658 
659 		pMacEntry->DebugTxCount++;
660 	}
661 
662 	return TRUE;
663 }
664 
CanDoAggregateTransmit(struct rt_rtmp_adapter * pAd,char * pPacket,struct rt_tx_blk * pTxBlk)665 BOOLEAN CanDoAggregateTransmit(struct rt_rtmp_adapter *pAd,
666 			       char * pPacket, struct rt_tx_blk *pTxBlk)
667 {
668 
669 	/*DBGPRINT(RT_DEBUG_TRACE, ("Check if can do aggregation! TxFrameType=%d!\n", pTxBlk->TxFrameType)); */
670 
671 	if (RTMP_GET_PACKET_WCID(pPacket) == MCAST_WCID)
672 		return FALSE;
673 
674 	if (RTMP_GET_PACKET_DHCP(pPacket) ||
675 	    RTMP_GET_PACKET_EAPOL(pPacket) || RTMP_GET_PACKET_WAI(pPacket))
676 		return FALSE;
677 
678 	if ((pTxBlk->TxFrameType == TX_AMSDU_FRAME) && ((pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket)) > (RX_BUFFER_AGGRESIZE - 100))) {	/* For AMSDU, allow the packets with total length < max-amsdu size */
679 		return FALSE;
680 	}
681 
682 	if ((pTxBlk->TxFrameType == TX_RALINK_FRAME) && (pTxBlk->TxPacketList.Number == 2)) {	/* For RALINK-Aggregation, allow two frames in one batch. */
683 		return FALSE;
684 	}
685 
686 	if ((INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA))	/* must be unicast to AP */
687 		return TRUE;
688 	else
689 		return FALSE;
690 
691 }
692 
693 /*
694 	========================================================================
695 
696 	Routine Description:
697 		To do the enqueue operation and extract the first item of waiting
698 		list. If a number of available shared memory segments could meet
699 		the request of extracted item, the extracted item will be fragmented
700 		into shared memory segments.
701 
702 	Arguments:
703 		pAd Pointer to our adapter
704 		pQueue		Pointer to Waiting Queue
705 
706 	Return Value:
707 		None
708 
709 	IRQL = DISPATCH_LEVEL
710 
711 	Note:
712 
713 	========================================================================
714 */
RTMPDeQueuePacket(struct rt_rtmp_adapter * pAd,IN BOOLEAN bIntContext,u8 QIdx,u8 Max_Tx_Packets)715 void RTMPDeQueuePacket(struct rt_rtmp_adapter *pAd, IN BOOLEAN bIntContext, u8 QIdx,	/* BulkOutPipeId */
716 		       u8 Max_Tx_Packets)
717 {
718 	struct rt_queue_entry *pEntry = NULL;
719 	void *pPacket;
720 	int Status = NDIS_STATUS_SUCCESS;
721 	u8 Count = 0;
722 	struct rt_queue_header *pQueue;
723 	unsigned long FreeNumber[NUM_OF_TX_RING];
724 	u8 QueIdx, sQIdx, eQIdx;
725 	unsigned long IrqFlags = 0;
726 	BOOLEAN hasTxDesc = FALSE;
727 	struct rt_tx_blk TxBlk;
728 	struct rt_tx_blk *pTxBlk;
729 
730 	if (QIdx == NUM_OF_TX_RING) {
731 		sQIdx = 0;
732 		eQIdx = 3;	/* 4 ACs, start from 0. */
733 	} else {
734 		sQIdx = eQIdx = QIdx;
735 	}
736 
737 	for (QueIdx = sQIdx; QueIdx <= eQIdx; QueIdx++) {
738 		Count = 0;
739 
740 		RTMP_START_DEQUEUE(pAd, QueIdx, IrqFlags);
741 
742 		while (1) {
743 			if ((RTMP_TEST_FLAG
744 			     (pAd,
745 			      (fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS |
746 			       fRTMP_ADAPTER_RADIO_OFF |
747 			       fRTMP_ADAPTER_RESET_IN_PROGRESS |
748 			       fRTMP_ADAPTER_HALT_IN_PROGRESS |
749 			       fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
750 				RTMP_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
751 				return;
752 			}
753 
754 			if (Count >= Max_Tx_Packets)
755 				break;
756 
757 			DEQUEUE_LOCK(&pAd->irq_lock, bIntContext, IrqFlags);
758 			if (&pAd->TxSwQueue[QueIdx] == NULL) {
759 				DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext,
760 					       IrqFlags);
761 				break;
762 			}
763 #ifdef RTMP_MAC_PCI
764 			FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
765 
766 			if (FreeNumber[QueIdx] <= 5) {
767 				/* free Tx(QueIdx) resources */
768 				RTMPFreeTXDUponTxDmaDone(pAd, QueIdx);
769 				FreeNumber[QueIdx] =
770 				    GET_TXRING_FREENO(pAd, QueIdx);
771 			}
772 #endif /* RTMP_MAC_PCI // */
773 
774 			/* probe the Queue Head */
775 			pQueue = &pAd->TxSwQueue[QueIdx];
776 			pEntry = pQueue->Head;
777 			if (pEntry == NULL) {
778 				DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext,
779 					       IrqFlags);
780 				break;
781 			}
782 
783 			pTxBlk = &TxBlk;
784 			NdisZeroMemory((u8 *)pTxBlk, sizeof(struct rt_tx_blk));
785 			/*InitializeQueueHeader(&pTxBlk->TxPacketList);         // Didn't need it because we already memzero it. */
786 			pTxBlk->QueIdx = QueIdx;
787 
788 			pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
789 
790 			/* Early check to make sure we have enoguh Tx Resource. */
791 			hasTxDesc =
792 			    RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk,
793 						      FreeNumber[QueIdx],
794 						      pPacket);
795 			if (!hasTxDesc) {
796 				pAd->PrivateInfo.TxRingFullCnt++;
797 
798 				DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext,
799 					       IrqFlags);
800 
801 				break;
802 			}
803 
804 			pTxBlk->TxFrameType = TxPktClassification(pAd, pPacket);
805 			pEntry = RemoveHeadQueue(pQueue);
806 			pTxBlk->TotalFrameNum++;
807 			pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket);	/* The real fragment number maybe vary */
808 			pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket);
809 			pTxBlk->pPacket = pPacket;
810 			InsertTailQueue(&pTxBlk->TxPacketList,
811 					PACKET_TO_QUEUE_ENTRY(pPacket));
812 
813 			if (pTxBlk->TxFrameType == TX_RALINK_FRAME
814 			    || pTxBlk->TxFrameType == TX_AMSDU_FRAME) {
815 				/* Enhance SW Aggregation Mechanism */
816 				if (NEED_QUEUE_BACK_FOR_AGG
817 				    (pAd, QueIdx, FreeNumber[QueIdx],
818 				     pTxBlk->TxFrameType)) {
819 					InsertHeadQueue(pQueue,
820 							PACKET_TO_QUEUE_ENTRY
821 							(pPacket));
822 					DEQUEUE_UNLOCK(&pAd->irq_lock,
823 						       bIntContext, IrqFlags);
824 					break;
825 				}
826 
827 				do {
828 					pEntry = pQueue->Head;
829 					if (pEntry == NULL)
830 						break;
831 
832 					/* For TX_AMSDU_FRAME/TX_RALINK_FRAME, Need to check if next pakcet can do aggregation. */
833 					pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
834 					FreeNumber[QueIdx] =
835 					    GET_TXRING_FREENO(pAd, QueIdx);
836 					hasTxDesc =
837 					    RTMP_HAS_ENOUGH_FREE_DESC(pAd,
838 								      pTxBlk,
839 								      FreeNumber
840 								      [QueIdx],
841 								      pPacket);
842 					if ((hasTxDesc == FALSE)
843 					    ||
844 					    (CanDoAggregateTransmit
845 					     (pAd, pPacket, pTxBlk) == FALSE))
846 						break;
847 
848 					/*Remove the packet from the TxSwQueue and insert into pTxBlk */
849 					pEntry = RemoveHeadQueue(pQueue);
850 					ASSERT(pEntry);
851 					pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
852 					pTxBlk->TotalFrameNum++;
853 					pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket);	/* The real fragment number maybe vary */
854 					pTxBlk->TotalFrameLen +=
855 					    GET_OS_PKT_LEN(pPacket);
856 					InsertTailQueue(&pTxBlk->TxPacketList,
857 							PACKET_TO_QUEUE_ENTRY
858 							(pPacket));
859 				} while (1);
860 
861 				if (pTxBlk->TxPacketList.Number == 1)
862 					pTxBlk->TxFrameType = TX_LEGACY_FRAME;
863 			}
864 #ifdef RTMP_MAC_USB
865 			DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
866 #endif /* RTMP_MAC_USB // */
867 			Count += pTxBlk->TxPacketList.Number;
868 
869 			/* Do HardTransmit now. */
870 			Status = STAHardTransmit(pAd, pTxBlk, QueIdx);
871 
872 #ifdef RTMP_MAC_PCI
873 			DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
874 			/* static rate also need NICUpdateFifoStaCounters() function. */
875 			/*if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)) */
876 			NICUpdateFifoStaCounters(pAd);
877 #endif /* RTMP_MAC_PCI // */
878 
879 		}
880 
881 		RTMP_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
882 
883 #ifdef RTMP_MAC_USB
884 		if (!hasTxDesc)
885 			RTUSBKickBulkOut(pAd);
886 #endif /* RTMP_MAC_USB // */
887 	}
888 
889 }
890 
891 /*
892 	========================================================================
893 
894 	Routine Description:
895 		Calculates the duration which is required to transmit out frames
896 	with given size and specified rate.
897 
898 	Arguments:
899 		pAd 	Pointer to our adapter
900 		Rate			Transmit rate
901 		Size			Frame size in units of byte
902 
903 	Return Value:
904 		Duration number in units of usec
905 
906 	IRQL = PASSIVE_LEVEL
907 	IRQL = DISPATCH_LEVEL
908 
909 	Note:
910 
911 	========================================================================
912 */
RTMPCalcDuration(struct rt_rtmp_adapter * pAd,u8 Rate,unsigned long Size)913 u16 RTMPCalcDuration(struct rt_rtmp_adapter *pAd, u8 Rate, unsigned long Size)
914 {
915 	unsigned long Duration = 0;
916 
917 	if (Rate < RATE_FIRST_OFDM_RATE)	/* CCK */
918 	{
919 		if ((Rate > RATE_1)
920 		    && OPSTATUS_TEST_FLAG(pAd,
921 					  fOP_STATUS_SHORT_PREAMBLE_INUSED))
922 			Duration = 96;	/* 72+24 preamble+plcp */
923 		else
924 			Duration = 192;	/* 144+48 preamble+plcp */
925 
926 		Duration += (u16)((Size << 4) / RateIdTo500Kbps[Rate]);
927 		if ((Size << 4) % RateIdTo500Kbps[Rate])
928 			Duration++;
929 	} else if (Rate <= RATE_LAST_OFDM_RATE)	/* OFDM rates */
930 	{
931 		Duration = 20 + 6;	/* 16+4 preamble+plcp + Signal Extension */
932 		Duration +=
933 		    4 * (u16)((11 + Size * 4) / RateIdTo500Kbps[Rate]);
934 		if ((11 + Size * 4) % RateIdTo500Kbps[Rate])
935 			Duration += 4;
936 	} else			/*mimo rate */
937 	{
938 		Duration = 20 + 6;	/* 16+4 preamble+plcp + Signal Extension */
939 	}
940 
941 	return (u16)Duration;
942 }
943 
944 /*
945 	========================================================================
946 
947 	Routine Description:
948 		Calculates the duration which is required to transmit out frames
949 	with given size and specified rate.
950 
951 	Arguments:
952 		pTxWI		Pointer to head of each MPDU to HW.
953 		Ack 		Setting for Ack requirement bit
954 		Fragment	Setting for Fragment bit
955 		RetryMode	Setting for retry mode
956 		Ifs 		Setting for IFS gap
957 		Rate		Setting for transmit rate
958 		Service 	Setting for service
959 		Length		Frame length
960 		TxPreamble	Short or Long preamble when using CCK rates
961 		QueIdx - 0-3, according to 802.11e/d4.4 June/2003
962 
963 	Return Value:
964 		None
965 
966 	IRQL = PASSIVE_LEVEL
967 	IRQL = DISPATCH_LEVEL
968 
969     See also : BASmartHardTransmit()    !
970 
971 	========================================================================
972 */
RTMPWriteTxWI(struct rt_rtmp_adapter * pAd,struct rt_txwi * pOutTxWI,IN BOOLEAN FRAG,IN BOOLEAN CFACK,IN BOOLEAN InsTimestamp,IN BOOLEAN AMPDU,IN BOOLEAN Ack,IN BOOLEAN NSeq,u8 BASize,u8 WCID,unsigned long Length,u8 PID,u8 TID,u8 TxRate,u8 Txopmode,IN BOOLEAN CfAck,IN HTTRANSMIT_SETTING * pTransmit)973 void RTMPWriteTxWI(struct rt_rtmp_adapter *pAd, struct rt_txwi * pOutTxWI, IN BOOLEAN FRAG, IN BOOLEAN CFACK, IN BOOLEAN InsTimestamp, IN BOOLEAN AMPDU, IN BOOLEAN Ack, IN BOOLEAN NSeq,	/* HW new a sequence. */
974 		   u8 BASize,
975 		   u8 WCID,
976 		   unsigned long Length,
977 		   u8 PID,
978 		   u8 TID,
979 		   u8 TxRate,
980 		   u8 Txopmode,
981 		   IN BOOLEAN CfAck, IN HTTRANSMIT_SETTING * pTransmit)
982 {
983 	struct rt_mac_table_entry *pMac = NULL;
984 	struct rt_txwi TxWI;
985 	struct rt_txwi * pTxWI;
986 
987 	if (WCID < MAX_LEN_OF_MAC_TABLE)
988 		pMac = &pAd->MacTab.Content[WCID];
989 
990 	/* */
991 	/* Always use Long preamble before verifiation short preamble functionality works well. */
992 	/* Todo: remove the following line if short preamble functionality works */
993 	/* */
994 	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
995 	NdisZeroMemory(&TxWI, TXWI_SIZE);
996 	pTxWI = &TxWI;
997 
998 	pTxWI->FRAG = FRAG;
999 
1000 	pTxWI->CFACK = CFACK;
1001 	pTxWI->TS = InsTimestamp;
1002 	pTxWI->AMPDU = AMPDU;
1003 	pTxWI->ACK = Ack;
1004 	pTxWI->txop = Txopmode;
1005 
1006 	pTxWI->NSEQ = NSeq;
1007 	/* John tune the performace with Intel Client in 20 MHz performance */
1008 	BASize = pAd->CommonCfg.TxBASize;
1009 	if (pAd->MACVersion == 0x28720200) {
1010 		if (BASize > 13)
1011 			BASize = 13;
1012 	} else {
1013 		if (BASize > 7)
1014 			BASize = 7;
1015 	}
1016 	pTxWI->BAWinSize = BASize;
1017 	pTxWI->ShortGI = pTransmit->field.ShortGI;
1018 	pTxWI->STBC = pTransmit->field.STBC;
1019 
1020 	pTxWI->WirelessCliID = WCID;
1021 	pTxWI->MPDUtotalByteCount = Length;
1022 	pTxWI->PacketId = PID;
1023 
1024 	/* If CCK or OFDM, BW must be 20 */
1025 	pTxWI->BW =
1026 	    (pTransmit->field.MODE <=
1027 	     MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
1028 
1029 	pTxWI->MCS = pTransmit->field.MCS;
1030 	pTxWI->PHYMODE = pTransmit->field.MODE;
1031 	pTxWI->CFACK = CfAck;
1032 
1033 	if (pMac) {
1034 		if (pAd->CommonCfg.bMIMOPSEnable) {
1035 			if ((pMac->MmpsMode == MMPS_DYNAMIC)
1036 			    && (pTransmit->field.MCS > 7)) {
1037 				/* Dynamic MIMO Power Save Mode */
1038 				pTxWI->MIMOps = 1;
1039 			} else if (pMac->MmpsMode == MMPS_STATIC) {
1040 				/* Static MIMO Power Save Mode */
1041 				if (pTransmit->field.MODE >= MODE_HTMIX
1042 				    && pTransmit->field.MCS > 7) {
1043 					pTxWI->MCS = 7;
1044 					pTxWI->MIMOps = 0;
1045 				}
1046 			}
1047 		}
1048 		/*pTxWI->MIMOps = (pMac->PsMode == PWR_MMPS)? 1:0; */
1049 		if (pMac->bIAmBadAtheros
1050 		    && (pMac->WepStatus != Ndis802_11WEPDisabled)) {
1051 			pTxWI->MpduDensity = 7;
1052 		} else {
1053 			pTxWI->MpduDensity = pMac->MpduDensity;
1054 		}
1055 	}
1056 
1057 	pTxWI->PacketId = pTxWI->MCS;
1058 	NdisMoveMemory(pOutTxWI, &TxWI, sizeof(struct rt_txwi));
1059 }
1060 
RTMPWriteTxWI_Data(struct rt_rtmp_adapter * pAd,struct rt_txwi * pTxWI,struct rt_tx_blk * pTxBlk)1061 void RTMPWriteTxWI_Data(struct rt_rtmp_adapter *pAd,
1062 			struct rt_txwi * pTxWI, struct rt_tx_blk *pTxBlk)
1063 {
1064 	HTTRANSMIT_SETTING *pTransmit;
1065 	struct rt_mac_table_entry *pMacEntry;
1066 	u8 BASize;
1067 
1068 	ASSERT(pTxWI);
1069 
1070 	pTransmit = pTxBlk->pTransmit;
1071 	pMacEntry = pTxBlk->pMacEntry;
1072 
1073 	/* */
1074 	/* Always use Long preamble before verifiation short preamble functionality works well. */
1075 	/* Todo: remove the following line if short preamble functionality works */
1076 	/* */
1077 	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
1078 	NdisZeroMemory(pTxWI, TXWI_SIZE);
1079 
1080 	pTxWI->FRAG = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag);
1081 	pTxWI->ACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAckRequired);
1082 	pTxWI->txop = pTxBlk->FrameGap;
1083 
1084 	pTxWI->WirelessCliID = pTxBlk->Wcid;
1085 
1086 	pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
1087 	pTxWI->CFACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bPiggyBack);
1088 
1089 	/* If CCK or OFDM, BW must be 20 */
1090 	pTxWI->BW =
1091 	    (pTransmit->field.MODE <=
1092 	     MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
1093 	pTxWI->AMPDU = ((pTxBlk->TxFrameType == TX_AMPDU_FRAME) ? TRUE : FALSE);
1094 
1095 	/* John tune the performace with Intel Client in 20 MHz performance */
1096 	BASize = pAd->CommonCfg.TxBASize;
1097 	if ((pTxBlk->TxFrameType == TX_AMPDU_FRAME) && (pMacEntry)) {
1098 		u8 RABAOriIdx = 0;	/*The RA's BA Originator table index. */
1099 
1100 		RABAOriIdx =
1101 		    pTxBlk->pMacEntry->BAOriWcidArray[pTxBlk->UserPriority];
1102 		BASize = pAd->BATable.BAOriEntry[RABAOriIdx].BAWinSize;
1103 	}
1104 
1105 	pTxWI->TxBF = pTransmit->field.TxBF;
1106 	pTxWI->BAWinSize = BASize;
1107 	pTxWI->ShortGI = pTransmit->field.ShortGI;
1108 	pTxWI->STBC = pTransmit->field.STBC;
1109 
1110 	pTxWI->MCS = pTransmit->field.MCS;
1111 	pTxWI->PHYMODE = pTransmit->field.MODE;
1112 
1113 	if (pMacEntry) {
1114 		if ((pMacEntry->MmpsMode == MMPS_DYNAMIC)
1115 		    && (pTransmit->field.MCS > 7)) {
1116 			/* Dynamic MIMO Power Save Mode */
1117 			pTxWI->MIMOps = 1;
1118 		} else if (pMacEntry->MmpsMode == MMPS_STATIC) {
1119 			/* Static MIMO Power Save Mode */
1120 			if (pTransmit->field.MODE >= MODE_HTMIX
1121 			    && pTransmit->field.MCS > 7) {
1122 				pTxWI->MCS = 7;
1123 				pTxWI->MIMOps = 0;
1124 			}
1125 		}
1126 
1127 		if (pMacEntry->bIAmBadAtheros
1128 		    && (pMacEntry->WepStatus != Ndis802_11WEPDisabled)) {
1129 			pTxWI->MpduDensity = 7;
1130 		} else {
1131 			pTxWI->MpduDensity = pMacEntry->MpduDensity;
1132 		}
1133 	}
1134 
1135 	/* for rate adapation */
1136 	pTxWI->PacketId = pTxWI->MCS;
1137 }
1138 
RTMPWriteTxWI_Cache(struct rt_rtmp_adapter * pAd,struct rt_txwi * pTxWI,struct rt_tx_blk * pTxBlk)1139 void RTMPWriteTxWI_Cache(struct rt_rtmp_adapter *pAd,
1140 			 struct rt_txwi * pTxWI, struct rt_tx_blk *pTxBlk)
1141 {
1142 	PHTTRANSMIT_SETTING /*pTxHTPhyMode, */ pTransmit;
1143 	struct rt_mac_table_entry *pMacEntry;
1144 
1145 	/* */
1146 	/* update TXWI */
1147 	/* */
1148 	pMacEntry = pTxBlk->pMacEntry;
1149 	pTransmit = pTxBlk->pTransmit;
1150 
1151 	/*if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)) */
1152 	/*if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pMacEntry)) */
1153 	/*if (TX_BLK_TEST_FLAG(pTxBlk, fTX_AutoRateSwitch)) */
1154 	if (pMacEntry->bAutoTxRateSwitch) {
1155 		pTxWI->txop = IFS_HTTXOP;
1156 
1157 		/* If CCK or OFDM, BW must be 20 */
1158 		pTxWI->BW =
1159 		    (pTransmit->field.MODE <=
1160 		     MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
1161 		pTxWI->ShortGI = pTransmit->field.ShortGI;
1162 		pTxWI->STBC = pTransmit->field.STBC;
1163 
1164 		pTxWI->MCS = pTransmit->field.MCS;
1165 		pTxWI->PHYMODE = pTransmit->field.MODE;
1166 
1167 		/* set PID for TxRateSwitching */
1168 		pTxWI->PacketId = pTransmit->field.MCS;
1169 	}
1170 
1171 	pTxWI->AMPDU = ((pMacEntry->NoBADataCountDown == 0) ? TRUE : FALSE);
1172 	pTxWI->MIMOps = 0;
1173 
1174 	if (pAd->CommonCfg.bMIMOPSEnable) {
1175 		/* MIMO Power Save Mode */
1176 		if ((pMacEntry->MmpsMode == MMPS_DYNAMIC)
1177 		    && (pTransmit->field.MCS > 7)) {
1178 			/* Dynamic MIMO Power Save Mode */
1179 			pTxWI->MIMOps = 1;
1180 		} else if (pMacEntry->MmpsMode == MMPS_STATIC) {
1181 			/* Static MIMO Power Save Mode */
1182 			if ((pTransmit->field.MODE >= MODE_HTMIX)
1183 			    && (pTransmit->field.MCS > 7)) {
1184 				pTxWI->MCS = 7;
1185 				pTxWI->MIMOps = 0;
1186 			}
1187 		}
1188 	}
1189 
1190 	pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
1191 
1192 }
1193 
1194 /* should be called only when - */
1195 /* 1. MEADIA_CONNECTED */
1196 /* 2. AGGREGATION_IN_USED */
1197 /* 3. Fragmentation not in used */
1198 /* 4. either no previous frame (pPrevAddr1=NULL) .OR. previoud frame is aggregatible */
TxFrameIsAggregatible(struct rt_rtmp_adapter * pAd,u8 * pPrevAddr1,u8 * p8023hdr)1199 BOOLEAN TxFrameIsAggregatible(struct rt_rtmp_adapter *pAd,
1200 			      u8 *pPrevAddr1, u8 *p8023hdr)
1201 {
1202 
1203 	/* can't aggregate EAPOL (802.1x) frame */
1204 	if ((p8023hdr[12] == 0x88) && (p8023hdr[13] == 0x8e))
1205 		return FALSE;
1206 
1207 	/* can't aggregate multicast/broadcast frame */
1208 	if (p8023hdr[0] & 0x01)
1209 		return FALSE;
1210 
1211 	if (INFRA_ON(pAd))	/* must be unicast to AP */
1212 		return TRUE;
1213 	else if ((pPrevAddr1 == NULL) || MAC_ADDR_EQUAL(pPrevAddr1, p8023hdr))	/* unicast to same STA */
1214 		return TRUE;
1215 	else
1216 		return FALSE;
1217 }
1218 
1219 /*
1220 	========================================================================
1221 
1222 	Routine Description:
1223 	   Check the MSDU Aggregation policy
1224 	1.HT aggregation is A-MSDU
1225 	2.legaacy rate aggregation is software aggregation by Ralink.
1226 
1227 	Arguments:
1228 
1229 	Return Value:
1230 
1231 	Note:
1232 
1233 	========================================================================
1234 */
PeerIsAggreOn(struct rt_rtmp_adapter * pAd,unsigned long TxRate,struct rt_mac_table_entry * pMacEntry)1235 BOOLEAN PeerIsAggreOn(struct rt_rtmp_adapter *pAd,
1236 		      unsigned long TxRate, struct rt_mac_table_entry *pMacEntry)
1237 {
1238 	unsigned long AFlags =
1239 	    (fCLIENT_STATUS_AMSDU_INUSED | fCLIENT_STATUS_AGGREGATION_CAPABLE);
1240 
1241 	if (pMacEntry != NULL && CLIENT_STATUS_TEST_FLAG(pMacEntry, AFlags)) {
1242 		if (pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX) {
1243 			return TRUE;
1244 		}
1245 #ifdef AGGREGATION_SUPPORT
1246 		if (TxRate >= RATE_6 && pAd->CommonCfg.bAggregationCapable && (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE)))) {	/* legacy  Ralink Aggregation support */
1247 			return TRUE;
1248 		}
1249 #endif /* AGGREGATION_SUPPORT // */
1250 	}
1251 
1252 	return FALSE;
1253 
1254 }
1255 
1256 /*
1257 	========================================================================
1258 
1259 	Routine Description:
1260 		Check and fine the packet waiting in SW queue with highest priority
1261 
1262 	Arguments:
1263 		pAd Pointer to our adapter
1264 
1265 	Return Value:
1266 		pQueue		Pointer to Waiting Queue
1267 
1268 	IRQL = DISPATCH_LEVEL
1269 
1270 	Note:
1271 
1272 	========================================================================
1273 */
RTMPCheckTxSwQueue(struct rt_rtmp_adapter * pAd,u8 * pQueIdx)1274 struct rt_queue_header *RTMPCheckTxSwQueue(struct rt_rtmp_adapter *pAd, u8 *pQueIdx)
1275 {
1276 
1277 	unsigned long Number;
1278 	/* 2004-11-15 to be removed. test aggregation only */
1279 /*      if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)) && (*pNumber < 2)) */
1280 /*               return NULL; */
1281 
1282 	Number = pAd->TxSwQueue[QID_AC_BK].Number
1283 	    + pAd->TxSwQueue[QID_AC_BE].Number
1284 	    + pAd->TxSwQueue[QID_AC_VI].Number
1285 	    + pAd->TxSwQueue[QID_AC_VO].Number;
1286 
1287 	if (pAd->TxSwQueue[QID_AC_VO].Head != NULL) {
1288 		*pQueIdx = QID_AC_VO;
1289 		return (&pAd->TxSwQueue[QID_AC_VO]);
1290 	} else if (pAd->TxSwQueue[QID_AC_VI].Head != NULL) {
1291 		*pQueIdx = QID_AC_VI;
1292 		return (&pAd->TxSwQueue[QID_AC_VI]);
1293 	} else if (pAd->TxSwQueue[QID_AC_BE].Head != NULL) {
1294 		*pQueIdx = QID_AC_BE;
1295 		return (&pAd->TxSwQueue[QID_AC_BE]);
1296 	} else if (pAd->TxSwQueue[QID_AC_BK].Head != NULL) {
1297 		*pQueIdx = QID_AC_BK;
1298 		return (&pAd->TxSwQueue[QID_AC_BK]);
1299 	}
1300 	/* No packet pending in Tx Sw queue */
1301 	*pQueIdx = QID_AC_BK;
1302 
1303 	return (NULL);
1304 }
1305 
1306 /*
1307 	========================================================================
1308 
1309 	Routine Description:
1310 		Suspend MSDU transmission
1311 
1312 	Arguments:
1313 		pAd 	Pointer to our adapter
1314 
1315 	Return Value:
1316 		None
1317 
1318 	Note:
1319 
1320 	========================================================================
1321 */
RTMPSuspendMsduTransmission(struct rt_rtmp_adapter * pAd)1322 void RTMPSuspendMsduTransmission(struct rt_rtmp_adapter *pAd)
1323 {
1324 	DBGPRINT(RT_DEBUG_TRACE, ("SCANNING, suspend MSDU transmission ...\n"));
1325 
1326 	/* */
1327 	/* Before BSS_SCAN_IN_PROGRESS, we need to keep Current R66 value and */
1328 	/* use Lowbound as R66 value on ScanNextChannel(...) */
1329 	/* */
1330 	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66,
1331 				    &pAd->BbpTuning.R66CurrentValue);
1332 
1333 	/* set BBP_R66 to 0x30/0x40 when scanning (AsicSwitchChannel will set R66 according to channel when scanning) */
1334 	/*RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x26 + GET_LNA_GAIN(pAd))); */
1335 	RTMPSetAGCInitValue(pAd, BW_20);
1336 
1337 	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1338 	/*RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x000f0000);                // abort all TX rings */
1339 }
1340 
1341 /*
1342 	========================================================================
1343 
1344 	Routine Description:
1345 		Resume MSDU transmission
1346 
1347 	Arguments:
1348 		pAd 	Pointer to our adapter
1349 
1350 	Return Value:
1351 		None
1352 
1353 	IRQL = DISPATCH_LEVEL
1354 
1355 	Note:
1356 
1357 	========================================================================
1358 */
RTMPResumeMsduTransmission(struct rt_rtmp_adapter * pAd)1359 void RTMPResumeMsduTransmission(struct rt_rtmp_adapter *pAd)
1360 {
1361 /*    u8                     IrqState; */
1362 
1363 	DBGPRINT(RT_DEBUG_TRACE, ("SCAN done, resume MSDU transmission ...\n"));
1364 
1365 	/* After finish BSS_SCAN_IN_PROGRESS, we need to restore Current R66 value */
1366 	/* R66 should not be 0 */
1367 	if (pAd->BbpTuning.R66CurrentValue == 0) {
1368 		pAd->BbpTuning.R66CurrentValue = 0x38;
1369 		DBGPRINT_ERR("RTMPResumeMsduTransmission, R66CurrentValue=0...\n");
1370 	}
1371 
1372 	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66,
1373 				     pAd->BbpTuning.R66CurrentValue);
1374 
1375 	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1376 /* sample, for IRQ LOCK to SEM LOCK */
1377 /*    IrqState = pAd->irq_disabled; */
1378 /*      if (IrqState) */
1379 /*              RTMPDeQueuePacket(pAd, TRUE, NUM_OF_TX_RING, MAX_TX_PROCESS); */
1380 /*    else */
1381 	RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1382 }
1383 
deaggregate_AMSDU_announce(struct rt_rtmp_adapter * pAd,void * pPacket,u8 * pData,unsigned long DataSize)1384 u32 deaggregate_AMSDU_announce(struct rt_rtmp_adapter *pAd,
1385 				void *pPacket,
1386 				u8 *pData, unsigned long DataSize)
1387 {
1388 	u16 PayloadSize;
1389 	u16 SubFrameSize;
1390 	struct rt_header_802_3 * pAMSDUsubheader;
1391 	u32 nMSDU;
1392 	u8 Header802_3[14];
1393 
1394 	u8 *pPayload, *pDA, *pSA, *pRemovedLLCSNAP;
1395 	void *pClonePacket;
1396 
1397 	nMSDU = 0;
1398 
1399 	while (DataSize > LENGTH_802_3) {
1400 
1401 		nMSDU++;
1402 
1403 		/*hex_dump("subheader", pData, 64); */
1404 		pAMSDUsubheader = (struct rt_header_802_3 *) pData;
1405 		/*pData += LENGTH_802_3; */
1406 		PayloadSize =
1407 		    pAMSDUsubheader->Octet[1] +
1408 		    (pAMSDUsubheader->Octet[0] << 8);
1409 		SubFrameSize = PayloadSize + LENGTH_802_3;
1410 
1411 		if ((DataSize < SubFrameSize) || (PayloadSize > 1518)) {
1412 			break;
1413 		}
1414 		/*DBGPRINT(RT_DEBUG_TRACE,("%d subframe: Size = %d\n",  nMSDU, PayloadSize)); */
1415 
1416 		pPayload = pData + LENGTH_802_3;
1417 		pDA = pData;
1418 		pSA = pData + MAC_ADDR_LEN;
1419 
1420 		/* convert to 802.3 header */
1421 		CONVERT_TO_802_3(Header802_3, pDA, pSA, pPayload, PayloadSize,
1422 				 pRemovedLLCSNAP);
1423 
1424 		if ((Header802_3[12] == 0x88) && (Header802_3[13] == 0x8E)) {
1425 			/* avoid local heap overflow, use dyanamic allocation */
1426 			struct rt_mlme_queue_elem *Elem =
1427 			    kmalloc(sizeof(struct rt_mlme_queue_elem),
1428 							MEM_ALLOC_FLAG);
1429 			if (Elem != NULL) {
1430 				memmove(Elem->Msg +
1431 					(LENGTH_802_11 + LENGTH_802_1_H),
1432 					pPayload, PayloadSize);
1433 				Elem->MsgLen =
1434 				    LENGTH_802_11 + LENGTH_802_1_H +
1435 				    PayloadSize;
1436 				/*WpaEAPOLKeyAction(pAd, Elem); */
1437 				REPORT_MGMT_FRAME_TO_MLME(pAd, BSSID_WCID,
1438 							  Elem->Msg,
1439 							  Elem->MsgLen, 0, 0, 0,
1440 							  0);
1441 				kfree(Elem);
1442 			}
1443 		}
1444 
1445 		{
1446 			if (pRemovedLLCSNAP) {
1447 				pPayload -= LENGTH_802_3;
1448 				PayloadSize += LENGTH_802_3;
1449 				NdisMoveMemory(pPayload, &Header802_3[0],
1450 					       LENGTH_802_3);
1451 			}
1452 		}
1453 
1454 		pClonePacket = ClonePacket(pAd, pPacket, pPayload, PayloadSize);
1455 		if (pClonePacket) {
1456 			ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pClonePacket,
1457 							 RTMP_GET_PACKET_IF
1458 							 (pPacket));
1459 		}
1460 
1461 		/* A-MSDU has padding to multiple of 4 including subframe header. */
1462 		/* align SubFrameSize up to multiple of 4 */
1463 		SubFrameSize = (SubFrameSize + 3) & (~0x3);
1464 
1465 		if (SubFrameSize > 1528 || SubFrameSize < 32) {
1466 			break;
1467 		}
1468 
1469 		if (DataSize > SubFrameSize) {
1470 			pData += SubFrameSize;
1471 			DataSize -= SubFrameSize;
1472 		} else {
1473 			/* end of A-MSDU */
1474 			DataSize = 0;
1475 		}
1476 	}
1477 
1478 	/* finally release original rx packet */
1479 	RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
1480 
1481 	return nMSDU;
1482 }
1483 
BA_Reorder_AMSDU_Announce(struct rt_rtmp_adapter * pAd,void * pPacket)1484 u32 BA_Reorder_AMSDU_Announce(struct rt_rtmp_adapter *pAd, void *pPacket)
1485 {
1486 	u8 *pData;
1487 	u16 DataSize;
1488 	u32 nMSDU = 0;
1489 
1490 	pData = (u8 *)GET_OS_PKT_DATAPTR(pPacket);
1491 	DataSize = (u16)GET_OS_PKT_LEN(pPacket);
1492 
1493 	nMSDU = deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize);
1494 
1495 	return nMSDU;
1496 }
1497 
1498 /*
1499 	==========================================================================
1500 	Description:
1501 		Look up the MAC address in the MAC table. Return NULL if not found.
1502 	Return:
1503 		pEntry - pointer to the MAC entry; NULL is not found
1504 	==========================================================================
1505 */
MacTableLookup(struct rt_rtmp_adapter * pAd,u8 * pAddr)1506 struct rt_mac_table_entry *MacTableLookup(struct rt_rtmp_adapter *pAd, u8 *pAddr)
1507 {
1508 	unsigned long HashIdx;
1509 	struct rt_mac_table_entry *pEntry = NULL;
1510 
1511 	HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
1512 	pEntry = pAd->MacTab.Hash[HashIdx];
1513 
1514 	while (pEntry
1515 	       && (pEntry->ValidAsCLI || pEntry->ValidAsWDS
1516 		   || pEntry->ValidAsApCli || pEntry->ValidAsMesh)) {
1517 		if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr)) {
1518 			break;
1519 		} else
1520 			pEntry = pEntry->pNext;
1521 	}
1522 
1523 	return pEntry;
1524 }
1525 
MacTableInsertEntry(struct rt_rtmp_adapter * pAd,u8 * pAddr,u8 apidx,IN BOOLEAN CleanAll)1526 struct rt_mac_table_entry *MacTableInsertEntry(struct rt_rtmp_adapter *pAd,
1527 				     u8 *pAddr,
1528 				     u8 apidx, IN BOOLEAN CleanAll)
1529 {
1530 	u8 HashIdx;
1531 	int i, FirstWcid;
1532 	struct rt_mac_table_entry *pEntry = NULL, *pCurrEntry;
1533 /*      u16  offset; */
1534 /*      unsigned long   addr; */
1535 
1536 	/* if FULL, return */
1537 	if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
1538 		return NULL;
1539 
1540 	FirstWcid = 1;
1541 
1542 	if (pAd->StaCfg.BssType == BSS_INFRA)
1543 		FirstWcid = 2;
1544 
1545 	/* allocate one MAC entry */
1546 	NdisAcquireSpinLock(&pAd->MacTabLock);
1547 	for (i = FirstWcid; i < MAX_LEN_OF_MAC_TABLE; i++)	/* skip entry#0 so that "entry index == AID" for fast lookup */
1548 	{
1549 		/* pick up the first available vacancy */
1550 		if ((pAd->MacTab.Content[i].ValidAsCLI == FALSE) &&
1551 		    (pAd->MacTab.Content[i].ValidAsWDS == FALSE) &&
1552 		    (pAd->MacTab.Content[i].ValidAsApCli == FALSE) &&
1553 		    (pAd->MacTab.Content[i].ValidAsMesh == FALSE)
1554 		    ) {
1555 			pEntry = &pAd->MacTab.Content[i];
1556 			if (CleanAll == TRUE) {
1557 				pEntry->MaxSupportedRate = RATE_11;
1558 				pEntry->CurrTxRate = RATE_11;
1559 				NdisZeroMemory(pEntry, sizeof(struct rt_mac_table_entry));
1560 				pEntry->PairwiseKey.KeyLen = 0;
1561 				pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
1562 			}
1563 			{
1564 				{
1565 					pEntry->ValidAsCLI = TRUE;
1566 					pEntry->ValidAsWDS = FALSE;
1567 					pEntry->ValidAsApCli = FALSE;
1568 					pEntry->ValidAsMesh = FALSE;
1569 					pEntry->ValidAsDls = FALSE;
1570 				}
1571 			}
1572 
1573 			pEntry->bIAmBadAtheros = FALSE;
1574 			pEntry->pAd = pAd;
1575 			pEntry->CMTimerRunning = FALSE;
1576 			pEntry->EnqueueEapolStartTimerRunning =
1577 			    EAPOL_START_DISABLE;
1578 			pEntry->RSNIE_Len = 0;
1579 			NdisZeroMemory(pEntry->R_Counter,
1580 				       sizeof(pEntry->R_Counter));
1581 			pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;
1582 
1583 			if (pEntry->ValidAsMesh)
1584 				pEntry->apidx =
1585 				    (apidx - MIN_NET_DEVICE_FOR_MESH);
1586 			else if (pEntry->ValidAsApCli)
1587 				pEntry->apidx =
1588 				    (apidx - MIN_NET_DEVICE_FOR_APCLI);
1589 			else if (pEntry->ValidAsWDS)
1590 				pEntry->apidx =
1591 				    (apidx - MIN_NET_DEVICE_FOR_WDS);
1592 			else
1593 				pEntry->apidx = apidx;
1594 
1595 			{
1596 				{
1597 					pEntry->AuthMode = pAd->StaCfg.AuthMode;
1598 					pEntry->WepStatus =
1599 					    pAd->StaCfg.WepStatus;
1600 					pEntry->PrivacyFilter =
1601 					    Ndis802_11PrivFilterAcceptAll;
1602 #ifdef RTMP_MAC_PCI
1603 					AsicRemovePairwiseKeyEntry(pAd,
1604 								   pEntry->
1605 								   apidx,
1606 								   (u8)i);
1607 #endif /* RTMP_MAC_PCI // */
1608 				}
1609 			}
1610 
1611 			pEntry->GTKState = REKEY_NEGOTIATING;
1612 			pEntry->PairwiseKey.KeyLen = 0;
1613 			pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
1614 			pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1615 
1616 			pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND;
1617 			COPY_MAC_ADDR(pEntry->Addr, pAddr);
1618 			pEntry->Sst = SST_NOT_AUTH;
1619 			pEntry->AuthState = AS_NOT_AUTH;
1620 			pEntry->Aid = (u16)i;	/*0; */
1621 			pEntry->CapabilityInfo = 0;
1622 			pEntry->PsMode = PWR_ACTIVE;
1623 			pEntry->PsQIdleCount = 0;
1624 			pEntry->NoDataIdleCount = 0;
1625 			pEntry->AssocDeadLine = MAC_TABLE_ASSOC_TIMEOUT;
1626 			pEntry->ContinueTxFailCnt = 0;
1627 			InitializeQueueHeader(&pEntry->PsQueue);
1628 
1629 			pAd->MacTab.Size++;
1630 			/* Add this entry into ASIC RX WCID search table */
1631 			RTMP_STA_ENTRY_ADD(pAd, pEntry);
1632 
1633 			DBGPRINT(RT_DEBUG_TRACE,
1634 				 ("MacTableInsertEntry - allocate entry #%d, Total= %d\n",
1635 				  i, pAd->MacTab.Size));
1636 			break;
1637 		}
1638 	}
1639 
1640 	/* add this MAC entry into HASH table */
1641 	if (pEntry) {
1642 		HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
1643 		if (pAd->MacTab.Hash[HashIdx] == NULL) {
1644 			pAd->MacTab.Hash[HashIdx] = pEntry;
1645 		} else {
1646 			pCurrEntry = pAd->MacTab.Hash[HashIdx];
1647 			while (pCurrEntry->pNext != NULL)
1648 				pCurrEntry = pCurrEntry->pNext;
1649 			pCurrEntry->pNext = pEntry;
1650 		}
1651 	}
1652 
1653 	NdisReleaseSpinLock(&pAd->MacTabLock);
1654 	return pEntry;
1655 }
1656 
1657 /*
1658 	==========================================================================
1659 	Description:
1660 		Delete a specified client from MAC table
1661 	==========================================================================
1662  */
MacTableDeleteEntry(struct rt_rtmp_adapter * pAd,u16 wcid,u8 * pAddr)1663 BOOLEAN MacTableDeleteEntry(struct rt_rtmp_adapter *pAd,
1664 			    u16 wcid, u8 *pAddr)
1665 {
1666 	u16 HashIdx;
1667 	struct rt_mac_table_entry *pEntry, *pPrevEntry, *pProbeEntry;
1668 	BOOLEAN Cancelled;
1669 	/*u16        offset; // unused variable */
1670 	/*u8 j;                      // unused variable */
1671 
1672 	if (wcid >= MAX_LEN_OF_MAC_TABLE)
1673 		return FALSE;
1674 
1675 	NdisAcquireSpinLock(&pAd->MacTabLock);
1676 
1677 	HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
1678 	/*pEntry = pAd->MacTab.Hash[HashIdx]; */
1679 	pEntry = &pAd->MacTab.Content[wcid];
1680 
1681 	if (pEntry
1682 	    && (pEntry->ValidAsCLI || pEntry->ValidAsApCli || pEntry->ValidAsWDS
1683 		|| pEntry->ValidAsMesh)) {
1684 		if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr)) {
1685 
1686 			/* Delete this entry from ASIC on-chip WCID Table */
1687 			RTMP_STA_ENTRY_MAC_RESET(pAd, wcid);
1688 
1689 			/* free resources of BA */
1690 			BASessionTearDownALL(pAd, pEntry->Aid);
1691 
1692 			pPrevEntry = NULL;
1693 			pProbeEntry = pAd->MacTab.Hash[HashIdx];
1694 			ASSERT(pProbeEntry);
1695 
1696 			/* update Hash list */
1697 			do {
1698 				if (pProbeEntry == pEntry) {
1699 					if (pPrevEntry == NULL) {
1700 						pAd->MacTab.Hash[HashIdx] =
1701 						    pEntry->pNext;
1702 					} else {
1703 						pPrevEntry->pNext =
1704 						    pEntry->pNext;
1705 					}
1706 					break;
1707 				}
1708 
1709 				pPrevEntry = pProbeEntry;
1710 				pProbeEntry = pProbeEntry->pNext;
1711 			} while (pProbeEntry);
1712 
1713 			/* not found ! */
1714 			ASSERT(pProbeEntry != NULL);
1715 
1716 			RTMP_STA_ENTRY_KEY_DEL(pAd, BSS0, wcid);
1717 
1718 			if (pEntry->EnqueueEapolStartTimerRunning !=
1719 			    EAPOL_START_DISABLE) {
1720 				RTMPCancelTimer(&pEntry->
1721 						EnqueueStartForPSKTimer,
1722 						&Cancelled);
1723 				pEntry->EnqueueEapolStartTimerRunning =
1724 				    EAPOL_START_DISABLE;
1725 			}
1726 
1727 			NdisZeroMemory(pEntry, sizeof(struct rt_mac_table_entry));
1728 			pAd->MacTab.Size--;
1729 			DBGPRINT(RT_DEBUG_TRACE,
1730 				 ("MacTableDeleteEntry1 - Total= %d\n",
1731 				  pAd->MacTab.Size));
1732 		} else {
1733 			DBGPRINT(RT_DEBUG_OFF,
1734 				 ("\n%s: Impossible Wcid = %d !\n",
1735 				  __func__, wcid));
1736 		}
1737 	}
1738 
1739 	NdisReleaseSpinLock(&pAd->MacTabLock);
1740 
1741 	/*Reset operating mode when no Sta. */
1742 	if (pAd->MacTab.Size == 0) {
1743 		pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode = 0;
1744 		RTMP_UPDATE_PROTECT(pAd);	/* edit by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet */
1745 	}
1746 
1747 	return TRUE;
1748 }
1749 
1750 /*
1751 	==========================================================================
1752 	Description:
1753 		This routine reset the entire MAC table. All packets pending in
1754 		the power-saving queues are freed here.
1755 	==========================================================================
1756  */
MacTableReset(struct rt_rtmp_adapter * pAd)1757 void MacTableReset(struct rt_rtmp_adapter *pAd)
1758 {
1759 	int i;
1760 
1761 	DBGPRINT(RT_DEBUG_TRACE, ("MacTableReset\n"));
1762 	/*NdisAcquireSpinLock(&pAd->MacTabLock); */
1763 
1764 	for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) {
1765 #ifdef RTMP_MAC_PCI
1766 		RTMP_STA_ENTRY_MAC_RESET(pAd, i);
1767 #endif /* RTMP_MAC_PCI // */
1768 		if (pAd->MacTab.Content[i].ValidAsCLI == TRUE) {
1769 
1770 			/* free resources of BA */
1771 			BASessionTearDownALL(pAd, i);
1772 
1773 			pAd->MacTab.Content[i].ValidAsCLI = FALSE;
1774 
1775 #ifdef RTMP_MAC_USB
1776 			NdisZeroMemory(pAd->MacTab.Content[i].Addr, 6);
1777 			RTMP_STA_ENTRY_MAC_RESET(pAd, i);
1778 #endif /* RTMP_MAC_USB // */
1779 
1780 			/*AsicDelWcidTab(pAd, i); */
1781 		}
1782 	}
1783 
1784 	return;
1785 }
1786 
1787 /*
1788 	==========================================================================
1789 	Description:
1790 
1791 	IRQL = DISPATCH_LEVEL
1792 
1793 	==========================================================================
1794 */
AssocParmFill(struct rt_rtmp_adapter * pAd,struct rt_mlme_assoc_req * AssocReq,u8 * pAddr,u16 CapabilityInfo,unsigned long Timeout,u16 ListenIntv)1795 void AssocParmFill(struct rt_rtmp_adapter *pAd,
1796 		   struct rt_mlme_assoc_req *AssocReq,
1797 		   u8 *pAddr,
1798 		   u16 CapabilityInfo,
1799 		   unsigned long Timeout, u16 ListenIntv)
1800 {
1801 	COPY_MAC_ADDR(AssocReq->Addr, pAddr);
1802 	/* Add mask to support 802.11b mode only */
1803 	AssocReq->CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO;	/* not cf-pollable, not cf-poll-request */
1804 	AssocReq->Timeout = Timeout;
1805 	AssocReq->ListenIntv = ListenIntv;
1806 }
1807 
1808 /*
1809 	==========================================================================
1810 	Description:
1811 
1812 	IRQL = DISPATCH_LEVEL
1813 
1814 	==========================================================================
1815 */
DisassocParmFill(struct rt_rtmp_adapter * pAd,struct rt_mlme_disassoc_req * DisassocReq,u8 * pAddr,u16 Reason)1816 void DisassocParmFill(struct rt_rtmp_adapter *pAd,
1817 		      struct rt_mlme_disassoc_req *DisassocReq,
1818 		      u8 *pAddr, u16 Reason)
1819 {
1820 	COPY_MAC_ADDR(DisassocReq->Addr, pAddr);
1821 	DisassocReq->Reason = Reason;
1822 }
1823 
1824 /*
1825 	========================================================================
1826 
1827 	Routine Description:
1828 		Check the out going frame, if this is an DHCP or ARP datagram
1829 	will be duplicate another frame at low data rate transmit.
1830 
1831 	Arguments:
1832 		pAd 		Pointer to our adapter
1833 		pPacket 	Pointer to outgoing Ndis frame
1834 
1835 	Return Value:
1836 		TRUE		To be duplicate at Low data rate transmit. (1mb)
1837 		FALSE		Do nothing.
1838 
1839 	IRQL = DISPATCH_LEVEL
1840 
1841 	Note:
1842 
1843 		MAC header + IP Header + UDP Header
1844 		  14 Bytes	  20 Bytes
1845 
1846 		UDP Header
1847 		00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|
1848 						Source Port
1849 		16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|
1850 					Destination Port
1851 
1852 		port 0x43 means Bootstrap Protocol, server.
1853 		Port 0x44 means Bootstrap Protocol, client.
1854 
1855 	========================================================================
1856 */
1857 
RTMPCheckDHCPFrame(struct rt_rtmp_adapter * pAd,void * pPacket)1858 BOOLEAN RTMPCheckDHCPFrame(struct rt_rtmp_adapter *pAd, void *pPacket)
1859 {
1860 	struct rt_packet_info PacketInfo;
1861 	unsigned long NumberOfBytesRead = 0;
1862 	unsigned long CurrentOffset = 0;
1863 	void *pVirtualAddress = NULL;
1864 	u32 NdisBufferLength;
1865 	u8 *pSrc;
1866 	u16 Protocol;
1867 	u8 ByteOffset36 = 0;
1868 	u8 ByteOffset38 = 0;
1869 	BOOLEAN ReadFirstParm = TRUE;
1870 
1871 	RTMP_QueryPacketInfo(pPacket, &PacketInfo, (u8 **) & pVirtualAddress,
1872 			     &NdisBufferLength);
1873 
1874 	NumberOfBytesRead += NdisBufferLength;
1875 	pSrc = (u8 *)pVirtualAddress;
1876 	Protocol = *(pSrc + 12) * 256 + *(pSrc + 13);
1877 
1878 	/* */
1879 	/* Check DHCP & BOOTP protocol */
1880 	/* */
1881 	while (NumberOfBytesRead <= PacketInfo.TotalPacketLength) {
1882 		if ((NumberOfBytesRead >= 35) && (ReadFirstParm == TRUE)) {
1883 			CurrentOffset =
1884 			    35 - (NumberOfBytesRead - NdisBufferLength);
1885 			ByteOffset36 = *(pSrc + CurrentOffset);
1886 			ReadFirstParm = FALSE;
1887 		}
1888 
1889 		if (NumberOfBytesRead >= 37) {
1890 			CurrentOffset =
1891 			    37 - (NumberOfBytesRead - NdisBufferLength);
1892 			ByteOffset38 = *(pSrc + CurrentOffset);
1893 			/*End of Read */
1894 			break;
1895 		}
1896 		return FALSE;
1897 	}
1898 
1899 	/* Check for DHCP & BOOTP protocol */
1900 	if ((ByteOffset36 != 0x44) || (ByteOffset38 != 0x43)) {
1901 		/* */
1902 		/* 2054 (hex 0806) for ARP datagrams */
1903 		/* if this packet is not ARP datagrams, then do nothing */
1904 		/* ARP datagrams will also be duplicate at 1mb broadcast frames */
1905 		/* */
1906 		if (Protocol != 0x0806)
1907 			return FALSE;
1908 	}
1909 
1910 	return TRUE;
1911 }
1912 
RTMPCheckEtherType(struct rt_rtmp_adapter * pAd,void * pPacket)1913 BOOLEAN RTMPCheckEtherType(struct rt_rtmp_adapter *pAd, void *pPacket)
1914 {
1915 	u16 TypeLen;
1916 	u8 Byte0, Byte1;
1917 	u8 *pSrcBuf;
1918 	u32 pktLen;
1919 	u16 srcPort, dstPort;
1920 	BOOLEAN status = TRUE;
1921 
1922 	pSrcBuf = GET_OS_PKT_DATAPTR(pPacket);
1923 	pktLen = GET_OS_PKT_LEN(pPacket);
1924 
1925 	ASSERT(pSrcBuf);
1926 
1927 	RTMP_SET_PACKET_SPECIFIC(pPacket, 0);
1928 
1929 	/* get Ethernet protocol field */
1930 	TypeLen = (pSrcBuf[12] << 8) | pSrcBuf[13];
1931 
1932 	pSrcBuf += LENGTH_802_3;	/* Skip the Ethernet Header. */
1933 
1934 	if (TypeLen <= 1500) {	/* 802.3, 802.3 LLC */
1935 		/*
1936 		   DestMAC(6) + SrcMAC(6) + Length(2) +
1937 		   DSAP(1) + SSAP(1) + Control(1) +
1938 		   if the DSAP = 0xAA, SSAP=0xAA, Contorl = 0x03, it has a 5-bytes SNAP header.
1939 		   => + SNAP (5, OriginationID(3) + etherType(2))
1940 		 */
1941 		if (pSrcBuf[0] == 0xAA && pSrcBuf[1] == 0xAA
1942 		    && pSrcBuf[2] == 0x03) {
1943 			Sniff2BytesFromNdisBuffer((char *)pSrcBuf, 6,
1944 						  &Byte0, &Byte1);
1945 			RTMP_SET_PACKET_LLCSNAP(pPacket, 1);
1946 			TypeLen = (u16)((Byte0 << 8) + Byte1);
1947 			pSrcBuf += 8;	/* Skip this LLC/SNAP header */
1948 		} else {
1949 			/*It just has 3-byte LLC header, maybe a legacy ether type frame. we didn't handle it. */
1950 		}
1951 	}
1952 	/* If it's a VLAN packet, get the real Type/Length field. */
1953 	if (TypeLen == 0x8100) {
1954 		/* 0x8100 means VLAN packets */
1955 
1956 		/* Dest. MAC Address (6-bytes) +
1957 		   Source MAC Address (6-bytes) +
1958 		   Length/Type = 802.1Q Tag Type (2-byte) +
1959 		   Tag Control Information (2-bytes) +
1960 		   Length / Type (2-bytes) +
1961 		   data payload (0-n bytes) +
1962 		   Pad (0-p bytes) +
1963 		   Frame Check Sequence (4-bytes) */
1964 
1965 		RTMP_SET_PACKET_VLAN(pPacket, 1);
1966 		Sniff2BytesFromNdisBuffer((char *)pSrcBuf, 2, &Byte0,
1967 					  &Byte1);
1968 		TypeLen = (u16)((Byte0 << 8) + Byte1);
1969 
1970 		pSrcBuf += 4;	/* Skip the VLAN Header. */
1971 	}
1972 
1973 	switch (TypeLen) {
1974 	case 0x0800:
1975 		{
1976 			ASSERT((pktLen > 34));
1977 			if (*(pSrcBuf + 9) == 0x11) {	/* udp packet */
1978 				ASSERT((pktLen > 34));	/* 14 for ethernet header, 20 for IP header */
1979 
1980 				pSrcBuf += 20;	/* Skip the IP header */
1981 				srcPort =
1982 				    OS_NTOHS(get_unaligned
1983 					     ((u16 *)(pSrcBuf)));
1984 				dstPort =
1985 				    OS_NTOHS(get_unaligned
1986 					     ((u16 *)(pSrcBuf + 2)));
1987 
1988 				if ((srcPort == 0x44 && dstPort == 0x43) || (srcPort == 0x43 && dstPort == 0x44)) {	/*It's a BOOTP/DHCP packet */
1989 					RTMP_SET_PACKET_DHCP(pPacket, 1);
1990 				}
1991 			}
1992 		}
1993 		break;
1994 	case 0x0806:
1995 		{
1996 			/*ARP Packet. */
1997 			RTMP_SET_PACKET_DHCP(pPacket, 1);
1998 		}
1999 		break;
2000 	case 0x888e:
2001 		{
2002 			/* EAPOL Packet. */
2003 			RTMP_SET_PACKET_EAPOL(pPacket, 1);
2004 		}
2005 		break;
2006 	default:
2007 		status = FALSE;
2008 		break;
2009 	}
2010 
2011 	return status;
2012 
2013 }
2014 
Update_Rssi_Sample(struct rt_rtmp_adapter * pAd,struct rt_rssi_sample * pRssi,struct rt_rxwi * pRxWI)2015 void Update_Rssi_Sample(struct rt_rtmp_adapter *pAd,
2016 			struct rt_rssi_sample *pRssi, struct rt_rxwi * pRxWI)
2017 {
2018 	char rssi0 = pRxWI->RSSI0;
2019 	char rssi1 = pRxWI->RSSI1;
2020 	char rssi2 = pRxWI->RSSI2;
2021 
2022 	if (rssi0 != 0) {
2023 		pRssi->LastRssi0 = ConvertToRssi(pAd, (char)rssi0, RSSI_0);
2024 		pRssi->AvgRssi0X8 =
2025 		    (pRssi->AvgRssi0X8 - pRssi->AvgRssi0) + pRssi->LastRssi0;
2026 		pRssi->AvgRssi0 = pRssi->AvgRssi0X8 >> 3;
2027 	}
2028 
2029 	if (rssi1 != 0) {
2030 		pRssi->LastRssi1 = ConvertToRssi(pAd, (char)rssi1, RSSI_1);
2031 		pRssi->AvgRssi1X8 =
2032 		    (pRssi->AvgRssi1X8 - pRssi->AvgRssi1) + pRssi->LastRssi1;
2033 		pRssi->AvgRssi1 = pRssi->AvgRssi1X8 >> 3;
2034 	}
2035 
2036 	if (rssi2 != 0) {
2037 		pRssi->LastRssi2 = ConvertToRssi(pAd, (char)rssi2, RSSI_2);
2038 		pRssi->AvgRssi2X8 =
2039 		    (pRssi->AvgRssi2X8 - pRssi->AvgRssi2) + pRssi->LastRssi2;
2040 		pRssi->AvgRssi2 = pRssi->AvgRssi2X8 >> 3;
2041 	}
2042 }
2043 
2044 /* Normal legacy Rx packet indication */
Indicate_Legacy_Packet(struct rt_rtmp_adapter * pAd,struct rt_rx_blk * pRxBlk,u8 FromWhichBSSID)2045 void Indicate_Legacy_Packet(struct rt_rtmp_adapter *pAd,
2046 			    struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
2047 {
2048 	void *pRxPacket = pRxBlk->pRxPacket;
2049 	u8 Header802_3[LENGTH_802_3];
2050 
2051 	/* 1. get 802.3 Header */
2052 	/* 2. remove LLC */
2053 	/*              a. pointer pRxBlk->pData to payload */
2054 	/*      b. modify pRxBlk->DataSize */
2055 	RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
2056 
2057 	if (pRxBlk->DataSize > MAX_RX_PKT_LEN) {
2058 
2059 		/* release packet */
2060 		RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
2061 		return;
2062 	}
2063 
2064 	STATS_INC_RX_PACKETS(pAd, FromWhichBSSID);
2065 
2066 #ifdef RTMP_MAC_USB
2067 	if (pAd->CommonCfg.bDisableReordering == 0) {
2068 		struct rt_ba_rec_entry *pBAEntry;
2069 		unsigned long Now32;
2070 		u8 Wcid = pRxBlk->pRxWI->WirelessCliID;
2071 		u8 TID = pRxBlk->pRxWI->TID;
2072 		u16 Idx;
2073 
2074 #define REORDERING_PACKET_TIMEOUT		((100 * OS_HZ)/1000)	/* system ticks -- 100 ms */
2075 
2076 		if (Wcid < MAX_LEN_OF_MAC_TABLE) {
2077 			Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
2078 			if (Idx != 0) {
2079 				pBAEntry = &pAd->BATable.BARecEntry[Idx];
2080 				/* update last rx time */
2081 				NdisGetSystemUpTime(&Now32);
2082 				if ((pBAEntry->list.qlen > 0) &&
2083 				    RTMP_TIME_AFTER((unsigned long)Now32,
2084 						    (unsigned long)(pBAEntry->
2085 								    LastIndSeqAtTimer
2086 								    +
2087 								    (REORDERING_PACKET_TIMEOUT)))
2088 				    ) {
2089 					DBGPRINT(RT_DEBUG_OFF,
2090 						 ("Indicate_Legacy_Packet():flush reordering_timeout_mpdus! RxWI->Flags=%d, pRxWI.TID=%d, RxD->AMPDU=%d!\n",
2091 						  pRxBlk->Flags,
2092 						  pRxBlk->pRxWI->TID,
2093 						  pRxBlk->RxD.AMPDU));
2094 					hex_dump("Dump the legacy Packet:",
2095 						 GET_OS_PKT_DATAPTR(pRxBlk->
2096 								    pRxPacket),
2097 						 64);
2098 					ba_flush_reordering_timeout_mpdus(pAd,
2099 									  pBAEntry,
2100 									  Now32);
2101 				}
2102 			}
2103 		}
2104 	}
2105 #endif /* RTMP_MAC_USB // */
2106 
2107 	wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
2108 
2109 	/* */
2110 	/* pass this 802.3 packet to upper layer or forward this packet to WM directly */
2111 	/* */
2112 	ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxPacket, FromWhichBSSID);
2113 }
2114 
2115 /* Normal, AMPDU or AMSDU */
CmmRxnonRalinkFrameIndicate(struct rt_rtmp_adapter * pAd,struct rt_rx_blk * pRxBlk,u8 FromWhichBSSID)2116 void CmmRxnonRalinkFrameIndicate(struct rt_rtmp_adapter *pAd,
2117 				 struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
2118 {
2119 	if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU)
2120 	    && (pAd->CommonCfg.bDisableReordering == 0)) {
2121 		Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID);
2122 	} else {
2123 		if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU)) {
2124 			/* handle A-MSDU */
2125 			Indicate_AMSDU_Packet(pAd, pRxBlk, FromWhichBSSID);
2126 		} else {
2127 			Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
2128 		}
2129 	}
2130 }
2131 
CmmRxRalinkFrameIndicate(struct rt_rtmp_adapter * pAd,struct rt_mac_table_entry * pEntry,struct rt_rx_blk * pRxBlk,u8 FromWhichBSSID)2132 void CmmRxRalinkFrameIndicate(struct rt_rtmp_adapter *pAd,
2133 			      struct rt_mac_table_entry *pEntry,
2134 			      struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
2135 {
2136 	u8 Header802_3[LENGTH_802_3];
2137 	u16 Msdu2Size;
2138 	u16 Payload1Size, Payload2Size;
2139 	u8 *pData2;
2140 	void *pPacket2 = NULL;
2141 
2142 	Msdu2Size = *(pRxBlk->pData) + (*(pRxBlk->pData + 1) << 8);
2143 
2144 	if ((Msdu2Size <= 1536) && (Msdu2Size < pRxBlk->DataSize)) {
2145 		/* skip two byte MSDU2 len */
2146 		pRxBlk->pData += 2;
2147 		pRxBlk->DataSize -= 2;
2148 	} else {
2149 		/* release packet */
2150 		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket,
2151 				    NDIS_STATUS_FAILURE);
2152 		return;
2153 	}
2154 
2155 	/* get 802.3 Header and  remove LLC */
2156 	RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
2157 
2158 	ASSERT(pRxBlk->pRxPacket);
2159 
2160 	/* Ralink Aggregation frame */
2161 	pAd->RalinkCounters.OneSecRxAggregationCount++;
2162 	Payload1Size = pRxBlk->DataSize - Msdu2Size;
2163 	Payload2Size = Msdu2Size - LENGTH_802_3;
2164 
2165 	pData2 = pRxBlk->pData + Payload1Size + LENGTH_802_3;
2166 
2167 	pPacket2 =
2168 	    duplicate_pkt(pAd, (pData2 - LENGTH_802_3), LENGTH_802_3, pData2,
2169 			  Payload2Size, FromWhichBSSID);
2170 
2171 	if (!pPacket2) {
2172 		/* release packet */
2173 		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket,
2174 				    NDIS_STATUS_FAILURE);
2175 		return;
2176 	}
2177 	/* update payload size of 1st packet */
2178 	pRxBlk->DataSize = Payload1Size;
2179 	wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
2180 
2181 	ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxBlk->pRxPacket,
2182 					 FromWhichBSSID);
2183 
2184 	if (pPacket2) {
2185 		ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket2, FromWhichBSSID);
2186 	}
2187 }
2188 
2189 #define RESET_FRAGFRAME(_fragFrame) \
2190 	{								\
2191 		_fragFrame.RxSize = 0;		\
2192 		_fragFrame.Sequence = 0;	\
2193 		_fragFrame.LastFrag = 0;	\
2194 		_fragFrame.Flags = 0;		\
2195 	}
2196 
RTMPDeFragmentDataFrame(struct rt_rtmp_adapter * pAd,struct rt_rx_blk * pRxBlk)2197 void *RTMPDeFragmentDataFrame(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk)
2198 {
2199 	struct rt_header_802_11 * pHeader = pRxBlk->pHeader;
2200 	void *pRxPacket = pRxBlk->pRxPacket;
2201 	u8 *pData = pRxBlk->pData;
2202 	u16 DataSize = pRxBlk->DataSize;
2203 	void *pRetPacket = NULL;
2204 	u8 *pFragBuffer = NULL;
2205 	BOOLEAN bReassDone = FALSE;
2206 	u8 HeaderRoom = 0;
2207 
2208 	ASSERT(pHeader);
2209 
2210 	HeaderRoom = pData - (u8 *) pHeader;
2211 
2212 	/* Re-assemble the fragmented packets */
2213 	if (pHeader->Frag == 0)	/* Frag. Number is 0 : First frag or only one pkt */
2214 	{
2215 		/* the first pkt of fragment, record it. */
2216 		if (pHeader->FC.MoreFrag) {
2217 			ASSERT(pAd->FragFrame.pFragPacket);
2218 			pFragBuffer =
2219 			    GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
2220 			pAd->FragFrame.RxSize = DataSize + HeaderRoom;
2221 			NdisMoveMemory(pFragBuffer, pHeader,
2222 				       pAd->FragFrame.RxSize);
2223 			pAd->FragFrame.Sequence = pHeader->Sequence;
2224 			pAd->FragFrame.LastFrag = pHeader->Frag;	/* Should be 0 */
2225 			ASSERT(pAd->FragFrame.LastFrag == 0);
2226 			goto done;	/* end of processing this frame */
2227 		}
2228 	} else			/*Middle & End of fragment */
2229 	{
2230 		if ((pHeader->Sequence != pAd->FragFrame.Sequence) ||
2231 		    (pHeader->Frag != (pAd->FragFrame.LastFrag + 1))) {
2232 			/* Fragment is not the same sequence or out of fragment number order */
2233 			/* Reset Fragment control blk */
2234 			RESET_FRAGFRAME(pAd->FragFrame);
2235 			DBGPRINT(RT_DEBUG_ERROR,
2236 				 ("Fragment is not the same sequence or out of fragment number order.\n"));
2237 			goto done;	/* give up this frame */
2238 		} else if ((pAd->FragFrame.RxSize + DataSize) > MAX_FRAME_SIZE) {
2239 			/* Fragment frame is too large, it exeeds the maximum frame size. */
2240 			/* Reset Fragment control blk */
2241 			RESET_FRAGFRAME(pAd->FragFrame);
2242 			DBGPRINT(RT_DEBUG_ERROR,
2243 				 ("Fragment frame is too large, it exeeds the maximum frame size.\n"));
2244 			goto done;	/* give up this frame */
2245 		}
2246 		/* */
2247 		/* Broadcom AP(BCM94704AGR) will send out LLC in fragment's packet, LLC only can accpet at first fragment. */
2248 		/* In this case, we will dropt it. */
2249 		/* */
2250 		if (NdisEqualMemory(pData, SNAP_802_1H, sizeof(SNAP_802_1H))) {
2251 			DBGPRINT(RT_DEBUG_ERROR,
2252 				 ("Find another LLC at Middle or End fragment(SN=%d, Frag=%d)\n",
2253 				  pHeader->Sequence, pHeader->Frag));
2254 			goto done;	/* give up this frame */
2255 		}
2256 
2257 		pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
2258 
2259 		/* concatenate this fragment into the re-assembly buffer */
2260 		NdisMoveMemory((pFragBuffer + pAd->FragFrame.RxSize), pData,
2261 			       DataSize);
2262 		pAd->FragFrame.RxSize += DataSize;
2263 		pAd->FragFrame.LastFrag = pHeader->Frag;	/* Update fragment number */
2264 
2265 		/* Last fragment */
2266 		if (pHeader->FC.MoreFrag == FALSE) {
2267 			bReassDone = TRUE;
2268 		}
2269 	}
2270 
2271 done:
2272 	/* always release rx fragmented packet */
2273 	RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
2274 
2275 	/* return defragmented packet if packet is reassembled completely */
2276 	/* otherwise return NULL */
2277 	if (bReassDone) {
2278 		void *pNewFragPacket;
2279 
2280 		/* allocate a new packet buffer for fragment */
2281 		pNewFragPacket =
2282 		    RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
2283 		if (pNewFragPacket) {
2284 			/* update RxBlk */
2285 			pRetPacket = pAd->FragFrame.pFragPacket;
2286 			pAd->FragFrame.pFragPacket = pNewFragPacket;
2287 			pRxBlk->pHeader =
2288 			    (struct rt_header_802_11 *) GET_OS_PKT_DATAPTR(pRetPacket);
2289 			pRxBlk->pData = (u8 *) pRxBlk->pHeader + HeaderRoom;
2290 			pRxBlk->DataSize = pAd->FragFrame.RxSize - HeaderRoom;
2291 			pRxBlk->pRxPacket = pRetPacket;
2292 		} else {
2293 			RESET_FRAGFRAME(pAd->FragFrame);
2294 		}
2295 	}
2296 
2297 	return pRetPacket;
2298 }
2299 
Indicate_AMSDU_Packet(struct rt_rtmp_adapter * pAd,struct rt_rx_blk * pRxBlk,u8 FromWhichBSSID)2300 void Indicate_AMSDU_Packet(struct rt_rtmp_adapter *pAd,
2301 			   struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
2302 {
2303 	u32 nMSDU;
2304 
2305 	update_os_packet_info(pAd, pRxBlk, FromWhichBSSID);
2306 	RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID);
2307 	nMSDU =
2308 	    deaggregate_AMSDU_announce(pAd, pRxBlk->pRxPacket, pRxBlk->pData,
2309 				       pRxBlk->DataSize);
2310 }
2311 
Indicate_EAPOL_Packet(struct rt_rtmp_adapter * pAd,struct rt_rx_blk * pRxBlk,u8 FromWhichBSSID)2312 void Indicate_EAPOL_Packet(struct rt_rtmp_adapter *pAd,
2313 			   struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
2314 {
2315 	struct rt_mac_table_entry *pEntry = NULL;
2316 
2317 	{
2318 		pEntry = &pAd->MacTab.Content[BSSID_WCID];
2319 		STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
2320 		return;
2321 	}
2322 
2323 	if (pEntry == NULL) {
2324 		DBGPRINT(RT_DEBUG_WARN,
2325 			 ("Indicate_EAPOL_Packet: drop and release the invalid packet.\n"));
2326 		/* release packet */
2327 		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket,
2328 				    NDIS_STATUS_FAILURE);
2329 		return;
2330 	}
2331 }
2332 
2333 #define BCN_TBTT_OFFSET		64	/*defer 64 us */
ReSyncBeaconTime(struct rt_rtmp_adapter * pAd)2334 void ReSyncBeaconTime(struct rt_rtmp_adapter *pAd)
2335 {
2336 
2337 	u32 Offset;
2338 
2339 	Offset = (pAd->TbttTickCount) % (BCN_TBTT_OFFSET);
2340 
2341 	pAd->TbttTickCount++;
2342 
2343 	/* */
2344 	/* The updated BeaconInterval Value will affect Beacon Interval after two TBTT */
2345 	/* beacasue the original BeaconInterval had been loaded into next TBTT_TIMER */
2346 	/* */
2347 	if (Offset == (BCN_TBTT_OFFSET - 2)) {
2348 		BCN_TIME_CFG_STRUC csr;
2349 		RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
2350 		csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod << 4) - 1;	/* ASIC register in units of 1/16 TU = 64us */
2351 		RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
2352 	} else {
2353 		if (Offset == (BCN_TBTT_OFFSET - 1)) {
2354 			BCN_TIME_CFG_STRUC csr;
2355 
2356 			RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
2357 			csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod) << 4;	/* ASIC register in units of 1/16 TU */
2358 			RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
2359 		}
2360 	}
2361 }
2362