Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  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         Module Name:
 28         sanity.c
 29 
 30         Abstract:
 31 
 32         Revision History:
 33         Who                     When                    What
 34         --------        ----------              ----------------------------------------------
 35         John Chang  2004-09-01      add WMM support
 36 */
 37 #include "../rt_config.h"
 38 
 39 extern UCHAR    CISCO_OUI[];
 40 
 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[];
 48 
 49 /*
 50     ==========================================================================
 51     Description:
 52         MLME message sanity check
 53     Return:
 54         TRUE if all parameters are OK, FALSE otherwise
 55     ==========================================================================
 56  */
 57 BOOLEAN MlmeStartReqSanity(
 58     IN PRTMP_ADAPTER pAd,
 59     IN VOID *Msg,
 60     IN ULONG MsgLen,
 61     OUT CHAR Ssid[],
 62     OUT UCHAR *pSsidLen)
 63 {
 64     MLME_START_REQ_STRUCT *Info;
 65 
 66     Info = (MLME_START_REQ_STRUCT *)(Msg);
 67 
 68     if (Info->SsidLen > MAX_LEN_OF_SSID)
 69     {
 70         DBGPRINT(RT_DEBUG_TRACE, ("MlmeStartReqSanity fail - wrong SSID length\n"));
 71         return FALSE;
 72     }
 73 
 74     *pSsidLen = Info->SsidLen;
 75     NdisMoveMemory(Ssid, Info->Ssid, *pSsidLen);
 76 
 77     return TRUE;
 78 }
 79 
 80 /*
 81     ==========================================================================
 82     Description:
 83         MLME message sanity check
 84     Return:
 85         TRUE if all parameters are OK, FALSE otherwise
 86 
 87     IRQL = DISPATCH_LEVEL
 88 
 89     ==========================================================================
 90  */
 91 BOOLEAN PeerAssocRspSanity(
 92     IN PRTMP_ADAPTER pAd,
 93     IN VOID *pMsg,
 94     IN ULONG MsgLen,
 95     OUT PUCHAR pAddr2,
 96     OUT USHORT *pCapabilityInfo,
 97     OUT USHORT *pStatus,
 98     OUT USHORT *pAid,
 99     OUT UCHAR SupRate[],
100     OUT UCHAR *pSupRateLen,
101     OUT UCHAR ExtRate[],
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)
110 {
111     CHAR          IeType, *Ptr;
112     PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
113     PEID_STRUCT   pEid;
114     ULONG         Length = 0;
115 
116         *pNewExtChannelOffset = 0xff;
117         *pHtCapabilityLen = 0;
118         *pAddHtInfoLen = 0;
119     COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
120     Ptr = pFrame->Octet;
121     Length += LENGTH_802_11;
122 
123     NdisMoveMemory(pCapabilityInfo, &pFrame->Octet[0], 2);
124     Length += 2;
125     NdisMoveMemory(pStatus,         &pFrame->Octet[2], 2);
126     Length += 2;
127     *pCkipFlag = 0;
128     *pExtRateLen = 0;
129     pEdcaParm->bValid = FALSE;
130 
131     if (*pStatus != MLME_SUCCESS)
132         return TRUE;
133 
134     NdisMoveMemory(pAid, &pFrame->Octet[4], 2);
135     Length += 2;
136 
137     // Aid already swaped byte order in RTMPFrameEndianChange() for big endian platform
138     *pAid = (*pAid) & 0x3fff; // AID is low 14-bit
139 
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))
144     {
145         DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspSanity fail - wrong SupportedRates IE\n"));
146         return FALSE;
147     }
148     else
149         NdisMoveMemory(SupRate, &pFrame->Octet[8], *pSupRateLen);
150 
151     Length = Length + 2 + *pSupRateLen;
152 
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)];
156 
157     // get variable fields from payload and advance the pointer
158     while ((Length + 2 + pEid->Len) <= MsgLen)
159     {
160         switch (pEid->Eid)
161         {
162             case IE_EXT_SUPP_RATES:
163                 if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES)
164                 {
165                     NdisMoveMemory(ExtRate, pEid->Octet, pEid->Len);
166                     *pExtRateLen = pEid->Len;
167                 }
168                 break;
169 
170              case IE_HT_CAP:
171             case IE_HT_CAP2:
172                         if (pEid->Len >= SIZE_HT_CAP_IE)  //Note: allow extension.!!
173                         {
174                                 NdisMoveMemory(pHtCapability, pEid->Octet, SIZE_HT_CAP_IE);
175 
176                                 *(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo));
177                                 *(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
178 
179                                 *pHtCapabilityLen = SIZE_HT_CAP_IE;
180                         }
181                         else
182                         {
183                                 DBGPRINT(RT_DEBUG_WARN, ("PeerAssocRspSanity - wrong IE_HT_CAP. \n"));
184                         }
185 
186                 break;
187             case IE_ADD_HT:
188             case IE_ADD_HT2:
189                         if (pEid->Len >= sizeof(ADD_HT_INFO_IE))
190                         {
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));
194 
195                                 *(USHORT *)(&pAddHtInfo->AddHtInfo2) = cpu2le16(*(USHORT *)(&pAddHtInfo->AddHtInfo2));
196                                 *(USHORT *)(&pAddHtInfo->AddHtInfo3) = cpu2le16(*(USHORT *)(&pAddHtInfo->AddHtInfo3));
197 
198                                 *pAddHtInfoLen = SIZE_ADD_HT_INFO_IE;
199                         }
200                         else
201                         {
202                                 DBGPRINT(RT_DEBUG_WARN, ("PeerAssocRspSanity - wrong IE_ADD_HT. \n"));
203                         }
204 
205                 break;
206             case IE_SECONDARY_CH_OFFSET:
207                         if (pEid->Len == 1)
208                         {
209                                 *pNewExtChannelOffset = pEid->Octet[0];
210                         }
211                         else
212                         {
213                                 DBGPRINT(RT_DEBUG_WARN, ("PeerAssocRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n"));
214                         }
215                 break;
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))
221                 break;
222 
223                 // 1. Copy CKIP flag byte to buffer for process
224                 *pCkipFlag = *(pEid->Octet + 8);
225                 break;
226 
227             case IE_AIRONET_IPADDRESS:
228                 if (pEid->Len != 0x0A)
229                 break;
230 
231                 // Get Cisco Aironet IP information
232                 if (NdisEqualMemory(pEid->Octet, CISCO_OUI, 3) == 1)
233                     NdisMoveMemory(pAd->StaCfg.AironetIPAddress, pEid->Octet + 4, 4);
234                 break;
235 
236             // CCX2, WMM use the same IE value
237             // case IE_CCX_V2:
238             case IE_VENDOR_SPECIFIC:
239                 // handle WME PARAMTER ELEMENT
240                 if (NdisEqualMemory(pEid->Octet, WME_PARM_ELEM, 6) && (pEid->Len == 24))
241                 {
242                     PUCHAR ptr;
243                     int i;
244 
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];
254                     for (i=0; i<4; i++)
255                     {
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
263                     }
264                 }
265 
266                 // handle CCX IE
267                 else
268                 {
269                     // 0. Check the size and CCX admin control
270                     if (pAd->StaCfg.CCXControl.field.Enable == 0)
271                         break;
272                     if (pEid->Len != 5)
273                         break;
274 
275                     // Turn CCX2 if matched
276                     if (NdisEqualMemory(pEid->Octet, Ccx2IeInfo, 5) == 1)
277                         pAd->StaCfg.CCXEnable = TRUE;
278                     break;
279                 }
280                 break;
281 
282             default:
283                 DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspSanity - ignore unrecognized EID = %d\n", pEid->Eid));
284                 break;
285         }
286 
287         Length = Length + 2 + pEid->Len;
288         pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
289     }
290 
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;
294 
295     return TRUE;
296 }
297 
298 /*
299     ==========================================================================
300     Description:
301         MLME message sanity check
302     Return:
303         TRUE if all parameters are OK, FALSE otherwise
304 
305         IRQL = DISPATCH_LEVEL
306 
307     ==========================================================================
308  */
309 BOOLEAN PeerProbeReqSanity(
310     IN PRTMP_ADAPTER pAd,
311     IN VOID *Msg,
312     IN ULONG MsgLen,
313     OUT PUCHAR pAddr2,
314     OUT CHAR Ssid[],
315     OUT UCHAR *pSsidLen)
316 {
317     UCHAR         Idx;
318     UCHAR             RateLen;
319     CHAR          IeType;
320     PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
321 
322     COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
323 
324     if ((pFrame->Octet[0] != IE_SSID) || (pFrame->Octet[1] > MAX_LEN_OF_SSID))
325     {
326         DBGPRINT(RT_DEBUG_TRACE, ("PeerProbeReqSanity fail - wrong SSID IE(Type=%d,Len=%d)\n",pFrame->Octet[0],pFrame->Octet[1]));
327         return FALSE;
328     }
329 
330     *pSsidLen = pFrame->Octet[1];
331     NdisMoveMemory(Ssid, &pFrame->Octet[2], *pSsidLen);
332 
333     Idx = *pSsidLen + 2;
334 
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)
339     {
340         DBGPRINT(RT_DEBUG_TRACE, ("PeerProbeReqSanity fail - wrong SupportRates IE(Type=%d,Len=%d)\n",pFrame->Octet[Idx],pFrame->Octet[Idx+1]));
341         return FALSE;
342     }
343     else
344     {
345         if ((pAd->CommonCfg.PhyMode == PHY_11G) && (RateLen < 8))
346             return (FALSE);
347     }
348 
349     return TRUE;
350 }
351 
352 /*
353     ==========================================================================
354     Description:
355 
356         IRQL = DISPATCH_LEVEL
357 
358     ==========================================================================
359  */
360 BOOLEAN GetTimBit(
361     IN CHAR *Ptr,
362     IN USHORT Aid,
363     OUT UCHAR *TimLen,
364     OUT UCHAR *BcastFlag,
365     OUT UCHAR *DtimCount,
366     OUT UCHAR *DtimPeriod,
367     OUT UCHAR *MessageToMe)
368 {
369     UCHAR          BitCntl, N1, N2, MyByte, MyBit;
370     CHAR          *IdxPtr;
371 
372     IdxPtr = Ptr;
373 
374     IdxPtr ++;
375     *TimLen = *IdxPtr;
376 
377     // get DTIM Count from TIM element
378     IdxPtr ++;
379     *DtimCount = *IdxPtr;
380 
381     // get DTIM Period from TIM element
382     IdxPtr++;
383     *DtimPeriod = *IdxPtr;
384 
385     // get Bitmap Control from TIM element
386     IdxPtr++;
387     BitCntl = *IdxPtr;
388 
389     if ((*DtimCount == 0) && (BitCntl & 0x01))
390         *BcastFlag = TRUE;
391     else
392         *BcastFlag = FALSE;
393 
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#
397 
398     if ((Aid < (N1 << 3)) || (Aid >= ((N2 + 1) << 3)))
399         *MessageToMe = FALSE;
400     else
401     {
402         MyByte = (Aid >> 3) - N1;                       // my byte position in the bitmap byte-stream
403         MyBit = Aid % 16 - ((MyByte & 0x01)? 8:0);
404 
405         IdxPtr += (MyByte + 1);
406 
407         //if (*IdxPtr)
408         //    DBGPRINT(RT_DEBUG_WARN, ("TIM bitmap = 0x%02x\n", *IdxPtr));
409 
410         if (*IdxPtr & (0x01 << MyBit))
411             *MessageToMe = TRUE;
412         else
413             *MessageToMe = FALSE;
414     }
415 
416     return TRUE;
417 }
418 
419 
  This page was automatically generated by the LXR engine.