VOID AsicUpdateWdsRxWCIDTable( IN PRTMP_ADAPTER pAd) { UINT index; MAC_TABLE_ENTRY *pEntry = NULL; for(index = 0; index < MAX_WDS_ENTRY; index++) { if (pAd->WdsTab.WdsEntry[index].Valid != TRUE) continue; pEntry = MacTableInsertWDSEntry(pAd, pAd->WdsTab.WdsEntry[index].PeerWdsAddr, index); RTMPSetSupportMCS(pAd, OPMODE_AP, pEntry, pAd->CommonCfg.SupRate, pAd->CommonCfg.SupRateLen, pAd->CommonCfg.ExtRate, pAd->CommonCfg.ExtRateLen, #ifdef DOT11_VHT_AC 0, NULL, #endif /* DOT11_VHT_AC */ &pAd->CommonCfg.HtCapability, sizeof(pAd->CommonCfg.HtCapability)); switch (pAd->WdsTab.WdsEntry[index].PhyMode) { case 0xff: /* user doesn't specific a Mode for WDS link. */ case MODE_OFDM: /* specific OFDM mode. */ pEntry->SupportRateMode = SUPPORT_OFDM_MODE; break; case MODE_CCK: pEntry->SupportRateMode = SUPPORT_CCK_MODE; break; #ifdef DOT11_N_SUPPORT case MODE_HTMIX: case MODE_HTGREENFIELD: pEntry->SupportRateMode = (SUPPORT_HT_MODE | SUPPORT_OFDM_MODE | SUPPORT_CCK_MODE); break; #endif /* DOT11_N_SUPPORT */ default: break; } } return; }
MAC_TABLE_ENTRY *FindWdsEntry( IN RTMP_ADAPTER *pAd, IN UCHAR Wcid, IN UCHAR *pAddr, IN UINT32 PhyMode) { MAC_TABLE_ENTRY *pEntry; RT_802_11_WDS_ENTRY *wds_entry; /* lookup the match wds entry for the incoming packet. */ pEntry = WdsTableLookupByWcid(pAd, Wcid, pAddr, TRUE); if (pEntry == NULL) pEntry = WdsTableLookup(pAd, pAddr, TRUE); /* Only Lazy mode will auto learning, match with FrDs=1 and ToDs=1 */ if((pEntry == NULL) && (pAd->WdsTab.Mode >= WDS_LAZY_MODE)) { INT WdsIdx = WdsEntryAlloc(pAd, pAddr); if (WdsIdx >= 0 && WdsIdx < MAX_WDS_ENTRY) { wds_entry = &pAd->WdsTab.WdsEntry[WdsIdx]; /* user doesn't specific a phy mode for WDS link. */ if (wds_entry->wdev.PhyMode == 0xff) wds_entry->wdev.PhyMode = PhyMode; pEntry = MacTableInsertWDSEntry(pAd, pAddr, (UCHAR)WdsIdx); RTMPSetSupportMCS(pAd, OPMODE_AP, pEntry, pAd->CommonCfg.SupRate, pAd->CommonCfg.SupRateLen, pAd->CommonCfg.ExtRate, pAd->CommonCfg.ExtRateLen, #ifdef DOT11_VHT_AC 0, NULL, #endif /* DOT11_VHT_AC */ &pAd->CommonCfg.HtCapability, sizeof(pAd->CommonCfg.HtCapability)); } else pEntry = NULL; } return pEntry; }
VOID AsicUpdateWdsRxWCIDTable(RTMP_ADAPTER *pAd) { UINT index; MAC_TABLE_ENTRY *pEntry = NULL; RT_802_11_WDS_ENTRY *wds_entry; for(index = 0; index < MAX_WDS_ENTRY; index++) { wds_entry = &pAd->WdsTab.WdsEntry[index]; if (pAd->WdsTab.Mode >= WDS_LAZY_MODE) { wds_entry->wdev.PhyMode = 0xff; if (WMODE_CAP_N(pAd->CommonCfg.PhyMode)) wds_entry->wdev.PhyMode = MODE_HTMIX; else { if (WMODE_EQUAL(pAd->CommonCfg.PhyMode, WMODE_B)) wds_entry->wdev.PhyMode = MODE_CCK; else wds_entry->wdev.PhyMode = MODE_OFDM; } } if (wds_entry->Valid != TRUE) continue; pEntry = MacTableInsertWDSEntry(pAd, wds_entry->PeerWdsAddr, index); RTMPSetSupportMCS(pAd, OPMODE_AP, pEntry, pAd->CommonCfg.SupRate, pAd->CommonCfg.SupRateLen, pAd->CommonCfg.ExtRate, pAd->CommonCfg.ExtRateLen, #ifdef DOT11_VHT_AC 0, NULL, #endif /* DOT11_VHT_AC */ &pAd->CommonCfg.HtCapability, sizeof(pAd->CommonCfg.HtCapability)); switch (wds_entry->wdev.PhyMode) { case 0xff: /* user doesn't specific a Mode for WDS link. */ case MODE_OFDM: /* specific OFDM mode. */ pEntry->SupportRateMode = SUPPORT_OFDM_MODE; if (WMODE_CAP_2G(pAd->CommonCfg.PhyMode)) pEntry->SupportRateMode |= SUPPORT_CCK_MODE; break; case MODE_CCK: pEntry->SupportRateMode = SUPPORT_CCK_MODE; break; #ifdef DOT11_N_SUPPORT case MODE_HTMIX: case MODE_HTGREENFIELD: pEntry->SupportRateMode = (SUPPORT_HT_MODE | SUPPORT_OFDM_MODE); if (WMODE_CAP_2G(pAd->CommonCfg.PhyMode)) pEntry->SupportRateMode |= SUPPORT_CCK_MODE; break; #endif /* DOT11_N_SUPPORT */ default: break; } } return; }
VOID ap_cmm_peer_assoc_req_action( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem, IN BOOLEAN isReassoc) { IE_LISTS *ie_list = NULL; HEADER_802_11 AssocRspHdr; USHORT CapabilityInfoForAssocResp; USHORT StatusCode = MLME_SUCCESS; USHORT Aid; PUCHAR pOutBuffer = NULL; NDIS_STATUS NStatus; ULONG FrameLen = 0; UCHAR MaxSupportedRate = 0; UCHAR SupRateLen, PhyMode, FlgIs11bSta; UCHAR i; MAC_TABLE_ENTRY *pEntry; #ifdef DBG UCHAR *sAssoc = isReassoc ? (PUCHAR)"ReASSOC" : (PUCHAR)"ASSOC"; #endif /* DBG */ UCHAR SubType; BOOLEAN bACLReject = FALSE; #ifdef DOT1X_SUPPORT PUINT8 pPmkid = NULL; UINT8 pmkid_count = 0; #endif /* DOT1X_SUPPORT */ MULTISSID_STRUCT *wdev; /* allocate memory */ os_alloc_mem(NULL, (UCHAR **)&ie_list, sizeof(IE_LISTS)); if (ie_list == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s(): mem alloc failed\n", __FUNCTION__)); return; } NdisZeroMemory(ie_list, sizeof(IE_LISTS)); if (!PeerAssocReqCmmSanity(pAd, isReassoc, Elem->Msg, Elem->MsgLen, ie_list)) goto LabelOK; /* check if AP address is same as us */ /* TODO */ /* goto label_err; */ pEntry = MacTableLookup(pAd, ie_list->Addr2); if (!pEntry) { DBGPRINT(RT_DEBUG_ERROR, ("NoAuth MAC - %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(ie_list->Addr2))); goto LabelOK; } if (!VALID_MBSS(pAd, pEntry->apidx)) { DBGPRINT(RT_DEBUG_ERROR, ("%s():pEntry bounding invalid wdev(apidx=%d)\n", __FUNCTION__, pEntry->apidx)); goto LabelOK; } wdev = &pAd->ApCfg.MBSSID[pEntry->apidx]; PhyMode = wdev->PhyMode; FlgIs11bSta = 1; for(i=0; i<ie_list->SupportedRatesLen; i++) { if (((ie_list->SupportedRates[i] & 0x7F) != 2) && ((ie_list->SupportedRates[i] & 0x7F) != 4) && ((ie_list->SupportedRates[i] & 0x7F) != 11) && ((ie_list->SupportedRates[i] & 0x7F) != 22)) { FlgIs11bSta = 0; break; } } /* clear the previous Pairwise key table */ if(pEntry->Aid != 0 && (pEntry->WepStatus >= Ndis802_11Encryption2Enabled #ifdef DOT1X_SUPPORT || wdev->IEEE8021X #endif /* DOT1X_SUPPORT */ )) { /* clear GTK state */ pEntry->GTKState = REKEY_NEGOTIATING; NdisZeroMemory(&pEntry->PairwiseKey, sizeof(CIPHER_KEY)); /* clear this entry as no-security mode */ AsicRemovePairwiseKeyEntry(pAd, pEntry->Aid); #ifdef DOT1X_SUPPORT /* Notify 802.1x daemon to clear this sta info */ if (pEntry->AuthMode == Ndis802_11AuthModeWPA || pEntry->AuthMode == Ndis802_11AuthModeWPA2 || wdev->IEEE8021X) DOT1X_InternalCmdAction(pAd, pEntry, DOT1X_DISCONNECT_ENTRY); #endif /* DOT1X_SUPPORT */ } /* for hidden SSID sake, SSID in AssociateRequest should be fully verified */ if ((ie_list->SsidLen != wdev->SsidLen) || (NdisEqualMemory(ie_list->Ssid, wdev->Ssid, ie_list->SsidLen)==0)) goto LabelOK; /* set a flag for sending Assoc-Fail response to unwanted STA later. */ if (! ApCheckAccessControlList(pAd, ie_list->Addr2, pEntry->apidx)) bACLReject = TRUE; DBGPRINT(RT_DEBUG_TRACE, ("%s - MBSS(%d), receive %s request from %02x:%02x:%02x:%02x:%02x:%02x\n", sAssoc, pEntry->apidx, sAssoc, PRINT_MAC(ie_list->Addr2))); /* supported rates array may not be sorted. sort it and find the maximum rate */ for (i=0; i<ie_list->SupportedRatesLen; i++) { if (MaxSupportedRate < (ie_list->SupportedRates[i] & 0x7f)) MaxSupportedRate = ie_list->SupportedRates[i] & 0x7f; } /* Assign RateLen here or we will select wrong rate table in APBuildAssociation() when 11N compile option is disabled. */ pEntry->RateLen = ie_list->SupportedRatesLen; RTMPSetSupportMCS(pAd, OPMODE_AP, pEntry, ie_list->SupportedRates, ie_list->SupportedRatesLen, NULL, 0, #ifdef DOT11_VHT_AC ie_list->vht_cap_len, &ie_list->vht_cap, #endif /* DOT11_VHT_AC */ &ie_list->HTCapability, ie_list->ht_cap_len); /* 2. qualify this STA's auth_asoc status in the MAC table, decide StatusCode */ StatusCode = APBuildAssociation(pAd, pEntry, ie_list, MaxSupportedRate, &Aid); #ifdef DOT11_VHT_AC if (ie_list->vht_cap_len) { VHT_CAP_INFO *vht_cap = &ie_list->vht_cap.vht_cap; //+++Add by shiang for debug if (WMODE_CAP_AC(pAd->CommonCfg.PhyMode)) { DBGPRINT(RT_DEBUG_TRACE, ("%s():Peer is VHT capable device!\n", __FUNCTION__)); //dump_vht_cap(pAd, &ie_list->vht_cap); } //---Add by shiang for debug } #endif /* DOT11_VHT_AC */ if (StatusCode == MLME_ASSOC_REJ_DATA_RATE) RTMPSendWirelessEvent(pAd, IW_STA_MODE_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0); /* 3. send Association Response */ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); if (NStatus != NDIS_STATUS_SUCCESS) goto LabelOK; DBGPRINT(RT_DEBUG_TRACE, ("%s - Send %s response (Status=%d)...\n", sAssoc, sAssoc, StatusCode)); Aid |= 0xc000; /* 2 most significant bits should be ON */ SubType = isReassoc ? SUBTYPE_REASSOC_RSP : SUBTYPE_ASSOC_RSP; CapabilityInfoForAssocResp = wdev->CapabilityInfo; /*use AP's cability */ /* fail in ACL checking => send an Assoc-Fail resp. */ SupRateLen = pAd->CommonCfg.SupRateLen; /* TODO: need to check rate in support rate element, not number */ if (FlgIs11bSta == 1) SupRateLen = 4; if (bACLReject == TRUE) { MgtMacHeaderInit(pAd, &AssocRspHdr, SubType, 0, ie_list->Addr2, wdev->Bssid); StatusCode = MLME_UNSPECIFY_FAIL; MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &AssocRspHdr, 2, &CapabilityInfoForAssocResp, 2, &StatusCode, 2, &Aid, 1, &SupRateIe, 1, &SupRateLen, SupRateLen, pAd->CommonCfg.SupRate, END_OF_ARGS); MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, (PVOID) pOutBuffer); RTMPSendWirelessEvent(pAd, IW_MAC_FILTER_LIST_EVENT_FLAG, ie_list->Addr2, pEntry->apidx, 0); goto LabelOK; } MgtMacHeaderInit(pAd, &AssocRspHdr, SubType, 0, ie_list->Addr2, wdev->Bssid); MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &AssocRspHdr, 2, &CapabilityInfoForAssocResp, 2, &StatusCode, 2, &Aid, 1, &SupRateIe, 1, &SupRateLen, SupRateLen, pAd->CommonCfg.SupRate, END_OF_ARGS); if ((pAd->CommonCfg.ExtRateLen) && (PhyMode != WMODE_B) && (FlgIs11bSta == 0)) { ULONG TmpLen; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &ExtRateIe, 1, &pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRate, END_OF_ARGS); FrameLen += TmpLen; } /* add WMM IE here */ if (wdev->bWmmCapable && CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE)) { ULONG TmpLen; 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], &wdev->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; }