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
37 #include "../rt_config.h"
39 extern UCHAR CISCO_OUI
[];
41 extern UCHAR WPA_OUI
[];
42 extern UCHAR RSN_OUI
[];
43 extern UCHAR WME_INFO_ELEM
[];
44 extern UCHAR WME_PARM_ELEM
[];
45 extern UCHAR Ccx2QosInfo
[];
46 extern UCHAR RALINK_OUI
[];
47 extern UCHAR BROADCOM_OUI
[];
50 ==========================================================================
52 MLME message sanity check
54 TRUE if all parameters are OK, FALSE otherwise
55 ==========================================================================
57 BOOLEAN
MlmeStartReqSanity(
64 MLME_START_REQ_STRUCT
*Info
;
66 Info
= (MLME_START_REQ_STRUCT
*)(Msg
);
68 if (Info
->SsidLen
> MAX_LEN_OF_SSID
)
70 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeStartReqSanity fail - wrong SSID length\n"));
74 *pSsidLen
= Info
->SsidLen
;
75 NdisMoveMemory(Ssid
, Info
->Ssid
, *pSsidLen
);
81 ==========================================================================
83 MLME message sanity check
85 TRUE if all parameters are OK, FALSE otherwise
89 ==========================================================================
91 BOOLEAN
PeerAssocRspSanity(
96 OUT USHORT
*pCapabilityInfo
,
100 OUT UCHAR
*pSupRateLen
,
102 OUT UCHAR
*pExtRateLen
,
103 OUT HT_CAPABILITY_IE
*pHtCapability
,
104 OUT ADD_HT_INFO_IE
*pAddHtInfo
, // AP might use this additional ht info IE
105 OUT UCHAR
*pHtCapabilityLen
,
106 OUT UCHAR
*pAddHtInfoLen
,
107 OUT UCHAR
*pNewExtChannelOffset
,
108 OUT PEDCA_PARM pEdcaParm
,
109 OUT UCHAR
*pCkipFlag
)
112 PFRAME_802_11 pFrame
= (PFRAME_802_11
)pMsg
;
116 *pNewExtChannelOffset
= 0xff;
117 *pHtCapabilityLen
= 0;
119 COPY_MAC_ADDR(pAddr2
, pFrame
->Hdr
.Addr2
);
121 Length
+= LENGTH_802_11
;
123 NdisMoveMemory(pCapabilityInfo
, &pFrame
->Octet
[0], 2);
125 NdisMoveMemory(pStatus
, &pFrame
->Octet
[2], 2);
129 pEdcaParm
->bValid
= FALSE
;
131 if (*pStatus
!= MLME_SUCCESS
)
134 NdisMoveMemory(pAid
, &pFrame
->Octet
[4], 2);
137 // Aid already swaped byte order in RTMPFrameEndianChange() for big endian platform
138 *pAid
= (*pAid
) & 0x3fff; // AID is low 14-bit
140 // -- get supported rates from payload and advance the pointer
141 IeType
= pFrame
->Octet
[6];
142 *pSupRateLen
= pFrame
->Octet
[7];
143 if ((IeType
!= IE_SUPP_RATES
) || (*pSupRateLen
> MAX_LEN_OF_SUPPORTED_RATES
))
145 DBGPRINT(RT_DEBUG_TRACE
, ("PeerAssocRspSanity fail - wrong SupportedRates IE\n"));
149 NdisMoveMemory(SupRate
, &pFrame
->Octet
[8], *pSupRateLen
);
151 Length
= Length
+ 2 + *pSupRateLen
;
153 // many AP implement proprietary IEs in non-standard order, we'd better
154 // tolerate mis-ordered IEs to get best compatibility
155 pEid
= (PEID_STRUCT
) &pFrame
->Octet
[8 + (*pSupRateLen
)];
157 // get variable fields from payload and advance the pointer
158 while ((Length
+ 2 + pEid
->Len
) <= MsgLen
)
162 case IE_EXT_SUPP_RATES
:
163 if (pEid
->Len
<= MAX_LEN_OF_SUPPORTED_RATES
)
165 NdisMoveMemory(ExtRate
, pEid
->Octet
, pEid
->Len
);
166 *pExtRateLen
= pEid
->Len
;
172 if (pEid
->Len
>= SIZE_HT_CAP_IE
) //Note: allow extension.!!
174 NdisMoveMemory(pHtCapability
, pEid
->Octet
, SIZE_HT_CAP_IE
);
176 *(USHORT
*)(&pHtCapability
->HtCapInfo
) = cpu2le16(*(USHORT
*)(&pHtCapability
->HtCapInfo
));
177 *(USHORT
*)(&pHtCapability
->ExtHtCapInfo
) = cpu2le16(*(USHORT
*)(&pHtCapability
->ExtHtCapInfo
));
179 *pHtCapabilityLen
= SIZE_HT_CAP_IE
;
183 DBGPRINT(RT_DEBUG_WARN
, ("PeerAssocRspSanity - wrong IE_HT_CAP. \n"));
189 if (pEid
->Len
>= sizeof(ADD_HT_INFO_IE
))
191 // This IE allows extension, but we can ignore extra bytes beyond our knowledge , so only
192 // copy first sizeof(ADD_HT_INFO_IE)
193 NdisMoveMemory(pAddHtInfo
, pEid
->Octet
, sizeof(ADD_HT_INFO_IE
));
195 *(USHORT
*)(&pAddHtInfo
->AddHtInfo2
) = cpu2le16(*(USHORT
*)(&pAddHtInfo
->AddHtInfo2
));
196 *(USHORT
*)(&pAddHtInfo
->AddHtInfo3
) = cpu2le16(*(USHORT
*)(&pAddHtInfo
->AddHtInfo3
));
198 *pAddHtInfoLen
= SIZE_ADD_HT_INFO_IE
;
202 DBGPRINT(RT_DEBUG_WARN
, ("PeerAssocRspSanity - wrong IE_ADD_HT. \n"));
206 case IE_SECONDARY_CH_OFFSET
:
209 *pNewExtChannelOffset
= pEid
->Octet
[0];
213 DBGPRINT(RT_DEBUG_WARN
, ("PeerAssocRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n"));
216 case IE_AIRONET_CKIP
:
217 // 0. Check Aironet IE length, it must be larger or equal to 28
218 // Cisco's AP VxWork version(will not be supported) used this IE length as 28
219 // Cisco's AP IOS version used this IE length as 30
220 if (pEid
->Len
< (CKIP_NEGOTIATION_LENGTH
- 2))
223 // 1. Copy CKIP flag byte to buffer for process
224 *pCkipFlag
= *(pEid
->Octet
+ 8);
227 case IE_AIRONET_IPADDRESS
:
228 if (pEid
->Len
!= 0x0A)
231 // Get Cisco Aironet IP information
232 if (NdisEqualMemory(pEid
->Octet
, CISCO_OUI
, 3) == 1)
233 NdisMoveMemory(pAd
->StaCfg
.AironetIPAddress
, pEid
->Octet
+ 4, 4);
236 // CCX2, WMM use the same IE value
238 case IE_VENDOR_SPECIFIC
:
239 // handle WME PARAMTER ELEMENT
240 if (NdisEqualMemory(pEid
->Octet
, WME_PARM_ELEM
, 6) && (pEid
->Len
== 24))
245 // parsing EDCA parameters
246 pEdcaParm
->bValid
= TRUE
;
247 pEdcaParm
->bQAck
= FALSE
; // pEid->Octet[0] & 0x10;
248 pEdcaParm
->bQueueRequest
= FALSE
; // pEid->Octet[0] & 0x20;
249 pEdcaParm
->bTxopRequest
= FALSE
; // pEid->Octet[0] & 0x40;
250 //pEdcaParm->bMoreDataAck = FALSE; // pEid->Octet[0] & 0x80;
251 pEdcaParm
->EdcaUpdateCount
= pEid
->Octet
[6] & 0x0f;
252 pEdcaParm
->bAPSDCapable
= (pEid
->Octet
[6] & 0x80) ? 1 : 0;
253 ptr
= &pEid
->Octet
[8];
256 UCHAR aci
= (*ptr
& 0x60) >> 5; // b5~6 is AC INDEX
257 pEdcaParm
->bACM
[aci
] = (((*ptr
) & 0x10) == 0x10); // b5 is ACM
258 pEdcaParm
->Aifsn
[aci
] = (*ptr
) & 0x0f; // b0~3 is AIFSN
259 pEdcaParm
->Cwmin
[aci
] = *(ptr
+1) & 0x0f; // b0~4 is Cwmin
260 pEdcaParm
->Cwmax
[aci
] = *(ptr
+1) >> 4; // b5~8 is Cwmax
261 pEdcaParm
->Txop
[aci
] = *(ptr
+2) + 256 * (*(ptr
+3)); // in unit of 32-us
262 ptr
+= 4; // point to next AC
269 // 0. Check the size and CCX admin control
270 if (pAd
->StaCfg
.CCXControl
.field
.Enable
== 0)
275 // Turn CCX2 if matched
276 if (NdisEqualMemory(pEid
->Octet
, Ccx2IeInfo
, 5) == 1)
277 pAd
->StaCfg
.CCXEnable
= TRUE
;
283 DBGPRINT(RT_DEBUG_TRACE
, ("PeerAssocRspSanity - ignore unrecognized EID = %d\n", pEid
->Eid
));
287 Length
= Length
+ 2 + pEid
->Len
;
288 pEid
= (PEID_STRUCT
)((UCHAR
*)pEid
+ 2 + pEid
->Len
);
291 // Force CCX2 enable to TRUE for those AP didn't replay CCX v2 IE, we still force it to be on
292 if (pAd
->StaCfg
.CCXControl
.field
.Enable
== 1)
293 pAd
->StaCfg
.CCXEnable
= TRUE
;
299 ==========================================================================
301 MLME message sanity check
303 TRUE if all parameters are OK, FALSE otherwise
305 IRQL = DISPATCH_LEVEL
307 ==========================================================================
309 BOOLEAN
PeerProbeReqSanity(
310 IN PRTMP_ADAPTER pAd
,
320 PFRAME_802_11 pFrame
= (PFRAME_802_11
)Msg
;
322 COPY_MAC_ADDR(pAddr2
, pFrame
->Hdr
.Addr2
);
324 if ((pFrame
->Octet
[0] != IE_SSID
) || (pFrame
->Octet
[1] > MAX_LEN_OF_SSID
))
326 DBGPRINT(RT_DEBUG_TRACE
, ("PeerProbeReqSanity fail - wrong SSID IE(Type=%d,Len=%d)\n",pFrame
->Octet
[0],pFrame
->Octet
[1]));
330 *pSsidLen
= pFrame
->Octet
[1];
331 NdisMoveMemory(Ssid
, &pFrame
->Octet
[2], *pSsidLen
);
335 // -- get supported rates from payload and advance the pointer
336 IeType
= pFrame
->Octet
[Idx
];
337 RateLen
= pFrame
->Octet
[Idx
+ 1];
338 if (IeType
!= IE_SUPP_RATES
)
340 DBGPRINT(RT_DEBUG_TRACE
, ("PeerProbeReqSanity fail - wrong SupportRates IE(Type=%d,Len=%d)\n",pFrame
->Octet
[Idx
],pFrame
->Octet
[Idx
+1]));
345 if ((pAd
->CommonCfg
.PhyMode
== PHY_11G
) && (RateLen
< 8))
353 ==========================================================================
356 IRQL = DISPATCH_LEVEL
358 ==========================================================================
364 OUT UCHAR
*BcastFlag
,
365 OUT UCHAR
*DtimCount
,
366 OUT UCHAR
*DtimPeriod
,
367 OUT UCHAR
*MessageToMe
)
369 UCHAR BitCntl
, N1
, N2
, MyByte
, MyBit
;
377 // get DTIM Count from TIM element
379 *DtimCount
= *IdxPtr
;
381 // get DTIM Period from TIM element
383 *DtimPeriod
= *IdxPtr
;
385 // get Bitmap Control from TIM element
389 if ((*DtimCount
== 0) && (BitCntl
& 0x01))
394 // Parse Partial Virtual Bitmap from TIM element
395 N1
= BitCntl
& 0xfe; // N1 is the first bitmap byte#
396 N2
= *TimLen
- 4 + N1
; // N2 is the last bitmap byte#
398 if ((Aid
< (N1
<< 3)) || (Aid
>= ((N2
+ 1) << 3)))
399 *MessageToMe
= FALSE
;
402 MyByte
= (Aid
>> 3) - N1
; // my byte position in the bitmap byte-stream
403 MyBit
= Aid
% 16 - ((MyByte
& 0x01)? 8:0);
405 IdxPtr
+= (MyByte
+ 1);
408 // DBGPRINT(RT_DEBUG_WARN, ("TIM bitmap = 0x%02x\n", *IdxPtr));
410 if (*IdxPtr
& (0x01 << MyBit
))
413 *MessageToMe
= FALSE
;