+ }
+
+ Sanity |= 0x4;
+ } else {
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("PeerBeaconAndProbeRspSanity - wrong IE_DS_PARM (len=%d)\n",
+ pEid->Len));
+ return FALSE;
+ }
+ break;
+
+ case IE_CF_PARM:
+ if (pEid->Len == 6) {
+ pCfParm->bValid = TRUE;
+ pCfParm->CfpCount = pEid->Octet[0];
+ pCfParm->CfpPeriod = pEid->Octet[1];
+ pCfParm->CfpMaxDuration =
+ pEid->Octet[2] + 256 * pEid->Octet[3];
+ pCfParm->CfpDurRemaining =
+ pEid->Octet[4] + 256 * pEid->Octet[5];
+ } else {
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("PeerBeaconAndProbeRspSanity - wrong IE_CF_PARM\n"));
+ return FALSE;
+ }
+ break;
+
+ case IE_IBSS_PARM:
+ if (pEid->Len == 2) {
+ NdisMoveMemory(pAtimWin, pEid->Octet,
+ pEid->Len);
+ } else {
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("PeerBeaconAndProbeRspSanity - wrong IE_IBSS_PARM\n"));
+ return FALSE;
+ }
+ break;
+
+ case IE_TIM:
+ if (INFRA_ON(pAd) && SubType == SUBTYPE_BEACON) {
+ GetTimBit((char *)pEid, pAd->StaActive.Aid,
+ &TimLen, pBcastFlag, pDtimCount,
+ pDtimPeriod, pMessageToMe);
+ }
+ break;
+ case IE_CHANNEL_SWITCH_ANNOUNCEMENT:
+ if (pEid->Len == 3) {
+ *pNewChannel = pEid->Octet[1]; /*extract new channel number */
+ }
+ break;
+
+ /* New for WPA */
+ /* CCX v2 has the same IE, we need to parse that too */
+ /* Wifi WMM use the same IE vale, need to parse that too */
+ /* case IE_WPA: */
+ case IE_VENDOR_SPECIFIC:
+ /* Check Broadcom/Atheros 802.11n OUI version, for HT Capability IE. */
+ /* This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan. */
+ /*if (NdisEqualMemory(pEid->Octet, BROADCOM_OUI, 3) && (pEid->Len >= 4))
+ {
+ if ((pEid->Octet[3] == OUI_BROADCOM_HT) && (pEid->Len >= 30))
+ {
+ {
+ NdisMoveMemory(pHtCapability, &pEid->Octet[4], sizeof(struct rt_ht_capability_ie));
+ *pHtCapabilityLen = SIZE_HT_CAP_IE; // Nnow we only support 26 bytes.
+ }
+ }
+ if ((pEid->Octet[3] == OUI_BROADCOM_HT) && (pEid->Len >= 26))
+ {
+ {
+ NdisMoveMemory(AddHtInfo, &pEid->Octet[4], sizeof(struct rt_add_ht_info_ie));
+ *AddHtInfoLen = SIZE_ADD_HT_INFO_IE; // Nnow we only support 26 bytes.
+ }
+ }
+ }
+ */
+ /* Check the OUI version, filter out non-standard usage */
+ if (NdisEqualMemory(pEid->Octet, RALINK_OUI, 3)
+ && (pEid->Len == 7)) {
+ /**pRalinkIe = pEid->Octet[3]; */
+ if (pEid->Octet[3] != 0)
+ *pRalinkIe = pEid->Octet[3];
+ else
+ *pRalinkIe = 0xf0000000; /* Set to non-zero value (can't set bit0-2) to represent this is Ralink Chip. So at linkup, we will set ralinkchip flag. */
+ }
+ /* This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan. */
+
+ /* Other vendors had production before IE_HT_CAP value is assigned. To backward support those old-firmware AP, */
+ /* Check broadcom-defiend pre-802.11nD1.0 OUI for HT related IE, including HT Capatilities IE and HT Information IE */
+ else if ((*pHtCapabilityLen == 0)
+ && NdisEqualMemory(pEid->Octet, PRE_N_HT_OUI,
+ 3) && (pEid->Len >= 4)
+ && (pAd->OpMode == OPMODE_STA)) {
+ if ((pEid->Octet[3] == OUI_PREN_HT_CAP)
+ && (pEid->Len >= 30)
+ && (*pHtCapabilityLen == 0)) {
+ NdisMoveMemory(pHtCapability,
+ &pEid->Octet[4],
+ sizeof
+ (struct rt_ht_capability_ie));
+ *pPreNHtCapabilityLen = SIZE_HT_CAP_IE;
+ }
+
+ if ((pEid->Octet[3] == OUI_PREN_ADD_HT)
+ && (pEid->Len >= 26)) {
+ NdisMoveMemory(AddHtInfo,
+ &pEid->Octet[4],
+ sizeof(struct rt_add_ht_info_ie));
+ *AddHtInfoLen = SIZE_ADD_HT_INFO_IE;
+ }
+ } else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)) {
+ /* Copy to pVIE which will report to microsoft bssid list. */
+ Ptr = (u8 *)pVIE;
+ NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid,
+ pEid->Len + 2);
+ *LengthVIE += (pEid->Len + 2);
+ } else
+ if (NdisEqualMemory(pEid->Octet, WME_PARM_ELEM, 6)
+ && (pEid->Len == 24)) {
+ u8 *ptr;
+ int i;
+
+ /* parsing EDCA parameters */
+ pEdcaParm->bValid = TRUE;
+ pEdcaParm->bQAck = FALSE; /* pEid->Octet[0] & 0x10; */
+ pEdcaParm->bQueueRequest = FALSE; /* pEid->Octet[0] & 0x20; */
+ pEdcaParm->bTxopRequest = FALSE; /* pEid->Octet[0] & 0x40; */
+ pEdcaParm->EdcaUpdateCount =
+ pEid->Octet[6] & 0x0f;
+ pEdcaParm->bAPSDCapable =
+ (pEid->Octet[6] & 0x80) ? 1 : 0;
+ ptr = &pEid->Octet[8];
+ for (i = 0; i < 4; i++) {
+ u8 aci = (*ptr & 0x60) >> 5; /* b5~6 is AC INDEX */
+ pEdcaParm->bACM[aci] = (((*ptr) & 0x10) == 0x10); /* b5 is ACM */
+ pEdcaParm->Aifsn[aci] = (*ptr) & 0x0f; /* b0~3 is AIFSN */
+ pEdcaParm->Cwmin[aci] = *(ptr + 1) & 0x0f; /* b0~4 is Cwmin */
+ pEdcaParm->Cwmax[aci] = *(ptr + 1) >> 4; /* b5~8 is Cwmax */
+ pEdcaParm->Txop[aci] = *(ptr + 2) + 256 * (*(ptr + 3)); /* in unit of 32-us */
+ ptr += 4; /* point to next AC */
+ }
+ } else
+ if (NdisEqualMemory(pEid->Octet, WME_INFO_ELEM, 6)
+ && (pEid->Len == 7)) {
+ /* parsing EDCA parameters */
+ pEdcaParm->bValid = TRUE;
+ pEdcaParm->bQAck = FALSE; /* pEid->Octet[0] & 0x10; */
+ pEdcaParm->bQueueRequest = FALSE; /* pEid->Octet[0] & 0x20; */
+ pEdcaParm->bTxopRequest = FALSE; /* pEid->Octet[0] & 0x40; */
+ pEdcaParm->EdcaUpdateCount =
+ pEid->Octet[6] & 0x0f;
+ pEdcaParm->bAPSDCapable =
+ (pEid->Octet[6] & 0x80) ? 1 : 0;
+
+ /* use default EDCA parameter */
+ pEdcaParm->bACM[QID_AC_BE] = 0;
+ pEdcaParm->Aifsn[QID_AC_BE] = 3;
+ pEdcaParm->Cwmin[QID_AC_BE] = CW_MIN_IN_BITS;
+ pEdcaParm->Cwmax[QID_AC_BE] = CW_MAX_IN_BITS;
+ pEdcaParm->Txop[QID_AC_BE] = 0;
+
+ pEdcaParm->bACM[QID_AC_BK] = 0;
+ pEdcaParm->Aifsn[QID_AC_BK] = 7;
+ pEdcaParm->Cwmin[QID_AC_BK] = CW_MIN_IN_BITS;
+ pEdcaParm->Cwmax[QID_AC_BK] = CW_MAX_IN_BITS;
+ pEdcaParm->Txop[QID_AC_BK] = 0;
+
+ pEdcaParm->bACM[QID_AC_VI] = 0;
+ pEdcaParm->Aifsn[QID_AC_VI] = 2;
+ pEdcaParm->Cwmin[QID_AC_VI] =
+ CW_MIN_IN_BITS - 1;
+ pEdcaParm->Cwmax[QID_AC_VI] = CW_MAX_IN_BITS;
+ pEdcaParm->Txop[QID_AC_VI] = 96; /* AC_VI: 96*32us ~= 3ms */
+
+ pEdcaParm->bACM[QID_AC_VO] = 0;
+ pEdcaParm->Aifsn[QID_AC_VO] = 2;
+ pEdcaParm->Cwmin[QID_AC_VO] =
+ CW_MIN_IN_BITS - 2;
+ pEdcaParm->Cwmax[QID_AC_VO] =
+ CW_MAX_IN_BITS - 1;
+ pEdcaParm->Txop[QID_AC_VO] = 48; /* AC_VO: 48*32us ~= 1.5ms */
+ }
+
+ break;
+
+ case IE_EXT_SUPP_RATES:
+ if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES) {
+ NdisMoveMemory(ExtRate, pEid->Octet, pEid->Len);
+ *pExtRateLen = pEid->Len;
+
+ /* TODO: 2004-09-14 not a good design here, cause it exclude extra rates */
+ /* from ScanTab. We should report as is. And filter out unsupported */
+ /* rates in MlmeAux. */
+ /* Check against the supported rates */
+ /* RTMPCheckRates(pAd, ExtRate, pExtRateLen); */
+ }
+ break;
+
+ case IE_ERP:
+ if (pEid->Len == 1) {
+ *pErp = (u8)pEid->Octet[0];
+ }
+ break;
+
+ case IE_AIRONET_CKIP:
+ /* 0. Check Aironet IE length, it must be larger or equal to 28 */
+ /* Cisco AP350 used length as 28 */
+ /* Cisco AP12XX used length as 30 */
+ if (pEid->Len < (CKIP_NEGOTIATION_LENGTH - 2))
+ break;
+
+ /* 1. Copy CKIP flag byte to buffer for process */
+ *pCkipFlag = *(pEid->Octet + 8);
+ break;
+
+ case IE_AP_TX_POWER:
+ /* AP Control of Client Transmit Power */
+ /*0. Check Aironet IE length, it must be 6 */
+ if (pEid->Len != 0x06)
+ break;
+
+ /* Get cell power limit in dBm */
+ if (NdisEqualMemory(pEid->Octet, CISCO_OUI, 3) == 1)
+ *pAironetCellPowerLimit = *(pEid->Octet + 4);
+ break;
+
+ /* WPA2 & 802.11i RSN */
+ case IE_RSN:
+ /* There is no OUI for version anymore, check the group cipher OUI before copying */
+ if (RTMPEqualMemory(pEid->Octet + 2, RSN_OUI, 3)) {
+ /* Copy to pVIE which will report to microsoft bssid list. */
+ Ptr = (u8 *)pVIE;
+ NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid,
+ pEid->Len + 2);
+ *LengthVIE += (pEid->Len + 2);
+ }
+ break;
+
+ default:
+ break;
+ }