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