/* ========================================================================== Description: MLME message sanity check Return: TRUE if all parameters are OK, FALSE otherwise IRQL = DISPATCH_LEVEL ========================================================================== */ BOOLEAN MlmeDelBAReqSanity( IN PRTMP_ADAPTER pAd, IN VOID *Msg, IN ULONG MsgLen) { MLME_DELBA_REQ_STRUCT *pInfo; pInfo = (MLME_DELBA_REQ_STRUCT *)Msg; if ((MsgLen != sizeof(MLME_DELBA_REQ_STRUCT))) { DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - message lenght not correct.\n")); return FALSE; } if ((pInfo->Wcid >= MAX_LEN_OF_MAC_TABLE)) { DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - The peer Mac is not associated yet.\n")); return FALSE; } if ((pInfo->TID & 0xf0)) { DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - The peer TID is incorrect.\n")); return FALSE; } if (NdisEqualMemory(pAd->MacTab.Content[pInfo->Wcid].Addr, pInfo->Addr, MAC_ADDR_LEN) == 0) { DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - the peer addr dosen't exist.\n")); return FALSE; } return TRUE; }
static inline VOID AutoChBssEntrySet( OUT BSSENTRY *pBss, IN PUCHAR pBssid, IN CHAR Ssid[], IN UCHAR SsidLen, IN UCHAR Channel, IN UCHAR ExtChOffset, IN CHAR Rssi) { COPY_MAC_ADDR(pBss->Bssid, pBssid); if (SsidLen > 0) { /* For hidden SSID AP, it might send beacon with SSID len equal to 0, Or send beacon /probe response with SSID len matching real SSID length, but SSID is all zero. such as "00-00-00-00" with length 4. We have to prevent this case overwrite correct table */ if (NdisEqualMemory(Ssid, ZeroSsid, SsidLen) == 0) { NdisMoveMemory(pBss->Ssid, Ssid, SsidLen); pBss->SsidLen = SsidLen; } } pBss->Channel = Channel; pBss->ExtChOffset = ExtChOffset; pBss->Rssi = Rssi; return; }
BOOLEAN RTMPReplayAttackDetection( IN PRTMP_ADAPTER pAd, IN PUCHAR pAddr2, IN CHAR Rssi0, IN CHAR Rssi1, IN CHAR Rssi2) { INT i; for (i = 0; i < pAd->ApCfg.BssidNum; i++) { /* Conflict SSID detection */ if (NdisEqualMemory(pAddr2, pAd->ApCfg.MBSSID[i].Bssid, MAC_ADDR_LEN)) { CHAR RcvdRssi; RcvdRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Rssi0, RSSI_0), ConvertToRssi(pAd, Rssi1, RSSI_1), ConvertToRssi(pAd, Rssi2, RSSI_2)); pAd->ApCfg.MBSSID[i].RcvdReplayAttackCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdReplayAttack = RcvdRssi; return TRUE; } } return FALSE; }
int _rtw_memcmp(void *dst, void *src, u32 sz) { #if defined (PLATFORM_LINUX)|| defined (PLATFORM_FREEBSD) //under Linux/GNU/GLibc, the return value of memcmp for two same mem. chunk is 0 if (!(memcmp(dst, src, sz))) return _TRUE; else return _FALSE; #endif #ifdef PLATFORM_WINDOWS //under Windows, the return value of NdisEqualMemory for two same mem. chunk is 1 if (NdisEqualMemory (dst, src, sz)) return _TRUE; else return _FALSE; #endif }
VOID WscAddEntryToAclList( IN PRTMP_ADAPTER pAd, IN INT ApIdx, IN PUCHAR pMacAddr) { PRT_802_11_ACL pACL = NULL; INT i; BOOLEAN bFound = FALSE; pACL = &pAd->ApCfg.MBSSID[ApIdx].AccessControlList; if ((pACL->Policy == 0) || (pACL->Policy == 2)) return; if (pACL->Num >= (MAX_NUM_OF_ACL_LIST - 1)) { DBGPRINT(RT_DEBUG_WARN, ("The AccessControlList is full, and no more entry can join the list!\n")); return; } for (i=0; i<pACL->Num; i++) { if (NdisEqualMemory(pACL->Entry[i].Addr, pMacAddr, MAC_ADDR_LEN)) bFound = TRUE; } if (bFound == FALSE) { NdisMoveMemory(pACL->Entry[i].Addr, pMacAddr, MAC_ADDR_LEN); pACL->Num++; } }
UCHAR P2pPerstTabDelete( IN PRTMP_ADAPTER pAd, IN UCHAR *pMacList) { PRT_P2P_TABLE Tab = &pAd->P2pTable; UCHAR i; for (i = 0; i < MAX_P2P_TABLE_SIZE; i++) { if (Tab->PerstEntry[i].bValid == TRUE) { if (NdisEqualMemory(Tab->PerstEntry[i].Addr, pMacList, 6)) { RTMPZeroMemory(&Tab->PerstEntry[i], sizeof(RT_P2P_PERSISTENT_ENTRY)); Tab->PerstEntry[i].bValid = FALSE; if (Tab->PerstNumber > 0) { Tab->PerstNumber--; } else DBGPRINT(RT_DEBUG_ERROR, (" P2P - Persistent table count error. \n")); DBGPRINT(RT_DEBUG_ERROR, (" P2P - Delete a Persistent Entry .Table Number = %d. \n", Tab->PerstNumber)); } return i; } } return 0xff; }
VOID RTMPRepeaterReconnectionCheck( IN PRTMP_ADAPTER pAd) { #ifdef APCLI_AUTO_CONNECT_SUPPORT INT i; PCHAR pApCliSsid, pApCliCfgSsid; UCHAR CfgSsidLen; NDIS_802_11_SSID Ssid; if (pAd->ApCfg.bMACRepeaterEn && pAd->ApCfg.MACRepeaterOuiMode == 2 && pAd->ApCfg.ApCliAutoConnectRunning == FALSE) { for (i = 0; i < MAX_APCLI_NUM; i++) { pApCliSsid = pAd->ApCfg.ApCliTab[i].Ssid; pApCliCfgSsid = pAd->ApCfg.ApCliTab[i].CfgSsid; CfgSsidLen = pAd->ApCfg.ApCliTab[i].CfgSsidLen; if ((pAd->ApCfg.ApCliTab[i].CtrlCurrState < APCLI_CTRL_AUTH || !NdisEqualMemory(pApCliSsid, pApCliCfgSsid, CfgSsidLen)) && pAd->ApCfg.ApCliTab[i].CfgSsidLen > 0 && pAd->Mlme.OneSecPeriodicRound % 23 == 0) { DBGPRINT(RT_DEBUG_TRACE, (" %s(): Scan channels for AP (%s)\n", __FUNCTION__, pApCliCfgSsid)); pAd->ApCfg.ApCliAutoConnectRunning = TRUE; Ssid.SsidLength = CfgSsidLen; NdisCopyMemory(Ssid.Ssid, pApCliCfgSsid, CfgSsidLen); ApSiteSurvey(pAd, &Ssid, SCAN_ACTIVE, FALSE); } } } #endif /* APCLI_AUTO_CONNECT_SUPPORT */ }
/* ========================================================================== Description: Some STA/AP Note: This action should never trigger AUTH state transition, therefore we separate it from AUTH state machine, and make it as a standalone service ========================================================================== */ VOID APCls2errAction( IN PRTMP_ADAPTER pAd, IN ULONG Wcid, IN PHEADER_802_11 pHeader) { HEADER_802_11 Hdr; PUCHAR pOutBuffer = NULL; NDIS_STATUS NStatus; ULONG FrameLen = 0; USHORT Reason = REASON_CLS2ERR; MAC_TABLE_ENTRY *pEntry = NULL; UCHAR idx; if (Wcid < MAX_LEN_OF_MAC_TABLE) { pEntry = &(pAd->MacTab.Content[Wcid]); } if (pEntry && IS_ENTRY_CLIENT(pEntry)) { /*ApLogEvent(pAd, pAddr, EVENT_DISASSOCIATED); */ MacTableDeleteEntry(pAd, pEntry->Aid, pHeader->Addr2); } else { for (idx = 0; idx < pAd->ApCfg.BssidNum; idx++) { PMULTISSID_STRUCT pMbss = &pAd->ApCfg.MBSSID[idx]; if (NdisEqualMemory(pMbss->Bssid, pHeader->Addr1, MAC_ADDR_LEN)) break; } if (idx == pAd->ApCfg.BssidNum) return; } /* send out DEAUTH request frame */ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); if (NStatus != NDIS_STATUS_SUCCESS) return; DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Class 2 error, Send DEAUTH frame to " "%02x:%02x:%02x:%02x:%02x:%02x \n", PRINT_MAC(pHeader->Addr2))); MgtMacHeaderInit(pAd, &Hdr, SUBTYPE_DEAUTH, 0, pHeader->Addr2, #ifdef P2P_SUPPORT pHeader->Addr1, #endif /* P2P_SUPPORT */ pHeader->Addr1); MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &Hdr, 2, &Reason, END_OF_ARGS); MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); }
/* ========================================================================== Description: Some STA/AP Note: This action should never trigger AUTH state transition, therefore we separate it from AUTH state machine, and make it as a standalone service ========================================================================== */ VOID APCls2errAction( IN PRTMP_ADAPTER pAd, IN ULONG Wcid, IN PHEADER_802_11 pHeader) { HEADER_802_11 Hdr; PUCHAR pOutBuffer = NULL; NDIS_STATUS NStatus; ULONG FrameLen = 0; USHORT Reason = REASON_CLS2ERR; MAC_TABLE_ENTRY *pEntry = NULL; if (Wcid < MAX_LEN_OF_MAC_TABLE) { pEntry = &(pAd->MacTab.Content[Wcid]); } if (pEntry && IS_ENTRY_CLIENT(pEntry)) { /*ApLogEvent(pAd, pAddr, EVENT_DISASSOCIATED); */ MacTableDeleteEntry(pAd, pEntry->Aid, pHeader->Addr2); } else { UCHAR bssid[MAC_ADDR_LEN]; NdisMoveMemory(bssid, pHeader->Addr1, MAC_ADDR_LEN); bssid[5] &= pAd->ApCfg.MacMask; if (NdisEqualMemory(pAd->CurrentAddress, bssid, MAC_ADDR_LEN) == 0) return; } /* send out DEAUTH request frame */ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); if (NStatus != NDIS_STATUS_SUCCESS) return; DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Class 2 error, Send DEAUTH frame to " "%02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(pHeader->Addr2))); MgtMacHeaderInit(pAd, &Hdr, SUBTYPE_DEAUTH, 0, pHeader->Addr2, pHeader->Addr1); MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &Hdr, 2, &Reason, END_OF_ARGS); MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); }
/* ========================================================================== Description: Check whether the received frame is WAPI frame. Arguments: pAd - pointer to our pAdapter context pData - the received frame DataByteCount - the received frame's length Return: TRUE - This frame is WAPI frame FALSE - otherwise ========================================================================== */ BOOLEAN RTMPCheckWAIframe( IN PUCHAR pData, IN ULONG DataByteCount) { if(DataByteCount < (LENGTH_802_1_H + LENGTH_WAI_H)) return FALSE; // Skip LLC header if (NdisEqualMemory(SNAP_802_1H, pData, 6)) { pData += 6; } // Skip 2-bytes EAPoL type if (NdisEqualMemory(WAPI_TYPE, pData, 2)) { DBGPRINT(RT_DEBUG_TRACE, ("--> Receive a WAI frame \n")); pData += 2; } else return FALSE; return TRUE; }
/* ========================================================================== Description: Check whether the received frame is WAPI frame. Arguments: pAd - pointer to our pAdapter context pData - the received frame DataByteCount - the received frame's length Return: TRUE - This frame is WAPI frame FALSE - otherwise ========================================================================== */ BOOLEAN RTMPCheckWAIframe( IN PUCHAR pData, IN ULONG DataByteCount) { if(DataByteCount < (LENGTH_802_1_H + LENGTH_WAI_H)) return FALSE; /* Skip LLC header */ if (NdisEqualMemory(SNAP_802_1H, pData, 6)) { pData += 6; } /* Skip 2-bytes EAPoL type */ if (NdisEqualMemory(WAPI_TYPE, pData, 2)) { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("--> Receive a WAI frame \n")); pData += 2; } else return FALSE; return TRUE; }
BOOLEAN NeighborMPCheck( IN PRTMP_ADAPTER pAd, IN PUCHAR pMeshId, IN UINT8 PathSelProtocolId, IN UINT8 PathSelMetricId) { BOOLEAN result = FALSE; if ((NdisEqualMemory(pMeshId, pAd->MeshTab.MeshId, pAd->MeshTab.MeshIdLen)) && (PathSelProtocolId == pAd->MeshTab.PathProtocolId) && (PathSelMetricId == pAd->MeshTab.PathMetricId)) result = TRUE; return result; }
VOID RTMPRepeaterReconnectionCheck( IN PRTMP_ADAPTER pAd) { #ifdef APCLI_AUTO_CONNECT_SUPPORT INT i; PCHAR pApCliSsid, pApCliCfgSsid; UCHAR CfgSsidLen; NDIS_802_11_SSID Ssid; USHORT SiteSurveyPeriod; if ((pAd->ApCfg.ApCliAutoConnectRunning == FALSE) #ifdef AP_PARTIAL_SCAN_SUPPORT && (pAd->ApCfg.bPartialScanning == FALSE) #endif /* AP_PARTIAL_SCAN_SUPPORT */ ) { for (i = 0; i < MAX_APCLI_NUM; i++) { if (!APCLI_IF_UP_CHECK(pAd, i) || (pAd->ApCfg.ApCliTab[i].Enable == FALSE)) continue; pApCliSsid = pAd->ApCfg.ApCliTab[i].Ssid; pApCliCfgSsid = pAd->ApCfg.ApCliTab[i].CfgSsid; CfgSsidLen = pAd->ApCfg.ApCliTab[i].CfgSsidLen; SiteSurveyPeriod = pAd->ApCfg.ApCliTab[i].ApCliSiteSurveyPeriod; if ((pAd->ApCfg.ApCliTab[i].CtrlCurrState < APCLI_CTRL_AUTH || !NdisEqualMemory(pApCliSsid, pApCliCfgSsid, CfgSsidLen)) && (pAd->ApCfg.ApCliTab[i].CfgSsidLen > 0) && (pAd->Mlme.OneSecPeriodicRound % SiteSurveyPeriod == 0)) { DBGPRINT(RT_DEBUG_TRACE, (" %s(): Scan channels for AP (%s)\n", __FUNCTION__, pApCliCfgSsid)); pAd->ApCfg.ApCliAutoConnectRunning = TRUE; #ifdef AP_PARTIAL_SCAN_SUPPORT pAd->ApCfg.bPartialScanning = TRUE; #endif /* AP_PARTIAL_SCAN_SUPPORT */ Ssid.SsidLength = CfgSsidLen; NdisCopyMemory(Ssid.Ssid, pApCliCfgSsid, CfgSsidLen); ApSiteSurvey(pAd, &Ssid, SCAN_ACTIVE, FALSE); } } } #endif /* APCLI_AUTO_CONNECT_SUPPORT */ }
/* ========================================================================== Description: MLME message sanity check Return: TRUE if all parameters are OK, FALSE otherwise IRQL = DISPATCH_LEVEL ========================================================================== */ BOOLEAN MlmeDelBAReqSanity( IN PRTMP_ADAPTER pAd, IN VOID *Msg, IN ULONG MsgLen) { MLME_DELBA_REQ_STRUCT *pInfo; UINT32 MaxWcidNum = MAX_LEN_OF_MAC_TABLE; pInfo = (MLME_DELBA_REQ_STRUCT *)Msg; #ifdef MAC_REPEATER_SUPPORT if (pAd->ApCfg.bMACRepeaterEn) MaxWcidNum = MAX_MAC_TABLE_SIZE_WITH_REPEATER; #endif /* MAC_REPEATER_SUPPORT */ if ((MsgLen != sizeof(MLME_DELBA_REQ_STRUCT))) { DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - message lenght not correct.\n")); return FALSE; } if ((pInfo->Wcid >= MaxWcidNum)) { DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - The peer Mac is not associated yet.\n")); return FALSE; } if ((pInfo->TID & 0xf0)) { DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - The peer TID is incorrect.\n")); return FALSE; } if (NdisEqualMemory(pAd->MacTab.Content[pInfo->Wcid].Addr, pInfo->Addr, MAC_ADDR_LEN) == 0) { DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - the peer addr dosen't exist.\n")); return FALSE; } return TRUE; }
UCHAR P2pPerstTabSearch( IN PRTMP_ADAPTER pAd, IN PUCHAR Addr, IN PUCHAR Bssid, IN PUCHAR InfAddr) { PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg; UCHAR i; PRT_P2P_TABLE Tab = &pAd->P2pTable; UCHAR index = P2P_NOT_FOUND; UCHAR Allff[MAC_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; UCHAR AllZero[MAC_ADDR_LEN] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; if ((Addr[0] & 0x1) == 0x1) return index; if (Addr && NdisEqualMemory(Allff, Addr, MAC_ADDR_LEN)) return index; if (Addr && NdisEqualMemory(AllZero, Addr, MAC_ADDR_LEN)) return index; for (i = 0; i < MAX_P2P_TABLE_SIZE; i++) { if ((Tab->PerstEntry[i].bValid == TRUE) && ((Addr && NdisEqualMemory(&Tab->PerstEntry[i].Addr, Addr, MAC_ADDR_LEN)) || (Bssid && NdisEqualMemory(&Tab->PerstEntry[i].Addr, Bssid, MAC_ADDR_LEN)) || (InfAddr && NdisEqualMemory(&Tab->PerstEntry[i].Addr, InfAddr, MAC_ADDR_LEN))) ) { DBGPRINT(RT_DEBUG_TRACE, (" P2P - i = %d. \n", i)); /* If My rule is client, it must be perst profile when I am in staion opmode. */ if((Tab->PerstEntry[i].MyRule == P2P_IS_CLIENT) && (pAd->OpMode == OPMODE_STA)) { index = i; } else if ((Tab->PerstEntry[i].MyRule == P2P_IS_GO) && (NdisEqualMemory(Tab->PerstEntry[i].Profile.MacAddr, pP2PCtrl->CurrentAddress, 6))) { index = i; } } } return index; }
/* ========================================================================== Description: mlme assoc req handling procedure Parameters: Adapter - Adapter pointer Elem - MLME Queue Element Pre: the station has been authenticated and the following information is stored in the config -# SSID -# supported rates and their length Post : -# An association request frame is generated and sent to the air -# Association timer starts -# Association state -> ASSOC_WAIT_RSP ========================================================================== */ static VOID ApCliMlmeAssocReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { NDIS_STATUS NStatus; BOOLEAN Cancelled; UCHAR ApAddr[6]; HEADER_802_11 AssocHdr; UCHAR WmeIe[9] = {IE_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00}; USHORT ListenIntv; ULONG Timeout; USHORT CapabilityInfo; PUCHAR pOutBuffer = NULL; ULONG FrameLen = 0; ULONG tmp; UCHAR SsidIe = IE_SSID; UCHAR SupRateIe = IE_SUPP_RATES; UCHAR ExtRateIe = IE_EXT_SUPP_RATES; APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg; USHORT ifIndex = (USHORT)(Elem->Priv); PULONG pCurrState = NULL; PAPCLI_STRUCT pApCliEntry = NULL; #ifdef APCLI_WPA_SUPPLICANT_SUPPORT USHORT VarIesOffset = 0; #endif /* APCLI_WPA_SUPPLICANT_SUPPORT */ UCHAR RSNIe = IE_WPA; #ifdef MAC_REPEATER_SUPPORT UCHAR CliIdx = 0xFF; #endif /* MAC_REPEATER_SUPPORT */ if ((ifIndex >= MAX_APCLI_NUM) #ifdef MAC_REPEATER_SUPPORT && (ifIndex < 64) #endif /* MAC_REPEATER_SUPPORT */ ) return; #ifdef MAC_REPEATER_SUPPORT if (ifIndex >= 64) { CliIdx = ((ifIndex - 64) % 16); ifIndex = ((ifIndex - 64) / 16); pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].RepeaterCli[CliIdx].AssocCurrState; } else #endif /* MAC_REPEATER_SUPPORT */ pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].AssocCurrState; pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex]; /* Block all authentication request durning WPA block period */ if (pApCliEntry->bBlockAssoc == TRUE) { DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - Block Auth request durning WPA block period!\n")); *pCurrState = APCLI_ASSOC_IDLE; ApCliCtrlMsg.Status = MLME_STATE_MACHINE_REJECT; MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_ASSOC_RSP, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex); } else if(MlmeAssocReqSanity(pAd, Elem->Msg, Elem->MsgLen, ApAddr, &CapabilityInfo, &Timeout, &ListenIntv)) { //RTMPCancelTimer(&pAd->ApCliMlmeAux.ApCliAssocTimer, &Cancelled); #ifdef MAC_REPEATER_SUPPORT if (CliIdx != 0xFF) RTMPCancelTimer(&pAd->ApCfg.ApCliTab[ifIndex].RepeaterCli[CliIdx].ApCliAssocTimer, &Cancelled); else #endif /* MAC_REPEATER_SUPPORT */ RTMPCancelTimer(&pApCliEntry->ApCliMlmeAux.ApCliAssocTimer, &Cancelled); /* allocate and send out AssocRsp frame */ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ if (NStatus != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_ERROR, ("APCLI_ASSOC - ApCliMlmeAssocReqAction() allocate memory failed \n")); *pCurrState = APCLI_ASSOC_IDLE; ApCliCtrlMsg.Status = MLME_FAIL_NO_RESOURCE; MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_ASSOC_RSP, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex); return; } #ifdef APCLI_WPA_SUPPLICANT_SUPPORT pApCliEntry->AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION); pApCliEntry->AssocInfo.AvailableRequestFixedIEs = NDIS_802_11_AI_REQFI_CAPABILITIES | NDIS_802_11_AI_REQFI_LISTENINTERVAL; pApCliEntry->AssocInfo.RequestFixedIEs.Capabilities = CapabilityInfo; pApCliEntry->AssocInfo.RequestFixedIEs.ListenInterval = ListenIntv; pApCliEntry->AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION); NdisZeroMemory(pApCliEntry->ReqVarIEs, MAX_VIE_LEN); /*First add SSID*/ VarIesOffset = 0; NdisMoveMemory(pApCliEntry->ReqVarIEs + VarIesOffset, &SsidIe, 1); VarIesOffset += 1; NdisMoveMemory(pApCliEntry->ReqVarIEs + VarIesOffset, &pAd->MlmeAux.SsidLen, 1); VarIesOffset += 1; NdisMoveMemory(pApCliEntry->ReqVarIEs + VarIesOffset, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen); VarIesOffset += pAd->MlmeAux.SsidLen; /*Second add Supported rates*/ NdisMoveMemory(pApCliEntry->ReqVarIEs + VarIesOffset, &SupRateIe, 1); VarIesOffset += 1; NdisMoveMemory(pApCliEntry->ReqVarIEs + VarIesOffset, &pAd->MlmeAux.SupRateLen, 1); VarIesOffset += 1; NdisMoveMemory(pApCliEntry->ReqVarIEs + VarIesOffset, pAd->MlmeAux.SupRate, pAd->MlmeAux.SupRateLen); VarIesOffset += pAd->MlmeAux.SupRateLen; #endif /* APCLI_WPA_SUPPLICANT_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - Send ASSOC request...\n")); ApCliMgtMacHeaderInit(pAd, &AssocHdr, SUBTYPE_ASSOC_REQ, 0, ApAddr, ApAddr, ifIndex); #ifdef MAC_REPEATER_SUPPORT if (CliIdx != 0xFF) COPY_MAC_ADDR(AssocHdr.Addr2, pAd->ApCfg.ApCliTab[ifIndex].RepeaterCli[CliIdx].CurrentAddress); #endif /* MAC_REPEATER_SUPPORT */ /* Build basic frame first */ MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &AssocHdr, 2, &CapabilityInfo, 2, &ListenIntv, 1, &SsidIe, 1, &pApCliEntry->ApCliMlmeAux.SsidLen, pApCliEntry->ApCliMlmeAux.SsidLen, pApCliEntry->ApCliMlmeAux.Ssid, 1, &SupRateIe, 1, &pApCliEntry->ApCliMlmeAux.SupRateLen, pApCliEntry->ApCliMlmeAux.SupRateLen, pApCliEntry->ApCliMlmeAux.SupRate, END_OF_ARGS); if(pApCliEntry->ApCliMlmeAux.ExtRateLen != 0) { MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, 1, &ExtRateIe, 1, &pApCliEntry->ApCliMlmeAux.ExtRateLen, pApCliEntry->ApCliMlmeAux.ExtRateLen, pApCliEntry->ApCliMlmeAux.ExtRate, END_OF_ARGS); FrameLen += tmp; } #ifdef DOT11_N_SUPPORT /* HT */ if ((pApCliEntry->ApCliMlmeAux.HtCapabilityLen > 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) { ULONG TmpLen; HT_CAPABILITY_IE HtCapabilityTmp; NdisZeroMemory(&HtCapabilityTmp, sizeof(HT_CAPABILITY_IE)); NdisMoveMemory(&HtCapabilityTmp, &pApCliEntry->ApCliMlmeAux.HtCapability, pApCliEntry->ApCliMlmeAux.HtCapabilityLen); #ifdef DOT11N_SS3_SUPPORT HtCapabilityTmp.MCSSet[2] = (pApCliEntry->ApCliMlmeAux.HtCapability.MCSSet[2] & pApCliEntry->RxMcsSet[2]); #endif /* DOT11N_SS3_SUPPORT */ #ifdef RT_BIG_ENDIAN *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo)); *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo)); #endif /* RT_BIG_ENDINA */ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &HtCapIe, 1, &pApCliEntry->ApCliMlmeAux.HtCapabilityLen, pApCliEntry->ApCliMlmeAux.HtCapabilityLen, &HtCapabilityTmp, END_OF_ARGS); FrameLen += TmpLen; } #ifdef DOT11N_DRAFT3 #ifdef APCLI_CERT_SUPPORT if (pAd->bApCliCertTest == TRUE) { ULONG TmpLen; EXT_CAP_INFO_ELEMENT extCapInfo; UCHAR extInfoLen; extInfoLen = sizeof (EXT_CAP_INFO_ELEMENT); NdisZeroMemory(&extCapInfo, extInfoLen); if ((pAd->CommonCfg.bBssCoexEnable == TRUE) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pAd->CommonCfg.Channel <= 14) ) { extCapInfo.BssCoexistMgmtSupport = 1; DBGPRINT(RT_DEBUG_TRACE, ("%s: BssCoexistMgmtSupport = 1\n", __FUNCTION__)); } MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &ExtCapIe, 1, &extInfoLen, extInfoLen, &extCapInfo, END_OF_ARGS); FrameLen += TmpLen; } #endif /* APCLI_CERT_SUPPORT */ #endif /* DOT11N_DRAFT3 */ #endif /* DOT11_N_SUPPORT */ #ifdef AGGREGATION_SUPPORT /* add Ralink proprietary IE to inform AP this STA is going to use AGGREGATION or PIGGY-BACK+AGGREGATION Case I: (Aggregation + Piggy-Back) 1. user enable aggregation, AND 2. Mac support piggy-back 3. AP annouces it's PIGGY-BACK+AGGREGATION-capable in BEACON Case II: (Aggregation) 1. user enable aggregation, AND 2. AP annouces it's AGGREGATION-capable in BEACON */ if (pAd->CommonCfg.bAggregationCapable) { #ifdef PIGGYBACK_SUPPORT if ((pAd->CommonCfg.bPiggyBackCapable) && ((pApCliEntry->ApCliMlmeAux.APRalinkIe & 0x00000003) == 3)) { ULONG TmpLen; UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x03, 0x00, 0x00, 0x00}; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 9, RalinkIe, END_OF_ARGS); FrameLen += TmpLen; } else #endif /* PIGGYBACK_SUPPORT */ if (pApCliEntry->ApCliMlmeAux.APRalinkIe & 0x00000001) { ULONG TmpLen; UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x01, 0x00, 0x00, 0x00}; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 9, RalinkIe, END_OF_ARGS); FrameLen += TmpLen; } } else { ULONG TmpLen; UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x06, 0x00, 0x00, 0x00}; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 9, RalinkIe, END_OF_ARGS); FrameLen += TmpLen; } #endif /* AGGREGATION_SUPPORT */ if (pApCliEntry->ApCliMlmeAux.APEdcaParm.bValid) { if (pApCliEntry->UapsdInfo.bAPSDCapable && pApCliEntry->ApCliMlmeAux.APEdcaParm.bAPSDCapable) { QBSS_STA_INFO_PARM QosInfo; NdisZeroMemory(&QosInfo, sizeof(QBSS_STA_INFO_PARM)); QosInfo.UAPSD_AC_BE = pAd->CommonCfg.bAPSDAC_BE; QosInfo.UAPSD_AC_BK = pAd->CommonCfg.bAPSDAC_BK; QosInfo.UAPSD_AC_VI = pAd->CommonCfg.bAPSDAC_VI; QosInfo.UAPSD_AC_VO = pAd->CommonCfg.bAPSDAC_VO; QosInfo.MaxSPLength = pAd->CommonCfg.MaxSPLength; WmeIe[8] |= *(PUCHAR)&QosInfo; } else { /* The Parameter Set Count is set to бз0би in the association request frames */ /* WmeIe[8] |= (pAd->MlmeAux.APEdcaParm.EdcaUpdateCount & 0x0f); */ } MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, 9, &WmeIe[0], END_OF_ARGS); FrameLen += tmp; } /* Append RSN_IE when WPAPSK OR WPA2PSK, */ if (((pApCliEntry->AuthMode == Ndis802_11AuthModeWPAPSK) || (pApCliEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)) #ifdef APCLI_WPA_SUPPLICANT_SUPPORT || (pApCliEntry->AuthMode >= Ndis802_11AuthModeWPA) #endif /* APCLI_WPA_SUPPLICANT_SUPPORT */ #ifdef WSC_AP_SUPPORT && ((pApCliEntry->WscControl.WscConfMode == WSC_DISABLE) || ((pApCliEntry->WscControl.WscConfMode != WSC_DISABLE) && !(pApCliEntry->WscControl.bWscTrigger ))) #endif /* WSC_AP_SUPPORT */ ) { RSNIe = IE_WPA; if ((pApCliEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) #ifdef APCLI_WPA_SUPPLICANT_SUPPORT ||(pApCliEntry->AuthMode == Ndis802_11AuthModeWPA2) #endif/*APCLI_WPA_SUPPLICANT_SUPPORT*/ ) RSNIe = IE_WPA2; #ifdef APCLI_WPA_SUPPLICANT_SUPPORT if (pApCliEntry->AuthMode == Ndis802_11AuthModeWPA2) { INT idx; BOOLEAN FoundPMK = FALSE; /* Search chched PMKID, append it if existed */ for (idx = 0; idx < PMKID_NO; idx++) { if (NdisEqualMemory(ApAddr, &pApCliEntry->SavedPMK[idx].BSSID, 6)) { FoundPMK = TRUE; break; } } /* When AuthMode is WPA2-Enterprise and AP reboot or STA lost AP, AP would not do PMK cache with STA after STA re-connect to AP again. In this case, driver doesn't need to send PMKID to AP and WpaSupplicant. */ if ((pApCliEntry->AuthMode == Ndis802_11AuthModeWPA2) && (NdisEqualMemory(pAd->MlmeAux.Bssid, pAd->CommonCfg.LastBssid, MAC_ADDR_LEN))) { FoundPMK = FALSE; } if (FoundPMK) { // Set PMK number *(PUSHORT) &pApCliEntry->RSN_IE[pApCliEntry->RSNIE_Len] = 1; NdisMoveMemory(&pApCliEntry->RSN_IE[pApCliEntry->RSNIE_Len + 2], &pApCliEntry->SavedPMK[idx].PMKID, 16); pApCliEntry->RSNIE_Len += 18; } } #ifdef SIOCSIWGENIE if ((pApCliEntry->WpaSupplicantUP & WPA_SUPPLICANT_ENABLE) && (pApCliEntry->bRSN_IE_FromWpaSupplicant == TRUE)) { ; } else #endif #endif /*APCLI_WPA_SUPPLICANT_SUPPORT*/ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, 1, &RSNIe, 1, &pApCliEntry->RSNIE_Len, pApCliEntry->RSNIE_Len, pApCliEntry->RSN_IE, END_OF_ARGS); FrameLen += tmp; } #ifdef APCLI_WPA_SUPPLICANT_SUPPORT #ifdef SIOCSIWGENIE if (((pApCliEntry->WpaSupplicantUP & 0x7F) != WPA_SUPPLICANT_ENABLE) || (pApCliEntry->bRSN_IE_FromWpaSupplicant == FALSE)) #endif { // Append Variable IE NdisMoveMemory(pApCliEntry->ReqVarIEs + VarIesOffset, &RSNIe, 1); VarIesOffset += 1; NdisMoveMemory(pApCliEntry->ReqVarIEs + VarIesOffset, &pApCliEntry->RSNIE_Len, 1); VarIesOffset += 1; NdisMoveMemory(pApCliEntry->ReqVarIEs + VarIesOffset, pApCliEntry->RSN_IE, pApCliEntry->RSNIE_Len); VarIesOffset += pAd->ApCfg.ApCliTab[ifIndex].RSNIE_Len; // Set Variable IEs Length pApCliEntry->ReqVarIELen = VarIesOffset; } #ifdef SIOCSIWGENIE if ((pApCliEntry->WpaSupplicantUP & WPA_SUPPLICANT_ENABLE) && (pApCliEntry->bRSN_IE_FromWpaSupplicant == TRUE)) { ULONG TmpWpaAssocIeLen = 0; MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpWpaAssocIeLen, pApCliEntry->WpaAssocIeLen, pApCliEntry->pWpaAssocIe, END_OF_ARGS); FrameLen += TmpWpaAssocIeLen; NdisMoveMemory(pApCliEntry->ReqVarIEs + VarIesOffset, pApCliEntry->pWpaAssocIe, pApCliEntry->WpaAssocIeLen); VarIesOffset += pApCliEntry->WpaAssocIeLen; // Set Variable IEs Length pApCliEntry->ReqVarIELen = VarIesOffset; } #endif #endif /* APCLI_WPA_SUPPLICANT_SUPPORT */ #ifdef WSC_AP_SUPPORT /* Add WSC IE if we are connecting to WSC AP */ if ((pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscConfMode != WSC_DISABLE) && (pAd->ApCfg.ApCliTab[ifIndex].WscControl.bWscTrigger)) { UCHAR *pWscBuf = NULL, WscIeLen = 0; ULONG WscTmpLen = 0; os_alloc_mem(pAd, (UCHAR **) & pWscBuf, 512); /* if( (pWscBuf = kmalloc(512, GFP_ATOMIC)) != NULL) */ if (pWscBuf != NULL) { NdisZeroMemory(pWscBuf, 512); WscBuildAssocReqIE(&pAd->ApCfg.ApCliTab[ifIndex].WscControl, pWscBuf, &WscIeLen); MakeOutgoingFrame(pOutBuffer + FrameLen, &WscTmpLen, WscIeLen, pWscBuf, END_OF_ARGS); FrameLen += WscTmpLen; /* kfree(pWscBuf); */ os_free_mem(NULL, pWscBuf); } else DBGPRINT(RT_DEBUG_WARN, ("%s:: WscBuf Allocate failed!\n", __FUNCTION__)); } #endif /* WSC_AP_SUPPORT */ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); #ifdef MAC_REPEATER_SUPPORT if (CliIdx != 0xFF) RTMPSetTimer(&pAd->ApCfg.ApCliTab[ifIndex].RepeaterCli[CliIdx].ApCliAssocTimer, Timeout); else #endif /* MAC_REPEATER_SUPPORT */ RTMPSetTimer(&pApCliEntry->ApCliMlmeAux.ApCliAssocTimer, Timeout); *pCurrState = APCLI_ASSOC_WAIT_RSP; } else { DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - ApCliMlmeAssocReqAction() sanity check failed. BUG!!!!!! \n")); *pCurrState = APCLI_ASSOC_IDLE; ApCliCtrlMsg.Status = MLME_INVALID_FORMAT; MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_ASSOC_RSP, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex); } return; }
static VOID APPeerAuthConfirmAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { AUTH_FRAME_INFO auth_info; PHEADER_802_11 pRcvHdr; MAC_TABLE_ENTRY *pEntry; UINT32 apidx; if (!APPeerAuthSanity(pAd, Elem->Msg, Elem->MsgLen, &auth_info)) return; apidx = get_apidx_by_addr(pAd, auth_info.addr1); if (apidx >= pAd->ApCfg.BssidNum) { DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Bssid not found\n")); return; } if ((pAd->ApCfg.MBSSID[apidx].wdev.if_dev != NULL) && !(RTMP_OS_NETDEV_STATE_RUNNING(pAd->ApCfg.MBSSID[apidx].wdev.if_dev))) { DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Bssid IF didn't up yet.\n")); return; } /* End of if */ if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE) { DBGPRINT(RT_DEBUG_ERROR, ("AUTH - Invalid wcid (%d).\n", Elem->Wcid)); return; } pEntry = &pAd->MacTab.Content[Elem->Wcid]; if (pEntry && IS_ENTRY_CLIENT(pEntry)) { if (!RTMPEqualMemory(auth_info.addr1, pAd->ApCfg.MBSSID[pEntry->func_tb_idx].wdev.bssid, MAC_ADDR_LEN)) { MacTableDeleteEntry(pAd, pEntry->wcid, pEntry->Addr); pEntry = NULL; DBGPRINT(RT_DEBUG_WARN, ("AUTH - Bssid does not match\n")); } else { if (pEntry->bIAmBadAtheros == TRUE) { AsicUpdateProtect(pAd, 8, ALLN_SETPROTECT, FALSE, FALSE); DBGPRINT(RT_DEBUG_TRACE, ("Atheros Problem. Turn on RTS/CTS!!!\n")); pEntry->bIAmBadAtheros = FALSE; } ASSERT(pEntry->Aid == Elem->Wcid); #ifdef DOT11_N_SUPPORT BASessionTearDownALL(pAd, pEntry->wcid); #endif /* DOT11_N_SUPPORT */ } } pRcvHdr = (PHEADER_802_11)(Elem->Msg); DBGPRINT(RT_DEBUG_TRACE, ("AUTH - MBSS(%d), Rcv AUTH seq#%d, Alg=%d, Status=%d from " "[wcid=%d]%02x:%02x:%02x:%02x:%02x:%02x\n", apidx, auth_info.auth_seq, auth_info.auth_alg, auth_info.auth_status, Elem->Wcid, PRINT_MAC(auth_info.addr2))); if (pEntry && MAC_ADDR_EQUAL(auth_info.addr2, pAd->ApMlmeAux.Addr)) { if ((pRcvHdr->FC.Wep == 1) && NdisEqualMemory(auth_info.Chtxt, pAd->ApMlmeAux.Challenge, CIPHER_TEXT_LEN)) { /* Successful */ APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, auth_info.auth_alg, auth_info.auth_seq + 1, MLME_SUCCESS); pEntry->AuthState = AS_AUTH_KEY; pEntry->Sst = SST_AUTH; } else { /* send wireless event - Authentication rejected because of challenge failure */ RTMPSendWirelessEvent(pAd, IW_AUTH_REJECT_CHALLENGE_FAILURE, pEntry->Addr, 0, 0); /* fail - wep bit is not set or challenge text is not equal */ APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, auth_info.auth_alg, auth_info.auth_seq + 1, MLME_REJ_CHALLENGE_FAILURE); MacTableDeleteEntry(pAd, pEntry->wcid, pEntry->Addr); /*Chtxt[127]='\0'; */ /*pAd->ApMlmeAux.Challenge[127]='\0'; */ DBGPRINT(RT_DEBUG_TRACE, ("%s\n", ((pRcvHdr->FC.Wep == 1) ? "challenge text is not equal" : "wep bit is not set"))); /*DBGPRINT(RT_DEBUG_TRACE, ("Sent Challenge = %s\n",&pAd->ApMlmeAux.Challenge[100])); */ /*DBGPRINT(RT_DEBUG_TRACE, ("Rcv Challenge = %s\n",&Chtxt[100])); */ } } else { /* fail for unknown reason. most likely is AuthRspAux machine be overwritten by another */ /* STA also using SHARED_KEY authentication */ APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, auth_info.auth_alg, auth_info.auth_seq + 1, MLME_UNSPECIFY_FAIL); /* If this STA exists, delete it. */ if (pEntry) MacTableDeleteEntry(pAd, pEntry->wcid, pEntry->Addr); } }
VOID CFG80211_ParseBeaconIE(RTMP_ADAPTER *pAd, BSS_STRUCT *pMbss, struct wifi_dev *wdev, const UCHAR *wpa_ie, const UCHAR *rsn_ie) { PEID_STRUCT pEid; PUCHAR pTmp; NDIS_802_11_ENCRYPTION_STATUS TmpCipher; NDIS_802_11_ENCRYPTION_STATUS PairCipher; /* Unicast cipher 1, this one has more secured cipher suite */ NDIS_802_11_ENCRYPTION_STATUS PairCipherAux; /* Unicast cipher 2 if AP announce two unicast cipher suite */ //NDIS_802_11_ENCRYPTION_STATUS GroupCipher; /* Group cipher */ PAKM_SUITE_STRUCT pAKM; USHORT Count; BOOLEAN bWPA = FALSE; BOOLEAN bWPA2 = FALSE; BOOLEAN bMix = FALSE; /* Security */ PairCipher = Ndis802_11WEPDisabled; PairCipherAux = Ndis802_11WEPDisabled; if ((wpa_ie == NULL) && (rsn_ie == NULL)) //open case { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("%s:: Open/None case\n", __FUNCTION__)); wdev->AuthMode = Ndis802_11AuthModeOpen; wdev->WepStatus = Ndis802_11WEPDisabled; wdev->WpaMixPairCipher = MIX_CIPHER_NOTUSE; } if ((wpa_ie != NULL)) //wpapsk/tkipaes case { pEid = (PEID_STRUCT)wpa_ie; pTmp = (PUCHAR)pEid; if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)) { wdev->AuthMode = Ndis802_11AuthModeOpen; MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("%s:: WPA case\n", __FUNCTION__)); bWPA = TRUE; pTmp += 11; switch (*pTmp) { case 1: MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("Group Ndis802_11GroupWEP40Enabled\n")); wdev->GroupKeyWepStatus = Ndis802_11GroupWEP40Enabled; break; case 5: MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("Group Ndis802_11GroupWEP104Enabled\n")); wdev->GroupKeyWepStatus = Ndis802_11GroupWEP104Enabled; break; case 2: MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("Group Ndis802_11TKIPEnable\n")); wdev->GroupKeyWepStatus = Ndis802_11TKIPEnable; break; case 4: MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,(" Group Ndis802_11AESEnable\n")); wdev->GroupKeyWepStatus = Ndis802_11AESEnable; break; default: break; } /* number of unicast suite*/ pTmp += 1; /* skip all unicast cipher suites*/ /*Count = *(PUSHORT) pTmp; */ Count = (pTmp[1]<<8) + pTmp[0]; pTmp += sizeof(USHORT); /* Parsing all unicast cipher suite*/ while (Count > 0) { /* Skip OUI*/ pTmp += 3; TmpCipher = Ndis802_11WEPDisabled; switch (*pTmp) { case 1: case 5: /* Although WEP is not allowed in WPA related auth mode, we parse it anyway*/ TmpCipher = Ndis802_11WEPEnabled; break; case 2: TmpCipher = Ndis802_11TKIPEnable; break; case 4: TmpCipher = Ndis802_11AESEnable; break; default: break; } if (TmpCipher > PairCipher) { /* Move the lower cipher suite to PairCipherAux*/ PairCipherAux = PairCipher; PairCipher = TmpCipher; } else { PairCipherAux = TmpCipher; } pTmp++; Count--; } switch (*pTmp) { case 1: /* Set AP support WPA-enterprise mode*/ wdev->AuthMode = Ndis802_11AuthModeWPA; break; case 2: /* Set AP support WPA-PSK mode*/ wdev->AuthMode = Ndis802_11AuthModeWPAPSK; break; default: break; } pTmp += 1; MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("AuthMode = %s\n",GetAuthMode(wdev->AuthMode))); if (wdev->GroupKeyWepStatus == PairCipher) { wdev->WpaMixPairCipher = MIX_CIPHER_NOTUSE; pMbss->wdev.WepStatus=wdev->GroupKeyWepStatus; } else { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("WPA Mix TKIPAES\n")); bMix = TRUE; } pMbss->RSNIE_Len[0] = wpa_ie[1]; NdisMoveMemory(pMbss->RSN_IE[0], wpa_ie+2, wpa_ie[1]);//copy rsn ie } else { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("%s:: WPA Open/None case\n", __FUNCTION__)); wdev->AuthMode = Ndis802_11AuthModeOpen; } } if ((rsn_ie != NULL)) { PRSN_IE_HEADER_STRUCT pRsnHeader; PCIPHER_SUITE_STRUCT pCipher; pEid = (PEID_STRUCT)rsn_ie; pTmp = (PUCHAR)pEid; pRsnHeader = (PRSN_IE_HEADER_STRUCT) pTmp; /* 0. Version must be 1*/ if (le2cpu16(pRsnHeader->Version) == 1) { pTmp += sizeof(RSN_IE_HEADER_STRUCT); /* 1. Check group cipher*/ pCipher = (PCIPHER_SUITE_STRUCT) pTmp; if (NdisEqualMemory(pTmp, RSN_OUI, 3)) { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("%s:: WPA2 case\n", __FUNCTION__)); bWPA2 = TRUE; wdev->AuthMode = Ndis802_11AuthModeOpen; switch (pCipher->Type) { case 1: MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("Ndis802_11GroupWEP40Enabled\n")); wdev->GroupKeyWepStatus = Ndis802_11GroupWEP40Enabled; break; case 5: MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("Ndis802_11GroupWEP104Enabled\n")); wdev->GroupKeyWepStatus = Ndis802_11GroupWEP104Enabled; break; case 2: MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("Ndis802_11TKIPEnable\n")); wdev->GroupKeyWepStatus = Ndis802_11TKIPEnable; break; case 4: MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("Ndis802_11AESEnable\n")); wdev->GroupKeyWepStatus = Ndis802_11AESEnable; break; default: break; } /* set to correct offset for next parsing*/ pTmp += sizeof(CIPHER_SUITE_STRUCT); /* 2. Get pairwise cipher counts*/ /*Count = *(PUSHORT) pTmp;*/ Count = (pTmp[1]<<8) + pTmp[0]; pTmp += sizeof(USHORT); /* 3. Get pairwise cipher*/ /* Parsing all unicast cipher suite*/ while (Count > 0) { /* Skip OUI*/ pCipher = (PCIPHER_SUITE_STRUCT) pTmp; TmpCipher = Ndis802_11WEPDisabled; switch (pCipher->Type) { case 1: case 5: /* Although WEP is not allowed in WPA related auth mode, we parse it anyway*/ TmpCipher = Ndis802_11WEPEnabled; break; case 2: TmpCipher = Ndis802_11TKIPEnable; break; case 4: TmpCipher = Ndis802_11AESEnable; break; default: break; } //pMbss->wdev.WepStatus = TmpCipher; if (TmpCipher > PairCipher) { /* Move the lower cipher suite to PairCipherAux*/ PairCipherAux = PairCipher; PairCipher = TmpCipher; } else { PairCipherAux = TmpCipher; } pTmp += sizeof(CIPHER_SUITE_STRUCT); Count--; } /* 4. get AKM suite counts*/ /*Count = *(PUSHORT) pTmp;*/ Count = (pTmp[1]<<8) + pTmp[0]; pTmp += sizeof(USHORT); /* 5. Get AKM ciphers*/ /* Parsing all AKM ciphers*/ while (Count > 0) { pAKM = (PAKM_SUITE_STRUCT) pTmp; if (!RTMPEqualMemory(pTmp, RSN_OUI, 3)) break; switch (pAKM->Type) { case 0: wdev->AuthMode = Ndis802_11AuthModeWPANone; break; case 1: /* Set AP support WPA-enterprise mode*/ wdev->AuthMode = Ndis802_11AuthModeWPA2; break; case 2: /* Set AP support WPA-PSK mode*/ wdev->AuthMode = Ndis802_11AuthModeWPA2PSK; break; default: wdev->AuthMode = Ndis802_11AuthModeMax; break; } pTmp += sizeof(AKM_SUITE_STRUCT); Count--; } MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("AuthMode = %s\n",GetAuthMode(wdev->AuthMode))); if (wdev->GroupKeyWepStatus == PairCipher) { wdev->WpaMixPairCipher = MIX_CIPHER_NOTUSE; pMbss->wdev.WepStatus=wdev->GroupKeyWepStatus; } else { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("WPA2 Mix TKIPAES\n")); bMix= TRUE; } if (bWPA2 && bWPA) { pMbss->RSNIE_Len[1] = rsn_ie[1]; NdisMoveMemory(pMbss->RSN_IE[1], rsn_ie+2, rsn_ie[1]);//copy rsn ie } else { pMbss->RSNIE_Len[0] = rsn_ie[1]; NdisMoveMemory(pMbss->RSN_IE[0], rsn_ie+2, rsn_ie[1]);//copy rsn ie } } else { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("%s::RSN Open/None case\n", __FUNCTION__)); wdev->AuthMode = Ndis802_11AuthModeOpen; } } } if (bWPA2 && bWPA) { wdev->AuthMode = Ndis802_11AuthModeWPA1PSKWPA2PSK; if (bMix) { wdev->WpaMixPairCipher = WPA_TKIPAES_WPA2_TKIPAES; wdev->WepStatus = Ndis802_11TKIPAESMix; } } else if (bWPA2) { if (bMix) { wdev->WpaMixPairCipher = WPA_NONE_WPA2_TKIPAES; wdev->WepStatus = Ndis802_11TKIPAESMix; } } else if (bWPA) { if (bMix) { wdev->WpaMixPairCipher = WPA_TKIPAES_WPA2_NONE; wdev->WepStatus = Ndis802_11TKIPAESMix; } } MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("\n bwpa2 %d, bwpa %d, bmix %d,AuthMode = %s ,wdev->WpaMixPairCipher = %d\ wdev->WepStatus = %d wdev->GroupKeyWepStatus %d pMbss->wdev.WepStatus = %d\n" ,bWPA2,bWPA,bMix,GetAuthMode(wdev->AuthMode),wdev->WpaMixPairCipher,wdev->WepStatus,wdev->GroupKeyWepStatus,pMbss->wdev.WepStatus)); }
/* ========================================================================== Description: Process the received ProbeRequest from clients Parameters: Elem - msg containing the ProbeReq frame ========================================================================== */ VOID APPeerProbeReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { UCHAR Addr2[MAC_ADDR_LEN]; CHAR Ssid[MAX_LEN_OF_SSID]; UCHAR SsidLen; HEADER_802_11 ProbeRspHdr; NDIS_STATUS NStatus; PUCHAR pOutBuffer = NULL; ULONG FrameLen = 0, TmpLen; LARGE_INTEGER FakeTimestamp; UCHAR DsLen = 1; UCHAR ErpIeLen = 1; UCHAR apidx = 0, PhyMode, SupRateLen; UCHAR RSNIe=IE_WPA, RSNIe2=IE_WPA2; BOOLEAN bRequestRssi=FALSE; #ifdef WSC_AP_SUPPORT UCHAR Addr3[MAC_ADDR_LEN]; PFRAME_802_11 pFrame = (PFRAME_802_11)Elem->Msg; COPY_MAC_ADDR(Addr3, pFrame->Hdr.Addr3); #endif /* WSC_AP_SUPPORT */ #ifdef WDS_SUPPORT /* if in bridge mode, no need to reply probe req. */ if (pAd->WdsTab.Mode == WDS_BRIDGE_MODE) return; #endif /* WDS_SUPPORT */ if (! PeerProbeReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, Ssid, &SsidLen, &bRequestRssi)) return; for(apidx=0; apidx<pAd->ApCfg.BssidNum; apidx++) { RSNIe = IE_WPA; if ((pAd->ApCfg.MBSSID[apidx].MSSIDDev != NULL) && !(RTMP_OS_NETDEV_STATE_RUNNING(pAd->ApCfg.MBSSID[apidx].MSSIDDev))) { /* the interface is down, so we can not send probe response */ continue; } PhyMode = pAd->ApCfg.MBSSID[apidx].PhyMode; if (((SsidLen == 0) && (! pAd->ApCfg.MBSSID[apidx].bHideSsid)) || #ifdef WSC_AP_SUPPORT /* buffalo WPS testbed STA send ProbrRequest ssid length = 32 and ssid are not AP , but DA are AP. for WPS test send ProbeResponse */ ((SsidLen == 32) && MAC_ADDR_EQUAL(Addr3, pAd->ApCfg.MBSSID[apidx].Bssid) && (pAd->ApCfg.MBSSID[apidx].bHideSsid == 0)) || #endif /* WSC_AP_SUPPORT */ ((SsidLen == pAd->ApCfg.MBSSID[apidx].SsidLen) && NdisEqualMemory(Ssid, pAd->ApCfg.MBSSID[apidx].Ssid, (ULONG) SsidLen))) ; else continue; /* check next BSS */ #ifdef RT_CFG80211_SUPPORT if (pAd->Cfg80211RegisterProbeReqFrame) { UINT32 freq; MAP_CHANNEL_ID_TO_KHZ(Elem->Channel, freq); freq /= 1000; CFG80211OS_RxMgmt(pAd->ApCfg.MBSSID[apidx].MSSIDDev, freq, (PUCHAR)Elem->Msg, Elem->MsgLen); } #endif /* RT_CFG80211_SUPPORT */ #ifdef BAND_STEERING BND_STRG_CHECK_CONNECTION_REQ( pAd, NULL, Addr2, Elem->MsgType, Elem->Rssi0, Elem->Rssi1, Elem->Rssi2, NULL); #endif /* BAND_STEERING */ /* allocate and send out ProbeRsp frame */ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); if (NStatus != NDIS_STATUS_SUCCESS) return; MgtMacHeaderInit(pAd, &ProbeRspHdr, SUBTYPE_PROBE_RSP, 0, Addr2, pAd->ApCfg.MBSSID[apidx].Bssid); if ((pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA) || (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPAPSK)) RSNIe = IE_WPA; else if ((pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA2) || (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA2PSK)) RSNIe = IE_WPA2; #ifdef WAPI_SUPPORT else if ((pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWAICERT) || (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWAIPSK)) RSNIe = IE_WAPI; #endif /* WAPI_SUPPORT */ { SupRateLen = pAd->CommonCfg.SupRateLen; if (PhyMode == WMODE_B) SupRateLen = 4; MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &ProbeRspHdr, TIMESTAMP_LEN, &FakeTimestamp, 2, &pAd->CommonCfg.BeaconPeriod, 2, &pAd->ApCfg.MBSSID[apidx].CapabilityInfo, 1, &SsidIe, 1, &pAd->ApCfg.MBSSID[apidx].SsidLen, pAd->ApCfg.MBSSID[apidx].SsidLen, pAd->ApCfg.MBSSID[apidx].Ssid, 1, &SupRateIe, 1, &SupRateLen, SupRateLen, pAd->CommonCfg.SupRate, 1, &DsIe, 1, &DsLen, 1, &pAd->CommonCfg.Channel, END_OF_ARGS); } if ((pAd->CommonCfg.ExtRateLen) && (PhyMode != WMODE_B)) { MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &ErpIe, 1, &ErpIeLen, 1, &pAd->ApCfg.ErpIeContent, 1, &ExtRateIe, 1, &pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRate, END_OF_ARGS); FrameLen += TmpLen; } #ifdef DOT11_N_SUPPORT if (WMODE_CAP_N(PhyMode) && (pAd->ApCfg.MBSSID[apidx].DesiredHtPhyInfo.bHtEnable)) { ULONG TmpLen; UCHAR HtLen, AddHtLen, NewExtLen; #ifdef RT_BIG_ENDIAN HT_CAPABILITY_IE HtCapabilityTmp; ADD_HT_INFO_IE addHTInfoTmp; #endif #ifdef A_BAND_SUPPORT if (pAd->CommonCfg.bExtChannelSwitchAnnouncement && (pAd->CommonCfg.Channel > 14)) { HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE HtExtChannelSwitchIe; build_ext_channel_switch_ie(pAd, &HtExtChannelSwitchIe); MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, sizeof(HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE), &HtExtChannelSwitchIe, END_OF_ARGS); FrameLen += TmpLen; } #endif /* A_BAND_SUPPORT */ HtLen = sizeof(pAd->CommonCfg.HtCapability); AddHtLen = sizeof(pAd->CommonCfg.AddHTInfo); NewExtLen = 1; /*New extension channel offset IE is included in Beacon, Probe Rsp or channel Switch Announcement Frame */ #ifndef RT_BIG_ENDIAN MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &HtCapIe, 1, &HtLen, sizeof(HT_CAPABILITY_IE), &pAd->CommonCfg.HtCapability, 1, &AddHtInfoIe, 1, &AddHtLen, sizeof(ADD_HT_INFO_IE), &pAd->CommonCfg.AddHTInfo, END_OF_ARGS); #else NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen); *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo)); #ifdef UNALIGNMENT_SUPPORT { EXT_HT_CAP_INFO extHtCapInfo; NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); } #else *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = cpu2le16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo)); #endif /* UNALIGNMENT_SUPPORT */ NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, AddHtLen); *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2)); *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3)); MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &HtCapIe, 1, &HtLen, HtLen, &HtCapabilityTmp, 1, &AddHtInfoIe, 1, &AddHtLen, AddHtLen, &addHTInfoTmp, END_OF_ARGS); #endif FrameLen += TmpLen; } #endif /* DOT11_N_SUPPORT */ /* Append RSN_IE when WPA OR WPAPSK, */ if (pAd->ApCfg.MBSSID[apidx].AuthMode < Ndis802_11AuthModeWPA) ; /* enough information */ else if ((pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1WPA2) || (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK)) { MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &RSNIe, 1, &pAd->ApCfg.MBSSID[apidx].RSNIE_Len[0], pAd->ApCfg.MBSSID[apidx].RSNIE_Len[0], pAd->ApCfg.MBSSID[apidx].RSN_IE[0], 1, &RSNIe2, 1, &pAd->ApCfg.MBSSID[apidx].RSNIE_Len[1], pAd->ApCfg.MBSSID[apidx].RSNIE_Len[1], pAd->ApCfg.MBSSID[apidx].RSN_IE[1], END_OF_ARGS); FrameLen += TmpLen; } else { MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &RSNIe, 1, &pAd->ApCfg.MBSSID[apidx].RSNIE_Len[0], pAd->ApCfg.MBSSID[apidx].RSNIE_Len[0], pAd->ApCfg.MBSSID[apidx].RSN_IE[0], END_OF_ARGS); FrameLen += TmpLen; } /* add WMM IE here */ if (pAd->ApCfg.MBSSID[apidx].bWmmCapable) { UCHAR i; UCHAR WmeParmIe[26] = {IE_VENDOR_SPECIFIC, 24, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0, 0}; WmeParmIe[8] = pAd->ApCfg.BssEdcaParm.EdcaUpdateCount & 0x0f; #ifdef UAPSD_SUPPORT UAPSD_MR_IE_FILL(WmeParmIe[8], &pAd->ApCfg.MBSSID[apidx].UapsdInfo); #endif /* UAPSD_SUPPORT */ for (i=QID_AC_BE; i<=QID_AC_VO; i++) { WmeParmIe[10+ (i*4)] = (i << 5) + /* b5-6 is ACI */ ((UCHAR)pAd->ApCfg.BssEdcaParm.bACM[i] << 4) + /* b4 is ACM */ (pAd->ApCfg.BssEdcaParm.Aifsn[i] & 0x0f); /* b0-3 is AIFSN */ WmeParmIe[11+ (i*4)] = (pAd->ApCfg.BssEdcaParm.Cwmax[i] << 4) + /* b5-8 is CWMAX */ (pAd->ApCfg.BssEdcaParm.Cwmin[i] & 0x0f); /* b0-3 is CWMIN */ WmeParmIe[12+ (i*4)] = (UCHAR)(pAd->ApCfg.BssEdcaParm.Txop[i] & 0xff); /* low byte of TXOP */ WmeParmIe[13+ (i*4)] = (UCHAR)(pAd->ApCfg.BssEdcaParm.Txop[i] >> 8); /* high byte of TXOP */ } MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 26, WmeParmIe, END_OF_ARGS); FrameLen += TmpLen; } #ifdef AP_QLOAD_SUPPORT if (pAd->FlgQloadEnable != 0) { FrameLen += QBSS_LoadElementAppend(pAd, pOutBuffer+FrameLen); } #endif /* AP_QLOAD_SUPPORT */ /* add country IE, power constraint IE */ if (pAd->CommonCfg.bCountryFlag) { ULONG TmpLen2=0; UCHAR *TmpFrame = NULL; os_alloc_mem(NULL, (UCHAR **)&TmpFrame, 256); if (TmpFrame != NULL) { NdisZeroMemory(TmpFrame, 256); /* prepare channel information */ #ifdef EXT_BUILD_CHANNEL_LIST BuildBeaconChList(pAd, TmpFrame, &TmpLen2); #else { ULONG TmpLen = 0; UCHAR MaxTxPower = GetCuntryMaxTxPwr(pAd, pAd->CommonCfg.Channel); MakeOutgoingFrame(TmpFrame+TmpLen2, &TmpLen, 1, &pAd->ChannelList[0].Channel, 1, &pAd->ChannelListNum, 1, &MaxTxPower, END_OF_ARGS); TmpLen2 += TmpLen; } #endif /* EXT_BUILD_CHANNEL_LIST */ os_free_mem(NULL, TmpFrame); } else DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); } #ifdef DOT11_N_SUPPORT #ifdef DOT11N_DRAFT3 /* P802.11n_D3.03, 7.3.2.60 Overlapping BSS Scan Parameters IE */ if (WMODE_CAP_N(PhyMode) && (pAd->CommonCfg.Channel <= 14) && (pAd->ApCfg.MBSSID[apidx].DesiredHtPhyInfo.bHtEnable) && (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == 1)) { OVERLAP_BSS_SCAN_IE OverlapScanParam; ULONG TmpLen; UCHAR OverlapScanIE, ScanIELen; OverlapScanIE = IE_OVERLAPBSS_SCAN_PARM; ScanIELen = 14; OverlapScanParam.ScanPassiveDwell = cpu2le16(pAd->CommonCfg.Dot11OBssScanPassiveDwell); OverlapScanParam.ScanActiveDwell = cpu2le16(pAd->CommonCfg.Dot11OBssScanActiveDwell); OverlapScanParam.TriggerScanInt = cpu2le16(pAd->CommonCfg.Dot11BssWidthTriggerScanInt); OverlapScanParam.PassiveTalPerChannel = cpu2le16(pAd->CommonCfg.Dot11OBssScanPassiveTotalPerChannel); OverlapScanParam.ActiveTalPerChannel = cpu2le16(pAd->CommonCfg.Dot11OBssScanActiveTotalPerChannel); OverlapScanParam.DelayFactor = cpu2le16(pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor); OverlapScanParam.ScanActThre = cpu2le16(pAd->CommonCfg.Dot11OBssScanActivityThre); MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &OverlapScanIE, 1, &ScanIELen, ScanIELen, &OverlapScanParam, END_OF_ARGS); FrameLen += TmpLen; } /* 7.3.2.27 Extended Capabilities IE */ { ULONG TmpLen; EXT_CAP_INFO_ELEMENT extCapInfo; UCHAR extInfoLen; extInfoLen = sizeof(EXT_CAP_INFO_ELEMENT); NdisZeroMemory(&extCapInfo, extInfoLen); /* P802.11n_D1.10, HT Information Exchange Support */ if (WMODE_CAP_N(PhyMode) && (pAd->CommonCfg.Channel <= 14) && (pAd->ApCfg.MBSSID[apidx].DesiredHtPhyInfo.bHtEnable) && (pAd->CommonCfg.bBssCoexEnable == TRUE)) { extCapInfo.BssCoexistMgmtSupport = 1; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &ExtCapIe, 1, &extInfoLen, extInfoLen, &extCapInfo, END_OF_ARGS); FrameLen += TmpLen; } } #endif /* DOT11N_DRAFT3 */ #endif /* DOT11_N_SUPPORT */ /* add Ralink-specific IE here - Byte0.b0=1 for aggregation, Byte0.b1=1 for piggy-back Byte0.b3=1 for rssi-feedback */ { ULONG TmpLen; UCHAR RalinkSpecificIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x00, 0x00, 0x00, 0x00}; if (pAd->CommonCfg.bAggregationCapable) RalinkSpecificIe[5] |= 0x1; if (pAd->CommonCfg.bPiggyBackCapable) RalinkSpecificIe[5] |= 0x2; #ifdef DOT11_N_SUPPORT if (pAd->CommonCfg.bRdg) RalinkSpecificIe[5] |= 0x4; #endif /* DOT11_N_SUPPORT */ #ifdef RSSI_FEEDBACK if (bRequestRssi == TRUE) { MAC_TABLE_ENTRY *pEntry=NULL; DBGPRINT(RT_DEBUG_ERROR, ("SYNC - Send PROBE_RSP to %02x:%02x:%02x:%02x:%02x:%02x...\n", PRINT_MAC(Addr2))); RalinkSpecificIe[5] |= 0x8; pEntry = MacTableLookup(pAd, Addr2); if (pEntry != NULL) { RalinkSpecificIe[6] = (UCHAR)pEntry->RssiSample.AvgRssi0; RalinkSpecificIe[7] = (UCHAR)pEntry->RssiSample.AvgRssi1; RalinkSpecificIe[8] = (UCHAR)pEntry->RssiSample.AvgRssi2; } } #endif /* RSSI_FEEDBACK */ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 9, RalinkSpecificIe, END_OF_ARGS); FrameLen += TmpLen; } #ifdef A_BAND_SUPPORT /* add Channel switch announcement IE */ if ((pAd->CommonCfg.Channel > 14) && (pAd->CommonCfg.bIEEE80211H == 1) && (pAd->Dot11_H.RDMode == RD_SWITCHING_MODE)) { UCHAR CSAIe=IE_CHANNEL_SWITCH_ANNOUNCEMENT; UCHAR CSALen=3; UCHAR CSAMode=1; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &CSAIe, 1, &CSALen, 1, &CSAMode, 1, &pAd->CommonCfg.Channel, 1, &pAd->Dot11_H.CSCount, END_OF_ARGS); FrameLen += TmpLen; #ifdef DOT11_N_SUPPORT if (pAd->CommonCfg.bExtChannelSwitchAnnouncement) { HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE HtExtChannelSwitchIe; build_ext_channel_switch_ie(pAd, &HtExtChannelSwitchIe); MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, sizeof(HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE), &HtExtChannelSwitchIe, END_OF_ARGS); FrameLen += TmpLen; } #endif /* DOT11_N_SUPPORT */ } #endif /* A_BAND_SUPPORT */ /* add country IE, power constraint IE */ if (pAd->CommonCfg.bCountryFlag) { ULONG TmpLen2=0; UCHAR TmpFrame[256]; UCHAR CountryIe = IE_COUNTRY; UCHAR MaxTxPower=16; #ifdef A_BAND_SUPPORT /* Only 802.11a APs that comply with 802.11h are required to include a Power Constrint Element(IE=32) in beacons and probe response frames */ if (pAd->CommonCfg.Channel > 14 && pAd->CommonCfg.bIEEE80211H == TRUE) { /* prepare power constraint IE */ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 3, PowerConstraintIE, END_OF_ARGS); FrameLen += TmpLen; #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(PhyMode)) { ULONG TmpLen; UINT8 vht_txpwr_env_ie = IE_VHT_TXPWR_ENV; UINT8 ie_len; VHT_TXPWR_ENV_IE txpwr_env; ie_len = build_vht_txpwr_envelope(pAd, (UCHAR *)&txpwr_env); MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &vht_txpwr_env_ie, 1, &ie_len, ie_len, &txpwr_env, END_OF_ARGS); FrameLen += TmpLen; } #endif /* DOT11_VHT_AC */ } #endif /* A_BAND_SUPPORT */ NdisZeroMemory(TmpFrame, sizeof(TmpFrame)); /* prepare channel information */ MakeOutgoingFrame(TmpFrame+TmpLen2, &TmpLen, 1, &pAd->ChannelList[0].Channel, 1, &pAd->ChannelListNum, 1, &MaxTxPower, END_OF_ARGS); TmpLen2 += TmpLen; /* need to do the padding bit check, and concatenate it */ if ((TmpLen2%2) == 0) { UCHAR TmpLen3 = TmpLen2+4; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &CountryIe, 1, &TmpLen3, 3, pAd->CommonCfg.CountryCode, TmpLen2+1, TmpFrame, END_OF_ARGS); } else { UCHAR TmpLen3 = TmpLen2+3; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &CountryIe, 1, &TmpLen3, 3, pAd->CommonCfg.CountryCode, TmpLen2, TmpFrame, END_OF_ARGS); } FrameLen += TmpLen; }/* Country IE - */ #ifdef DOT11_N_SUPPORT if (WMODE_CAP_N(PhyMode) && (pAd->ApCfg.MBSSID[apidx].DesiredHtPhyInfo.bHtEnable)) { ULONG TmpLen; UCHAR HtLen, AddHtLen;/*, NewExtLen; */ #ifdef RT_BIG_ENDIAN HT_CAPABILITY_IE HtCapabilityTmp; ADD_HT_INFO_IE addHTInfoTmp; #endif HtLen = sizeof(pAd->CommonCfg.HtCapability); AddHtLen = sizeof(pAd->CommonCfg.AddHTInfo); if (pAd->bBroadComHT == TRUE) { UCHAR epigram_ie_len; UCHAR BROADCOM_HTC[4] = {0x0, 0x90, 0x4c, 0x33}; UCHAR BROADCOM_AHTINFO[4] = {0x0, 0x90, 0x4c, 0x34}; epigram_ie_len = HtLen + 4; #ifndef RT_BIG_ENDIAN MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_HTC[0], HtLen, &pAd->CommonCfg.HtCapability, END_OF_ARGS); #else NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen); *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo)); #ifdef UNALIGNMENT_SUPPORT { EXT_HT_CAP_INFO extHtCapInfo; NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); } #else *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = cpu2le16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo)); #endif /* UNALIGNMENT_SUPPORT */ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_HTC[0], HtLen, &HtCapabilityTmp, END_OF_ARGS); #endif FrameLen += TmpLen; epigram_ie_len = AddHtLen + 4; #ifndef RT_BIG_ENDIAN MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_AHTINFO[0], AddHtLen, &pAd->CommonCfg.AddHTInfo, END_OF_ARGS); #else NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, AddHtLen); *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2)); *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3)); MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_AHTINFO[0], AddHtLen, &addHTInfoTmp, END_OF_ARGS); #endif FrameLen += TmpLen; } #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(PhyMode) && (pAd->CommonCfg.Channel > 14)) { FrameLen += build_vht_ies(pAd, (UCHAR *)(pOutBuffer+FrameLen), SUBTYPE_PROBE_RSP, pAd->CommonCfg.vht_max_mcs_cap); } #endif /* DOT11_VHT_AC */ } #endif /* DOT11_N_SUPPORT */ #ifdef WSC_AP_SUPPORT /* for windows 7 logo test */ if ((pAd->ApCfg.MBSSID[apidx].WscControl.WscConfMode != WSC_DISABLE) && #ifdef DOT1X_SUPPORT (pAd->ApCfg.MBSSID[apidx].IEEE8021X == FALSE) && #endif /* DOT1X_SUPPORT */ (pAd->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11WEPEnabled)) { /* Non-WPS Windows XP and Vista PCs are unable to determine if a WEP enalbed network is static key based or 802.1X based. If the legacy station gets an EAP-Rquest/Identity from the AP, it assume the WEP network is 802.1X enabled & will prompt the user for 802.1X credentials. If the legacy station doesn't receive anything after sending an EAPOL-Start, it will assume the WEP network is static key based and prompt user for the WEP key. <<from "WPS and Static Key WEP Networks">> A WPS enabled AP should include this IE in the beacon when the AP is hosting a static WEP key network. The IE would be 7 bytes long with the Extended Capability field set to 0 (all bits zero) http://msdn.microsoft.com/library/default.asp?url=/library/en-us/randz/protocol/securing_public_wi-fi_hotspots.asp */ ULONG TempLen1 = 0; UCHAR PROVISION_SERVICE_IE[7] = {0xDD, 0x05, 0x00, 0x50, 0xF2, 0x05, 0x00}; MakeOutgoingFrame(pOutBuffer+FrameLen, &TempLen1, 7, PROVISION_SERVICE_IE, END_OF_ARGS); FrameLen += TempLen1; } /* add Simple Config Information Element */ if ((pAd->ApCfg.MBSSID[apidx].WscControl.WscConfMode > WSC_DISABLE) && (pAd->ApCfg.MBSSID[apidx].WscIEProbeResp.ValueLen)) { ULONG WscTmpLen = 0; MakeOutgoingFrame(pOutBuffer+FrameLen, &WscTmpLen, pAd->ApCfg.MBSSID[apidx].WscIEProbeResp.ValueLen, pAd->ApCfg.MBSSID[apidx].WscIEProbeResp.Value, END_OF_ARGS); FrameLen += WscTmpLen; } #endif /* WSC_AP_SUPPORT */ #ifdef RT_CFG80211_SUPPORT if (pAd->ApCfg.MBSSID[apidx].ProbRespExtraIeLen != 0) { MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, pAd->ApCfg.MBSSID[apidx].ProbRespExtraIeLen, &pAd->ApCfg.MBSSID[apidx].ProbRespExtraIe[0], END_OF_ARGS); FrameLen += TmpLen; } #endif /* RT_CFG80211_SUPPORT */ /* 802.11n 11.1.3.2.2 active scanning. sending probe response with MCS rate is */ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); }
/* ========================================================================== Description: MLME message sanity check Return: TRUE if all parameters are OK, FALSE otherwise ========================================================================== */ static BOOLEAN APPeerAuthSanity( IN RTMP_ADAPTER *pAd, IN VOID *Msg, IN ULONG MsgLen, IN AUTH_FRAME_INFO *auth_info) { PFRAME_802_11 Fr = (PFRAME_802_11)Msg; COPY_MAC_ADDR(auth_info->addr1, &Fr->Hdr.Addr1); /* BSSID */ COPY_MAC_ADDR(auth_info->addr2, &Fr->Hdr.Addr2); /* SA */ // TODO: shiang-usw, how about the endian issue here?? NdisMoveMemory(&auth_info->auth_alg, &Fr->Octet[0], 2); NdisMoveMemory(&auth_info->auth_seq, &Fr->Octet[2], 2); NdisMoveMemory(&auth_info->auth_status, &Fr->Octet[4], 2); if (auth_info->auth_alg == AUTH_MODE_OPEN) { if (auth_info->auth_seq == 1 || auth_info->auth_seq == 2) return TRUE; else { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s(): fail - wrong Seg# (=%d)\n", __FUNCTION__, auth_info->auth_seq)); return FALSE; } } else if (auth_info->auth_alg == AUTH_MODE_KEY) { if (auth_info->auth_seq == 1 || auth_info->auth_seq == 4) return TRUE; else if (auth_info->auth_seq == 2 || auth_info->auth_seq == 3) { NdisMoveMemory(auth_info->Chtxt, &Fr->Octet[8], CIPHER_TEXT_LEN); return TRUE; } else { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s(): fail - wrong Seg# (=%d)\n", __FUNCTION__, auth_info->auth_seq)); return FALSE; } } #ifdef DOT11R_FT_SUPPORT else if (auth_info->auth_alg == AUTH_MODE_FT) { PEID_STRUCT eid_ptr; UCHAR *Ptr; UCHAR WPA2_OUI[3]={0x00,0x0F,0xAC}; PFT_INFO pFtInfo = &auth_info->FtInfo; NdisZeroMemory(pFtInfo, sizeof(FT_INFO)); Ptr = &Fr->Octet[6]; eid_ptr = (PEID_STRUCT) Ptr; /* get variable fields from payload and advance the pointer */ while(((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((UCHAR*)Fr + MsgLen)) { switch(eid_ptr->Eid) { case IE_FT_MDIE: FT_FillMdIeInfo(eid_ptr, &pFtInfo->MdIeInfo); break; case IE_FT_FTIE: FT_FillFtIeInfo(eid_ptr, &pFtInfo->FtIeInfo); break; case IE_FT_RIC_DATA: /* record the pointer of first RDIE. */ if (pFtInfo->RicInfo.pRicInfo == NULL) { pFtInfo->RicInfo.pRicInfo = &eid_ptr->Eid; pFtInfo->RicInfo.Len = ((UCHAR*)Fr + MsgLen) - (UCHAR*)eid_ptr + 1; } if ((pFtInfo->RicInfo.RicIEsLen + eid_ptr->Len + 2) < MAX_RICIES_LEN) { NdisMoveMemory(&pFtInfo->RicInfo.RicIEs[pFtInfo->RicInfo.RicIEsLen], &eid_ptr->Eid, eid_ptr->Len + 2); pFtInfo->RicInfo.RicIEsLen += eid_ptr->Len + 2; } break; case IE_FT_RIC_DESCRIPTOR: if ((pFtInfo->RicInfo.RicIEsLen + eid_ptr->Len + 2) < MAX_RICIES_LEN) { NdisMoveMemory(&pFtInfo->RicInfo.RicIEs[pFtInfo->RicInfo.RicIEsLen], &eid_ptr->Eid, eid_ptr->Len + 2); pFtInfo->RicInfo.RicIEsLen += eid_ptr->Len + 2; } break; case IE_RSN: if (NdisEqualMemory(&eid_ptr->Octet[2], WPA2_OUI, sizeof(WPA2_OUI))) { NdisMoveMemory(pFtInfo->RSN_IE, eid_ptr, eid_ptr->Len + 2); pFtInfo->RSNIE_Len = eid_ptr->Len + 2; } break; default: break; } eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len); } } #endif /* DOT11R_FT_SUPPORT */ else { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s(): fail - wrong algorithm (=%d)\n", __FUNCTION__, auth_info->auth_alg)); return FALSE; } return TRUE; }
int rt28xx_init( IN PRTMP_ADAPTER pAd, IN PSTRING pDefaultMac, IN PSTRING pHostName) { UINT index; UCHAR TmpPhy; NDIS_STATUS Status; UINT32 MacCsr0 = 0; #ifdef CONFIG_STA_SUPPORT #ifdef PCIE_PS_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { // If dirver doesn't wake up firmware here, // NICLoadFirmware will hang forever when interface is up again. if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) { AUTO_WAKEUP_STRUC AutoWakeupCfg; AsicForceWakeup(pAd, TRUE); AutoWakeupCfg.word = 0; RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word); OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE); } } #endif // PCIE_PS_SUPPORT // #endif // CONFIG_STA_SUPPORT // // reset Adapter flags RTMP_CLEAR_FLAGS(pAd); // Init BssTab & ChannelInfo tabbles for auto channel select. #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { AutoChBssTableInit(pAd); ChannelInfoInit(pAd); } #endif // CONFIG_AP_SUPPORT // #ifdef DOT11_N_SUPPORT // Allocate BA Reordering memory if (ba_reordering_resource_init(pAd, MAX_REORDERING_MPDU_NUM) != TRUE) goto err1; #endif // DOT11_N_SUPPORT // // Make sure MAC gets ready. index = 0; do { RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0); pAd->MACVersion = MacCsr0; if ((pAd->MACVersion != 0x00) && (pAd->MACVersion != 0xFFFFFFFF)) break; if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) goto err1; RTMPusecDelay(10); } while (index++ < 100); DBGPRINT(RT_DEBUG_TRACE, ("MAC_CSR0 [ Ver:Rev=0x%08x]\n", pAd->MACVersion)); #ifdef RTMP_MAC_PCI // To fix driver disable/enable hang issue when radio off RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x2); #endif // RTMP_MAC_PCI // // Disable DMA RT28XXDMADisable(pAd); // Load 8051 firmware Status = NICLoadFirmware(pAd); if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT_ERR(("NICLoadFirmware failed, Status[=0x%08x]\n", Status)); goto err1; } NICLoadRateSwitchingParams(pAd); // Disable interrupts here which is as soon as possible // This statement should never be true. We might consider to remove it later #ifdef RTMP_MAC_PCI if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE)) { RTMP_ASIC_INTERRUPT_DISABLE(pAd); } #endif // RTMP_MAC_PCI // #ifdef RESOURCE_PRE_ALLOC Status = RTMPInitTxRxRingMemory(pAd); #else Status = RTMPAllocTxRxRingMemory(pAd); #endif // RESOURCE_PRE_ALLOC // if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT_ERR(("RTMPAllocTxRxMemory failed, Status[=0x%08x]\n", Status)); goto err2; } RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE); // initialize MLME // Status = RtmpMgmtTaskInit(pAd); if (Status != NDIS_STATUS_SUCCESS) goto err3; Status = MlmeInit(pAd); if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT_ERR(("MlmeInit failed, Status[=0x%08x]\n", Status)); goto err4; } #ifdef RMTP_RBUS_SUPPORT #ifdef VIDEO_TURBINE_SUPPORT VideoConfigInit(pAd); #endif // VIDEO_TURBINE_SUPPORT // #endif // RMTP_RBUS_SUPPORT // // Initialize pAd->StaCfg, pAd->ApCfg, pAd->CommonCfg to manufacture default // UserCfgInit(pAd); Status = RtmpNetTaskInit(pAd); if (Status != NDIS_STATUS_SUCCESS) goto err5; // COPY_MAC_ADDR(pAd->ApCfg.MBSSID[apidx].Bssid, netif->hwaddr); // pAd->bForcePrintTX = TRUE; CfgInitHook(pAd); #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) APInitialize(pAd); #endif // CONFIG_AP_SUPPORT // #ifdef BLOCK_NET_IF initblockQueueTab(pAd); #endif // BLOCK_NET_IF // Status = MeasureReqTabInit(pAd); if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT_ERR(("MeasureReqTabInit failed, Status[=0x%08x]\n",Status)); goto err6; } Status = TpcReqTabInit(pAd); if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT_ERR(("TpcReqTabInit failed, Status[=0x%08x]\n",Status)); goto err6; } // // Init the hardware, we need to init asic before read registry, otherwise mac register will be reset // Status = NICInitializeAdapter(pAd, TRUE); if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT_ERR(("NICInitializeAdapter failed, Status[=0x%08x]\n", Status)); if (Status != NDIS_STATUS_SUCCESS) goto err6; } // Read parameters from Config File Status = RTMPReadParametersHook(pAd); DBGPRINT(RT_DEBUG_OFF, ("1. Phy Mode = %d\n", pAd->CommonCfg.PhyMode)); if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT_ERR(("RTMPReadParametersHook failed, Status[=0x%08x]\n",Status)); goto err6; } #ifdef DOT11_N_SUPPORT //Init Ba Capability parameters. // RT28XX_BA_INIT(pAd); pAd->CommonCfg.DesiredHtPhy.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity; pAd->CommonCfg.DesiredHtPhy.AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable; pAd->CommonCfg.DesiredHtPhy.AmsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize; pAd->CommonCfg.DesiredHtPhy.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode; // UPdata to HT IE pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode; pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize; pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity; #endif // DOT11_N_SUPPORT // // after reading Registry, we now know if in AP mode or STA mode // Load 8051 firmware; crash when FW image not existent // Status = NICLoadFirmware(pAd); // if (Status != NDIS_STATUS_SUCCESS) // break; DBGPRINT(RT_DEBUG_OFF, ("2. Phy Mode = %d\n", pAd->CommonCfg.PhyMode)); // We should read EEPROM for all cases. rt2860b NICReadEEPROMParameters(pAd, (PUCHAR)pDefaultMac); #ifdef CONFIG_STA_SUPPORT #endif // CONFIG_STA_SUPPORT // DBGPRINT(RT_DEBUG_OFF, ("3. Phy Mode = %d\n", pAd->CommonCfg.PhyMode)); NICInitAsicFromEEPROM(pAd); //rt2860b #ifdef RTMP_INTERNAL_TX_ALC // // Initialize the desired TSSI table // InitDesiredTSSITable(pAd); #endif // RTMP_INTERNAL_TX_ALC // // Set PHY to appropriate mode TmpPhy = pAd->CommonCfg.PhyMode; pAd->CommonCfg.PhyMode = 0xff; RTMPSetPhyMode(pAd, TmpPhy); #ifdef DOT11_N_SUPPORT SetCommonHT(pAd); #endif // DOT11_N_SUPPORT // // No valid channels. if (pAd->ChannelListNum == 0) { DBGPRINT(RT_DEBUG_ERROR, ("Wrong configuration. No valid channel found. Check \"ContryCode\" and \"ChannelGeography\" setting.\n")); goto err6; } #ifdef DOT11_N_SUPPORT DBGPRINT(RT_DEBUG_OFF, ("MCS Set = %02x %02x %02x %02x %02x\n", pAd->CommonCfg.HtCapability.MCSSet[0], pAd->CommonCfg.HtCapability.MCSSet[1], pAd->CommonCfg.HtCapability.MCSSet[2], pAd->CommonCfg.HtCapability.MCSSet[3], pAd->CommonCfg.HtCapability.MCSSet[4])); #endif // DOT11_N_SUPPORT // #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { #ifdef AP_QLOAD_SUPPORT /* init QBSS Element */ QBSS_LoadInit(pAd); #endif // AP_QLOAD_SUPPORT // } #endif // CONFIG_AP_SUPPORT // // APInitialize(pAd); #ifdef IKANOS_VX_1X0 VR_IKANOS_FP_Init(pAd->ApCfg.BssidNum, pAd->PermanentAddress); #endif // IKANOS_VX_1X0 // // // Initialize RF register to default value // AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); AsicLockChannel(pAd, pAd->CommonCfg.Channel); /* Some modules init must be called before APStartUp(). Or APStartUp() will make up beacon content and call other modules API to get some information to fill. */ #ifdef WMM_ACM_SUPPORT #ifdef CONFIG_AP_SUPPORT ACMP_Init(pAd, pAd->CommonCfg.APEdcaParm.bACM[0], pAd->CommonCfg.APEdcaParm.bACM[1], pAd->CommonCfg.APEdcaParm.bACM[2], pAd->CommonCfg.APEdcaParm.bACM[3], 0); #endif // CONFIG_AP_SUPPORT // #ifdef CONFIG_STA_SUPPORT ACMP_Init(pAd); #endif // CONFIG_STA_SUPPORT // #endif // WMM_ACM_SUPPORT // if (pAd && (Status != NDIS_STATUS_SUCCESS)) { // // Undo everything if it failed // if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { // NdisMDeregisterInterrupt(&pAd->Interrupt); RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE); } // RTMPFreeAdapter(pAd); // we will free it in disconnect() } else if (pAd) { // Microsoft HCT require driver send a disconnect event after driver initialization. OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); // pAd->IndicateMediaState = NdisMediaStateDisconnected; RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE); DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event B!\n")); #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { if (pAd->ApCfg.bAutoChannelAtBootup || (pAd->CommonCfg.Channel == 0)) { UINT8 BBPValue = 0; // Enable Interrupt first due to we need to scan channel to receive beacons. RTMP_IRQ_ENABLE(pAd); // Now Enable RxTx RTMPEnableRxTx(pAd); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP); // Let BBP register at 20MHz to do scan RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); BBPValue &= (~0x18); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); DBGPRINT(RT_DEBUG_ERROR, ("SYNC - BBP R4 to 20MHz.l\n")); // Now we can receive the beacon and do the listen beacon // use default BW to select channel pAd->CommonCfg.Channel = AP_AUTO_CH_SEL(pAd, pAd->ApCfg.AutoChannelAlg); pAd->ApCfg.bAutoChannelAtBootup = FALSE; } #ifdef DOT11_N_SUPPORT // If phymode > PHY_11ABGN_MIXED and BW=40 check extension channel, after select channel N_ChannelCheck(pAd); #ifdef DOT11N_DRAFT3 /* We only do this Overlapping BSS Scan when system up, for the other situation of channel changing, we depends on station's report to adjust ourself. */ if (pAd->CommonCfg.bForty_Mhz_Intolerant == TRUE) { DBGPRINT(RT_DEBUG_TRACE, ("Disable 20/40 BSSCoex Channel Scan(BssCoex=%d, 40MHzIntolerant=%d)\n", pAd->CommonCfg.bBssCoexEnable, pAd->CommonCfg.bForty_Mhz_Intolerant)); } else if(pAd->CommonCfg.bBssCoexEnable == TRUE) { DBGPRINT(RT_DEBUG_TRACE, ("Enable 20/40 BSSCoex Channel Scan(BssCoex=%d)\n", pAd->CommonCfg.bBssCoexEnable)); APOverlappingBSSScan(pAd); } RTMP_11N_D3_TimerInit(pAd); // RTMPInitTimer(pAd, &pAd->CommonCfg.Bss2040CoexistTimer, GET_TIMER_FUNCTION(Bss2040CoexistTimeOut), pAd, FALSE); #endif // DOT11N_DRAFT3 // #endif // DOT11_N_SUPPORT // #ifdef RELASE_EXCLUDE /* 3090, 3090A and 3390 all support hadware tone radar function. But the soluation of those are different. 3090 is the old one. */ #endif // RELASE_EXCLUDE // APStartUp(pAd); DBGPRINT(RT_DEBUG_OFF, ("Main bssid = %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(pAd->ApCfg.MBSSID[BSS0].Bssid))); } #endif // CONFIG_AP_SUPPORT // }// end of else #ifdef WSC_INCLUDED #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { INT apidx; #ifdef HOSTAPD_SUPPORT if (pAd->ApCfg.Hostapd == TRUE) { DBGPRINT(RT_DEBUG_TRACE, ("WPS is control by hostapd now.\n")); } else #endif //HOSTAPD_SUPPORT// for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++) { PWSC_CTRL pWscControl; UCHAR zeros16[16]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; pWscControl = &pAd->ApCfg.MBSSID[apidx].WscControl; DBGPRINT(RT_DEBUG_TRACE, ("Generate UUID for apidx(%d)\n", apidx)); if (NdisEqualMemory(&pWscControl->Wsc_Uuid_E[0], zeros16, UUID_LEN_HEX)) WscGenerateUUID(pAd, &pWscControl->Wsc_Uuid_E[0], &pWscControl->Wsc_Uuid_Str[0], apidx, FALSE); WscInit(pAd, FALSE, apidx); if (pWscControl->WscEnrolleePinCode == 0) { pWscControl->WscEnrolleePinCode = GenerateWpsPinCode(pAd, FALSE, apidx); pWscControl->WscEnrolleePinCodeLen = 8; } } } #endif // CONFIG_AP_SUPPORT // #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { PWSC_CTRL pWscControl = &pAd->StaCfg.WscControl; WscGenerateUUID(pAd, &pWscControl->Wsc_Uuid_E[0], &pWscControl->Wsc_Uuid_Str[0], 0, FALSE); WscInit(pAd, BSS0); if (pWscControl->WscEnrolleePinCode == 0) { pWscControl->WscEnrolleePinCode = GenerateWpsPinCode(pAd, BSS0); pWscControl->WscEnrolleePinCodeLen = 8; } } #endif // CONFIG_STA_SUPPORT // /* WSC hardware push button function 0811 */ WSC_HDR_BTN_Init(pAd); #endif // WSC_INCLUDED // // Set up the Mac address RtmpOSNetDevAddrSet(pAd->net_dev, &pAd->CurrentAddress[0]); // Various AP function init #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { #ifdef MBSS_SUPPORT /* the function can not be moved to RT2860_probe() even register_netdev() is changed as register_netdevice(). Or in some PC, kernel will panic (Fedora 4) */ RT28xx_MBSS_Init(pAd, pAd->net_dev); #endif // MBSS_SUPPORT // #ifdef WDS_SUPPORT RT28xx_WDS_Init(pAd, pAd->net_dev); #endif // WDS_SUPPORT // #ifdef APCLI_SUPPORT RT28xx_ApCli_Init(pAd, pAd->net_dev); #endif // APCLI_SUPPORT // } #endif // CONFIG_AP_SUPPORT // #ifdef RTMP_RBUS_SUPPORT #ifdef VIDEO_TURBINE_SUPPORT VideoTurbineDynamicTune(pAd); #endif // VIDEO_TURBINE_SUPPORT // #endif // RTMP_RBUS_SUPPORT // #ifdef RTMP_RBUS_SUPPORT #ifdef RT3XXX_ANTENNA_DIVERSITY_SUPPORT RT3XXX_AntDiversity_Init(pAd); #endif // RT3XXX_ANTENNA_DIVERSITY_SUPPORT // #endif // RTMP_RBUS_SUPPORT // #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { #ifdef MAT_SUPPORT MATEngineInit(pAd); #endif // MAT_SUPPORT // #ifdef CLIENT_WDS CliWds_ProxyTabInit(pAd); #endif // CLIENT_WDS // } #endif // CONFIG_AP_SUPPORT // #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { #ifdef DOT11Z_TDLS_SUPPORT TDLS_Table_Init(pAd); #endif // DOT11Z_TDLS_SUPPORT // #ifdef WPA_SUPPLICANT_SUPPORT #ifndef NATIVE_WPA_SUPPLICANT_SUPPORT // send wireless event to wpa_supplicant for infroming interface up. RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, RT_INTERFACE_UP, NULL, NULL, 0); #endif // NATIVE_WPA_SUPPLICANT_SUPPORT // #endif // WPA_SUPPLICANT_SUPPORT // } #endif // CONFIG_STA_SUPPORT // #if defined(RT2883) || defined(RT3883) #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { if (IS_RT2883(pAd) || IS_RT3883(pAd)) { #ifdef RANGE_EXT_SUPPORT RTMP_IO_WRITE32(pAd, HT_FBK_CFG1, 0xedcba980); #endif // RANGE_EXT_SUPPORT // RTMP_IO_WRITE32(pAd, TX_FBK_CFG_3S_0, 0x12111008); RTMP_IO_WRITE32(pAd, TX_FBK_CFG_3S_1, 0x16151413); } #ifdef STREAM_MODE_SUPPORT if (pAd->CommonCfg.StreamMode > 0) { ULONG streamWord = StreamModeRegVal(pAd); RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR0_L, (ULONG)(pAd->CommonCfg.StreamModeMac[0][0]) | (ULONG)(pAd->CommonCfg.StreamModeMac[0][1] << 8) | (ULONG)(pAd->CommonCfg.StreamModeMac[0][2] << 16) | (ULONG)(pAd->CommonCfg.StreamModeMac[0][3] << 24)); RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR0_H, streamWord | (ULONG)(pAd->CommonCfg.StreamModeMac[0][4]) | (ULONG)(pAd->CommonCfg.StreamModeMac[0][5] << 8)); RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR1_L, (ULONG)(pAd->CommonCfg.StreamModeMac[1][0]) | (ULONG)(pAd->CommonCfg.StreamModeMac[1][1] << 8) | (ULONG)(pAd->CommonCfg.StreamModeMac[1][2] << 16) | (ULONG)(pAd->CommonCfg.StreamModeMac[1][3] << 24)); RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR1_H, streamWord | (ULONG)(pAd->CommonCfg.StreamModeMac[1][4]) | (ULONG)(pAd->CommonCfg.StreamModeMac[1][5] << 8)); RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR2_L, (ULONG)(pAd->CommonCfg.StreamModeMac[2][0]) | (ULONG)(pAd->CommonCfg.StreamModeMac[2][1] << 8) | (ULONG)(pAd->CommonCfg.StreamModeMac[2][2] << 16) | (ULONG)(pAd->CommonCfg.StreamModeMac[2][3] << 24)); RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR2_H, streamWord | (ULONG)(pAd->CommonCfg.StreamModeMac[2][4]) | (ULONG)(pAd->CommonCfg.StreamModeMac[2][5] << 8)); RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR3_L, (ULONG)(pAd->CommonCfg.StreamModeMac[3][0]) | (ULONG)(pAd->CommonCfg.StreamModeMac[3][1] << 8) | (ULONG)(pAd->CommonCfg.StreamModeMac[3][2] << 16) | (ULONG)(pAd->CommonCfg.StreamModeMac[3][3] << 24)); RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR3_H, streamWord | (ULONG)(pAd->CommonCfg.StreamModeMac[3][4]) | (ULONG)(pAd->CommonCfg.StreamModeMac[3][5] << 8)); } #endif // STREAM_MODE_SUPPORT // } #endif // CONFIG_AP_SUPPORT // if (pAd->CommonCfg.FineAGC) { UINT8 BBPValue = 0; BBP_IO_READ8_BY_REG_ID(pAd, BBP_R65, &BBPValue); BBPValue |= 0x40; // turn on fine AGC BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R65, BBPValue); } else { UINT8 BBPValue = 0; BBP_IO_READ8_BY_REG_ID(pAd, BBP_R65, &BBPValue); BBPValue &= ~0x40; // turn off fine AGC BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R65, BBPValue); } #endif // defined(RT2883) || defined(RT3883) // #ifdef DOT11_N_SUPPORT #ifdef TXBF_SUPPORT if (pAd->CommonCfg.ITxBfTimeout) { RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R179, 0x02); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R180, 0); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R182, pAd->CommonCfg.ITxBfTimeout & 0xFF); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R180, 1); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R182, (pAd->CommonCfg.ITxBfTimeout>>8) & 0xFF); }
int rt28xx_init( IN PRTMP_ADAPTER pAd, IN PSTRING pDefaultMac, IN PSTRING pHostName) { UINT index; UCHAR TmpPhy; NDIS_STATUS Status; UINT32 MacCsr0 = 0; UINT16 ChipId = 0; // reset Adapter flags RTMP_CLEAR_FLAGS(pAd); // Init BssTab & ChannelInfo tabbles for auto channel select. #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { //#ifdef AUTO_CH_SELECT_ENHANCE AutoChBssTableInit(pAd); ChannelInfoInit(pAd); //#endif // AUTO_CH_SELECT_ENHANCE // } #endif // CONFIG_AP_SUPPORT // #ifdef DOT11_N_SUPPORT // Allocate BA Reordering memory if (ba_reordering_resource_init(pAd, MAX_REORDERING_MPDU_NUM) != TRUE) goto err1; #endif // DOT11_N_SUPPORT // // Make sure MAC gets ready. index = 0; do { RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0); pAd->MACVersion = MacCsr0; /* The purpose is to identify RT5390H */ RT28xx_EEPROM_READ16(pAd, 0x00, ChipId); pAd->ChipId = ChipId; if ((pAd->MACVersion != 0x00) && (pAd->MACVersion != 0xFFFFFFFF)) break; if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) goto err1; RTMPusecDelay(10); } while (index++ < 100); DBGPRINT(RT_DEBUG_TRACE, ("MAC_CSR0 [ Ver:Rev=0x%08x]\n", pAd->MACVersion)); #ifdef RT5390 if (IS_RT5390H(pAd)) DBGPRINT(RT_DEBUG_ERROR, ("The chip belongs to 0x%04x\n", pAd->ChipId)); #endif /* RT5390 */ #ifdef SPECIFIC_BCN_BUF_SUPPORT pAd->BcnCB.DYN_MAX_MBSSID_NUM = 1; if (IS_RT5390(pAd) || IS_RT3593(pAd)) { pAd->BcnCB.bHighShareMemSupport = 1; pAd->BcnCB.DYN_HW_BEACON_BASE0 = 0x4000; pAd->BcnCB.DYN_HW_BEACON_MAX_SIZE = 0x2000; pAd->BcnCB.DYN_HW_BEACON_MAX_COUNT = 16; #ifdef MBSS_SUPPORT #ifdef APCLI_SUPPORT pAd->BcnCB.DYN_MAX_MBSSID_NUM = 8 - MAX_MESH_NUM; #else pAd->BcnCB.DYN_MAX_MBSSID_NUM = 16 - MAX_MESH_NUM; #endif // APCLI_SUPPORT // #endif // MBSS_SUPPORT // } else { pAd->BcnCB.bHighShareMemSupport = 0; pAd->BcnCB.DYN_HW_BEACON_BASE0 = 0x7800; pAd->BcnCB.DYN_HW_BEACON_MAX_SIZE = 0x1000; pAd->BcnCB.DYN_HW_BEACON_MAX_COUNT = 8; #ifdef MBSS_SUPPORT pAd->BcnCB.DYN_MAX_MBSSID_NUM = (pAd->BcnCB.DYN_HW_BEACON_MAX_COUNT - MAX_MESH_NUM - MAX_APCLI_NUM); #endif // MBSS_SUPPORT // } #endif // SPECIFIC_BCN_BUF_SUPPORT // #ifdef RTMP_MAC_PCI #if defined(RT3090) || defined(RT3592) || defined(RT3390) || defined(RT3593) || defined(RT5390) /*Iverson patch PCIE L1 issue to make sure that driver can be read,write ,BBP and RF register at pcie L.1 level */ if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd) || IS_RT3593(pAd) || IS_RT5390(pAd))&&pAd->infType==RTMP_DEV_INF_PCIE) { RTMP_IO_READ32(pAd, AUX_CTRL, &MacCsr0); MacCsr0 |= 0x402; RTMP_IO_WRITE32(pAd, AUX_CTRL, MacCsr0); DBGPRINT(RT_DEBUG_TRACE, ("AUX_CTRL = 0x%x\n", MacCsr0)); } #endif // RT3090 // // To fix driver disable/enable hang issue when radio off RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x2); #endif // RTMP_MAC_PCI // // Disable DMA RT28XXDMADisable(pAd); // Load 8051 firmware Status = NICLoadFirmware(pAd); if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT_ERR(("NICLoadFirmware failed, Status[=0x%08x]\n", Status)); goto err1; } NICLoadRateSwitchingParams(pAd); // Disable interrupts here which is as soon as possible // This statement should never be true. We might consider to remove it later #ifdef RTMP_MAC_PCI if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE)) { RTMP_ASIC_INTERRUPT_DISABLE(pAd); } #endif // RTMP_MAC_PCI // #ifdef RESOURCE_PRE_ALLOC Status = RTMPInitTxRxRingMemory(pAd); #else Status = RTMPAllocTxRxRingMemory(pAd); #endif // RESOURCE_PRE_ALLOC // if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT_ERR(("RTMPAllocTxRxMemory failed, Status[=0x%08x]\n", Status)); goto err2; } RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE); // initialize MLME // Status = RtmpMgmtTaskInit(pAd); if (Status != NDIS_STATUS_SUCCESS) goto err3; Status = MlmeInit(pAd); if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT_ERR(("MlmeInit failed, Status[=0x%08x]\n", Status)); goto err4; } #ifdef RMTP_RBUS_SUPPORT #ifdef VIDEO_TURBINE_SUPPORT VideoConfigInit(pAd); #endif // VIDEO_TURBINE_SUPPORT // #endif // RMTP_RBUS_SUPPORT // // Initialize pAd->StaCfg, pAd->ApCfg, pAd->CommonCfg to manufacture default // UserCfgInit(pAd); Status = RtmpNetTaskInit(pAd); if (Status != NDIS_STATUS_SUCCESS) goto err5; // COPY_MAC_ADDR(pAd->ApCfg.MBSSID[apidx].Bssid, netif->hwaddr); // pAd->bForcePrintTX = TRUE; CfgInitHook(pAd); #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) APInitialize(pAd); #endif // CONFIG_AP_SUPPORT // #ifdef BLOCK_NET_IF initblockQueueTab(pAd); #endif // BLOCK_NET_IF // Status = MeasureReqTabInit(pAd); if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT_ERR(("MeasureReqTabInit failed, Status[=0x%08x]\n",Status)); goto err6; } Status = TpcReqTabInit(pAd); if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT_ERR(("TpcReqTabInit failed, Status[=0x%08x]\n",Status)); goto err6; } // // Init the hardware, we need to init asic before read registry, otherwise mac register will be reset // Status = NICInitializeAdapter(pAd, TRUE); if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT_ERR(("NICInitializeAdapter failed, Status[=0x%08x]\n", Status)); if (Status != NDIS_STATUS_SUCCESS) goto err6; } #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { } #endif // CONFIG_AP_SUPPORT // // Read parameters from Config File /* unknown, it will be updated in NICReadEEPROMParameters */ pAd->RfIcType = RFIC_UNKNOWN; Status = RTMPReadParametersHook(pAd); DBGPRINT(RT_DEBUG_OFF, ("1. Phy Mode = %d\n", pAd->CommonCfg.PhyMode)); if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT_ERR(("RTMPReadParametersHook failed, Status[=0x%08x]\n",Status)); goto err6; } #ifdef DOT11_N_SUPPORT //Init Ba Capability parameters. // RT28XX_BA_INIT(pAd); pAd->CommonCfg.DesiredHtPhy.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity; pAd->CommonCfg.DesiredHtPhy.AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable; pAd->CommonCfg.DesiredHtPhy.AmsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize; pAd->CommonCfg.DesiredHtPhy.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode; // UPdata to HT IE pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode; pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize; pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity; #endif // DOT11_N_SUPPORT // // after reading Registry, we now know if in AP mode or STA mode // Load 8051 firmware; crash when FW image not existent // Status = NICLoadFirmware(pAd); // if (Status != NDIS_STATUS_SUCCESS) // break; DBGPRINT(RT_DEBUG_OFF, ("2. Phy Mode = %d\n", pAd->CommonCfg.PhyMode)); // We should read EEPROM for all cases. rt2860b NICReadEEPROMParameters(pAd, (PUCHAR)pDefaultMac); DBGPRINT(RT_DEBUG_OFF, ("3. Phy Mode = %d\n", pAd->CommonCfg.PhyMode)); NICInitAsicFromEEPROM(pAd); //rt2860b #ifdef RTMP_INTERNAL_TX_ALC // // Initialize the desired TSSI table // InitDesiredTSSITable(pAd); #endif // RTMP_INTERNAL_TX_ALC // #if defined(RT5390) || defined(RT5370) // // Temperature compensation, initialize the lookup table // DBGPRINT(RT_DEBUG_ERROR, ("IS_RT5392 = %d, bAutoTxAgcG = %d\n", IS_RT5392(pAd), pAd->bAutoTxAgcG)); if (IS_RT5392(pAd) && pAd->bAutoTxAgcG && pAd->CommonCfg.TempComp != 0) { InitLookupTable(pAd); } #endif // defined(RT5390) || defined(RT5370) // // Set PHY to appropriate mode TmpPhy = pAd->CommonCfg.PhyMode; pAd->CommonCfg.PhyMode = 0xff; RTMPSetPhyMode(pAd, TmpPhy); #ifdef DOT11_N_SUPPORT SetCommonHT(pAd); #endif // DOT11_N_SUPPORT // // No valid channels. if (pAd->ChannelListNum == 0) { DBGPRINT(RT_DEBUG_ERROR, ("Wrong configuration. No valid channel found. Check \"ContryCode\" and \"ChannelGeography\" setting.\n")); goto err6; } #ifdef DOT11_N_SUPPORT DBGPRINT(RT_DEBUG_OFF, ("MCS Set = %02x %02x %02x %02x %02x\n", pAd->CommonCfg.HtCapability.MCSSet[0], pAd->CommonCfg.HtCapability.MCSSet[1], pAd->CommonCfg.HtCapability.MCSSet[2], pAd->CommonCfg.HtCapability.MCSSet[3], pAd->CommonCfg.HtCapability.MCSSet[4])); #endif // DOT11_N_SUPPORT // #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { #ifdef AP_QLOAD_SUPPORT /* init QBSS Element */ QBSS_LoadInit(pAd); #endif // AP_QLOAD_SUPPORT // //#ifdef DOT11K_RRM_SUPPORT // RRM_CfgInit(pAd); //#endif // DOT11K_RRM_SUPPORT // } #endif // CONFIG_AP_SUPPORT // // APInitialize(pAd); #ifdef IKANOS_VX_1X0 VR_IKANOS_FP_Init(pAd->ApCfg.BssidNum, pAd->PermanentAddress); #endif // IKANOS_VX_1X0 // #ifdef CONFIG_AP_SUPPORT // // Initialize RF register to default value // if (pAd->OpMode == OPMODE_AP) { AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); AsicLockChannel(pAd, pAd->CommonCfg.Channel); } #endif // CONFIG_AP_SUPPORT // /* Some modules init must be called before APStartUp(). Or APStartUp() will make up beacon content and call other modules API to get some information to fill. */ #ifdef WMM_ACM_SUPPORT #ifdef CONFIG_AP_SUPPORT ACMP_Init(pAd, pAd->CommonCfg.APEdcaParm.bACM[0], pAd->CommonCfg.APEdcaParm.bACM[1], pAd->CommonCfg.APEdcaParm.bACM[2], pAd->CommonCfg.APEdcaParm.bACM[3], 0); #endif // CONFIG_AP_SUPPORT // #endif // WMM_ACM_SUPPORT // if (pAd && (Status != NDIS_STATUS_SUCCESS)) { // // Undo everything if it failed // if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { // NdisMDeregisterInterrupt(&pAd->Interrupt); RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE); } // RTMPFreeAdapter(pAd); // we will free it in disconnect() } else if (pAd) { // Microsoft HCT require driver send a disconnect event after driver initialization. OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE); DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event B!\n")); #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { if (pAd->ApCfg.bAutoChannelAtBootup || (pAd->CommonCfg.Channel == 0)) { UINT8 BBPValue = 0; // Enable Interrupt first due to we need to scan channel to receive beacons. RTMP_IRQ_ENABLE(pAd); // Now Enable RxTx RTMPEnableRxTx(pAd); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP); // Let BBP register at 20MHz to do scan RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); BBPValue &= (~0x18); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); DBGPRINT(RT_DEBUG_ERROR, ("SYNC - BBP R4 to 20MHz.l\n")); // Now we can receive the beacon and do the listen beacon // use default BW to select channel pAd->CommonCfg.Channel = AP_AUTO_CH_SEL(pAd, pAd->ApCfg.AutoChannelAlg); pAd->ApCfg.bAutoChannelAtBootup = FALSE; } #ifdef DOT11_N_SUPPORT // If phymode > PHY_11ABGN_MIXED and BW=40 check extension channel, after select channel N_ChannelCheck(pAd); #ifdef DOT11N_DRAFT3 /* We only do this Overlapping BSS Scan when system up, for the other situation of channel changing, we depends on station's report to adjust ourself. */ if (pAd->CommonCfg.bForty_Mhz_Intolerant == TRUE) { DBGPRINT(RT_DEBUG_TRACE, ("Disable 20/40 BSSCoex Channel Scan(BssCoex=%d, 40MHzIntolerant=%d)\n", pAd->CommonCfg.bBssCoexEnable, pAd->CommonCfg.bForty_Mhz_Intolerant)); } else if(pAd->CommonCfg.bBssCoexEnable == TRUE) { DBGPRINT(RT_DEBUG_TRACE, ("Enable 20/40 BSSCoex Channel Scan(BssCoex=%d)\n", pAd->CommonCfg.bBssCoexEnable)); APOverlappingBSSScan(pAd); } RTMP_11N_D3_TimerInit(pAd); // RTMPInitTimer(pAd, &pAd->CommonCfg.Bss2040CoexistTimer, GET_TIMER_FUNCTION(Bss2040CoexistTimeOut), pAd, FALSE); #endif // DOT11N_DRAFT3 // #endif // DOT11_N_SUPPORT // #ifdef RT3090 #ifdef TONE_RADAR_DETECT_SUPPORT if (IS_RT3090A(pAd) || IS_RT3390(pAd) || IS_RT5390(pAd)) pAd->CommonCfg.carrier_func=TONE_RADAR_V2; else pAd->CommonCfg.carrier_func=TONE_RADAR_V1; #endif // TONE_RADAR_DETECT_SUPPORT // #endif // RT3090 // APStartUp(pAd); DBGPRINT(RT_DEBUG_OFF, ("Main bssid = %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(pAd->ApCfg.MBSSID[BSS0].Bssid))); } #endif // CONFIG_AP_SUPPORT // }// end of else #ifdef WSC_INCLUDED #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { INT apidx; #ifdef HOSTAPD_SUPPORT if (pAd->ApCfg.Hostapd == TRUE) { DBGPRINT(RT_DEBUG_TRACE, ("WPS is control by hostapd now.\n")); } else #endif //HOSTAPD_SUPPORT// for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++) { PWSC_CTRL pWscControl; UCHAR zeros16[16]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; pWscControl = &pAd->ApCfg.MBSSID[apidx].WscControl; DBGPRINT(RT_DEBUG_TRACE, ("Generate UUID for apidx(%d)\n", apidx)); if (NdisEqualMemory(&pWscControl->Wsc_Uuid_E[0], zeros16, UUID_LEN_HEX)) WscGenerateUUID(pAd, &pWscControl->Wsc_Uuid_E[0], &pWscControl->Wsc_Uuid_Str[0], apidx, FALSE); WscInit(pAd, FALSE, apidx); } } #endif // CONFIG_AP_SUPPORT // /* WSC hardware push button function 0811 */ WSC_HDR_BTN_Init(pAd); #endif // WSC_INCLUDED // // Set up the Mac address RtmpOSNetDevAddrSet(pAd->net_dev, &pAd->CurrentAddress[0]); // Various AP function init #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { #ifdef MBSS_SUPPORT /* the function can not be moved to RT2860_probe() even register_netdev() is changed as register_netdevice(). Or in some PC, kernel will panic (Fedora 4) */ RT28xx_MBSS_Init(pAd, pAd->net_dev); #endif // MBSS_SUPPORT // #ifdef WDS_SUPPORT RT28xx_WDS_Init(pAd, pAd->net_dev); #endif // WDS_SUPPORT // #ifdef APCLI_SUPPORT RT28xx_ApCli_Init(pAd, pAd->net_dev); #endif // APCLI_SUPPORT // } #endif // CONFIG_AP_SUPPORT // #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { #ifdef MAT_SUPPORT MATEngineInit(pAd); #endif // MAT_SUPPORT // #ifdef CLIENT_WDS CliWds_ProxyTabInit(pAd); #endif // CLIENT_WDS // } #endif // CONFIG_AP_SUPPORT // #ifdef RT33xx if (IS_RT3390(pAd)) { RTMP_TxEvmCalibration(pAd); } #endif // RT33xx // DBGPRINT_S(Status, ("<==== rt28xx_init, Status=%x\n", Status)); return TRUE; err6: MeasureReqTabExit(pAd); TpcReqTabExit(pAd); err5: RtmpNetTaskExit(pAd); UserCfgExit(pAd); err4: MlmeHalt(pAd); err3: RtmpMgmtTaskExit(pAd); err2: #ifdef RESOURCE_PRE_ALLOC RTMPResetTxRxRingMemory(pAd); #else RTMPFreeTxRxRingMemory(pAd); #endif // RESOURCE_PRE_ALLOC // err1: #ifdef DOT11_N_SUPPORT if(pAd->mpdu_blk_pool.mem) os_free_mem(pAd, pAd->mpdu_blk_pool.mem); // free BA pool #endif // DOT11_N_SUPPORT // // shall not set priv to NULL here because the priv didn't been free yet. //net_dev->priv = 0; #ifdef INF_AMAZON_SE err0: #endif // INF_AMAZON_SE // #ifdef ST err0: #endif // ST // DBGPRINT(RT_DEBUG_ERROR, ("!!! rt28xx Initialized fail !!!\n")); return FALSE; }
BOOLEAN MeshKeySelectionAction( IN PRTMP_ADAPTER pAd, IN PMESH_LINK_ENTRY pMeshLinkEntry, IN PUCHAR pMscIe, IN PUCHAR pPmkId, IN UCHAR PmkIdLen) { PMESH_SECURITY_CAPABILITY_IE pPeerMSCIE; BOOLEAN bValidLocalKey = FALSE; BOOLEAN bCachedPeerKey = FALSE; if (pAd->MeshTab.EasyMeshSecurity) { pMeshLinkEntry->MeshKeySelection = MESH_KEY_NONE; return TRUE; } pPeerMSCIE = (PMESH_SECURITY_CAPABILITY_IE)pMscIe; /* The key selection procedure first determines */ /* if Initial MSA Authentication shall occur. */ if (PmkIdLen == 0 || pAd->MeshTab.bInitialMsaDone == FALSE || pAd->MeshTab.PMKID_Len == 0 || !NdisEqualMemory(pPeerMSCIE->MKDDID, pAd->MeshTab.LocalMSCIE.MKDDID, MAC_ADDR_LEN)) { pMeshLinkEntry->MeshKeySelection = MESH_KEY_NONE; return TRUE; } if (PmkIdLen == MESH_MAX_PMKID_LEN) { if (NdisEqualMemory(pMeshLinkEntry->PMK_MA_NAME, pPmkId + LEN_PMKID, MESH_PMK_NAME_LEN)) bValidLocalKey = TRUE; } if (PmkIdLen >= LEN_PMKID && pAd->MeshTab.bKeyholderDone) { if (NdisEqualMemory(pMeshLinkEntry->PMK_MA_NAME, pPmkId, MESH_PMK_NAME_LEN)) bCachedPeerKey = TRUE; } /* The key selection procedure, it refers to IEEE 802.11s/D1.06 Table-s46 */ if (bValidLocalKey == FALSE && bCachedPeerKey == FALSE) { /* No PMK-MA available and no connection to MKD available, it shall close this link */ if (pPeerMSCIE->MeshSecurityConfig.field.ConnectedToMKD == 0 && pAd->MeshTab.LocalMSCIE.MeshSecurityConfig.field.ConnectedToMKD == 0) { return FALSE; } /* Local MP connected to MKD, but peer MP not */ else if (pPeerMSCIE->MeshSecurityConfig.field.ConnectedToMKD == 0 && pAd->MeshTab.LocalMSCIE.MeshSecurityConfig.field.ConnectedToMKD == 1) { pMeshLinkEntry->MeshKeySelection = MESH_KEY_PMKMA_PEER; } /* Peer MP connected to MKD, but local MP not */ else if (pPeerMSCIE->MeshSecurityConfig.field.ConnectedToMKD == 1 && pAd->MeshTab.LocalMSCIE.MeshSecurityConfig.field.ConnectedToMKD == 0) { pMeshLinkEntry->MeshKeySelection = MESH_KEY_PMKMA_LOCAL; } /* Peer and local MP both connected to MKD */ else { if (pMeshLinkEntry->bValidLocalMpAsSelector) pMeshLinkEntry->MeshKeySelection = MESH_KEY_PMKMA_PEER; else pMeshLinkEntry->MeshKeySelection = MESH_KEY_PMKMA_LOCAL; } } else if (bValidLocalKey == FALSE && bCachedPeerKey == TRUE) { pMeshLinkEntry->MeshKeySelection = MESH_KEY_PMKMA_PEER; } else if (bValidLocalKey == TRUE && bCachedPeerKey == FALSE) { pMeshLinkEntry->MeshKeySelection = MESH_KEY_PMKMA_LOCAL; } else { if (pMeshLinkEntry->bValidLocalMpAsSelector) pMeshLinkEntry->MeshKeySelection = MESH_KEY_PMKMA_PEER; else pMeshLinkEntry->MeshKeySelection = MESH_KEY_PMKMA_LOCAL; } return TRUE; }
BOOLEAN PeerAssocReqCmmSanity( IN PRTMP_ADAPTER pAd, IN BOOLEAN isReassoc, IN VOID *Msg, IN ULONG MsgLen, OUT PUCHAR pAddr2, OUT USHORT *pCapabilityInfo, OUT USHORT *pListenInterval, OUT PUCHAR pApAddr, OUT UCHAR *pSsidLen, OUT char *Ssid, OUT UCHAR *pRatesLen, OUT UCHAR Rates[], OUT UCHAR *RSN, OUT UCHAR *pRSNLen, OUT BOOLEAN *pbWmmCapable, #ifdef WSC_AP_SUPPORT OUT BOOLEAN *pWscCapable, #endif // WSC_AP_SUPPORT // OUT ULONG *pRalinkIe, OUT EXT_CAP_INFO_ELEMENT *pExtCapInfo, OUT UCHAR *pHtCapabilityLen, OUT HT_CAPABILITY_IE *pHtCapability) { CHAR *Ptr; PFRAME_802_11 Fr = (PFRAME_802_11)Msg; PEID_STRUCT eid_ptr; UCHAR Sanity = 0; UCHAR WPA1_OUI[4] = { 0x00, 0x50, 0xF2, 0x01 }; UCHAR WPA2_OUI[3] = { 0x00, 0x0F, 0xAC }; MAC_TABLE_ENTRY *pEntry = (MAC_TABLE_ENTRY *)NULL; // to prevent caller from using garbage output value *pSsidLen = 0; *pRatesLen = 0; *pRSNLen = 0; *pbWmmCapable = FALSE; *pRalinkIe = 0; *pHtCapabilityLen= 0; COPY_MAC_ADDR(pAddr2, &Fr->Hdr.Addr2); pEntry = MacTableLookup(pAd, pAddr2); if (pEntry == NULL) return FALSE; Ptr = (PCHAR)Fr->Octet; NdisMoveMemory(pCapabilityInfo, &Fr->Octet[0], 2); NdisMoveMemory(pListenInterval, &Fr->Octet[2], 2); if (isReassoc) { NdisMoveMemory(pApAddr, &Fr->Octet[4], 6); eid_ptr = (PEID_STRUCT) &Fr->Octet[10]; } else { eid_ptr = (PEID_STRUCT) &Fr->Octet[4]; } // get variable fields from payload and advance the pointer while (((UCHAR *)eid_ptr + eid_ptr->Len + 1) < ((UCHAR *)Fr + MsgLen)) { switch(eid_ptr->Eid) { case IE_SSID: if (((Sanity&0x1) == 1)) break; if ((eid_ptr->Len <= MAX_LEN_OF_SSID)) { Sanity |= 0x01; NdisMoveMemory(Ssid, eid_ptr->Octet, eid_ptr->Len); *pSsidLen = eid_ptr->Len; DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - SsidLen = %d \n", *pSsidLen)); } else { DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - wrong IE_SSID\n")); return FALSE; } break; case IE_SUPP_RATES: if ((eid_ptr->Len <= MAX_LEN_OF_SUPPORTED_RATES) && (eid_ptr->Len > 0)) { Sanity |= 0x02; NdisMoveMemory(Rates, eid_ptr->Octet, eid_ptr->Len); DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - IE_SUPP_RATES., Len=%d. " "Rates[0]=%x\n", eid_ptr->Len, Rates[0])); DBGPRINT(RT_DEBUG_TRACE, ("Rates[1]=%x %x %x %x %x %x %x\n", Rates[1], Rates[2], Rates[3], Rates[4], Rates[5], Rates[6], Rates[7])); *pRatesLen = eid_ptr->Len; } else { UCHAR RateDefault[8] = \ { 0x82, 0x84, 0x8b, 0x96, 0x12, 0x24, 0x48, 0x6c }; // HT rate not ready yet. return true temporarily. rt2860c //DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - wrong IE_SUPP_RATES\n")); Sanity |= 0x02; *pRatesLen = 8; NdisMoveMemory(Rates, RateDefault, 8); DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - wrong IE_SUPP_RATES., Len=%d\n", eid_ptr->Len)); } break; case IE_EXT_SUPP_RATES: if (eid_ptr->Len + *pRatesLen <= MAX_LEN_OF_SUPPORTED_RATES) { NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, eid_ptr->Len); *pRatesLen = (*pRatesLen) + eid_ptr->Len; } else { NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, MAX_LEN_OF_SUPPORTED_RATES - (*pRatesLen)); *pRatesLen = MAX_LEN_OF_SUPPORTED_RATES; } break; case IE_HT_CAP: if (eid_ptr->Len >= sizeof(HT_CAPABILITY_IE)) { NdisMoveMemory(pHtCapability, eid_ptr->Octet, SIZE_HT_CAP_IE); *(USHORT *)(&pHtCapability->HtCapInfo) = \ cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo)); #ifdef UNALIGNMENT_SUPPORT { EXT_HT_CAP_INFO extHtCapInfo; NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&pHtCapability->ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); NdisMoveMemory((PUCHAR)(&pHtCapability->ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); } #else *(USHORT *)(&pHtCapability->ExtHtCapInfo) = \ cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo)); #endif // UNALIGNMENT_SUPPORT // *pHtCapabilityLen = SIZE_HT_CAP_IE; Sanity |= 0x10; DBGPRINT(RT_DEBUG_WARN, ("PeerAssocReqSanity - IE_HT_CAP\n")); } else { DBGPRINT(RT_DEBUG_WARN, ("PeerAssocReqSanity - wrong IE_HT_CAP.eid_ptr->Len = %d\n", eid_ptr->Len)); } break; case IE_EXT_CAPABILITY: if (eid_ptr->Len >= sizeof(EXT_CAP_INFO_ELEMENT)) { NdisMoveMemory(pExtCapInfo, eid_ptr->Octet, sizeof(EXT_CAP_INFO_ELEMENT)); DBGPRINT(RT_DEBUG_WARN, ("PeerAssocReqSanity - IE_EXT_CAPABILITY!\n")); } break; case IE_WPA: // same as IE_VENDOR_SPECIFIC case IE_WPA2: #ifdef WSC_AP_SUPPORT if (NdisEqualMemory(eid_ptr->Octet, WPS_OUI, 4)) { #ifdef WSC_V2_SUPPORT if ((pAd->ApCfg.MBSSID[pEntry->apidx].WscControl.WscV2Info.bWpsEnable) || (pAd->ApCfg.MBSSID[pEntry->apidx].WscControl.WscV2Info.bEnableWpsV2 == FALSE)) #endif // WSC_V2_SUPPORT // *pWscCapable = TRUE; break; } #endif // WSC_AP_SUPPORT // /* Handle Atheros and Broadcom draft 11n STAs */ if (NdisEqualMemory(eid_ptr->Octet, BROADCOM_OUI, 3)) { switch (eid_ptr->Octet[3]) { case 0x33: if ((eid_ptr->Len-4) == sizeof(HT_CAPABILITY_IE)) { NdisMoveMemory(pHtCapability, &eid_ptr->Octet[4], SIZE_HT_CAP_IE); *(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo)); #ifdef UNALIGNMENT_SUPPORT { EXT_HT_CAP_INFO extHtCapInfo; NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&pHtCapability->ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); NdisMoveMemory((PUCHAR)(&pHtCapability->ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); } #else *(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo)); #endif // UNALIGNMENT_SUPPORT // *pHtCapabilityLen = SIZE_HT_CAP_IE; } break; default: // ignore other cases break; } } if (NdisEqualMemory(eid_ptr->Octet, RALINK_OUI, 3) && (eid_ptr->Len == 7)) { //*pRalinkIe = eid_ptr->Octet[3]; if (eid_ptr->Octet[3] != 0) *pRalinkIe = eid_ptr->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. break; } // WMM_IE if (NdisEqualMemory(eid_ptr->Octet, WME_INFO_ELEM, 6) && (eid_ptr->Len == 7)) { *pbWmmCapable = TRUE; #ifdef UAPSD_AP_SUPPORT UAPSD_AssocParse(pAd, pEntry, (UINT8 *)&eid_ptr->Octet[6]); #endif // UAPSD_AP_SUPPORT // break; } if (pAd->ApCfg.MBSSID[pEntry->apidx].AuthMode < Ndis802_11AuthModeWPA) break; /* If this IE did not begins with 00:0x50:0xf2:0x01, it would be proprietary. So we ignore it. */ if (!NdisEqualMemory(eid_ptr->Octet, WPA1_OUI, sizeof(WPA1_OUI)) && !NdisEqualMemory(&eid_ptr->Octet[2], WPA2_OUI, sizeof(WPA2_OUI))) { DBGPRINT(RT_DEBUG_TRACE, ("Not RSN IE, maybe WMM IE!!!\n")); break; } if (/*(eid_ptr->Len <= MAX_LEN_OF_RSNIE) &&*/ (eid_ptr->Len >= MIN_LEN_OF_RSNIE)) { if (!pEntry) return FALSE; hex_dump("Received RSNIE in Assoc-Req", (UCHAR *)eid_ptr, eid_ptr->Len + 2); // Copy whole RSNIE context NdisMoveMemory(RSN, eid_ptr, eid_ptr->Len + 2); *pRSNLen=eid_ptr->Len + 2; } else { *pRSNLen=0; DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - missing IE_WPA(%d)\n",eid_ptr->Len)); return FALSE; } break; #ifdef WAPI_SUPPORT case IE_WAPI: if ((pAd->ApCfg.MBSSID[pEntry->apidx].AuthMode != Ndis802_11AuthModeWAICERT) && (pAd->ApCfg.MBSSID[pEntry->apidx].AuthMode != Ndis802_11AuthModeWAIPSK)) break; // Sanity check the validity of WIE // Todo - AlbertY // Copy whole WAPI-IE context NdisMoveMemory(RSN, eid_ptr, eid_ptr->Len + 2); *pRSNLen=eid_ptr->Len + 2; DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - IE_WAPI(%d)\n",eid_ptr->Len)); break; #endif // WAPI_SUPPORT // default: break; } eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len); } if ((Sanity&0x3) != 0x03) { DBGPRINT(RT_DEBUG_WARN, ("PeerAssocReqSanity - missing mandatory field\n")); return FALSE; } else { DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - success\n")); return TRUE; } }
/* ========================================================================== Description: mlme assoc req handling procedure Parameters: Adapter - Adapter pointer Elem - MLME Queue Element Pre: the station has been authenticated and the following information is stored in the config -# SSID -# supported rates and their length -# listen interval (Adapter->PortCfg.default_listen_count) -# Transmit power (Adapter->PortCfg.tx_power) Post : -# An association request frame is generated and sent to the air -# Association timer starts -# Association state -> ASSOC_WAIT_RSP ========================================================================== */ VOID MlmeAssocReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { UCHAR ApAddr[6]; HEADER_802_11 AssocHdr; UCHAR WmeIe[9] = {IE_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, STA_QOS_CAPABILITY}; UCHAR CipherTmp[64]; UCHAR CipherTmpLen; USHORT ListenIntv; ULONG Timeout; USHORT CapabilityInfo; PUCHAR pOutBuffer = NULL; ULONG FrameLen = 0; ULONG tmp; UCHAR VarIesOffset; USHORT Status; ULONG idx; BOOLEAN FoundPMK = FALSE; USHORT NStatus; BOOLEAN TimerCancelled; // Block all authentication request durning WPA block period if (pAd->PortCfg.bBlockAssoc == TRUE) { DBGPRINT(RT_DEBUG_TRACE, "ASSOC - Block Assoc request durning WPA block period!\n"); pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; Status = MLME_STATE_MACHINE_REJECT; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status); } // check sanity first else if (MlmeAssocReqSanity(pAd, Elem->Msg, Elem->MsgLen, ApAddr, &CapabilityInfo, &Timeout, &ListenIntv)) { RTMPCancelTimer(&pAd->MlmeAux.AssocTimer,&TimerCancelled); COPY_MAC_ADDR(pAd->MlmeAux.Bssid, ApAddr); // allocate and send out AssocRsp frame NStatus = MlmeAllocateMemory(pAd, (PVOID *)&pOutBuffer); //Get an unused nonpaged memory if (NStatus != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_TRACE,"ASSOC - MlmeAssocReqAction() allocate memory failed \n"); pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; Status = MLME_FAIL_NO_RESOURCE; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status); return; } // Add by James 03/06/27 pAd->PortCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION); // Association don't need to report MAC address pAd->PortCfg.AssocInfo.AvailableRequestFixedIEs = NDIS_802_11_AI_REQFI_CAPABILITIES | NDIS_802_11_AI_REQFI_LISTENINTERVAL; pAd->PortCfg.AssocInfo.RequestFixedIEs.Capabilities = CapabilityInfo; pAd->PortCfg.AssocInfo.RequestFixedIEs.ListenInterval = ListenIntv; // Only reassociate need this //COPY_MAC_ADDR(pAd->PortCfg.AssocInfo.RequestFixedIEs.CurrentAPAddress, ApAddr); pAd->PortCfg.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION); // First add SSID VarIesOffset = 0; NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, &SsidIe, 1); VarIesOffset += 1; NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, &pAd->MlmeAux.SsidLen, 1); VarIesOffset += 1; NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen); VarIesOffset += pAd->MlmeAux.SsidLen; // Second add Supported rates NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, &SupRateIe, 1); VarIesOffset += 1; NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, &pAd->MlmeAux.SupRateLen, 1); VarIesOffset += 1; NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, pAd->MlmeAux.SupRate, pAd->MlmeAux.SupRateLen); VarIesOffset += pAd->MlmeAux.SupRateLen; // End Add by James DBGPRINT(RT_DEBUG_TRACE, "ASSOC - Send ASSOC request...\n"); MgtMacHeaderInit(pAd, &AssocHdr, SUBTYPE_ASSOC_REQ, 0, ApAddr, ApAddr); // Build basic frame first MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &AssocHdr, 2, &CapabilityInfo, 2, &ListenIntv, 1, &SsidIe, 1, &pAd->MlmeAux.SsidLen, pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid, 1, &SupRateIe, 1, &pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate, END_OF_ARGS); if (pAd->MlmeAux.ExtRateLen != 0) { MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, 1, &ExtRateIe, 1, &pAd->MlmeAux.ExtRateLen, pAd->MlmeAux.ExtRateLen, pAd->MlmeAux.ExtRate, END_OF_ARGS); FrameLen += tmp; } if (pAd->MlmeAux.APEdcaParm.bValid) { WmeIe[8] |= (pAd->MlmeAux.APEdcaParm.EdcaUpdateCount & 0x0f); MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, 9, &WmeIe[0], END_OF_ARGS); FrameLen += tmp; } // For WPA / WPA-PSK if ((pAd->PortCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->PortCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) { // Copy WPA template to buffer CipherTmpLen = sizeof(CipherWpaTemplate); NdisMoveMemory(CipherTmp, CipherWpaTemplate, CipherTmpLen); // Modify Group cipher CipherTmp[11] = ((pAd->PortCfg.GroupCipher == Ndis802_11Encryption2Enabled) ? 0x2 : 0x4); // Modify Pairwise cipher CipherTmp[17] = ((pAd->PortCfg.PairCipher == Ndis802_11Encryption2Enabled) ? 0x2 : 0x4); // Modify AKM CipherTmp[23] = ((pAd->PortCfg.AuthMode == Ndis802_11AuthModeWPA) ? 0x1 : 0x2); // Make outgoing frame MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, CipherTmpLen, &CipherTmp[0], END_OF_ARGS); FrameLen += tmp; // Append Variable IE printk("%s(): WPA/WPAPSK, Fill the ReqVarIEs with CipherTmp!\n", __FUNCTION__); NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, CipherTmp, CipherTmpLen); VarIesOffset += CipherTmpLen; // Set Variable IEs Length pAd->PortCfg.ReqVarIELen = VarIesOffset; pAd->PortCfg.AssocInfo.RequestIELength = VarIesOffset; // OffsetResponseIEs follow ReqVarIE pAd->PortCfg.AssocInfo.OffsetResponseIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION) + pAd->PortCfg.ReqVarIELen; } // For WPA2 / WPA2-PSK else if ((pAd->PortCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->PortCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) { // Copy WPA2 template to buffer CipherTmpLen = sizeof(CipherWpa2Template); NdisMoveMemory(CipherTmp, CipherWpa2Template, CipherTmpLen); // Modify Group cipher CipherTmp[7] = ((pAd->PortCfg.GroupCipher == Ndis802_11Encryption2Enabled) ? 0x2 : 0x4); // Modify Pairwise cipher CipherTmp[13] = ((pAd->PortCfg.PairCipher == Ndis802_11Encryption2Enabled) ? 0x2 : 0x4); // Modify AKM CipherTmp[19] = ((pAd->PortCfg.AuthMode == Ndis802_11AuthModeWPA2) ? 0x1 : 0x2); // Check for WPA PMK cache list if (pAd->PortCfg.AuthMode == Ndis802_11AuthModeWPA2) { // Search chched PMKID, append it if existed for (idx = 0; idx < PMKID_NO; idx++) { if (NdisEqualMemory(ApAddr, &pAd->PortCfg.SavedPMK[idx].BSSID, 6)) { FoundPMK = TRUE; break; } } if (FoundPMK) { // Update length within RSN IE CipherTmp[1] += 18; // Set PMK number *(PUSHORT) &CipherTmp[CipherTmpLen] = 1; NdisMoveMemory(&CipherTmp[CipherTmpLen + 2], &pAd->PortCfg.SavedPMK[idx].PMKID, 16); CipherTmpLen += 18; } } // Make outgoing frame MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, CipherTmpLen, &CipherTmp[0], END_OF_ARGS); FrameLen += tmp; // Append Variable IE printk("%s(): WPA2/WPA2PSK fill the ReqVarIEs with CipherTmp!\n", __FUNCTION__); NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, CipherTmp, CipherTmpLen); VarIesOffset += CipherTmpLen; // Set Variable IEs Length pAd->PortCfg.ReqVarIELen = VarIesOffset; pAd->PortCfg.AssocInfo.RequestIELength = VarIesOffset; // OffsetResponseIEs follow ReqVarIE pAd->PortCfg.AssocInfo.OffsetResponseIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION) + pAd->PortCfg.ReqVarIELen; } else { // Do nothing ; } #if 0 //AGGREGATION_SUPPORT // add Ralink proprietary IE to inform AP this STA is going to use AGGREGATION, only when - // 1. user enable aggregation, AND // 2. AP annouces it's AGGREGATION-capable in BEACON if (pAd->PortCfg.bAggregationCapable && (pAd->MlmeAux.APRalinkIe & 0x00000001)) { ULONG TmpLen; UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x01, 0x00, 0x00, 0x00}; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 9, RalinkIe, END_OF_ARGS); FrameLen += TmpLen; } #endif MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); RTMPSetTimer(&pAd->MlmeAux.AssocTimer, Timeout); pAd->Mlme.AssocMachine.CurrState = ASSOC_WAIT_RSP; } else { DBGPRINT(RT_DEBUG_TRACE,"ASSOC - MlmeAssocReqAction() sanity check failed. BUG!!!!!! \n"); pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; Status = MLME_INVALID_FORMAT; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status); } }
ULONG InsertWfdSubelmtTlv( IN PRTMP_ADAPTER pAd, IN UCHAR SubId, IN PUCHAR pInBuffer, IN PUCHAR pOutBuffer, IN UINT Action) { PRT_WFD_CONFIG pWFDCtrl = &pAd->StaCfg.WfdCfg; PUCHAR pDest; ULONG Length, tmpValue = 0; USHORT EidLen = 0; pDest = pOutBuffer; RTMPZeroMemory(pDest, 255); *pDest = SubId; pDest += 1; Length = 0; switch (SubId) { case SUBID_WFD_DEVICE_INFO: { WFD_DEVICE_INFO DevInfo; PUSHORT pDevInfo = &DevInfo; RTMPZeroMemory(&DevInfo, sizeof(WFD_DEVICE_INFO)); EidLen = SUBID_WFD_DEVICE_INFO_LEN; tmpValue = cpu2be16(EidLen); RTMPMoveMemory(pDest, &tmpValue, 2); DevInfo.DeviceType = pWFDCtrl->DeviceType; DevInfo.SourceCoupled = pWFDCtrl->SourceCoupled; DevInfo.SinkCoupled = pWFDCtrl->SinkCoupled; DevInfo.SessionAvail = pWFDCtrl->SessionAvail; DevInfo.WSD = pWFDCtrl->WSD; if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (INFRA_ON(pAd))) DevInfo.PC = pWFDCtrl->PC; else DevInfo.PC = WFD_PC_P2P; DevInfo.CP = pWFDCtrl->CP; DevInfo.TimeSync = pWFDCtrl->TimeSync; /* RTMPMoveMemory(pDest + 1, &DevInfo, sizeof(WFD_DEVICE_INFO)); */ tmpValue = cpu2be16(*pDevInfo); RTMPMoveMemory((pDest + 2), &tmpValue, 2); tmpValue = cpu2be16(pWFDCtrl->RtspPort); RTMPMoveMemory((pDest + 4), &tmpValue, 2); tmpValue = cpu2be16(pWFDCtrl->MaxThroughput); RTMPMoveMemory((pDest + 6), &tmpValue, 2); Length = 9; break; } case SUBID_WFD_ASSOCIATED_BSSID: { UCHAR AllZero[MAC_ADDR_LEN] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; if ((Action == ACTION_GAS_INITIAL_REQ) || (Action == ACTION_GAS_INITIAL_RSP)) { EidLen = SUBID_WFD_ASSOCIATED_BSSID_LEN; tmpValue = cpu2be16(EidLen); RTMPMoveMemory(pDest, &tmpValue, 2); Length = EidLen + 3; if (!NdisEqualMemory(AllZero, pAd->CommonCfg.Bssid, MAC_ADDR_LEN) && (Action == ACTION_GAS_INITIAL_RSP)) { RTMPMoveMemory(pDest + 2, pAd->CommonCfg.Bssid, MAC_ADDR_LEN); } } else { if (!NdisEqualMemory(AllZero, pAd->CommonCfg.Bssid, MAC_ADDR_LEN)) { EidLen = SUBID_WFD_ASSOCIATED_BSSID_LEN; tmpValue = cpu2be16(EidLen); RTMPMoveMemory(pDest, &tmpValue, 2); RTMPMoveMemory(pDest + 2, pAd->CommonCfg.Bssid, MAC_ADDR_LEN); Length = EidLen + 3; } } break; } case SUBID_WFD_AUDIO_FORMATS: { if ((Action == ACTION_GAS_INITIAL_REQ) || (Action == ACTION_GAS_INITIAL_RSP)) { EidLen = SUBID_WFD_AUDIO_FORMATS_LEN; tmpValue = cpu2be16(EidLen); RTMPMoveMemory(pDest, &tmpValue, 2); Length = EidLen + 3; } break; } case SUBID_WFD_VIDEO_FORMATS: { if ((Action == ACTION_GAS_INITIAL_REQ) || (Action == ACTION_GAS_INITIAL_RSP)) { EidLen = SUBID_WFD_VIDEO_FORMATS_LEN; tmpValue = cpu2be16(EidLen); RTMPMoveMemory(pDest, &tmpValue, 2); Length = EidLen + 3; } break; } case SUBID_WFD_3D_VIDEO_FORMATS: { if ((Action == ACTION_GAS_INITIAL_REQ) || (Action == ACTION_GAS_INITIAL_RSP)) { EidLen = SUBID_WFD_3D_VIDEO_FORMATS_LEN; tmpValue = cpu2be16(EidLen); RTMPMoveMemory(pDest, &tmpValue, 2); Length = EidLen + 3; } break; } case SUBID_WFD_CONTENT_PROTECTION: { if ((Action == ACTION_GAS_INITIAL_REQ) || (Action == ACTION_GAS_INITIAL_RSP)) { EidLen = SUBID_WFD_CONTENT_PROTECTION_LEN; tmpValue = cpu2be16(EidLen); RTMPMoveMemory(pDest, &tmpValue, 2); Length = EidLen + 3; } break; } case SUBID_WFD_COUPLED_SINK_INFO: { // if ((pWFDCtrl->DeviceType != WFD_SOURCE ) && (pWFDCtrl->SinkCoupled == WFD_COUPLED_SUPPORT)) { WFD_COUPLED_SINK_INFO SinkInfo; RTMPZeroMemory(&SinkInfo, sizeof(WFD_COUPLED_SINK_INFO)); EidLen = SUBID_WFD_COUPLED_SINK_INFO_LEN; tmpValue = cpu2be16(EidLen); RTMPMoveMemory(pDest, &tmpValue, 2); SinkInfo.CoupledStat = pWFDCtrl->CoupledSinkStatus.CoupledStat; RTMPMoveMemory(pDest + 2, &SinkInfo, sizeof(WFD_COUPLED_SINK_INFO)); Length = EidLen + 3; } break; } case SUBID_WFD_EXTENDED_CAP: { if ((Action == ACTION_GAS_INITIAL_REQ) || (Action == ACTION_GAS_INITIAL_RSP)) { EidLen = SUBID_WFD_EXTENDED_CAP_LEN; tmpValue = cpu2be16(EidLen); RTMPMoveMemory(pDest, &tmpValue, 2); Length = EidLen + 3; } break; } case SUBID_WFD_LOCAL_IP_ADDR: { if ((Action == ACTION_GAS_INITIAL_REQ) || (Action == ACTION_GAS_INITIAL_RSP)) { EidLen = SUBID_WFD_LOCAL_IP_ADDR_LEN; tmpValue = cpu2be16(EidLen); RTMPMoveMemory(pDest, &tmpValue, 2); Length = EidLen + 3; } else { EidLen = SUBID_WFD_LOCAL_IP_ADDR_LEN; tmpValue = cpu2be16(EidLen); RTMPMoveMemory(pDest, &tmpValue, 2); RTMPMoveMemory(pDest + 2, &pWFDCtrl->wfd_serv_disc_query_info.wfd_local_ip_ie, SUBID_WFD_LOCAL_IP_ADDR_LEN); Length = EidLen + 3; } break; } case SUBID_WFD_SESSION_INFO: { INT i = 0, NumOfDev = 0; UCHAR P2pIdx = P2P_NOT_FOUND; PRT_P2P_TABLE Tab = &pAd->P2pTable; if (P2P_GO_ON(pAd) #ifdef RT_CFG80211_SUPPORT || (pWFDCtrl->bSuppGoOn) #endif /* RT_CFG80211_SUPPORT */ ) { for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) { MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[i]; P2pIdx = P2pGroupTabSearch(pAd, pEntry->Addr); if ((P2pIdx < MAX_P2P_GROUP_SIZE) && (Tab->Client[P2pIdx].WfdEntryInfo.bWfdClient == TRUE)) NumOfDev++; } EidLen = 24*NumOfDev; tmpValue = cpu2be16(EidLen); RTMPMoveMemory(pDest, &tmpValue, 2); DBGPRINT(RT_DEBUG_INFO, ("%s:: NumOfDev = %d, Len = %d\n", __FUNCTION__, NumOfDev, *pDest)); pDest+=2; for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) { MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[i]; P2pIdx = P2pGroupTabSearch(pAd, pEntry->Addr); if ((P2pIdx < MAX_P2P_GROUP_SIZE) && (Tab->Client[P2pIdx].WfdEntryInfo.bWfdClient == TRUE)) { INT j = 0; WFD_SESSION_INFO SessionInfo; RTMPZeroMemory(&SessionInfo, sizeof(WFD_SESSION_INFO)); SessionInfo.Length = 23; RTMPMoveMemory(&SessionInfo.DeviceAddr[0], &pAd->P2pTable.Client[P2pIdx].addr[0], MAC_ADDR_LEN); RTMPMoveMemory(&SessionInfo.Bssid[0], &pAd->P2pTable.Client[P2pIdx].WfdEntryInfo.assoc_addr[0], MAC_ADDR_LEN); /* Below is the WFD Device Information */ SessionInfo.WfdDevInfo.DeviceType = pAd->P2pTable.Client[P2pIdx].WfdEntryInfo.wfd_devive_type; SessionInfo.WfdDevInfo.SourceCoupled = pAd->P2pTable.Client[P2pIdx].WfdEntryInfo.source_coupled; SessionInfo.WfdDevInfo.SinkCoupled = pAd->P2pTable.Client[P2pIdx].WfdEntryInfo.sink_coupled; SessionInfo.WfdDevInfo.SessionAvail = pAd->P2pTable.Client[P2pIdx].WfdEntryInfo.session_avail; SessionInfo.WfdDevInfo.WSD = pAd->P2pTable.Client[P2pIdx].WfdEntryInfo.wfd_service_discovery; SessionInfo.WfdDevInfo.PC = pAd->P2pTable.Client[P2pIdx].WfdEntryInfo.wfd_PC; SessionInfo.WfdDevInfo.TimeSync = pAd->P2pTable.Client[P2pIdx].WfdEntryInfo.wfd_time_sync; SessionInfo.MaxThroughput = pAd->P2pTable.Client[P2pIdx].WfdEntryInfo.max_throughput; SessionInfo.CoupledSinkInfo = pAd->P2pTable.Client[P2pIdx].WfdEntryInfo.coupled_sink_status; /* So far we cannot know the address of coupled devices, the coupled address will be filled "0" until WiFi Display spec. is ready for this part. */ RTMPMoveMemory(&SessionInfo.CoupledPeerAddr[0], &pAd->P2pTable.Client[P2pIdx].WfdEntryInfo.coupled_peer_addr[0], MAC_ADDR_LEN); RTMPMoveMemory(pDest, &SessionInfo, sizeof(WFD_SESSION_INFO)); for (j = 0; j < 24; j++) DBGPRINT(RT_DEBUG_INFO, ("%02x ", *(pDest+j))); DBGPRINT(RT_DEBUG_INFO, ("\n")); pDest += 24; } } Length = 24*NumOfDev + 3; } break; } case SUBID_WFD_ALTERNATE_MAC_ADDR: { UCHAR AllZero[MAC_ADDR_LEN] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; if (!NdisEqualMemory(AllZero, pAd->CurrentAddress, MAC_ADDR_LEN)) { EidLen = SUBID_WFD_ALTERNATE_MAC_ADDR_LEN; *((PUSHORT) (pDest)) = cpu2be16(EidLen); RTMPMoveMemory(pDest + 2, pAd->CurrentAddress, MAC_ADDR_LEN); Length = EidLen + 3; } break; } default: *pDest = 0; Length = 0; break; } return Length; }
/* ======================================================================== Routine Description: This routine is used to check if a rogue AP sent an 802.11 management frame to a client using our BSSID. Arguments: pAd - Pointer to our adapter pHeader - Pointer to 802.11 header Return Value: TRUE - This is a spoofed frame FALSE - This isn't a spoofed frame ======================================================================== */ BOOLEAN RTMPSpoofedMgmtDetection( IN RTMP_ADAPTER *pAd, IN HEADER_802_11 *pHeader, IN RX_BLK *rxblk) { INT i; for (i = 0; i < pAd->ApCfg.BssidNum; i++) { /* Spoofed BSSID detection */ if (NdisEqualMemory(pHeader->Addr2, pAd->ApCfg.MBSSID[i].wdev.bssid, MAC_ADDR_LEN)) { CHAR RcvdRssi; struct raw_rssi_info rssi_info; rssi_info.raw_rssi[0] = rxblk->rx_signal.raw_rssi[0]; rssi_info.raw_rssi[1] = rxblk->rx_signal.raw_rssi[1]; rssi_info.raw_rssi[2] = rxblk->rx_signal.raw_rssi[2]; RcvdRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, &rssi_info, RSSI_IDX_0), ConvertToRssi(pAd, &rssi_info, RSSI_IDX_1), ConvertToRssi(pAd, &rssi_info, RSSI_IDX_2)); switch (pHeader->FC.SubType) { case SUBTYPE_ASSOC_RSP: pAd->ApCfg.MBSSID[i].RcvdSpoofedAssocRespCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedAssocResp = RcvdRssi; break; case SUBTYPE_REASSOC_RSP: pAd->ApCfg.MBSSID[i].RcvdSpoofedReassocRespCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedReassocResp = RcvdRssi; break; case SUBTYPE_PROBE_RSP: pAd->ApCfg.MBSSID[i].RcvdSpoofedProbeRespCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedProbeResp = RcvdRssi; break; case SUBTYPE_BEACON: pAd->ApCfg.MBSSID[i].RcvdSpoofedBeaconCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedBeacon = RcvdRssi; break; case SUBTYPE_DISASSOC: pAd->ApCfg.MBSSID[i].RcvdSpoofedDisassocCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedDisassoc = RcvdRssi; break; case SUBTYPE_AUTH: pAd->ApCfg.MBSSID[i].RcvdSpoofedAuthCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedAuth = RcvdRssi; break; case SUBTYPE_DEAUTH: pAd->ApCfg.MBSSID[i].RcvdSpoofedDeauthCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedDeauth = RcvdRssi; break; default: pAd->ApCfg.MBSSID[i].RcvdSpoofedUnknownMgmtCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedUnknownMgmt = RcvdRssi; break; } return TRUE; } } return FALSE; }
/* ========================================================================== Description: MLME message sanity check Return: TRUE if all parameters are OK, FALSE otherwise ========================================================================== */ BOOLEAN PeerAssocRspSanity( IN PRTMP_ADAPTER pAd, IN VOID *pMsg, IN ULONG MsgLen, OUT PUCHAR pAddr2, OUT USHORT *pCapabilityInfo, OUT USHORT *pStatus, OUT USHORT *pAid, OUT UCHAR SupRate[], OUT UCHAR *pSupRateLen, OUT UCHAR ExtRate[], OUT UCHAR *pExtRateLen, OUT PEDCA_PARM pEdcaParm) { CHAR IeType, *Ptr; PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg; PEID_STRUCT pEid; ULONG Length = 0; COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2); Ptr = pFrame->Octet; Length += LENGTH_802_11; *pCapabilityInfo = *(USHORT *)(&pFrame->Octet[0]); Length += 2; *pStatus = *(USHORT *)(&pFrame->Octet[2]); Length += 2; *pExtRateLen = 0; pEdcaParm->bValid = FALSE; if (*pStatus != MLME_SUCCESS) return TRUE; *pAid = *(USHORT *)(&pFrame->Octet[4]); Length += 2; // change Endian in RTMPFrameEndianChange() on big endian platform //*pAid = le2cpu16(*pAid); // TODO: check big endian issue &0x3fff *pAid = (*pAid) & 0x3fff; // AID is low 14-bit // -- get supported rates from payload and advance the pointer IeType = pFrame->Octet[6]; *pSupRateLen = pFrame->Octet[7]; if ((IeType != IE_SUPP_RATES) || (*pSupRateLen > MAX_LEN_OF_SUPPORTED_RATES)) { DBGPRINT(RT_DEBUG_TRACE, "PeerAssocRspSanity fail - wrong SupportedRates IE\n"); return FALSE; } else memcpy(SupRate, &pFrame->Octet[8], *pSupRateLen); Length = Length + 2 + *pSupRateLen; // many AP implement proprietary IEs in non-standard order, we'd better // tolerate mis-ordered IEs to get best compatibility pEid = (PEID_STRUCT) &pFrame->Octet[8 + (*pSupRateLen)]; // get variable fields from payload and advance the pointer while ((Length + 2 + pEid->Len) <= MsgLen) { switch (pEid->Eid) { case IE_EXT_SUPP_RATES: if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES) { memcpy(ExtRate, pEid->Octet, pEid->Len); *pExtRateLen = pEid->Len; } break; case IE_VENDOR_SPECIFIC: // handle WME PARAMTER ELEMENT if (NdisEqualMemory(pEid->Octet, WME_PARM_ELEM, 6) && (pEid->Len == 24)) { PUCHAR 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->bMoreDataAck = FALSE; // pEid->Octet[0] & 0x80; pEdcaParm->EdcaUpdateCount = pEid->Octet[6] & 0x0f; ptr = &pEid->Octet[8]; for (i=0; i<4; i++) { UCHAR 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 } } break; #if 0 case IE_EDCA_PARAMETER: if (pEid->Len == 18) { PUCHAR ptr; int i; pEdcaParm->bValid = TRUE; pEdcaParm->bQAck = pEid->Octet[0] & 0x10; pEdcaParm->bQueueRequest = pEid->Octet[0] & 0x20; pEdcaParm->bTxopRequest = pEid->Octet[0] & 0x40; // pEdcaParm->bMoreDataAck = pEid->Octet[0] & 0x80; pEdcaParm->EdcaUpdateCount = pEid->Octet[0] & 0x0f; ptr = &pEid->Octet[2]; for (i=0; i<4; i++) { UCHAR 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 } } break; #endif default: DBGPRINT(RT_DEBUG_TRACE, "PeerAssocRspSanity - ignore unrecognized EID = %d\n", pEid->Eid); break; }
/* ========================================================================== Description: MLME message sanity check Return: TRUE if all parameters are OK, FALSE otherwise IRQL = DISPATCH_LEVEL ========================================================================== */ BOOLEAN PeerAssocRspSanity( IN PRTMP_ADAPTER pAd, IN VOID *pMsg, IN ULONG MsgLen, OUT PUCHAR pAddr2, OUT USHORT *pCapabilityInfo, OUT USHORT *pStatus, OUT USHORT *pAid, OUT UCHAR SupRate[], OUT UCHAR *pSupRateLen, OUT UCHAR ExtRate[], OUT UCHAR *pExtRateLen, OUT HT_CAPABILITY_IE *pHtCapability, OUT ADD_HT_INFO_IE *pAddHtInfo, /* AP might use this additional ht info IE */ OUT UCHAR *pHtCapabilityLen, OUT UCHAR *pAddHtInfoLen, OUT UCHAR *pNewExtChannelOffset, OUT PEDCA_PARM pEdcaParm, OUT EXT_CAP_INFO_ELEMENT *pExtCapInfo, OUT UCHAR *pCkipFlag) { CHAR IeType, *Ptr; PFRAME_802_11 pFrame = (PFRAME_802_11) pMsg; PEID_STRUCT pEid; ULONG Length = 0; *pNewExtChannelOffset = 0xff; *pHtCapabilityLen = 0; *pAddHtInfoLen = 0; COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2); Ptr = (PCHAR) pFrame->Octet; Length += LENGTH_802_11; NdisMoveMemory(pCapabilityInfo, &pFrame->Octet[0], 2); Length += 2; NdisMoveMemory(pStatus, &pFrame->Octet[2], 2); Length += 2; *pCkipFlag = 0; *pExtRateLen = 0; pEdcaParm->bValid = FALSE; if (*pStatus != MLME_SUCCESS) return TRUE; NdisMoveMemory(pAid, &pFrame->Octet[4], 2); Length += 2; /* Aid already swaped byte order in RTMPFrameEndianChange() for big endian platform */ *pAid = (*pAid) & 0x3fff; /* AID is low 14-bit */ /* -- get supported rates from payload and advance the pointer */ IeType = pFrame->Octet[6]; *pSupRateLen = pFrame->Octet[7]; if ((IeType != IE_SUPP_RATES) || (*pSupRateLen > MAX_LEN_OF_SUPPORTED_RATES)) { DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspSanity fail - wrong SupportedRates IE\n")); return FALSE; } else NdisMoveMemory(SupRate, &pFrame->Octet[8], *pSupRateLen); Length = Length + 2 + *pSupRateLen; /* many AP implement proprietary IEs in non-standard order, we'd better tolerate mis-ordered IEs to get best compatibility */ pEid = (PEID_STRUCT) & pFrame->Octet[8 + (*pSupRateLen)]; /* get variable fields from payload and advance the pointer */ while ((Length + 2 + pEid->Len) <= MsgLen) { switch (pEid->Eid) { case IE_EXT_SUPP_RATES: if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES) { NdisMoveMemory(ExtRate, pEid->Octet, pEid->Len); *pExtRateLen = pEid->Len; } break; case IE_HT_CAP: case IE_HT_CAP2: if (pEid->Len >= SIZE_HT_CAP_IE) { /* Note: allow extension.!! */ NdisMoveMemory(pHtCapability, pEid->Octet, SIZE_HT_CAP_IE); *(USHORT *) (&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *) (&pHtCapability->HtCapInfo)); *(USHORT *) (&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *) (&pHtCapability->ExtHtCapInfo)); *pHtCapabilityLen = SIZE_HT_CAP_IE; } else { DBGPRINT(RT_DEBUG_WARN, ("PeerAssocRspSanity - wrong IE_HT_CAP. \n")); } break; #ifdef DOT11_N_SUPPORT case IE_ADD_HT: case IE_ADD_HT2: if (pEid->Len >= sizeof (ADD_HT_INFO_IE)) { /* This IE allows extension, but we can ignore extra bytes beyond our knowledge , so only copy first sizeof(ADD_HT_INFO_IE) */ NdisMoveMemory(pAddHtInfo, pEid->Octet, sizeof (ADD_HT_INFO_IE)); *(USHORT *) (&pAddHtInfo->AddHtInfo2) = cpu2le16(*(USHORT *) (&pAddHtInfo->AddHtInfo2)); *(USHORT *) (&pAddHtInfo->AddHtInfo3) = cpu2le16(*(USHORT *) (&pAddHtInfo->AddHtInfo3)); *pAddHtInfoLen = SIZE_ADD_HT_INFO_IE; } else { DBGPRINT(RT_DEBUG_WARN, ("PeerAssocRspSanity - wrong IE_ADD_HT. \n")); } break; case IE_SECONDARY_CH_OFFSET: if (pEid->Len == 1) { *pNewExtChannelOffset = pEid->Octet[0]; } else { DBGPRINT(RT_DEBUG_WARN, ("PeerAssocRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n")); } #endif /* DOT11_N_SUPPORT */ break; case IE_VENDOR_SPECIFIC: /* handle WME PARAMTER ELEMENT */ if (NdisEqualMemory(pEid->Octet, WME_PARM_ELEM, 6) && (pEid->Len == 24)) { PUCHAR 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 = (PUCHAR) & pEid->Octet[8]; for (i = 0; i < 4; i++) { UCHAR 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 */ } } break; case IE_EXT_CAPABILITY: if (pEid->Len >= sizeof (EXT_CAP_INFO_ELEMENT)) { NdisMoveMemory(pExtCapInfo, &pEid->Octet[0], sizeof (EXT_CAP_INFO_ELEMENT)); DBGPRINT(RT_DEBUG_WARN, ("PeerAssocReqSanity - IE_EXT_CAPABILITY!\n")); } break; default: DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspSanity - ignore unrecognized EID = %d\n", pEid->Eid)); break; } Length = Length + 2 + pEid->Len; pEid = (PEID_STRUCT) ((UCHAR *) pEid + 2 + pEid->Len); }
/* ======================================================================== Routine Description: This routine is used to check if a rogue AP sent an 802.11 management frame to a client using our BSSID. Arguments: pAd - Pointer to our adapter pHeader - Pointer to 802.11 header Return Value: TRUE - This is a spoofed frame FALSE - This isn't a spoofed frame ======================================================================== */ BOOLEAN RTMPSpoofedMgmtDetection( IN PRTMP_ADAPTER pAd, IN PHEADER_802_11 pHeader, IN CHAR Rssi0, IN CHAR Rssi1, IN CHAR Rssi2) { int i; for (i = 0; i < pAd->ApCfg.BssidNum; i++) { /* Spoofed BSSID detection */ if (NdisEqualMemory(pHeader->Addr2, pAd->ApCfg.MBSSID[i].Bssid, MAC_ADDR_LEN)) { CHAR RcvdRssi; RcvdRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Rssi0, RSSI_0), ConvertToRssi(pAd, Rssi1, RSSI_1), ConvertToRssi(pAd, Rssi2, RSSI_2)); switch (pHeader->FC.SubType) { case SUBTYPE_ASSOC_RSP: pAd->ApCfg.MBSSID[i].RcvdSpoofedAssocRespCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedAssocResp = RcvdRssi; break; case SUBTYPE_REASSOC_RSP: pAd->ApCfg.MBSSID[i].RcvdSpoofedReassocRespCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedReassocResp = RcvdRssi; break; case SUBTYPE_PROBE_RSP: pAd->ApCfg.MBSSID[i].RcvdSpoofedProbeRespCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedProbeResp = RcvdRssi; break; case SUBTYPE_BEACON: pAd->ApCfg.MBSSID[i].RcvdSpoofedBeaconCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedBeacon = RcvdRssi; break; case SUBTYPE_DISASSOC: pAd->ApCfg.MBSSID[i].RcvdSpoofedDisassocCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedDisassoc = RcvdRssi; break; case SUBTYPE_AUTH: pAd->ApCfg.MBSSID[i].RcvdSpoofedAuthCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedAuth = RcvdRssi; break; case SUBTYPE_DEAUTH: pAd->ApCfg.MBSSID[i].RcvdSpoofedDeauthCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedDeauth = RcvdRssi; break; default: pAd->ApCfg.MBSSID[i].RcvdSpoofedUnknownMgmtCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedUnknownMgmt = RcvdRssi; break; } return TRUE; } } return FALSE; }