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
38 #include "../rt_config.h"
41 extern UCHAR CISCO_OUI
[];
43 extern UCHAR WPA_OUI
[];
44 extern UCHAR RSN_OUI
[];
45 extern UCHAR WME_INFO_ELEM
[];
46 extern UCHAR WME_PARM_ELEM
[];
47 extern UCHAR Ccx2QosInfo
[];
48 extern UCHAR RALINK_OUI
[];
49 extern UCHAR BROADCOM_OUI
[];
52 ==========================================================================
54 MLME message sanity check
56 TRUE if all parameters are OK, FALSE otherwise
57 ==========================================================================
59 BOOLEAN
MlmeStartReqSanity(
66 MLME_START_REQ_STRUCT
*Info
;
68 Info
= (MLME_START_REQ_STRUCT
*)(Msg
);
70 if (Info
->SsidLen
> MAX_LEN_OF_SSID
)
72 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeStartReqSanity fail - wrong SSID length\n"));
76 *pSsidLen
= Info
->SsidLen
;
77 NdisMoveMemory(Ssid
, Info
->Ssid
, *pSsidLen
);
83 ==========================================================================
85 MLME message sanity check
87 TRUE if all parameters are OK, FALSE otherwise
91 ==========================================================================
93 BOOLEAN
PeerAssocRspSanity(
98 OUT USHORT
*pCapabilityInfo
,
102 OUT UCHAR
*pSupRateLen
,
104 OUT UCHAR
*pExtRateLen
,
105 OUT HT_CAPABILITY_IE
*pHtCapability
,
106 OUT ADD_HT_INFO_IE
*pAddHtInfo
, // AP might use this additional ht info IE
107 OUT UCHAR
*pHtCapabilityLen
,
108 OUT UCHAR
*pAddHtInfoLen
,
109 OUT UCHAR
*pNewExtChannelOffset
,
110 OUT PEDCA_PARM pEdcaParm
,
111 OUT UCHAR
*pCkipFlag
)
114 PFRAME_802_11 pFrame
= (PFRAME_802_11
)pMsg
;
118 *pNewExtChannelOffset
= 0xff;
119 *pHtCapabilityLen
= 0;
121 COPY_MAC_ADDR(pAddr2
, pFrame
->Hdr
.Addr2
);
122 Ptr
= (PCHAR
)pFrame
->Octet
;
123 Length
+= LENGTH_802_11
;
125 NdisMoveMemory(pCapabilityInfo
, &pFrame
->Octet
[0], 2);
127 NdisMoveMemory(pStatus
, &pFrame
->Octet
[2], 2);
131 pEdcaParm
->bValid
= FALSE
;
133 if (*pStatus
!= MLME_SUCCESS
)
136 NdisMoveMemory(pAid
, &pFrame
->Octet
[4], 2);
139 // Aid already swaped byte order in RTMPFrameEndianChange() for big endian platform
140 *pAid
= (*pAid
) & 0x3fff; // AID is low 14-bit
142 // -- get supported rates from payload and advance the pointer
143 IeType
= pFrame
->Octet
[6];
144 *pSupRateLen
= pFrame
->Octet
[7];
145 if ((IeType
!= IE_SUPP_RATES
) || (*pSupRateLen
> MAX_LEN_OF_SUPPORTED_RATES
))
147 DBGPRINT(RT_DEBUG_TRACE
, ("PeerAssocRspSanity fail - wrong SupportedRates IE\n"));
151 NdisMoveMemory(SupRate
, &pFrame
->Octet
[8], *pSupRateLen
);
154 Length
= Length
+ 2 + *pSupRateLen
;
156 // many AP implement proprietary IEs in non-standard order, we'd better
157 // tolerate mis-ordered IEs to get best compatibility
158 pEid
= (PEID_STRUCT
) &pFrame
->Octet
[8 + (*pSupRateLen
)];
160 // get variable fields from payload and advance the pointer
161 while ((Length
+ 2 + pEid
->Len
) <= MsgLen
)
165 case IE_EXT_SUPP_RATES
:
166 if (pEid
->Len
<= MAX_LEN_OF_SUPPORTED_RATES
)
168 NdisMoveMemory(ExtRate
, pEid
->Octet
, pEid
->Len
);
169 *pExtRateLen
= pEid
->Len
;
175 if (pEid
->Len
>= SIZE_HT_CAP_IE
) //Note: allow extension.!!
177 NdisMoveMemory(pHtCapability
, pEid
->Octet
, SIZE_HT_CAP_IE
);
179 *(USHORT
*)(&pHtCapability
->HtCapInfo
) = cpu2le16(*(USHORT
*)(&pHtCapability
->HtCapInfo
));
180 *(USHORT
*)(&pHtCapability
->ExtHtCapInfo
) = cpu2le16(*(USHORT
*)(&pHtCapability
->ExtHtCapInfo
));
182 *pHtCapabilityLen
= SIZE_HT_CAP_IE
;
186 DBGPRINT(RT_DEBUG_WARN
, ("PeerAssocRspSanity - wrong IE_HT_CAP. \n"));
190 #ifdef DOT11_N_SUPPORT
193 if (pEid
->Len
>= sizeof(ADD_HT_INFO_IE
))
195 // This IE allows extension, but we can ignore extra bytes beyond our knowledge , so only
196 // copy first sizeof(ADD_HT_INFO_IE)
197 NdisMoveMemory(pAddHtInfo
, pEid
->Octet
, sizeof(ADD_HT_INFO_IE
));
199 *(USHORT
*)(&pAddHtInfo
->AddHtInfo2
) = cpu2le16(*(USHORT
*)(&pAddHtInfo
->AddHtInfo2
));
200 *(USHORT
*)(&pAddHtInfo
->AddHtInfo3
) = cpu2le16(*(USHORT
*)(&pAddHtInfo
->AddHtInfo3
));
202 *pAddHtInfoLen
= SIZE_ADD_HT_INFO_IE
;
206 DBGPRINT(RT_DEBUG_WARN
, ("PeerAssocRspSanity - wrong IE_ADD_HT. \n"));
210 case IE_SECONDARY_CH_OFFSET
:
213 *pNewExtChannelOffset
= pEid
->Octet
[0];
217 DBGPRINT(RT_DEBUG_WARN
, ("PeerAssocRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n"));
219 #endif // DOT11_N_SUPPORT //
222 case IE_VENDOR_SPECIFIC
:
223 // handle WME PARAMTER ELEMENT
224 if (NdisEqualMemory(pEid
->Octet
, WME_PARM_ELEM
, 6) && (pEid
->Len
== 24))
229 // parsing EDCA parameters
230 pEdcaParm
->bValid
= TRUE
;
231 pEdcaParm
->bQAck
= FALSE
; // pEid->Octet[0] & 0x10;
232 pEdcaParm
->bQueueRequest
= FALSE
; // pEid->Octet[0] & 0x20;
233 pEdcaParm
->bTxopRequest
= FALSE
; // pEid->Octet[0] & 0x40;
234 //pEdcaParm->bMoreDataAck = FALSE; // pEid->Octet[0] & 0x80;
235 pEdcaParm
->EdcaUpdateCount
= pEid
->Octet
[6] & 0x0f;
236 pEdcaParm
->bAPSDCapable
= (pEid
->Octet
[6] & 0x80) ? 1 : 0;
237 ptr
= (PUCHAR
)&pEid
->Octet
[8];
240 UCHAR aci
= (*ptr
& 0x60) >> 5; // b5~6 is AC INDEX
241 pEdcaParm
->bACM
[aci
] = (((*ptr
) & 0x10) == 0x10); // b5 is ACM
242 pEdcaParm
->Aifsn
[aci
] = (*ptr
) & 0x0f; // b0~3 is AIFSN
243 pEdcaParm
->Cwmin
[aci
] = *(ptr
+1) & 0x0f; // b0~4 is Cwmin
244 pEdcaParm
->Cwmax
[aci
] = *(ptr
+1) >> 4; // b5~8 is Cwmax
245 pEdcaParm
->Txop
[aci
] = *(ptr
+2) + 256 * (*(ptr
+3)); // in unit of 32-us
246 ptr
+= 4; // point to next AC
251 DBGPRINT(RT_DEBUG_TRACE
, ("PeerAssocRspSanity - ignore unrecognized EID = %d\n", pEid
->Eid
));
255 Length
= Length
+ 2 + pEid
->Len
;
256 pEid
= (PEID_STRUCT
)((UCHAR
*)pEid
+ 2 + pEid
->Len
);
264 ==========================================================================
266 MLME message sanity check
268 TRUE if all parameters are OK, FALSE otherwise
270 IRQL = DISPATCH_LEVEL
272 ==========================================================================
274 BOOLEAN
PeerProbeReqSanity(
275 IN PRTMP_ADAPTER pAd
,
285 PFRAME_802_11 pFrame
= (PFRAME_802_11
)Msg
;
287 COPY_MAC_ADDR(pAddr2
, pFrame
->Hdr
.Addr2
);
289 if ((pFrame
->Octet
[0] != IE_SSID
) || (pFrame
->Octet
[1] > MAX_LEN_OF_SSID
))
291 DBGPRINT(RT_DEBUG_TRACE
, ("PeerProbeReqSanity fail - wrong SSID IE(Type=%d,Len=%d)\n",pFrame
->Octet
[0],pFrame
->Octet
[1]));
295 *pSsidLen
= pFrame
->Octet
[1];
296 NdisMoveMemory(Ssid
, &pFrame
->Octet
[2], *pSsidLen
);
300 // -- get supported rates from payload and advance the pointer
301 IeType
= pFrame
->Octet
[Idx
];
302 RateLen
= pFrame
->Octet
[Idx
+ 1];
303 if (IeType
!= IE_SUPP_RATES
)
305 DBGPRINT(RT_DEBUG_TRACE
, ("PeerProbeReqSanity fail - wrong SupportRates IE(Type=%d,Len=%d)\n",pFrame
->Octet
[Idx
],pFrame
->Octet
[Idx
+1]));
310 if ((pAd
->CommonCfg
.PhyMode
== PHY_11G
) && (RateLen
< 8))
318 ==========================================================================
321 IRQL = DISPATCH_LEVEL
323 ==========================================================================
329 OUT UCHAR
*BcastFlag
,
330 OUT UCHAR
*DtimCount
,
331 OUT UCHAR
*DtimPeriod
,
332 OUT UCHAR
*MessageToMe
)
334 UCHAR BitCntl
, N1
, N2
, MyByte
, MyBit
;
342 // get DTIM Count from TIM element
344 *DtimCount
= *IdxPtr
;
346 // get DTIM Period from TIM element
348 *DtimPeriod
= *IdxPtr
;
350 // get Bitmap Control from TIM element
354 if ((*DtimCount
== 0) && (BitCntl
& 0x01))
359 // Parse Partial Virtual Bitmap from TIM element
360 N1
= BitCntl
& 0xfe; // N1 is the first bitmap byte#
361 N2
= *TimLen
- 4 + N1
; // N2 is the last bitmap byte#
363 if ((Aid
< (N1
<< 3)) || (Aid
>= ((N2
+ 1) << 3)))
364 *MessageToMe
= FALSE
;
367 MyByte
= (Aid
>> 3) - N1
; // my byte position in the bitmap byte-stream
368 MyBit
= Aid
% 16 - ((MyByte
& 0x01)? 8:0);
370 IdxPtr
+= (MyByte
+ 1);
373 // DBGPRINT(RT_DEBUG_WARN, ("TIM bitmap = 0x%02x\n", *IdxPtr));
375 if (*IdxPtr
& (0x01 << MyBit
))
378 *MessageToMe
= FALSE
;