2 *************************************************************************
4 * 5F., No.36, Taiyuan St., Jhubei City,
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 *************************************************************************
34 -------- ---------- ----------------------------------------------
35 John Chang 2004-09-01 add WMM support
36 Justin P. Mattock 11/07/2010 Fix typos
38 #include "../rt_config.h"
40 extern u8 CISCO_OUI[];
44 extern u8 WME_INFO_ELEM[];
45 extern u8 WME_PARM_ELEM[];
46 extern u8 Ccx2QosInfo[];
47 extern u8 RALINK_OUI[];
48 extern u8 BROADCOM_OUI[];
51 ==========================================================================
53 MLME message sanity check
55 TRUE if all parameters are OK, FALSE otherwise
56 ==========================================================================
58 BOOLEAN MlmeStartReqSanity(struct rt_rtmp_adapter *pAd,
61 char Ssid[], u8 * pSsidLen)
63 struct rt_mlme_start_req *Info;
65 Info = (struct rt_mlme_start_req *)(Msg);
67 if (Info->SsidLen > MAX_LEN_OF_SSID) {
68 DBGPRINT(RT_DEBUG_TRACE,
69 ("MlmeStartReqSanity fail - wrong SSID length\n"));
73 *pSsidLen = Info->SsidLen;
74 NdisMoveMemory(Ssid, Info->Ssid, *pSsidLen);
80 ==========================================================================
82 MLME message sanity check
84 TRUE if all parameters are OK, FALSE otherwise
88 ==========================================================================
90 BOOLEAN PeerAssocRspSanity(struct rt_rtmp_adapter *pAd, void * pMsg, unsigned long MsgLen, u8 *pAddr2, u16 * pCapabilityInfo, u16 * pStatus, u16 * pAid, u8 SupRate[], u8 * pSupRateLen, u8 ExtRate[], u8 * pExtRateLen, struct rt_ht_capability_ie * pHtCapability, struct rt_add_ht_info_ie * pAddHtInfo, /* AP might use this additional ht info IE */
91 u8 * pHtCapabilityLen,
93 u8 * pNewExtChannelOffset,
94 struct rt_edca_parm *pEdcaParm, u8 * pCkipFlag)
97 struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *) pMsg;
99 unsigned long Length = 0;
101 *pNewExtChannelOffset = 0xff;
102 *pHtCapabilityLen = 0;
104 COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
105 Ptr = (char *)pFrame->Octet;
106 Length += LENGTH_802_11;
108 NdisMoveMemory(pCapabilityInfo, &pFrame->Octet[0], 2);
110 NdisMoveMemory(pStatus, &pFrame->Octet[2], 2);
114 pEdcaParm->bValid = FALSE;
116 if (*pStatus != MLME_SUCCESS)
119 NdisMoveMemory(pAid, &pFrame->Octet[4], 2);
122 /* Aid already swapped byte order in RTMPFrameEndianChange() for big endian platform */
123 *pAid = (*pAid) & 0x3fff; /* AID is low 14-bit */
125 /* -- get supported rates from payload and advance the pointer */
126 IeType = pFrame->Octet[6];
127 *pSupRateLen = pFrame->Octet[7];
128 if ((IeType != IE_SUPP_RATES)
129 || (*pSupRateLen > MAX_LEN_OF_SUPPORTED_RATES)) {
130 DBGPRINT(RT_DEBUG_TRACE,
131 ("PeerAssocRspSanity fail - wrong SupportedRates IE\n"));
134 NdisMoveMemory(SupRate, &pFrame->Octet[8], *pSupRateLen);
136 Length = Length + 2 + *pSupRateLen;
138 /* many AP implement proprietary IEs in non-standard order, we'd better */
139 /* tolerate mis-ordered IEs to get best compatibility */
140 pEid = (struct rt_eid *) & pFrame->Octet[8 + (*pSupRateLen)];
142 /* get variable fields from payload and advance the pointer */
143 while ((Length + 2 + pEid->Len) <= MsgLen) {
145 case IE_EXT_SUPP_RATES:
146 if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES) {
147 NdisMoveMemory(ExtRate, pEid->Octet, pEid->Len);
148 *pExtRateLen = pEid->Len;
154 if (pEid->Len >= SIZE_HT_CAP_IE) /*Note: allow extension! */
156 NdisMoveMemory(pHtCapability, pEid->Octet,
159 *(u16 *) (&pHtCapability->HtCapInfo) =
161 (&pHtCapability->HtCapInfo));
162 *(u16 *) (&pHtCapability->ExtHtCapInfo) =
164 (&pHtCapability->ExtHtCapInfo));
166 *pHtCapabilityLen = SIZE_HT_CAP_IE;
168 DBGPRINT(RT_DEBUG_WARN,
169 ("PeerAssocRspSanity - wrong IE_HT_CAP. \n"));
175 if (pEid->Len >= sizeof(struct rt_add_ht_info_ie)) {
176 /* This IE allows extension, but we can ignore extra bytes beyond our knowledge , so only */
177 /* copy first sizeof(struct rt_add_ht_info_ie) */
178 NdisMoveMemory(pAddHtInfo, pEid->Octet,
179 sizeof(struct rt_add_ht_info_ie));
181 *(u16 *) (&pAddHtInfo->AddHtInfo2) =
183 (&pAddHtInfo->AddHtInfo2));
184 *(u16 *) (&pAddHtInfo->AddHtInfo3) =
186 (&pAddHtInfo->AddHtInfo3));
188 *pAddHtInfoLen = SIZE_ADD_HT_INFO_IE;
190 DBGPRINT(RT_DEBUG_WARN,
191 ("PeerAssocRspSanity - wrong IE_ADD_HT. \n"));
195 case IE_SECONDARY_CH_OFFSET:
196 if (pEid->Len == 1) {
197 *pNewExtChannelOffset = pEid->Octet[0];
199 DBGPRINT(RT_DEBUG_WARN,
200 ("PeerAssocRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n"));
204 case IE_VENDOR_SPECIFIC:
205 /* handle WME PARAMTER ELEMENT */
206 if (NdisEqualMemory(pEid->Octet, WME_PARM_ELEM, 6)
207 && (pEid->Len == 24)) {
211 /* parsing EDCA parameters */
212 pEdcaParm->bValid = TRUE;
213 pEdcaParm->bQAck = FALSE; /* pEid->Octet[0] & 0x10; */
214 pEdcaParm->bQueueRequest = FALSE; /* pEid->Octet[0] & 0x20; */
215 pEdcaParm->bTxopRequest = FALSE; /* pEid->Octet[0] & 0x40; */
216 /*pEdcaParm->bMoreDataAck = FALSE; // pEid->Octet[0] & 0x80; */
217 pEdcaParm->EdcaUpdateCount =
218 pEid->Octet[6] & 0x0f;
219 pEdcaParm->bAPSDCapable =
220 (pEid->Octet[6] & 0x80) ? 1 : 0;
221 ptr = (u8 *)& pEid->Octet[8];
222 for (i = 0; i < 4; i++) {
223 u8 aci = (*ptr & 0x60) >> 5; /* b5~6 is AC INDEX */
224 pEdcaParm->bACM[aci] = (((*ptr) & 0x10) == 0x10); /* b5 is ACM */
225 pEdcaParm->Aifsn[aci] = (*ptr) & 0x0f; /* b0~3 is AIFSN */
226 pEdcaParm->Cwmin[aci] = *(ptr + 1) & 0x0f; /* b0~4 is Cwmin */
227 pEdcaParm->Cwmax[aci] = *(ptr + 1) >> 4; /* b5~8 is Cwmax */
228 pEdcaParm->Txop[aci] = *(ptr + 2) + 256 * (*(ptr + 3)); /* in unit of 32-us */
229 ptr += 4; /* point to next AC */
234 DBGPRINT(RT_DEBUG_TRACE,
235 ("PeerAssocRspSanity - ignore unrecognized EID = %d\n",
240 Length = Length + 2 + pEid->Len;
241 pEid = (struct rt_eid *) ((u8 *) pEid + 2 + pEid->Len);
248 ==========================================================================
250 MLME message sanity check
252 TRUE if all parameters are OK, FALSE otherwise
254 IRQL = DISPATCH_LEVEL
256 ==========================================================================
258 BOOLEAN PeerProbeReqSanity(struct rt_rtmp_adapter *pAd,
260 unsigned long MsgLen,
262 char Ssid[], u8 * pSsidLen)
267 struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *) Msg;
269 COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
271 if ((pFrame->Octet[0] != IE_SSID)
272 || (pFrame->Octet[1] > MAX_LEN_OF_SSID)) {
273 DBGPRINT(RT_DEBUG_TRACE,
274 ("PeerProbeReqSanity fail - wrong SSID IE(Type=%d,Len=%d)\n",
275 pFrame->Octet[0], pFrame->Octet[1]));
279 *pSsidLen = pFrame->Octet[1];
280 NdisMoveMemory(Ssid, &pFrame->Octet[2], *pSsidLen);
284 /* -- get supported rates from payload and advance the pointer */
285 IeType = pFrame->Octet[Idx];
286 RateLen = pFrame->Octet[Idx + 1];
287 if (IeType != IE_SUPP_RATES) {
288 DBGPRINT(RT_DEBUG_TRACE,
289 ("PeerProbeReqSanity fail - wrong SupportRates IE(Type=%d,Len=%d)\n",
290 pFrame->Octet[Idx], pFrame->Octet[Idx + 1]));
293 if ((pAd->CommonCfg.PhyMode == PHY_11G) && (RateLen < 8))
301 ==========================================================================
304 IRQL = DISPATCH_LEVEL
306 ==========================================================================
308 BOOLEAN GetTimBit(char * Ptr,
313 u8 * DtimPeriod, u8 * MessageToMe)
315 u8 BitCntl, N1, N2, MyByte, MyBit;
323 /* get DTIM Count from TIM element */
325 *DtimCount = *IdxPtr;
327 /* get DTIM Period from TIM element */
329 *DtimPeriod = *IdxPtr;
331 /* get Bitmap Control from TIM element */
335 if ((*DtimCount == 0) && (BitCntl & 0x01))
340 /* Parse Partial Virtual Bitmap from TIM element */
341 N1 = BitCntl & 0xfe; /* N1 is the first bitmap byte# */
342 N2 = *TimLen - 4 + N1; /* N2 is the last bitmap byte# */
344 if ((Aid < (N1 << 3)) || (Aid >= ((N2 + 1) << 3)))
345 *MessageToMe = FALSE;
347 MyByte = (Aid >> 3) - N1; /* my byte position in the bitmap byte-stream */
348 MyBit = Aid % 16 - ((MyByte & 0x01) ? 8 : 0);
350 IdxPtr += (MyByte + 1);
353 /* DBGPRINT(RT_DEBUG_WARN, ("TIM bitmap = 0x%02x\n", *IdxPtr)); */
355 if (*IdxPtr & (0x01 << MyBit))
358 *MessageToMe = FALSE;