/* ======================================================================== Routine Description: Update HT IE from our capability. Arguments: Send all HT IE in beacon/probe rsp/assoc rsp/action frame. ======================================================================== */ VOID RTMPUpdateHTIE( IN RT_HT_CAPABILITY *pRtHt, IN UCHAR *pMcsSet, OUT HT_CAPABILITY_IE *pHtCapability, OUT ADD_HT_INFO_IE *pAddHtInfo) { RTMPZeroMemory(pHtCapability, sizeof(HT_CAPABILITY_IE)); RTMPZeroMemory(pAddHtInfo, sizeof(ADD_HT_INFO_IE)); pHtCapability->HtCapInfo.ChannelWidth = pRtHt->ChannelWidth; pHtCapability->HtCapInfo.MimoPs = pRtHt->MimoPs; pHtCapability->HtCapInfo.GF = pRtHt->GF; pHtCapability->HtCapInfo.ShortGIfor20 = pRtHt->ShortGIfor20; pHtCapability->HtCapInfo.ShortGIfor40 = pRtHt->ShortGIfor40; pHtCapability->HtCapInfo.TxSTBC = pRtHt->TxSTBC; pHtCapability->HtCapInfo.RxSTBC = pRtHt->RxSTBC; pHtCapability->HtCapInfo.AMsduSize = pRtHt->AmsduSize; pHtCapability->HtCapParm.MaxRAmpduFactor = pRtHt->MaxRAmpduFactor; pHtCapability->HtCapParm.MpduDensity = pRtHt->MpduDensity; pAddHtInfo->AddHtInfo.ExtChanOffset = pRtHt->ExtChanOffset ; pAddHtInfo->AddHtInfo.RecomWidth = pRtHt->RecomWidth; pAddHtInfo->AddHtInfo2.OperaionMode = pRtHt->OperaionMode; pAddHtInfo->AddHtInfo2.NonGfPresent = pRtHt->NonGfPresent; RTMPMoveMemory(pAddHtInfo->MCSSet, /*pRtHt->MCSSet*/pMcsSet, 4); /* rt2860 only support MCS max=32, no need to copy all 16 uchar.*/ DBGPRINT(RT_DEBUG_TRACE,("RTMPUpdateHTIE <== \n")); }
/* ======================================================================== Routine Description: Clear the desire HT info per interface Arguments: ======================================================================== */ VOID RTMPDisableDesiredHtInfo(struct rtmp_adapter *pAd) { struct rtmp_wifi_dev *wdev; #ifdef CONFIG_AP_SUPPORT UINT8 idx = 0; IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { for (idx = 0; idx < pAd->ApCfg.BssidNum; idx++) { wdev = &pAd->ApCfg.MBSSID[idx].wdev; RTMPZeroMemory(&wdev->DesiredHtPhyInfo, sizeof(RT_PHY_INFO)); } } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { RTMPZeroMemory(&pAd->StaCfg.wdev.DesiredHtPhyInfo, sizeof(RT_PHY_INFO)); } #endif /* CONFIG_STA_SUPPORT */ }
/* ======================================================================== Routine Description: Clear the desire HT info per interface Arguments: ======================================================================== */ VOID RTMPDisableDesiredHtInfo( IN PRTMP_ADAPTER pAd) { #ifdef CONFIG_AP_SUPPORT UINT8 apidx = 0; #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++) { RTMPZeroMemory(&pAd->ApCfg.MBSSID[apidx].DesiredHtPhyInfo, sizeof(RT_PHY_INFO)); } #ifdef WDS_SUPPORT for (apidx = 0; apidx < MAX_WDS_ENTRY; apidx++) { RTMPZeroMemory(&pAd->WdsTab.WdsEntry[apidx].DesiredHtPhyInfo, sizeof(RT_PHY_INFO)); } #endif /* WDS_SUPPORT */ #ifdef APCLI_SUPPORT for (apidx = 0; apidx < MAX_APCLI_NUM; apidx++) { RTMPZeroMemory(&pAd->ApCfg.ApCliTab[apidx].DesiredHtPhyInfo, sizeof(RT_PHY_INFO)); } #endif /* APCLI_SUPPORT */ } #endif /* CONFIG_AP_SUPPORT */ }
/* ======================================================================== Routine Description: Clear the desire HT info per interface Arguments: ======================================================================== */ VOID RTMPDisableDesiredHtInfo(RTMP_ADAPTER *pAd) { struct wifi_dev *wdev = NULL; #ifdef CONFIG_AP_SUPPORT UINT8 idx = 0; IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { for (idx = 0; idx < pAd->ApCfg.BssidNum; idx++) { wdev = &pAd->ApCfg.MBSSID[idx].wdev; RTMPZeroMemory(&wdev->DesiredHtPhyInfo, sizeof(RT_PHY_INFO)); } #ifdef WDS_SUPPORT for (idx = 0; idx < MAX_WDS_ENTRY; idx++) { RTMPZeroMemory(&pAd->WdsTab.WdsEntry[idx].wdev.DesiredHtPhyInfo, sizeof(RT_PHY_INFO)); } #endif /* WDS_SUPPORT */ #ifdef APCLI_SUPPORT for (idx = 0; idx < MAX_APCLI_NUM; idx++) { RTMPZeroMemory(&pAd->ApCfg.ApCliTab[idx].wdev.DesiredHtPhyInfo, sizeof(RT_PHY_INFO)); } #endif /* APCLI_SUPPORT */ } #endif /* CONFIG_AP_SUPPORT */ }
VOID ComposePsPoll(RTMP_ADAPTER *pAd) { TXINFO_STRUC *pTxInfo; TXWI_STRUC *pTxWI; UINT8 TXWISize = pAd->chipCap.TXWISize; UCHAR *buf; USHORT data_len; DBGPRINT(RT_DEBUG_TRACE, ("ComposePsPoll\n")); NdisZeroMemory(&pAd->PsPollFrame, sizeof (PSPOLL_FRAME)); pAd->PsPollFrame.FC.PwrMgmt = 0; pAd->PsPollFrame.FC.Type = BTYPE_CNTL; pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL; pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000; COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid); COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress); buf = &pAd->PsPollContext.TransferBuffer->field.WirelessPacket[0]; pTxInfo = (TXINFO_STRUC *)buf; pTxWI = (TXWI_STRUC *)&buf[TXINFO_SIZE]; RTMPZeroMemory(buf, 100); data_len = sizeof (PSPOLL_FRAME); rlt_usb_write_txinfo(pAd, pTxInfo, data_len + TXWISize + TSO_SIZE, TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE); RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, data_len, 0, 0, (UCHAR) pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit); RTMPMoveMemory((VOID *)&buf[TXWISize + TXINFO_SIZE + TSO_SIZE], (VOID *)&pAd->PsPollFrame, data_len); /* Append 4 extra zero bytes. */ pAd->PsPollContext.BulkOutSize = TXINFO_SIZE + TXWISize + TSO_SIZE + data_len + 4; }
/* IRQL = DISPATCH_LEVEL */ VOID ComposeNullFrame(RTMP_ADAPTER *pAd) { TXINFO_STRUC *pTxInfo; TXWI_STRUC *pTxWI; UCHAR *buf; UINT8 TXWISize = pAd->chipCap.TXWISize; USHORT data_len = sizeof(pAd->NullFrame);; NdisZeroMemory(&pAd->NullFrame, data_len); pAd->NullFrame.FC.Type = BTYPE_DATA; pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC; pAd->NullFrame.FC.ToDs = 1; COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid); COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress); COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid); buf = &pAd->NullContext.TransferBuffer->field.WirelessPacket[0]; RTMPZeroMemory(buf, 100); pTxInfo = (TXINFO_STRUC *)buf; pTxWI = (TXWI_STRUC *)&buf[TXINFO_SIZE]; rlt_usb_write_txinfo(pAd, pTxInfo, (USHORT)(data_len + TXWISize + TSO_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE); RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, data_len, 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit); RTMPMoveMemory((VOID *)&buf[TXWISize + TXINFO_SIZE], (VOID *)&pAd->NullFrame, data_len); pAd->NullContext.BulkOutSize = TXINFO_SIZE + TXWISize + TSO_SIZE + data_len + 4; }
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; }
/* ========================================================================== Description: Init P2P Group Table. Parameters: Note: ========================================================================== */ VOID P2pGroupTabInit( IN PRTMP_ADAPTER pAd) { PRT_P2P_TABLE Tab = &pAd->P2pTable; UCHAR i; DBGPRINT(RT_DEBUG_ERROR, ("P2pGroupTabInit . \n")); for (i = 0; i < MAX_P2P_GROUP_SIZE; i++) { Tab->Client[i].P2pClientState = P2PSTATE_NONE; Tab->Client[i].Rule = P2P_IS_CLIENT; Tab->Client[i].DevCapability = 0; Tab->Client[i].GroupCapability = 0; RTMPZeroMemory(Tab->Client[i].addr, MAC_ADDR_LEN); RTMPZeroMemory(Tab->Client[i].bssid, MAC_ADDR_LEN); RTMPZeroMemory(Tab->Client[i].InterfaceAddr, MAC_ADDR_LEN); RTMPZeroMemory(Tab->Client[i].Ssid, MAX_LEN_OF_SSID); RTMPZeroMemory(Tab->Client[i].PrimaryDevType, P2P_DEVICE_TYPE_LEN); RTMPZeroMemory(Tab->Client[i].SecondaryDevType, P2P_DEVICE_TYPE_LEN); RTMPZeroMemory(Tab->Client[i].DeviceName, P2P_DEVICE_NAME_LEN); Tab->Client[i].DeviceNameLen = 0; Tab->Client[i].SsidLen = 0; Tab->Client[i].GoIntent = 0; Tab->Client[i].OpChannel = 0; Tab->Client[i].ListenChannel = 0; Tab->Client[i].ConfigMethod = 0; Tab->Client[i].P2pClientState = P2PSTATE_NONE; Tab->Client[i].StateCount = 0; Tab->Client[i].bValid = FALSE; } Tab->ClientNumber = 0; return; }
VOID ApCliSiteSurvey( IN RTMP_ADAPTER *pAd, IN UCHAR ifIndex, IN NDIS_802_11_SSID *pSsid, IN UCHAR ScanType, IN BOOLEAN ChannelSel) { MLME_SCAN_REQ_STRUCT ScanReq; if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) { /* * Still scanning, ignore this scan. */ DBGPRINT(RT_DEBUG_TRACE, ("ApCliSiteSurvey:: scanning now\n")); return; } if(ifIndex >= MAX_APCLI_NUM) return; #ifdef WSC_AP_SUPPORT if ((pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscConfMode != WSC_DISABLE) && (pAd->ApCfg.ApCliTab[ifIndex].WscControl.bWscTrigger == TRUE)) { DBGPRINT(RT_DEBUG_TRACE, ("%s(): Stop scanning due to WPS triggered!\n",__FUNCTION__)); return; } #endif /* WSC_AP_SUPPORT */ AsicDisableSync(pAd); #ifdef AP_PARTIAL_SCAN_SUPPORT if (((pAd->ApCfg.bPartialScanning == TRUE) && (pAd->ApCfg.LastPartialScanChannel == 0)) || (pAd->ApCfg.bPartialScanning == FALSE)) #endif /* AP_PARTIAL_SCAN_SUPPORT */ { BssTableInit(&pAd->ScanTab); } pAd->Mlme.ApSyncMachine.CurrState = AP_SYNC_IDLE; pAd->ApCfg.ApCliTab[ifIndex].SyncCurrState = APCLI_SYNC_IDLE; RTMPZeroMemory(ScanReq.Ssid, MAX_LEN_OF_SSID); ScanReq.SsidLen = 0; if (pSsid) { ScanReq.SsidLen = pSsid->SsidLength; NdisMoveMemory(ScanReq.Ssid, pSsid->Ssid, pSsid->SsidLength); } ScanReq.BssType = BSS_ANY; ScanReq.ScanType = ScanType; pAd->ApCfg.bAutoChannelAtBootup = ChannelSel; MlmeEnqueue(pAd, APCLI_SYNC_STATE_MACHINE, APCLI_MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq, 0); RTMP_MLME_HANDLER(pAd); }
VOID P2pCrednTabDelete( IN PRTMP_ADAPTER pAd, IN UCHAR *pAddr) { PRT_P2P_TABLE Tab = &pAd->P2pTable; UCHAR i; /*UCHAR Zero[6] = {0,0,0,0,0,0}; */ DBGPRINT(RT_DEBUG_ERROR, (" P2P - P2pCrednTabDelete \n")); for (i = 0; i < MAX_P2P_TABLE_SIZE; i++) { if (RTMPEqualMemory(pAddr, Tab->TempCredential[i].InterAddr, MAC_ADDR_LEN)) { Tab->TempCredential[i].bValid = FALSE; RTMPZeroMemory(Tab->TempCredential[i].InterAddr, MAC_ADDR_LEN); RTMPZeroMemory(&Tab->TempCredential[i].Profile, sizeof(WSC_CREDENTIAL)); } } }
UCHAR P2pGroupTabDelete( IN PRTMP_ADAPTER pAd, IN UCHAR p2pindex, IN PUCHAR Addr) { UCHAR index = 0xff; PRT_P2P_CLIENT_ENTRY pP2pEntry; if ((p2pindex >= MAX_P2P_GROUP_SIZE) && (Addr != NULL)) index = P2pGroupTabSearch(pAd, Addr); else index = p2pindex; DBGPRINT(RT_DEBUG_TRACE,("P2pGroupTabDelete . index = %d. \n", index)); if (index < MAX_P2P_GROUP_SIZE) { pP2pEntry = &pAd->P2pTable.Client[index]; /* Before connected, there is WPS provisioning process. */ /* So maybe receive disassoc frame. but we can't delete p2p client entry . */ /* So need to check P2pClientState is connected, then we can delete the entry. */ DBGPRINT(RT_DEBUG_ERROR, ("P2pGroupTabDelete index %d. search addr[3~5] is %x %x %x\n", index, Addr[3],Addr[4],Addr[5])); RTMPZeroMemory(pP2pEntry->addr, MAC_ADDR_LEN); RTMPZeroMemory(pP2pEntry->bssid, MAC_ADDR_LEN); RTMPZeroMemory(pP2pEntry->InterfaceAddr, MAC_ADDR_LEN); /* Assign a strange address first. */ pP2pEntry->addr[3] = 0x55; pP2pEntry->bssid[3] = 0x55; pP2pEntry->InterfaceAddr[3] = 0x55; RTMPZeroMemory(pP2pEntry->PrimaryDevType, P2P_DEVICE_TYPE_LEN); RTMPZeroMemory(pP2pEntry->SecondaryDevType, P2P_DEVICE_TYPE_LEN); RTMPZeroMemory(pP2pEntry->DeviceName, P2P_DEVICE_NAME_LEN); pP2pEntry->NumSecondaryType = 0; pP2pEntry->DeviceNameLen = 0; pP2pEntry->ConfigMethod = 0; pP2pEntry->OpChannel = 0; pP2pEntry->ListenChannel = 0; pP2pEntry->Dpid = DEV_PASS_ID_NOSPEC; pP2pEntry->MyGOIndex = 0xff; pP2pEntry->Peerip = 0; pP2pEntry->ConfigTimeOut = 0; pP2pEntry->Rule = P2P_IS_CLIENT; RTMPZeroMemory(pP2pEntry->Ssid, MAX_LEN_OF_SSID); pP2pEntry->SsidLen = 0; pP2pEntry->GoIntent = 0; if ((pAd->P2pTable.ClientNumber > 0) && (pP2pEntry->P2pClientState != P2PSTATE_NONE)) pAd->P2pTable.ClientNumber--; pP2pEntry->P2pClientState = P2PSTATE_NONE; } return index; }
INT Set_P2P_Reset_Proc( IN PRTMP_ADAPTER pAd, IN PSTRING arg) { /*UINT32 DiscPerd = 0;*/ POS_COOKIE pObj; PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg; pObj = (POS_COOKIE) pAd->OS_Cookie; if (pObj->ioctl_if_type != INT_P2P) return 0; if (P2P_CLI_ON(pAd)) P2P_CliStop(pAd); else if (P2P_GO_ON(pAd)) { P2P_GoStop(pAd); if (INFRA_ON(pAd)) AsicEnableBssSync(pAd); } P2PCfgInit(pAd); P2pGroupTabInit(pAd); pP2PCtrl->Rule = P2P_IS_DEVICE; pAd->flg_p2p_OpStatusFlags = P2P_DISABLE; pP2PCtrl->ConfigMethod = 0x188; pAd->ApCfg.MBSSID[MAIN_MBSSID].WscControl.WscConfStatus = WSC_SCSTATE_UNCONFIGURED; pP2PCtrl->GoFormCurrentState = P2P_GO_FORM_IDLE; pP2PCtrl->DiscCurrentState = P2P_DISC_IDLE; pP2PCtrl->CtrlCurrentState = P2P_CTRL_IDLE; NdisZeroMemory(&pP2PCtrl->P2pCounter, sizeof(P2P_COUNTER_STRUCT)); P2pSetListenIntBias(pAd, 3); RTMPZeroMemory(pAd->P2pCfg.SSID, MAX_LEN_OF_SSID); RTMPMoveMemory(pAd->P2pCfg.SSID, WILDP2PSSID, WILDP2PSSIDLEN); pP2PCtrl->SSIDLen = WILDP2PSSIDLEN; /* Set Dpid to "not specified". it means, GUI doesn't set for connection yet. */ pP2PCtrl->Dpid = DEV_PASS_ID_NOSPEC; RTMPZeroMemory(pAd->P2pCfg.ConnectingMAC, MAC_ADDR_LEN); return TRUE; }
VOID RtmpUSBNullFrameKickOut( IN RTMP_ADAPTER *pAd, IN UCHAR QueIdx, IN UCHAR *pNullFrame, IN UINT32 frameLen) { if (pAd->NullContext.InUse == FALSE) { PTX_CONTEXT pNullContext; TXINFO_STRUC *pTxInfo; TXWI_STRUC *pTxWI; UCHAR *pWirelessPkt; UINT8 TXWISize = pAd->chipCap.TXWISize; pNullContext = &(pAd->NullContext); /* Set the in use bit*/ pNullContext->InUse = TRUE; pWirelessPkt = (PUCHAR)&pNullContext->TransferBuffer->field.WirelessPacket[0]; RTMPZeroMemory(&pWirelessPkt[0], 100); pTxInfo = (TXINFO_STRUC *)&pWirelessPkt[0]; rlt_usb_write_txinfo(pAd, pTxInfo, (USHORT)(frameLen + TXWISize + TSO_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE); pTxInfo->TxInfoQSEL = FIFO_EDCA; pTxWI = (TXWI_STRUC *)&pWirelessPkt[TXINFO_SIZE]; RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, frameLen, 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit); #ifdef RT_BIG_ENDIAN RTMPWIEndianChange(pAd, (PUCHAR)pTxWI, TYPE_TXWI); #endif /* RT_BIG_ENDIAN */ RTMPMoveMemory(&pWirelessPkt[TXWISize + TXINFO_SIZE + TSO_SIZE], pNullFrame, frameLen); #ifdef RT_BIG_ENDIAN RTMPFrameEndianChange(pAd, (PUCHAR)&pWirelessPkt[TXINFO_SIZE + TXWISize + TSO_SIZE], DIR_WRITE, FALSE); #endif /* RT_BIG_ENDIAN */ pAd->NullContext.BulkOutSize = TXINFO_SIZE + TXWISize + TSO_SIZE + frameLen + 4; pAd->NullContext.BulkOutSize = ( pAd->NullContext.BulkOutSize + 3) & (~3); /* Fill out frame length information for global Bulk out arbitor*/ /*pNullContext->BulkOutSize = TransferBufferLength;*/ DBGPRINT(RT_DEBUG_TRACE, ("%s - Send NULL Frame @%d Mbps...\n", __FUNCTION__, RateIdToMbps[pAd->CommonCfg.TxRate])); RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL); pAd->Sequence = (pAd->Sequence+1) & MAXSEQ; /* Kick bulk out */ RTUSBKickBulkOut(pAd); } }
void RtmpUSBNullFrameKickOut(struct rt_rtmp_adapter *pAd, u8 QueIdx, u8 * pNullFrame, u32 frameLen) { if (pAd->NullContext.InUse == FALSE) { struct rt_tx_context *pNullContext; struct rt_txinfo *pTxInfo; struct rt_txwi * pTxWI; u8 *pWirelessPkt; pNullContext = &(pAd->NullContext); /* Set the in use bit */ pNullContext->InUse = TRUE; pWirelessPkt = (u8 *)& pNullContext->TransferBuffer->field. WirelessPacket[0]; RTMPZeroMemory(&pWirelessPkt[0], 100); pTxInfo = (struct rt_txinfo *)& pWirelessPkt[0]; RTMPWriteTxInfo(pAd, pTxInfo, (u16)(sizeof(struct rt_header_802_11) + TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE); pTxInfo->QSEL = FIFO_EDCA; pTxWI = (struct rt_txwi *) & pWirelessPkt[TXINFO_SIZE]; RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(struct rt_header_802_11)), 0, 0, (u8)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit); RTMPMoveMemory(&pWirelessPkt[TXWI_SIZE + TXINFO_SIZE], &pAd->NullFrame, sizeof(struct rt_header_802_11)); pAd->NullContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4; /* Fill out frame length information for global Bulk out arbitor */ /*pNullContext->BulkOutSize = TransferBufferLength; */ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - send NULL Frame @%d Mbps...\n", RateIdToMbps[pAd->CommonCfg.TxRate])); RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL); /* Kick bulk out */ RTUSBKickBulkOut(pAd); } }
VOID RtmpUSBNullFrameKickOut( IN RTMP_ADAPTER *pAd, IN UCHAR QueIdx, IN UCHAR *pNullFrame, IN UINT32 frameLen) { if (pAd->NullContext.InUse == FALSE) { PTX_CONTEXT pNullContext; PTXINFO_STRUC pTxInfo; PTXWI_STRUC pTxWI; PUCHAR pWirelessPkt; pNullContext = &(pAd->NullContext); // Set the in use bit pNullContext->InUse = TRUE; pWirelessPkt = (PUCHAR)&pNullContext->TransferBuffer->field.WirelessPacket[0]; RTMPZeroMemory(&pWirelessPkt[0], 100); pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[0]; RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(HEADER_802_11)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE); pTxInfo->QSEL = FIFO_EDCA; pTxWI = (PTXWI_STRUC)&pWirelessPkt[TXINFO_SIZE]; RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(HEADER_802_11)), 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit); #ifdef RT_BIG_ENDIAN RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI); #endif // RT_BIG_ENDIAN // RTMPMoveMemory(&pWirelessPkt[TXWI_SIZE+TXINFO_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11)); #ifdef RT_BIG_ENDIAN RTMPFrameEndianChange(pAd, (PUCHAR)&pWirelessPkt[TXINFO_SIZE + TXWI_SIZE], DIR_WRITE, FALSE); #endif // RT_BIG_ENDIAN // pAd->NullContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4; // Fill out frame length information for global Bulk out arbitor //pNullContext->BulkOutSize = TransferBufferLength; DBGPRINT(RT_DEBUG_TRACE, ("SYNC - send NULL Frame @%d Mbps...\n", RateIdToMbps[pAd->CommonCfg.TxRate])); RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL); // Kick bulk out RTUSBKickBulkOut(pAd); } }
VOID P2pCrednTabClean( IN PRTMP_ADAPTER pAd) { UCHAR i; RT_GO_CREDENTIAL_ENTRY *pCrednEntry; DBGPRINT(RT_DEBUG_TRACE,("P2pCrednTabClean . \n")); for (i = 0; i < 2/*MAX_P2P_SAVECREDN_SIZE*/; i++) { pCrednEntry = &pAd->P2pTable.TempCredential[i]; RTMPZeroMemory(pCrednEntry, sizeof(RT_GO_CREDENTIAL_ENTRY)); pCrednEntry->bValid = FALSE; } return; }
VOID P2pPerstTabClean( IN PRTMP_ADAPTER pAd) { PRT_P2P_PERSISTENT_ENTRY pP2pPerstEntry; UCHAR i; DBGPRINT(RT_DEBUG_TRACE,("P2pPerstTabClean . \n")); for (i = 0; i < MAX_P2P_TABLE_SIZE; i++) { pP2pPerstEntry = &pAd->P2pTable.PerstEntry[i]; RTMPZeroMemory(pP2pPerstEntry, sizeof(RT_P2P_PERSISTENT_ENTRY)); pP2pPerstEntry->bValid = FALSE; } pAd->P2pTable.PerstNumber = 0; return; }
BOOLEAN WscGetXmlSSID( IN STRING *pXmlData, OUT NDIS_802_11_SSID *pSsid) { STRING *ptr, *pBuffer = pXmlData; ptr = rtstrstr(pBuffer, (PSTRING)XML_SSID_START); if (ptr == NULL) { DBGPRINT(RT_DEBUG_TRACE, ("WscGetXmlSSID: missing <ssid\n")); return FALSE; } pBuffer = ptr + strlen(XML_SSID_START); ptr = rtstrstr(pBuffer, ">"); if (ptr) { pBuffer = ptr + 1; } ptr = rtstrstr(pBuffer, (PSTRING)XML_SSID_END); if (ptr == NULL) { DBGPRINT(RT_DEBUG_TRACE, ("WscGetXmlSSID: missing </ssid>\n")); return FALSE; } pSsid->SsidLength = (UINT)(ptr - pBuffer); RTMPZeroMemory(pSsid->Ssid, NDIS_802_11_LENGTH_SSID); if ((pSsid->SsidLength > 0) && (pSsid->SsidLength < 33)) { RTMPMoveMemory(pSsid->Ssid, pBuffer, pSsid->SsidLength); } else { pSsid->SsidLength = 0; return FALSE; } return TRUE; }
VOID RtmpUSBNullFrameKickOut( IN RTMP_ADAPTER *pAd, IN UCHAR QueIdx, IN UCHAR *pNullFrame, IN UINT32 frameLen) { if (pAd->NullContext.InUse == FALSE) { PTX_CONTEXT pNullContext; PTXINFO_STRUC pTxInfo; PTXWI_STRUC pTxWI; PUCHAR pWirelessPkt; pNullContext = &(pAd->NullContext); pNullContext->InUse = TRUE; pWirelessPkt = (PUCHAR)&pNullContext->TransferBuffer->field.WirelessPacket[0]; RTMPZeroMemory(&pWirelessPkt[0], 100); pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[0]; RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(HEADER_802_11)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE); pTxInfo->QSEL = FIFO_EDCA; pTxWI = (PTXWI_STRUC)&pWirelessPkt[TXINFO_SIZE]; RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(HEADER_802_11)), 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit); RTMPMoveMemory(&pWirelessPkt[TXWI_SIZE+TXINFO_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11)); pAd->NullContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4; DBGPRINT(RT_DEBUG_TRACE, ("SYNC - send NULL Frame @%d Mbps...\n", RateIdToMbps[pAd->CommonCfg.TxRate])); RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL); RTUSBKickBulkOut(pAd); } }
VOID FT_OTD_ActParmFill( IN PRTMP_ADAPTER pAd, IN OUT MLME_FT_REQ_STRUCT *FtReq, IN PUCHAR pAddr, IN NDIS_802_11_AUTHENTICATION_MODE AuthMode, IN PFT_MDIE_INFO FtMdieInfo, IN PFT_FTIE_INFO FtFtieInfo, IN UCHAR VarIeLen, IN PUCHAR pVarIe) { RTMPZeroMemory(FtReq, sizeof (MLME_FT_REQ_STRUCT)); COPY_MAC_ADDR(FtReq->TargetAddr, pAddr); if (AuthMode >= Ndis802_11AuthModeWPA) FtReq->HaveRSN = 1; FtReq->Timeout = FT_ACT_TIMEOUT; FT_SET_MDID(FtReq->MdIe.MdId, FtMdieInfo->MdId); FtReq->MdIe.FtCapPlc.word = FtMdieInfo->FtCapPlc.word; RTMPMoveMemory(&FtReq->SNonce[0], FtFtieInfo->SNonce, 32); RTMPMoveMemory(&FtReq->R0khId[0], FtFtieInfo->R0khId, FtFtieInfo->R0khIdLen); FtReq->R0khIdLen = FtFtieInfo->R0khIdLen; RTMPMoveMemory(&FtReq->VIe[0], pVarIe, VarIeLen); }
/* ======================================================================== Routine Description: Caller ensures we has 802.11n support. Calls at setting HT from AP/STASetinformation Arguments: pAd - Pointer to our adapter phymode - ======================================================================== */ VOID RTMPSetHT( IN RTMP_ADAPTER *pAd, IN OID_SET_HT_PHYMODE *pHTPhyMode) { UCHAR RxStream = pAd->CommonCfg.RxStream; #ifdef CONFIG_AP_SUPPORT INT apidx; #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_MULTI_CHANNEL #if defined(RT_CFG80211_SUPPORT) && defined(CONFIG_AP_SUPPORT) BSS_STRUCT *pMbss = &pAd->ApCfg.MBSSID[CFG_GO_BSSID_IDX]; struct wifi_dev *wdev = &pMbss->wdev; #endif /* defined(RT_CFG80211_SUPPORT) && defined(CONFIG_AP_SUPPORT) */ #endif /* CONFIG_MULTI_CHANNEL */ INT bw; RT_HT_CAPABILITY *rt_ht_cap = &pAd->CommonCfg.DesiredHtPhy; HT_CAPABILITY_IE *ht_cap= &pAd->CommonCfg.HtCapability; #ifdef CONFIG_AP_SUPPORT /* sanity check for extention channel */ if (CHAN_PropertyCheck(pAd, pAd->CommonCfg.Channel, CHANNEL_NO_FAT_BELOW | CHANNEL_NO_FAT_ABOVE) == TRUE) { /* only 20MHz is allowed */ pHTPhyMode->BW = 0; } else if (pHTPhyMode->ExtOffset == EXTCHA_BELOW) { /* extension channel below this channel is not allowed */ if (CHAN_PropertyCheck(pAd, pAd->CommonCfg.Channel, CHANNEL_NO_FAT_BELOW) == TRUE) { pHTPhyMode->ExtOffset = EXTCHA_ABOVE; } } else if (pHTPhyMode->ExtOffset == EXTCHA_ABOVE) { /* extension channel above this channel is not allowed */ if (CHAN_PropertyCheck(pAd, pAd->CommonCfg.Channel, CHANNEL_NO_FAT_ABOVE) == TRUE) { pHTPhyMode->ExtOffset = EXTCHA_BELOW; } } #endif /* CONFIG_AP_SUPPORT */ MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("RTMPSetHT : HT_mode(%d), ExtOffset(%d), MCS(%d), BW(%d), STBC(%d), SHORTGI(%d)\n", pHTPhyMode->HtMode, pHTPhyMode->ExtOffset, pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->SHORTGI)); /* Don't zero supportedHyPhy structure.*/ RTMPZeroMemory(ht_cap, sizeof(HT_CAPABILITY_IE)); RTMPZeroMemory(&pAd->CommonCfg.AddHTInfo, sizeof(pAd->CommonCfg.AddHTInfo)); RTMPZeroMemory(&pAd->CommonCfg.NewExtChanOffset, sizeof(pAd->CommonCfg.NewExtChanOffset)); RTMPZeroMemory(rt_ht_cap, sizeof(RT_HT_CAPABILITY)); if (pAd->CommonCfg.bRdg) { ht_cap->ExtHtCapInfo.PlusHTC = 1; ht_cap->ExtHtCapInfo.RDGSupport = 1; } else { ht_cap->ExtHtCapInfo.PlusHTC = 0; ht_cap->ExtHtCapInfo.RDGSupport = 0; } ht_cap->HtCapParm.MaxRAmpduFactor = pAd->chipCap.AMPDUFactor; rt_ht_cap->MaxRAmpduFactor = pAd->chipCap.AMPDUFactor; MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("RTMPSetHT : RxBAWinLimit = %d\n", pAd->CommonCfg.BACapability.field.RxBAWinLimit)); /* Mimo power save, A-MSDU size, */ rt_ht_cap->AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable; rt_ht_cap->AmsduSize = (UCHAR)pAd->CommonCfg.BACapability.field.AmsduSize; rt_ht_cap->MimoPs = (UCHAR)pAd->CommonCfg.BACapability.field.MMPSmode; rt_ht_cap->MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity; ht_cap->HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize; ht_cap->HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode; if (pAd->CommonCfg.ht_ldpc && (pAd->chipCap.phy_caps & fPHY_CAP_LDPC)) ht_cap->HtCapInfo.ht_rx_ldpc = 1; else ht_cap->HtCapInfo.ht_rx_ldpc = 0; ht_cap->HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity; MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("RTMPSetHT : AMsduSize = %d, MimoPs = %d, MpduDensity = %d, MaxRAmpduFactor = %d\n", rt_ht_cap->AmsduSize, rt_ht_cap->MimoPs, rt_ht_cap->MpduDensity, rt_ht_cap->MaxRAmpduFactor)); if(pHTPhyMode->HtMode == HTMODE_GF) { ht_cap->HtCapInfo.GF = 1; rt_ht_cap->GF = 1; } else rt_ht_cap->GF = 0; /* Decide Rx MCSSet*/ switch (RxStream) { case 3: ht_cap->MCSSet[2] = 0xff; case 2: ht_cap->MCSSet[1] = 0xff; case 1: default: ht_cap->MCSSet[0] = 0xff; break; } if (pAd->CommonCfg.bForty_Mhz_Intolerant && (pHTPhyMode->BW == BW_40)) { pHTPhyMode->BW = BW_20; ht_cap->HtCapInfo.Forty_Mhz_Intolerant = 1; } // TODO: shiang-6590, how about the "bw" when channel 14 for JP region??? //CFG_TODO bw = BW_20; if(pHTPhyMode->BW == BW_40) { ht_cap->MCSSet[4] = 0x1; /* MCS 32*/ ht_cap->HtCapInfo.ChannelWidth = 1; if (pAd->CommonCfg.Channel <= 14) ht_cap->HtCapInfo.CCKmodein40 = 1; rt_ht_cap->ChannelWidth = 1; pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 1; pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = (pHTPhyMode->ExtOffset == EXTCHA_BELOW)? (EXTCHA_BELOW): EXTCHA_ABOVE; /* Set Regsiter for extension channel position.*/ AsicSetCtrlCh(pAd, pHTPhyMode->ExtOffset); /* Turn on BBP 40MHz mode now only as AP . */ /* Sta can turn on BBP 40MHz after connection with 40MHz AP. Sta only broadcast 40MHz capability before connection.*/ if ((pAd->OpMode == OPMODE_AP) || INFRA_ON(pAd) || ADHOC_ON(pAd) ) { bbp_set_ctrlch(pAd, pHTPhyMode->ExtOffset); #ifdef GREENAP_SUPPORT if (pAd->ApCfg.bGreenAPActive == 1) bw = BW_20; else #endif /* GREENAP_SUPPORT */ bw = BW_40; } } else { ht_cap->HtCapInfo.ChannelWidth = 0; rt_ht_cap->ChannelWidth = 0; pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 0; pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = EXTCHA_NONE; pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel; /* Turn on BBP 20MHz mode by request here.*/ bw = BW_20; } #ifdef DOT11_VHT_AC if (pHTPhyMode->BW == BW_40 && pAd->CommonCfg.vht_bw == VHT_BW_80 && pAd->CommonCfg.vht_cent_ch) bw = BW_80; #endif /* DOT11_VHT_AC */ #ifdef CONFIG_MULTI_CHANNEL #if defined(RT_CFG80211_SUPPORT) && defined(CONFIG_AP_SUPPORT) if ((wdev->bw == BW_20) && (wdev->channel != 0)) bbp_set_bw(pAd, wdev->bw); else if (INFRA_ON(pAd)) bbp_set_bw(pAd, pAd->StaCfg.wdev.bw); else #endif /* defined(RT_CFG80211_SUPPORT) && defined(CONFIG_AP_SUPPORT) */ #endif /* CONFIG_MULTI_CHANNEL */ bbp_set_bw(pAd, bw); if(pHTPhyMode->STBC == STBC_USE) { if (pAd->Antenna.field.TxPath >= 2) { ht_cap->HtCapInfo.TxSTBC = 1; rt_ht_cap->TxSTBC = 1; } else { ht_cap->HtCapInfo.TxSTBC = 0; rt_ht_cap->TxSTBC = 0; } /* RxSTBC 0: not support, 1: support for 1SS 2: support for 1SS, 2SS 3: support for 1SS, 2SS, 3SS */ if (pAd->Antenna.field.RxPath >= 1) { ht_cap->HtCapInfo.RxSTBC = 1; rt_ht_cap->RxSTBC = 1; } else { ht_cap->HtCapInfo.RxSTBC = 0; rt_ht_cap->RxSTBC = 0; } } else { rt_ht_cap->TxSTBC = 0; rt_ht_cap->RxSTBC = 0; } if(pHTPhyMode->SHORTGI == GI_400) { ht_cap->HtCapInfo.ShortGIfor20 = 1; //ht_cap->HtCapInfo.ShortGIfor40 = 1; rt_ht_cap->ShortGIfor20 = 1; if(pHTPhyMode->BW == BW_40) { ht_cap->HtCapInfo.ShortGIfor40 = 1; rt_ht_cap->ShortGIfor40 = 1; } else { ht_cap->HtCapInfo.ShortGIfor40 = 0; rt_ht_cap->ShortGIfor40 = 0; } } else { ht_cap->HtCapInfo.ShortGIfor20 = 0; ht_cap->HtCapInfo.ShortGIfor40 = 0; rt_ht_cap->ShortGIfor20 = 0; rt_ht_cap->ShortGIfor40 = 0; } /* We support link adaptation for unsolicit MCS feedback, set to 2.*/ pAd->CommonCfg.AddHTInfo.ControlChan = pAd->CommonCfg.Channel; /* 1, the extension channel above the control channel. */ /* EDCA parameters used for AP's own transmission*/ if (pAd->CommonCfg.APEdcaParm.bValid == FALSE) set_default_ap_edca_param(pAd); AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm); #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++) RTMPSetIndividualHT(pAd, apidx); #ifdef WDS_SUPPORT for (apidx = 0; apidx < MAX_WDS_ENTRY; apidx++) RTMPSetIndividualHT(pAd, apidx + MIN_NET_DEVICE_FOR_WDS); #endif /* WDS_SUPPORT */ #ifdef APCLI_SUPPORT for (apidx = 0; apidx < MAX_APCLI_NUM; apidx++) RTMPSetIndividualHT(pAd, apidx + MIN_NET_DEVICE_FOR_APCLI); #endif /* APCLI_SUPPORT */ } #endif /* CONFIG_AP_SUPPORT */ }
VOID PeerBeacon( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN]; CHAR Ssid[MAX_LEN_OF_SSID]; CF_PARM CfParm; UCHAR SsidLen, MessageToMe=0, BssType, Channel, NewChannel, index=0; UCHAR DtimCount=0, DtimPeriod=0, BcastFlag=0; USHORT CapabilityInfo, AtimWin, BeaconPeriod; LARGE_INTEGER TimeStamp; USHORT TbttNumToNextWakeUp; UCHAR Erp; UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES]; UCHAR SupRateLen, ExtRateLen; UCHAR CkipFlag; USHORT LenVIE; UCHAR AironetCellPowerLimit; EDCA_PARM EdcaParm; QBSS_LOAD_PARM QbssLoad; QOS_CAPABILITY_PARM QosCapability; ULONG RalinkIe; UCHAR VarIE[MAX_VIE_LEN]; NDIS_802_11_VARIABLE_IEs *pVIE = NULL; HT_CAPABILITY_IE HtCapability; ADD_HT_INFO_IE AddHtInfo; UCHAR HtCapabilityLen, PreNHtCapabilityLen; UCHAR AddHtInfoLen; UCHAR NewExtChannelOffset = 0xff; #ifdef RALINK_ATE if (ATE_ON(pAd)) { return; } #endif if (!(INFRA_ON(pAd) || ADHOC_ON(pAd) )) return; pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE; pVIE->Length = 0; RTMPZeroMemory(&HtCapability, sizeof(HtCapability)); RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE)); if (PeerBeaconAndProbeRspSanity(pAd, Elem->Msg, Elem->MsgLen, Elem->Channel, Addr2, Bssid, Ssid, &SsidLen, &BssType, &BeaconPeriod, &Channel, &NewChannel, &TimeStamp, &CfParm, &AtimWin, &CapabilityInfo, &Erp, &DtimCount, &DtimPeriod, &BcastFlag, &MessageToMe, SupRate, &SupRateLen, ExtRate, &ExtRateLen, &CkipFlag, &AironetCellPowerLimit, &EdcaParm, &QbssLoad, &QosCapability, &RalinkIe, &HtCapabilityLen, &PreNHtCapabilityLen, &HtCapability, &AddHtInfoLen, &AddHtInfo, &NewExtChannelOffset, &LenVIE, pVIE)) { BOOLEAN is_my_bssid, is_my_ssid; ULONG Bssidx, Now; BSS_ENTRY *pBss; CHAR RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2)); is_my_bssid = MAC_ADDR_EQUAL(Bssid, pAd->CommonCfg.Bssid)? TRUE : FALSE; is_my_ssid = SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen)? TRUE:FALSE; if ((! is_my_ssid) && (! is_my_bssid)) return; if (pAd->Mlme.CntlMachine.CurrState == CNTL_WAIT_DISASSOC) return; #ifdef DOT11_N_SUPPORT if (AddHtInfoLen != 0) Channel = AddHtInfo.ControlChan; if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0)) HtCapabilityLen = SIZE_HT_CAP_IE; #endif Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel); if (Bssidx == BSS_NOT_FOUND) { Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod, &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, &HtCapability, &AddHtInfo,HtCapabilityLen,AddHtInfoLen,NewExtChannelOffset, Channel, RealRssi, TimeStamp, CkipFlag, &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE); if (Bssidx == BSS_NOT_FOUND) return; NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].PTSF, &Elem->Msg[24], 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4); } if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0) && (Channel != NewChannel)) { AsicSwitchChannel(pAd, 1, FALSE); AsicLockChannel(pAd, 1); LinkDown(pAd, FALSE); MlmeQueueInit(&pAd->Mlme.Queue); BssTableInit(&pAd->ScanTab); RTMPusecDelay(1000000); for (index = 0 ; index < pAd->ChannelListNum; index++) { if (pAd->ChannelList[index].Channel == NewChannel) { pAd->ScanTab.BssEntry[Bssidx].Channel = NewChannel; pAd->CommonCfg.Channel = NewChannel; AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); AsicLockChannel(pAd, pAd->CommonCfg.Channel); DBGPRINT(RT_DEBUG_TRACE, ("PeerBeacon - STA receive channel switch announcement IE (New Channel =%d)\n", NewChannel)); break; } } if (index >= pAd->ChannelListNum) { DBGPRINT_ERR(("PeerBeacon(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum)); } } if ((! is_my_bssid) && ADHOC_ON(pAd)) { INT i; if (pAd->StaCfg.WepStatus != pAd->ScanTab.BssEntry[Bssidx].WepStatus) { return; } for (i = 0; i < 6; i++) { if (Bssid[i] > pAd->CommonCfg.Bssid[i]) { DBGPRINT(RT_DEBUG_TRACE, ("SYNC - merge to the IBSS with bigger BSSID=%02x:%02x:%02x:%02x:%02x:%02x\n", Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5])); AsicDisableSync(pAd); COPY_MAC_ADDR(pAd->CommonCfg.Bssid, Bssid); AsicSetBssid(pAd, pAd->CommonCfg.Bssid); MakeIbssBeacon(pAd); AsicEnableIbssSync(pAd); is_my_bssid = TRUE; break; } else if (Bssid[i] < pAd->CommonCfg.Bssid[i]) break; } } NdisGetSystemUpTime(&Now); pBss = &pAd->ScanTab.BssEntry[Bssidx]; pBss->Rssi = RealRssi; pBss->LastBeaconRxTime = Now; if (is_my_bssid) { RXWI_STRUC RxWI; pAd->StaCfg.DtimCount = DtimCount; pAd->StaCfg.DtimPeriod = DtimPeriod; pAd->StaCfg.LastBeaconRxTime = Now; RxWI.RSSI0 = Elem->Rssi0; RxWI.RSSI1 = Elem->Rssi1; RxWI.RSSI2 = Elem->Rssi2; Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, &RxWI); if (AironetCellPowerLimit != 0xFF) { ChangeToCellPowerLimit(pAd, AironetCellPowerLimit); } else { pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault; } if (ADHOC_ON(pAd) && (CAP_IS_IBSS_ON(CapabilityInfo))) { UCHAR MaxSupportedRateIn500Kbps = 0; UCHAR idx; MAC_TABLE_ENTRY *pEntry; for (idx=0; idx<SupRateLen; idx++) { if (MaxSupportedRateIn500Kbps < (SupRate[idx] & 0x7f)) MaxSupportedRateIn500Kbps = SupRate[idx] & 0x7f; } for (idx=0; idx<ExtRateLen; idx++) { if (MaxSupportedRateIn500Kbps < (ExtRate[idx] & 0x7f)) MaxSupportedRateIn500Kbps = ExtRate[idx] & 0x7f; } pEntry = MacTableLookup(pAd, Addr2); if ((ADHOC_ON(pAd) && (Elem->Wcid == RESERVED_WCID)) || (pEntry && ((pEntry->LastBeaconRxTime + ADHOC_ENTRY_BEACON_LOST_TIME) < Now))) { if (pEntry == NULL) pEntry = MacTableInsertEntry(pAd, Addr2, BSS0, FALSE); if (StaAddMacTableEntry(pAd, pEntry, MaxSupportedRateIn500Kbps, &HtCapability, HtCapabilityLen, &AddHtInfo, AddHtInfoLen, CapabilityInfo) == FALSE) { DBGPRINT(RT_DEBUG_TRACE, ("ADHOC - Add Entry failed.\n")); return; } if (pEntry && (Elem->Wcid == RESERVED_WCID)) { idx = pAd->StaCfg.DefaultKeyId; RTMP_STA_SECURITY_INFO_ADD(pAd, BSS0, idx, pEntry); } } if (pEntry && pEntry->ValidAsCLI) pEntry->LastBeaconRxTime = Now; if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) { OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); pAd->IndicateMediaState = NdisMediaStateConnected; RTMP_IndicateMediaState(pAd); pAd->ExtraInfo = GENERAL_LINK_UP; AsicSetBssid(pAd, pAd->CommonCfg.Bssid); Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel); if (Bssidx == BSS_NOT_FOUND) { Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod, &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, &HtCapability, &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, RealRssi, TimeStamp, 0, &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE); } DBGPRINT(RT_DEBUG_TRACE, ("ADHOC fOP_STATUS_MEDIA_STATE_CONNECTED.\n")); } } if (INFRA_ON(pAd)) { BOOLEAN bUseShortSlot, bUseBGProtection; bUseShortSlot = CAP_IS_SHORT_SLOT(CapabilityInfo); if (bUseShortSlot != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED)) AsicSetSlotTime(pAd, bUseShortSlot); bUseBGProtection = (pAd->CommonCfg.UseBGProtection == 1) || ((pAd->CommonCfg.UseBGProtection == 0) && ERP_IS_USE_PROTECTION(Erp)); if (pAd->CommonCfg.Channel > 14) bUseBGProtection = FALSE; if (bUseBGProtection != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED)) { if (bUseBGProtection) { OPSTATUS_SET_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED); AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, (OFDMSETPROTECT|CCKSETPROTECT|ALLN_SETPROTECT),FALSE,(pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)); } else { OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED); AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, (OFDMSETPROTECT|CCKSETPROTECT|ALLN_SETPROTECT),TRUE,(pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)); } DBGPRINT(RT_DEBUG_WARN, ("SYNC - AP changed B/G protection to %d\n", bUseBGProtection)); } #ifdef DOT11_N_SUPPORT if ((AddHtInfoLen != 0) && ((AddHtInfo.AddHtInfo2.OperaionMode != pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode) || (AddHtInfo.AddHtInfo2.NonGfPresent != pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent))) { pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent = AddHtInfo.AddHtInfo2.NonGfPresent; pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode = AddHtInfo.AddHtInfo2.OperaionMode; if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1) { AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE); } else AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE); DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP changed N OperaionMode to %d\n", pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode)); } #endif if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED) && ERP_IS_USE_BARKER_PREAMBLE(Erp)) { MlmeSetTxPreamble(pAd, Rt802_11PreambleLong); DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP forced to use LONG preamble\n")); } if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && (EdcaParm.bValid == TRUE) && (EdcaParm.EdcaUpdateCount != pAd->CommonCfg.APEdcaParm.EdcaUpdateCount)) { DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP change EDCA parameters(from %d to %d)\n", pAd->CommonCfg.APEdcaParm.EdcaUpdateCount, EdcaParm.EdcaUpdateCount)); AsicSetEdcaParm(pAd, &EdcaParm); } NdisMoveMemory(&pAd->CommonCfg.APQbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM)); NdisMoveMemory(&pAd->CommonCfg.APQosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM)); } if ((INFRA_ON(pAd) && (pAd->StaCfg.Psm == PWR_SAVE)) || (pAd->CommonCfg.bAPSDForcePowerSave)) { UCHAR FreeNumber; if (MessageToMe) { #ifdef RTMP_MAC_PCI if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) { if (pAd->Antenna.field.RxPath > 1) RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3); } #endif if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable && pAd->CommonCfg.bAPSDAC_BE && pAd->CommonCfg.bAPSDAC_BK && pAd->CommonCfg.bAPSDAC_VI && pAd->CommonCfg.bAPSDAC_VO) { pAd->CommonCfg.bNeedSendTriggerFrame = TRUE; } else RTMP_PS_POLL_ENQUEUE(pAd); } else if (BcastFlag && (DtimCount == 0) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM)) { #ifdef RTMP_MAC_PCI if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) { if (pAd->Antenna.field.RxPath > 1) RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3); } #endif } else if ((pAd->TxSwQueue[QID_AC_BK].Number != 0) || (pAd->TxSwQueue[QID_AC_BE].Number != 0) || (pAd->TxSwQueue[QID_AC_VI].Number != 0) || (pAd->TxSwQueue[QID_AC_VO].Number != 0) || (RTMPFreeTXDRequest(pAd, QID_AC_BK, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) || (RTMPFreeTXDRequest(pAd, QID_AC_BE, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) || (RTMPFreeTXDRequest(pAd, QID_AC_VI, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) || (RTMPFreeTXDRequest(pAd, QID_AC_VO, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) || (RTMPFreeTXDRequest(pAd, QID_MGMT, MGMT_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS)) { #ifdef RTMP_MAC_PCI if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) { if (pAd->Antenna.field.RxPath > 1) RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3); } #endif } else { if ((pAd->CommonCfg.bACMAPSDTr[QID_AC_VO]) || (pAd->CommonCfg.bACMAPSDTr[QID_AC_VI]) || (pAd->CommonCfg.bACMAPSDTr[QID_AC_BK]) || (pAd->CommonCfg.bACMAPSDTr[QID_AC_BE])) { } else { USHORT NextDtim = DtimCount; if (NextDtim == 0) NextDtim = DtimPeriod; TbttNumToNextWakeUp = pAd->StaCfg.DefaultListenCount; if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim)) TbttNumToNextWakeUp = NextDtim; if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) { pAd->ThisTbttNumToNextWakeUp = TbttNumToNextWakeUp; AsicSleepThenAutoWakeup(pAd, pAd->ThisTbttNumToNextWakeUp); } } } } } } }
VOID PeerBeaconAtJoinAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN]; UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen, BssType, Channel, MessageToMe, DtimCount, DtimPeriod, BcastFlag, NewChannel; LARGE_INTEGER TimeStamp; USHORT BeaconPeriod, AtimWin, CapabilityInfo; CF_PARM Cf; BOOLEAN TimerCancelled; UCHAR Erp; UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES]; UCHAR SupRateLen, ExtRateLen; UCHAR CkipFlag; USHORT LenVIE; UCHAR AironetCellPowerLimit; EDCA_PARM EdcaParm; QBSS_LOAD_PARM QbssLoad; QOS_CAPABILITY_PARM QosCapability; USHORT Status; UCHAR VarIE[MAX_VIE_LEN]; NDIS_802_11_VARIABLE_IEs *pVIE = NULL; ULONG RalinkIe; ULONG Idx; HT_CAPABILITY_IE HtCapability; ADD_HT_INFO_IE AddHtInfo; UCHAR HtCapabilityLen = 0, PreNHtCapabilityLen = 0; UCHAR AddHtInfoLen; UCHAR NewExtChannelOffset = 0xff; #ifdef DOT11_N_SUPPORT UCHAR CentralChannel; BOOLEAN bAllowNrate = FALSE; #endif pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE; pVIE->Length = 0; RTMPZeroMemory(&HtCapability, sizeof(HtCapability)); RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE)); if (PeerBeaconAndProbeRspSanity(pAd, Elem->Msg, Elem->MsgLen, Elem->Channel, Addr2, Bssid, (PCHAR)Ssid, &SsidLen, &BssType, &BeaconPeriod, &Channel, &NewChannel, &TimeStamp, &Cf, &AtimWin, &CapabilityInfo, &Erp, &DtimCount, &DtimPeriod, &BcastFlag, &MessageToMe, SupRate, &SupRateLen, ExtRate, &ExtRateLen, &CkipFlag, &AironetCellPowerLimit, &EdcaParm, &QbssLoad, &QosCapability, &RalinkIe, &HtCapabilityLen, &PreNHtCapabilityLen, &HtCapability, &AddHtInfoLen, &AddHtInfo, &NewExtChannelOffset, &LenVIE, pVIE)) { if ((BssType == BSS_ADHOC) && (pAd->CommonCfg.PhyMode == PHY_11G) && ((SupRateLen+ExtRateLen)< 12)) return; if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Bssid)) { DBGPRINT(RT_DEBUG_TRACE, ("SYNC - receive desired BEACON at JoinWaitBeacon... Channel = %d\n", Channel)); RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled); pAd->StaCfg.RssiSample.LastRssi0 = ConvertToRssi(pAd, Elem->Rssi0, RSSI_0); pAd->StaCfg.RssiSample.LastRssi1 = ConvertToRssi(pAd, Elem->Rssi1, RSSI_1); pAd->StaCfg.RssiSample.LastRssi2 = ConvertToRssi(pAd, Elem->Rssi2, RSSI_2); pAd->StaCfg.RssiSample.AvgRssi0 = pAd->StaCfg.RssiSample.LastRssi0; pAd->StaCfg.RssiSample.AvgRssi0X8 = pAd->StaCfg.RssiSample.AvgRssi0 << 3; pAd->StaCfg.RssiSample.AvgRssi1 = pAd->StaCfg.RssiSample.LastRssi1; pAd->StaCfg.RssiSample.AvgRssi1X8 = pAd->StaCfg.RssiSample.AvgRssi1 << 3; pAd->StaCfg.RssiSample.AvgRssi2 = pAd->StaCfg.RssiSample.LastRssi2; pAd->StaCfg.RssiSample.AvgRssi2X8 = pAd->StaCfg.RssiSample.AvgRssi2 << 3; if (pAd->MlmeAux.SsidLen == 0) { NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen); pAd->MlmeAux.SsidLen = SsidLen; } else { Idx = BssSsidTableSearch(&pAd->ScanTab, Bssid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Channel); if (Idx == BSS_NOT_FOUND) { CHAR Rssi = 0; Rssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2)); Idx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, (CHAR *) Ssid, SsidLen, BssType, BeaconPeriod, &Cf, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, &HtCapability, &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, Rssi, TimeStamp, CkipFlag, &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE); if (Idx != BSS_NOT_FOUND) { NdisMoveMemory(pAd->ScanTab.BssEntry[Idx].PTSF, &Elem->Msg[24], 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4); CapabilityInfo = pAd->ScanTab.BssEntry[Idx].CapabilityInfo; } } else { CapabilityInfo = pAd->ScanTab.BssEntry[Idx].CapabilityInfo; } } NdisMoveMemory(pAd->MlmeAux.Bssid, Bssid, MAC_ADDR_LEN); pAd->MlmeAux.CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO; pAd->MlmeAux.BssType = BssType; pAd->MlmeAux.BeaconPeriod = BeaconPeriod; pAd->MlmeAux.Channel = Channel; pAd->MlmeAux.AtimWin = AtimWin; pAd->MlmeAux.CfpPeriod = Cf.CfpPeriod; pAd->MlmeAux.CfpMaxDuration = Cf.CfpMaxDuration; pAd->MlmeAux.APRalinkIe = RalinkIe; pAd->MlmeAux.SupRateLen = SupRateLen; NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate, SupRateLen); RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen); pAd->MlmeAux.ExtRateLen = ExtRateLen; NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate, ExtRateLen); RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen); NdisZeroMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, 16); #ifdef DOT11_N_SUPPORT if (((pAd->StaCfg.WepStatus != Ndis802_11WEPEnabled) && (pAd->StaCfg.WepStatus != Ndis802_11Encryption2Enabled)) || (pAd->CommonCfg.HT_DisallowTKIP == FALSE)) { bAllowNrate = TRUE; } pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset; pAd->MlmeAux.HtCapabilityLen = HtCapabilityLen; RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE); if (((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0)) && ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (bAllowNrate))) { RTMPMoveMemory(&pAd->MlmeAux.AddHtInfo, &AddHtInfo, SIZE_ADD_HT_INFO_IE); NdisMoveMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, HtCapability.MCSSet, 16); pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset; pAd->MlmeAux.HtCapabilityLen = SIZE_HT_CAP_IE; pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE; if (PreNHtCapabilityLen > 0) pAd->StaActive.SupportedPhyInfo.bPreNHt = TRUE; RTMPCheckHt(pAd, BSSID_WCID, &HtCapability, &AddHtInfo); DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction! (MpduDensity=%d, MaxRAmpduFactor=%d, BW=%d)\n", pAd->StaActive.SupportedHtPhy.MpduDensity, pAd->StaActive.SupportedHtPhy.MaxRAmpduFactor, HtCapability.HtCapInfo.ChannelWidth)); if (AddHtInfoLen > 0) { CentralChannel = AddHtInfo.ControlChan; if ((AddHtInfo.ControlChan > 2)&& (AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW) && (HtCapability.HtCapInfo.ChannelWidth == BW_40)) { CentralChannel = AddHtInfo.ControlChan - 2; } else if ((AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) && (HtCapability.HtCapInfo.ChannelWidth == BW_40)) { CentralChannel = AddHtInfo.ControlChan + 2; } if (pAd->MlmeAux.CentralChannel != CentralChannel) DBGPRINT(RT_DEBUG_ERROR, ("PeerBeaconAtJoinAction HT===>Beacon Central Channel = %d, Control Channel = %d. Mlmeaux CentralChannel = %d\n", CentralChannel, AddHtInfo.ControlChan, pAd->MlmeAux.CentralChannel)); DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction HT===>Central Channel = %d, Control Channel = %d, .\n", CentralChannel, AddHtInfo.ControlChan)); } } else #endif { if ((HtCapabilityLen == 0) && (PreNHtCapabilityLen == 0)) pAd->MlmeAux.CentralChannel = pAd->MlmeAux.Channel; pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE; pAd->MlmeAux.NewExtChannelOffset = 0xff; RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE); pAd->MlmeAux.HtCapabilityLen = 0; RTMPZeroMemory(&pAd->MlmeAux.AddHtInfo, SIZE_ADD_HT_INFO_IE); } RTMPUpdateMlmeRate(pAd); if ((pAd->CommonCfg.bWmmCapable) #ifdef DOT11_N_SUPPORT || (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) #endif ) { NdisMoveMemory(&pAd->MlmeAux.APEdcaParm, &EdcaParm, sizeof(EDCA_PARM)); NdisMoveMemory(&pAd->MlmeAux.APQbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM)); NdisMoveMemory(&pAd->MlmeAux.APQosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM)); } else { NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(EDCA_PARM)); NdisZeroMemory(&pAd->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM)); NdisZeroMemory(&pAd->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM)); } DBGPRINT(RT_DEBUG_TRACE, ("SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n", pAd->MlmeAux.SupRateLen, pAd->MlmeAux.ExtRateLen)); if (AironetCellPowerLimit != 0xFF) { ChangeToCellPowerLimit(pAd, AironetCellPowerLimit); } else pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault; pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; Status = MLME_SUCCESS; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status); } } }
/* ========================================================================== Description: This routine is executed every second - 1. Decide the overall channel quality 2. Check if need to upgrade the TX rate to any client 3. perform MAC table maintenance, including ageout no-traffic clients, and release packet buffer in PSQ is fail to TX in time. ========================================================================== */ VOID APMlmePeriodicExec( PRTMP_ADAPTER pAd) { /* Reqeust by David 2005/05/12 It make sense to disable Adjust Tx Power on AP mode, since we can't take care all of the client's situation ToDo: need to verify compatibility issue with WiFi product. */ #ifdef CARRIER_DETECTION_SUPPORT if (isCarrierDetectExist(pAd) == TRUE) { PCARRIER_DETECTION_STRUCT pCarrierDetect = &pAd->CommonCfg.CarrierDetect; if (pCarrierDetect->OneSecIntCount < pCarrierDetect->CarrierGoneThreshold) { pCarrierDetect->CD_State = CD_NORMAL; pCarrierDetect->recheck = pCarrierDetect->recheck1; if (pCarrierDetect->Debug != RT_DEBUG_TRACE) { DBGPRINT(RT_DEBUG_TRACE, ("Carrier gone\n")); /* start all TX actions. */ APMakeAllBssBeacon(pAd); APUpdateAllBeaconFrame(pAd); AsicEnableBssSync(pAd); } else { printk("Carrier gone\n"); } } pCarrierDetect->OneSecIntCount = 0; } #endif /* CARRIER_DETECTION_SUPPORT */ RTMP_CHIP_HIGH_POWER_TUNING(pAd, &pAd->ApCfg.RssiSample); /* Disable Adjust Tx Power for WPA WiFi-test. */ /* Because high TX power results in the abnormal disconnection of Intel BG-STA. */ /*#ifndef WIFI_TEST */ /* if (pAd->CommonCfg.bWiFiTest == FALSE) */ /* for SmartBit 64-byte stream test */ /* removed based on the decision of Ralink congress at 2011/7/06 */ /* if (pAd->MacTab.Size > 0) */ AsicAdjustTxPower(pAd); /*#endif // WIFI_TEST */ #ifdef RTMP_TEMPERATURE_COMPENSATION MT76x0_TemperatureCompensation(pAd); #endif /* RTMP_TEMPERATURE_COMPENSATION */ /* BBP TUNING: dynamic tune BBP R66 to find a balance between sensibility and noise isolation */ /* AsicBbpTuning2(pAd); */ /* walk through MAC table, see if switching TX rate is required */ /* MAC table maintenance */ if (pAd->Mlme.PeriodicRound % MLME_TASK_EXEC_MULTIPLE == 0) { /* one second timer */ MacTableMaintenance(pAd); #ifdef FPGA_MODE if (pAd->fpga_tr_stop) { UINT32 mac_val; /* enable/disable tx/rx*/ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &mac_val); switch (pAd->fpga_tr_stop) { case 3: //stop tx + rx mac_val &= (~0xc); break; case 2: // stop rx mac_val &= (~0x8); break; case 1: // stop tx mac_val &= (~0x4); break; case 4: default: mac_val |= 0x0c; break; } RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, mac_val); } #endif /* FGPA_MODE */ RTMPMaintainPMKIDCache(pAd); #ifdef WDS_SUPPORT WdsTableMaintenance(pAd); #endif /* WDS_SUPPORT */ #ifdef CLIENT_WDS CliWds_ProxyTabMaintain(pAd); #endif /* CLIENT_WDS */ } APUpdateCapabilityAndErpIe(pAd); #ifdef APCLI_SUPPORT if (pAd->Mlme.OneSecPeriodicRound % 2 == 0) ApCliIfMonitor(pAd); if (pAd->Mlme.OneSecPeriodicRound % 2 == 1) ApCliIfUp(pAd); { INT loop; ULONG Now32; UINT32 MaxWcidNum = MAX_LEN_OF_MAC_TABLE; #ifdef MAC_REPEATER_SUPPORT if (pAd->ApCfg.bMACRepeaterEn) { MaxWcidNum = MAX_MAC_TABLE_SIZE_WITH_REPEATER; #ifdef APCLI_AUTO_CONNECT_SUPPORT RTMPRepeaterReconnectionCheck(pAd); #endif /* APCLI_AUTO_CONNECT_SUPPORT */ } #endif /* MAC_REPEATER_SUPPORT */ NdisGetSystemUpTime(&Now32); for (loop = 0; loop < MAX_APCLI_NUM; loop++) { PAPCLI_STRUCT pApCliEntry = &pAd->ApCfg.ApCliTab[loop]; if ((pApCliEntry->Valid == TRUE) && (pApCliEntry->MacTabWCID < MaxWcidNum)) { /* update channel quality for Roaming and UI LinkQuality display */ MlmeCalculateChannelQuality(pAd, &pAd->MacTab.Content[pApCliEntry->MacTabWCID], Now32); } } } #endif /* APCLI_SUPPORT */ #ifdef DOT11_N_SUPPORT if (pAd->CommonCfg.bHTProtect) { /*APUpdateCapabilityAndErpIe(pAd); */ APUpdateOperationMode(pAd); if (pAd->CommonCfg.IOTestParm.bRTSLongProtOn == FALSE) { AsicUpdateProtect(pAd, (USHORT)pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, pAd->MacTab.fAnyStationNonGF); } } #endif /* DOT11_N_SUPPORT */ #ifdef A_BAND_SUPPORT if ( (pAd->CommonCfg.Channel > 14) && (pAd->CommonCfg.bIEEE80211H == 1) ) { #ifdef DFS_SUPPORT ApRadarDetectPeriodic(pAd); #else pAd->Dot11_H.InServiceMonitorCount++; if (pAd->Dot11_H.RDMode == RD_SILENCE_MODE) { if (pAd->Dot11_H.RDCount++ > pAd->Dot11_H.ChMovingTime) { AsicEnableBssSync(pAd); pAd->Dot11_H.RDMode = RD_NORMAL_MODE; } } #endif /* !DFS_SUPPORT */ } #endif /* A_BAND_SUPPORT */ /* resume Improved Scanning*/ if ((pAd->ApCfg.bImprovedScan) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) && (pAd->Mlme.ApSyncMachine.CurrState == AP_SCAN_PENDING)) { MLME_SCAN_REQ_STRUCT ScanReq; AsicDisableSync(pAd); RTMPZeroMemory(ScanReq.Ssid, MAX_LEN_OF_SSID); ScanReq.SsidLen = pAd->MlmeAux.SsidLen; NdisMoveMemory(ScanReq.Ssid, pAd->MlmeAux.Ssid, ScanReq.SsidLen); ScanReq.BssType = BSS_ANY; #ifdef APCLI_CONNECTION_TRIAL ScanReq.ScanType = FAST_SCAN_ACTIVE; #else ScanReq.ScanType = SCAN_ACTIVE; #endif /* APCLI_CONNECTION_TRIAL */ MlmeEnqueue(pAd, AP_SYNC_STATE_MACHINE, APMT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq, 0); RTMP_MLME_HANDLER(pAd); DBGPRINT(RT_DEBUG_TRACE, ("bImprovedScan ............. Resume for bImprovedScan, SCAN_PENDING .............. \n")); } }
INT ATESetUpFrame( IN PRTMP_ADAPTER pAd, IN UINT32 TxIdx) { PATE_INFO pATEInfo = &(pAd->ate); UINT pos = 0; PTX_CONTEXT pNullContext; PUCHAR pDest; HTTRANSMIT_SETTING TxHTPhyMode; TXWI_STRUC *pTxWI; TXINFO_STRUC *pTxInfo; UINT32 TransferBufferLength, OrgBufferLength = 0; UCHAR padLen = 0; UINT8 TXWISize = pAd->chipCap.TXWISize; #ifdef RALINK_QA PHEADER_802_11 pHeader80211 = NULL; #endif /* RALINK_QA */ if ((RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) { return -1; } /* We always use QID_AC_BE and FIFO_EDCA in ATE mode. */ pNullContext = &(pAd->NullContext); ASSERT(pNullContext != NULL); if (pNullContext->InUse == FALSE) { /* set the in use bit */ pNullContext->InUse = TRUE; NdisZeroMemory(&(pAd->NullFrame), sizeof(HEADER_802_11)); /* fill 802.11 header */ #ifdef RALINK_QA if (pATEInfo->bQATxStart == TRUE) { pHeader80211 = NdisMoveMemory(&(pAd->NullFrame), pATEInfo->Header, pATEInfo->HLen); } else #endif /* RALINK_QA */ { NdisMoveMemory(&(pAd->NullFrame), TemplateFrame, sizeof(HEADER_802_11)); } #ifdef RT_BIG_ENDIAN RTMPFrameEndianChange(pAd, (PUCHAR)&(pAd->NullFrame), DIR_READ, FALSE); #endif /* RT_BIG_ENDIAN */ #ifdef RALINK_QA if (pATEInfo->bQATxStart == TRUE) { /* modify sequence number... */ if (pATEInfo->TxDoneCount == 0) { pATEInfo->seq = pHeader80211->Sequence; } else { pHeader80211->Sequence = ++pATEInfo->seq; } /* We already got all the address fields from QA GUI. */ } else #endif /* RALINK_QA */ { COPY_MAC_ADDR(pAd->NullFrame.Addr1, pATEInfo->Addr1); COPY_MAC_ADDR(pAd->NullFrame.Addr2, pATEInfo->Addr2); COPY_MAC_ADDR(pAd->NullFrame.Addr3, pATEInfo->Addr3); } RTMPZeroMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[0], TX_BUFFER_NORMSIZE); pTxInfo = (TXINFO_STRUC *)&pAd->NullContext.TransferBuffer->field.WirelessPacket[0]; #ifdef RALINK_QA if (pATEInfo->bQATxStart == TRUE) { /* Avoid to exceed the range of WirelessPacket[]. */ ASSERT(pATEInfo->TxInfo.TxInfoPktLen <= (MAX_FRAME_SIZE - 34/* == 2312 */)); NdisMoveMemory(pTxInfo, &(pATEInfo->TxInfo), sizeof(pATEInfo->TxInfo)); } else #endif /* RALINK_QA */ { /* Avoid to exceed the range of WirelessPacket[]. */ ASSERT(pATEInfo->TxLength <= (MAX_FRAME_SIZE - 34/* == 2312 */)); /* pTxInfo->TxInfoPktLen will be updated to include padding later */ ATEWriteTxInfo(pAd, pTxInfo, (USHORT)(TXWISize + pATEInfo->TxLength) , TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE); pTxInfo->TxInfoQSEL = FIFO_EDCA; } pTxWI = (TXWI_STRUC *)&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE]; /* fill TxWI */ if (pATEInfo->bQATxStart == TRUE) { TxHTPhyMode.field.BW = pATEInfo->TxWI.TxWIBW; TxHTPhyMode.field.ShortGI = pATEInfo->TxWI.TxWIShortGI; TxHTPhyMode.field.STBC = pATEInfo->TxWI.TxWISTBC; TxHTPhyMode.field.MCS = pATEInfo->TxWI.TxWIMCS; TxHTPhyMode.field.MODE = pATEInfo->TxWI.TxWIPHYMODE; ATEWriteTxWI(pAd, pTxWI, pATEInfo->TxWI.TxWIFRAG, pATEInfo->TxWI.TxWITS, pATEInfo->TxWI.TxWIAMPDU, pATEInfo->TxWI.TxWIACK, pATEInfo->TxWI.TxWINSEQ, pATEInfo->TxWI.TxWIBAWinSize, BSSID_WCID, pATEInfo->TxWI.TxWIMPDUByteCnt/* include 802.11 header */, pATEInfo->TxWI.TxWIPacketId, 0, pATEInfo->TxWI.TxWITXOP/*IFS_HTTXOP*/, pATEInfo->TxWI.TxWICFACK /*FALSE*/, TxHTPhyMode); } else { TxHTPhyMode.field.BW = pATEInfo->TxWI.TxWIBW; TxHTPhyMode.field.ShortGI = pATEInfo->TxWI.TxWIShortGI; TxHTPhyMode.field.STBC = 0; TxHTPhyMode.field.MCS = pATEInfo->TxWI.TxWIMCS; TxHTPhyMode.field.MODE = pATEInfo->TxWI.TxWIPHYMODE; ATEWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE /* No ack required. */, FALSE, 0, BSSID_WCID, pATEInfo->TxLength, 0, 0, IFS_HTTXOP, FALSE, TxHTPhyMode); } hex_dump("ATE", pAd->NullContext.TransferBuffer->field.WirelessPacket, 24); dump_txinfo(pAd, pTxInfo); dumpTxWI(pAd, pTxWI); RTMPMoveMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE + TXWISize], &pAd->NullFrame, sizeof(HEADER_802_11)); pDest = &(pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE + TXWISize + sizeof(HEADER_802_11)]); /* prepare frame payload */ #ifdef RALINK_QA if (pATEInfo->bQATxStart == TRUE) { /* copy the pattern one by one to the frame payload */ if ((pATEInfo->PLen != 0) && (pATEInfo->DLen != 0)) { for (pos = 0; pos < pATEInfo->DLen; pos += pATEInfo->PLen) { RTMPMoveMemory(pDest, pATEInfo->Pattern, pATEInfo->PLen); pDest += pATEInfo->PLen; } } TransferBufferLength = TXINFO_SIZE + TXWISize + pATEInfo->TxWI.TxWIMPDUByteCnt; } else #endif /* RALINK_QA */ { for (pos = 0; pos < (pATEInfo->TxLength - sizeof(HEADER_802_11)); pos++) { /* default payload is 0xA5 */ *pDest = pATEInfo->Payload; pDest += 1; } TransferBufferLength = TXINFO_SIZE + TXWISize + pATEInfo->TxLength; } OrgBufferLength = TransferBufferLength; TransferBufferLength = (TransferBufferLength + 3) & (~3); /* Always add 4 extra bytes at every packet. */ padLen = TransferBufferLength - OrgBufferLength + 4;/* 4 == last packet padding */ /* RTMP_PKT_TAIL_PADDING == 11. [11 == 3(max 4 byte padding) + 4(last packet padding) + 4(MaxBulkOutsize align padding)] */ ASSERT((padLen <= (RTMP_PKT_TAIL_PADDING - 4/* 4 == MaxBulkOutsize alignment padding */))); /* Now memzero all extra padding bytes. */ NdisZeroMemory(pDest, padLen); pDest += padLen; /* Update pTxInfo->TxInfoPktLen to include padding. */ pTxInfo->TxInfoPktLen = TransferBufferLength - TXINFO_SIZE; TransferBufferLength += 4; /* If TransferBufferLength is multiple of 64, add extra 4 bytes again. */ if ((TransferBufferLength % pAd->BulkOutMaxPacketSize) == 0) { NdisZeroMemory(pDest, 4); TransferBufferLength += 4; } /* Fill out frame length information for global Bulk out arbitor. */ pAd->NullContext.BulkOutSize = TransferBufferLength; } #ifdef RT_BIG_ENDIAN RTMPWIEndianChange(pAd, (PUCHAR)pTxWI, TYPE_TXWI); RTMPFrameEndianChange(pAd, (((PUCHAR)pTxInfo) + TXWISize + TXINFO_SIZE), DIR_WRITE, FALSE); RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO); #endif /* RT_BIG_ENDIAN */ hex_dump("ATE TX", &pAd->NullContext.TransferBuffer->field.WirelessPacket[0], TXWISize + TXINFO_SIZE); return 0; }
/* ========================================================================== Description: When waiting joining the (I)BSS, beacon received from external ========================================================================== */ static VOID ApCliPeerProbeRspAtJoinAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN]; UCHAR /* Ssid[MAX_LEN_OF_SSID], */ SsidLen=0, BssType, Channel=0, MessageToMe, DtimCount, DtimPeriod, BcastFlag; UCHAR *Ssid = NULL; LARGE_INTEGER TimeStamp; USHORT BeaconPeriod, AtimWin, CapabilityInfo; /* UINT FrameLen = 0; */ CF_PARM Cf; UCHAR Erp; UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES]; UCHAR SupRateLen, ExtRateLen; UCHAR CkipFlag; USHORT LenVIE; UCHAR AironetCellPowerLimit; EDCA_PARM EdcaParm; QBSS_LOAD_PARM QbssLoad; QOS_CAPABILITY_PARM QosCapability; /* UCHAR VarIE[MAX_VIE_LEN]; // Total VIE length = MAX_VIE_LEN - -5 */ UCHAR *VarIE = NULL; NDIS_802_11_VARIABLE_IEs *pVIE = NULL; ULONG RalinkIe; APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg; /* HT_CAPABILITY_IE HtCapability; */ /* ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE */ HT_CAPABILITY_IE *pHtCapability = NULL; ADD_HT_INFO_IE *pAddHtInfo = NULL; /* AP might use this additional ht info IE */ UCHAR HtCapabilityLen; UCHAR AddHtInfoLen; UCHAR NewChannel; UCHAR NewExtChannelOffset = 0xff; PAPCLI_STRUCT pApCliEntry = NULL; #ifdef DOT11_N_SUPPORT UCHAR CentralChannel; #endif /* DOT11_N_SUPPORT */ #ifdef CONFIG_STA_SUPPORT UCHAR pPreNHtCapabilityLen = 0; #endif /* CONFIG_STA_SUPPORT */ EXT_CAP_INFO_ELEMENT ExtCapInfo; USHORT ifIndex = (USHORT)(Elem->Priv); PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].SyncCurrState; if (ifIndex >= MAX_APCLI_NUM) return; /* allocate memory */ os_alloc_mem(NULL, (UCHAR **)&VarIE, MAX_VIE_LEN); if (VarIE == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); goto LabelErr; } os_alloc_mem(NULL, (UCHAR **)&pHtCapability, sizeof(HT_CAPABILITY_IE)); if (pHtCapability == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); goto LabelErr; } os_alloc_mem(NULL, (UCHAR **)&pAddHtInfo, sizeof(ADD_HT_INFO_IE)); if (pAddHtInfo == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); goto LabelErr; } os_alloc_mem(NULL, (UCHAR **)&Ssid, MAX_LEN_OF_SSID); if (Ssid == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); goto LabelErr; } /* Init Variable IE structure */ pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE; pVIE->Length = 0; RTMPZeroMemory(pHtCapability, sizeof(HT_CAPABILITY_IE)); RTMPZeroMemory(pAddHtInfo, sizeof(ADD_HT_INFO_IE)); RTMPZeroMemory(&QosCapability, sizeof(QosCapability)); RTMPZeroMemory(&EdcaParm, sizeof(EdcaParm)); if (PeerBeaconAndProbeRspSanity(pAd, Elem->Msg, Elem->MsgLen, Elem->Channel, Addr2, Bssid, (PCHAR) Ssid, &SsidLen, &BssType, &BeaconPeriod, &Channel, &NewChannel, &TimeStamp, &Cf, &AtimWin, &CapabilityInfo, &Erp, &DtimCount, &DtimPeriod, &BcastFlag, &MessageToMe, SupRate, &SupRateLen, ExtRate, &ExtRateLen, &CkipFlag, &AironetCellPowerLimit, &EdcaParm, &QbssLoad, &QosCapability, &RalinkIe, &HtCapabilityLen, #ifdef CONFIG_STA_SUPPORT &pPreNHtCapabilityLen, #endif /* CONFIG_STA_SUPPORT */ pHtCapability, &ExtCapInfo, &AddHtInfoLen, pAddHtInfo, &NewExtChannelOffset, &LenVIE, pVIE)) { /* BEACON from desired BSS/IBSS found. We should be able to decide most BSS parameters here. Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATEION? Do we need to receover back all parameters belonging to previous BSS? A. Should be not. There's no back-door recover to previous AP. It still need a new JOIN-AUTH-ASSOC sequence. */ INT ssidEqualFlag = FALSE; INT ssidEmptyFlag = FALSE; INT bssidEqualFlag = FALSE; INT bssidEmptyFlag = FALSE; INT matchFlag = FALSE; pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex]; /* Check the Probe-Rsp's Bssid. */ if(!MAC_ADDR_EQUAL(pApCliEntry->CfgApCliBssid, ZERO_MAC_ADDR)) bssidEqualFlag = MAC_ADDR_EQUAL(pApCliEntry->CfgApCliBssid, Bssid); else bssidEmptyFlag = TRUE; /* Check the Probe-Rsp's Ssid. */ if(pApCliEntry->CfgSsidLen != 0) ssidEqualFlag = SSID_EQUAL(pApCliEntry->CfgSsid, pApCliEntry->CfgSsidLen, Ssid, SsidLen); else ssidEmptyFlag = TRUE; /* bssid and ssid, Both match. */ if (bssidEqualFlag && ssidEqualFlag) matchFlag = TRUE; /* ssid match but bssid doesn't be indicate. */ else if(ssidEqualFlag && bssidEmptyFlag) matchFlag = TRUE; /* user doesn't indicate any bssid or ssid. AP-Clinet will auto pick a AP to join by most strong siganl strength. */ else if (bssidEmptyFlag && ssidEmptyFlag) matchFlag = TRUE; DBGPRINT(RT_DEBUG_TRACE, ("SYNC - bssidEqualFlag=%d, ssidEqualFlag=%d, matchFlag=%d\n", bssidEqualFlag, ssidEqualFlag, matchFlag)); if (matchFlag) { /* Validate RSN IE if necessary, then copy store this information */ if ((LenVIE > 0) #ifdef WSC_AP_SUPPORT && ((pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscConfMode == WSC_DISABLE) || (pAd->ApCfg.ApCliTab[ifIndex].WscControl.bWscTrigger == FALSE)) #endif /* WSC_AP_SUPPORT */ ) { if (ApCliValidateRSNIE(pAd, (PEID_STRUCT)pVIE, LenVIE, ifIndex)) { pApCliEntry->ApCliMlmeAux.VarIELen = LenVIE; NdisMoveMemory(pApCliEntry->ApCliMlmeAux.VarIEs, pVIE, pApCliEntry->ApCliMlmeAux.VarIELen); } else { /* ignore this response */ pApCliEntry->ApCliMlmeAux.VarIELen = 0; DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The RSN IE of this received Probe-resp is dis-match !!!!!!!!!! \n")); goto LabelErr; } } else { if (pApCliEntry->AuthMode >= Ndis802_11AuthModeWPA #ifdef WSC_AP_SUPPORT && ((pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscConfMode == WSC_DISABLE) || (pAd->ApCfg.ApCliTab[ifIndex].WscControl.bWscTrigger == FALSE)) #endif /* WSC_AP_SUPPORT */ ) { /* ignore this response */ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The received Probe-resp has empty RSN IE !!!!!!!!!! \n")); goto LabelErr; } pApCliEntry->ApCliMlmeAux.VarIELen = 0; } DBGPRINT(RT_DEBUG_TRACE, ("SYNC - receive desired PROBE_RSP at JoinWaitProbeRsp... Channel = %d\n", Channel)); /* if the Bssid doesn't be indicated then you need to decide which AP to connect by most strong Rssi signal strength. */ if (bssidEqualFlag == FALSE) { /* caculate real rssi value. */ CHAR Rssi0 = ConvertToRssi(pAd, Elem->Rssi0, RSSI_0); CHAR Rssi1 = ConvertToRssi(pAd, Elem->Rssi1, RSSI_1); CHAR Rssi2 = ConvertToRssi(pAd, Elem->Rssi2, RSSI_2); LONG RealRssi = (LONG)(RTMPMaxRssi(pAd, Rssi0, Rssi1, Rssi2)); DBGPRINT(RT_DEBUG_TRACE, ("SYNC - previous Rssi = %ld current Rssi=%ld\n", pApCliEntry->ApCliMlmeAux.Rssi, (LONG)RealRssi)); if (pApCliEntry->ApCliMlmeAux.Rssi > (LONG)RealRssi) goto LabelErr; else pApCliEntry->ApCliMlmeAux.Rssi = RealRssi; } else { BOOLEAN Cancelled; RTMPCancelTimer(&pApCliEntry->ApCliMlmeAux.ProbeTimer, &Cancelled); } NdisMoveMemory(pApCliEntry->ApCliMlmeAux.Ssid, Ssid, SsidLen); pApCliEntry->ApCliMlmeAux.SsidLen = SsidLen; NdisMoveMemory(pApCliEntry->ApCliMlmeAux.Bssid, Bssid, MAC_ADDR_LEN); pApCliEntry->ApCliMlmeAux.CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO; pApCliEntry->ApCliMlmeAux.BssType = BssType; pApCliEntry->ApCliMlmeAux.BeaconPeriod = BeaconPeriod; pApCliEntry->ApCliMlmeAux.Channel = Channel; pApCliEntry->ApCliMlmeAux.AtimWin = AtimWin; pApCliEntry->ApCliMlmeAux.CfpPeriod = Cf.CfpPeriod; pApCliEntry->ApCliMlmeAux.CfpMaxDuration = Cf.CfpMaxDuration; pApCliEntry->ApCliMlmeAux.APRalinkIe = RalinkIe; /* Copy AP's supported rate to ApCliMlmeAux for creating assoication request */ /* Also filter out not supported rate */ pApCliEntry->ApCliMlmeAux.SupRateLen = SupRateLen; NdisMoveMemory(pApCliEntry->ApCliMlmeAux.SupRate, SupRate, SupRateLen); RTMPCheckRates(pAd, pApCliEntry->ApCliMlmeAux.SupRate, &(pApCliEntry->ApCliMlmeAux.SupRateLen)); pApCliEntry->ApCliMlmeAux.ExtRateLen = ExtRateLen; NdisMoveMemory(pApCliEntry->ApCliMlmeAux.ExtRate, ExtRate, ExtRateLen); RTMPCheckRates(pAd, pApCliEntry->ApCliMlmeAux.ExtRate, &pApCliEntry->ApCliMlmeAux.ExtRateLen); #ifdef APCLI_CERT_SUPPORT /* Get the ext capability info element */ if (pAd->bApCliCertTest == TRUE) { NdisMoveMemory(&pApCliEntry->ApCliMlmeAux.ExtCapInfo, &ExtCapInfo,sizeof(ExtCapInfo)); #ifdef DOT11_N_SUPPORT #ifdef DOT11N_DRAFT3 DBGPRINT(RT_DEBUG_TRACE, ("\x1b[31m ApCliMlmeAux.ExtCapInfo=%d \x1b[m\n", pApCliEntry->ApCliMlmeAux.ExtCapInfo.BssCoexistMgmtSupport)); //zero debug 210121122 if (pAd->CommonCfg.bBssCoexEnable == TRUE) pAd->CommonCfg.ExtCapIE.BssCoexistMgmtSupport = 1; #endif /* DOT11N_DRAFT3 */ #endif /* DOT11_N_SUPPORT */ } #endif /* APCLI_CERT_SUPPORT */ #ifdef DOT11_N_SUPPORT NdisZeroMemory(pAd->ApCfg.ApCliTab[ifIndex].RxMcsSet,sizeof(pAd->ApCfg.ApCliTab[ifIndex].RxMcsSet)); /* filter out un-supported ht rates */ if ((HtCapabilityLen > 0) && (pApCliEntry->DesiredHtPhyInfo.bHtEnable) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) { RTMPZeroMemory(&(pApCliEntry->ApCliMlmeAux.HtCapability), SIZE_HT_CAP_IE); pApCliEntry->ApCliMlmeAux.NewExtChannelOffset = NewExtChannelOffset; pApCliEntry->ApCliMlmeAux.HtCapabilityLen = HtCapabilityLen; ApCliCheckHt(pAd, ifIndex, pHtCapability, pAddHtInfo); if (AddHtInfoLen > 0) { CentralChannel = pAddHtInfo->ControlChan; /* Check again the Bandwidth capability of this AP. */ if ((pAddHtInfo->ControlChan > 2)&& (pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_BELOW) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40)) { CentralChannel = pAddHtInfo->ControlChan - 2; } else if ((pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40)) { CentralChannel = pAddHtInfo->ControlChan + 2; } DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction HT===>Central Channel = %d, Control Channel = %d, .\n", CentralChannel, pAddHtInfo->ControlChan)); } } else #endif /* DOT11_N_SUPPORT */ { RTMPZeroMemory(&(pApCliEntry->ApCliMlmeAux.HtCapability), SIZE_HT_CAP_IE); RTMPZeroMemory(&(pApCliEntry->ApCliMlmeAux.AddHtInfo), SIZE_ADD_HT_INFO_IE); pApCliEntry->ApCliMlmeAux.HtCapabilityLen = 0; } ApCliUpdateMlmeRate(pAd, ifIndex); #ifdef DOT11_N_SUPPORT /* copy QOS related information */ if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) { NdisMoveMemory(&(pApCliEntry->ApCliMlmeAux.APEdcaParm), &EdcaParm, sizeof(EDCA_PARM)); NdisMoveMemory(&(pApCliEntry->ApCliMlmeAux.APQbssLoad), &QbssLoad, sizeof(QBSS_LOAD_PARM)); NdisMoveMemory(&(pApCliEntry->ApCliMlmeAux.APQosCapability), &QosCapability, sizeof(QOS_CAPABILITY_PARM)); } else #endif /* DOT11_N_SUPPORT */ { NdisZeroMemory(&(pApCliEntry->ApCliMlmeAux.APEdcaParm), sizeof(EDCA_PARM)); NdisZeroMemory(&(pApCliEntry->ApCliMlmeAux.APQbssLoad), sizeof(QBSS_LOAD_PARM)); NdisZeroMemory(&(pApCliEntry->ApCliMlmeAux.APQosCapability), sizeof(QOS_CAPABILITY_PARM)); } DBGPRINT(RT_DEBUG_TRACE, ("APCLI SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n", pApCliEntry->ApCliMlmeAux.SupRateLen, pApCliEntry->ApCliMlmeAux.ExtRateLen)); if (AironetCellPowerLimit != 0xFF) { /*We need to change our TxPower for CCX 2.0 AP Control of Client Transmit Power */ ChangeToCellPowerLimit(pAd, AironetCellPowerLimit); } else /*Used the default TX Power Percentage. */ pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault; #ifdef WSC_AP_SUPPORT #ifdef DOT11_N_SUPPORT if ((pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscConfMode != WSC_DISABLE) && (pAd->ApCfg.ApCliTab[ifIndex].WscControl.bWscTrigger == TRUE)) { ADD_HTINFO RootApHtInfo, ApHtInfo; ApHtInfo = pAd->CommonCfg.AddHTInfo.AddHtInfo; RootApHtInfo = pAddHtInfo->AddHtInfo; if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) && (RootApHtInfo.RecomWidth) && (RootApHtInfo.ExtChanOffset != ApHtInfo.ExtChanOffset)) { /*STRING ChStr[5] = {0}; */ if (RootApHtInfo.ExtChanOffset == EXTCHA_ABOVE) Set_HtExtcha_Proc(pAd, "1"); else Set_HtExtcha_Proc(pAd, "0"); goto LabelErr; } } #endif /* DOT11_N_SUPPORT */ #endif /* WSC_AP_SUPPORT */ if(bssidEqualFlag == TRUE) { *pCurrState = APCLI_SYNC_IDLE; ApCliCtrlMsg.Status = MLME_SUCCESS; #ifdef MAC_REPEATER_SUPPORT ApCliCtrlMsg.BssIdx = ifIndex; ApCliCtrlMsg.CliIdx = 0xFF; #endif /* MAC_REPEATER_SUPPORT */ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_PROBE_RSP, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex); } } /* not to me BEACON, ignored */ } /* sanity check fail, ignore this frame */ LabelErr: if (VarIE != NULL) os_free_mem(NULL, VarIE); if (pHtCapability != NULL) os_free_mem(NULL, pHtCapability); if (pAddHtInfo != NULL) os_free_mem(NULL, pAddHtInfo); if (Ssid != NULL) os_free_mem(NULL, Ssid); return; }
/* ========================================================================== Description: peer sends assoc rsp back Parameters: Elme - MLME message containing the received frame ========================================================================== */ static VOID ApCliPeerAssocRspAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { BOOLEAN Cancelled; USHORT CapabilityInfo, Status, Aid; UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], SupRateLen; UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRateLen; UCHAR Addr2[MAC_ADDR_LEN]; EDCA_PARM EdcaParm; UCHAR CkipFlag; APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg; HT_CAPABILITY_IE HtCapability; ADD_HT_INFO_IE AddHtInfo; /* AP might use this additional ht info IE */ UCHAR HtCapabilityLen; UCHAR AddHtInfoLen; UCHAR NewExtChannelOffset = 0xff; USHORT ifIndex = (USHORT)(Elem->Priv); ULONG *pCurrState = NULL; #ifdef DOT11_VHT_AC PAPCLI_STRUCT pApCliEntry = NULL; #endif /* DOT11_VHT_AC */ #ifdef MAC_REPEATER_SUPPORT UCHAR CliIdx = 0xFF; #endif /* MAC_REPEATER_SUPPORT */ IE_LISTS *ie_list = NULL; 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; #ifdef DOT11_VHT_AC pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex]; #endif /* DOT11_VHT_AC */ os_alloc_mem(pAd, (UCHAR **)&ie_list, sizeof(IE_LISTS)); if (ie_list == NULL) { DBGPRINT(RT_DEBUG_OFF, ("%s():mem alloc failed!\n", __FUNCTION__)); return; } NdisZeroMemory((UCHAR *)ie_list, sizeof(IE_LISTS)); if (ApCliPeerAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &CapabilityInfo, &Status, &Aid, SupRate, &SupRateLen, ExtRate, &ExtRateLen, &HtCapability, &AddHtInfo, &HtCapabilityLen,&AddHtInfoLen,&NewExtChannelOffset, &EdcaParm, &CkipFlag, ie_list)) { /* The frame is for me ? */ if(MAC_ADDR_EQUAL(Addr2, pAd->ApCfg.ApCliTab[ifIndex].MlmeAux.Bssid)) { DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - receive ASSOC_RSP to me (status=%d)\n", Status)); #if defined(RT_CFG80211_P2P_CONCURRENT_DEVICE) || defined(CFG80211_MULTI_STA) /* Store the AssocRsp Frame to wpa_supplicant via CFG80211 */ NdisZeroMemory(pAd->ApCfg.ApCliTab[ifIndex].ResVarIEs, MAX_VIE_LEN); pAd->ApCfg.ApCliTab[ifIndex].ResVarIELen = 0; PFRAME_802_11 pFrame = (PFRAME_802_11) (Elem->Msg); pAd->ApCfg.ApCliTab[ifIndex].ResVarIELen = Elem->MsgLen - 6 - sizeof (HEADER_802_11); NdisCopyMemory(pAd->ApCfg.ApCliTab[ifIndex].ResVarIEs, &pFrame->Octet[6], pAd->ApCfg.ApCliTab[ifIndex].ResVarIELen); #endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE || CFG80211_MULTI_STA */ #ifdef MAC_REPEATER_SUPPORT if (CliIdx != 0xFF) RTMPCancelTimer(&pAd->ApCfg.ApCliTab[ifIndex].RepeaterCli[CliIdx].ApCliAssocTimer, &Cancelled); else #endif /* MAC_REPEATER_SUPPORT */ RTMPCancelTimer(&pAd->ApCfg.ApCliTab[ifIndex].MlmeAux.ApCliAssocTimer, &Cancelled); if(Status == MLME_SUCCESS) { /* go to procedure listed on page 376 */ #ifdef MAC_REPEATER_SUPPORT if (CliIdx == 0xFF) #endif /* MAC_REPEATER_SUPPORT */ { ApCliAssocPostProc(pAd, Addr2, CapabilityInfo, ifIndex, SupRate, SupRateLen, ExtRate, ExtRateLen, &EdcaParm, &HtCapability, HtCapabilityLen, &AddHtInfo); #ifdef DOT11_VHT_AC RTMPZeroMemory(&pApCliEntry->MlmeAux.vht_cap, sizeof(VHT_CAP_IE)); RTMPZeroMemory(&pApCliEntry->MlmeAux.vht_op, sizeof(VHT_OP_IE)); pApCliEntry->MlmeAux.vht_cap_len = 0; pApCliEntry->MlmeAux.vht_op_len = 0; if (WMODE_CAP_AC(pAd->CommonCfg.PhyMode) && ie_list->vht_cap_len && ie_list->vht_op_len) { DBGPRINT(RT_DEBUG_TRACE, ("There is vht le at Assoc Rsp ifIndex=%d vht_cap_len=%d\n", ifIndex,ie_list->vht_cap_len)); NdisMoveMemory(&pApCliEntry->MlmeAux.vht_cap, &(ie_list->vht_cap), ie_list->vht_cap_len); pApCliEntry->MlmeAux.vht_cap_len = ie_list->vht_cap_len; NdisMoveMemory(&pApCliEntry->MlmeAux.vht_op, &(ie_list->vht_op), ie_list->vht_op_len); pApCliEntry->MlmeAux.vht_op_len = ie_list->vht_op_len; } #endif /* DOT11_VHT_AC */ } ApCliCtrlMsg.Status = MLME_SUCCESS; #ifdef MAC_REPEATER_SUPPORT ApCliCtrlMsg.BssIdx = ifIndex; ApCliCtrlMsg.CliIdx = CliIdx; ifIndex = (USHORT)(Elem->Priv); #endif /* MAC_REPEATER_SUPPORT */ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_ASSOC_RSP, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex); } else { ApCliCtrlMsg.Status = Status; MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_ASSOC_RSP, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex); } *pCurrState = APCLI_ASSOC_IDLE; } } else { DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - ApCliPeerAssocRspAction() sanity check fail\n")); } if (ie_list) os_free_mem(pAd, ie_list); return; }
/* ========================================================================== Description: When waiting joining the (I)BSS, beacon received from external ========================================================================== */ static VOID ApCliPeerProbeRspAtJoinAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { USHORT LenVIE; UCHAR *VarIE = NULL; NDIS_802_11_VARIABLE_IEs *pVIE = NULL; APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg; PAPCLI_STRUCT pApCliEntry = NULL; struct wifi_dev *wdev; #ifdef DOT11_N_SUPPORT UCHAR CentralChannel; #endif /* DOT11_N_SUPPORT */ USHORT ifIndex = (USHORT)(Elem->Priv); ULONG *pCurrState; BCN_IE_LIST *ie_list = NULL; if (ifIndex >= MAX_APCLI_NUM) return; /* Init Variable IE structure */ os_alloc_mem(NULL, (UCHAR **)&VarIE, MAX_VIE_LEN); if (VarIE == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); goto LabelErr; } pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE; pVIE->Length = 0; os_alloc_mem(NULL, (UCHAR **)&ie_list, sizeof(BCN_IE_LIST)); if (ie_list == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate ie_list fail!!!\n", __FUNCTION__)); goto LabelErr; } NdisZeroMemory(ie_list, sizeof(BCN_IE_LIST)); pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].SyncCurrState; if (PeerBeaconAndProbeRspSanity(pAd, Elem->Msg, Elem->MsgLen, Elem->Channel, ie_list, &LenVIE, pVIE)) { /* BEACON from desired BSS/IBSS found. We should be able to decide most BSS parameters here. Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATEION? Do we need to receover back all parameters belonging to previous BSS? A. Should be not. There's no back-door recover to previous AP. It still need a new JOIN-AUTH-ASSOC sequence. */ INT ssidEqualFlag = FALSE; INT ssidEmptyFlag = FALSE; INT bssidEqualFlag = FALSE; INT bssidEmptyFlag = FALSE; INT matchFlag = FALSE; ULONG Bssidx; CHAR RealRssi = -127; RealRssi = (LONG)(RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2))); /* Update ScanTab */ Bssidx = BssTableSearch(&pAd->ScanTab, ie_list->Bssid, ie_list->Channel); if (Bssidx == BSS_NOT_FOUND) { /* discover new AP of this network, create BSS entry */ Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, ie_list, -127, LenVIE, pVIE); if (Bssidx == BSS_NOT_FOUND) /* return if BSS table full */ { DBGPRINT(RT_DEBUG_ERROR, ("ERROR: Driver ScanTable Full In Apcli ProbeRsp Join\n")); goto LabelErr; } NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].PTSF, &Elem->Msg[24], 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4); pAd->ScanTab.BssEntry[Bssidx].MinSNR = Elem->Signal % 10; if (pAd->ScanTab.BssEntry[Bssidx].MinSNR == 0) pAd->ScanTab.BssEntry[Bssidx].MinSNR = -5; NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].MacAddr, ie_list->Addr2, MAC_ADDR_LEN); } #ifdef RT_CFG80211_P2P_CONCURRENT_DEVICE DBGPRINT(RT_DEBUG_TRACE, ("Info: Update the SSID %s in Kernel Table\n", ie_list->Ssid)); RT_CFG80211_SCANNING_INFORM(pAd, Bssidx, ie_list->Channel, (UCHAR *)Elem->Msg, Elem->MsgLen, RealRssi); #endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE */ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex]; wdev = &pApCliEntry->wdev; /* Check the Probe-Rsp's Bssid. */ if(!MAC_ADDR_EQUAL(pApCliEntry->CfgApCliBssid, ZERO_MAC_ADDR)) bssidEqualFlag = MAC_ADDR_EQUAL(pApCliEntry->CfgApCliBssid, ie_list->Bssid); else bssidEmptyFlag = TRUE; /* Check the Probe-Rsp's Ssid. */ if(pApCliEntry->CfgSsidLen != 0) ssidEqualFlag = SSID_EQUAL(pApCliEntry->CfgSsid, pApCliEntry->CfgSsidLen, ie_list->Ssid, ie_list->SsidLen); else ssidEmptyFlag = TRUE; /* bssid and ssid, Both match. */ if (bssidEqualFlag && ssidEqualFlag) matchFlag = TRUE; /* ssid match but bssid doesn't be indicate. */ else if(ssidEqualFlag && bssidEmptyFlag) matchFlag = TRUE; /* user doesn't indicate any bssid or ssid. AP-Clinet will auto pick a AP to join by most strong siganl strength. */ else if (bssidEmptyFlag && ssidEmptyFlag) matchFlag = TRUE; DBGPRINT(RT_DEBUG_TRACE, ("SYNC - bssidEqualFlag=%d, ssidEqualFlag=%d, matchFlag=%d\n", bssidEqualFlag, ssidEqualFlag, matchFlag)); if (matchFlag) { /* Validate RSN IE if necessary, then copy store this information */ if ((LenVIE > 0) #ifdef RT_CFG80211_P2P_CONCURRENT_DEVICE /* When using CFG80211 and trigger WPS, do not check security. */ && ! (pApCliEntry->wpa_supplicant_info.WpaSupplicantUP & WPA_SUPPLICANT_ENABLE_WPS) #endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE */ ) { if (ApCliValidateRSNIE(pAd, (PEID_STRUCT)pVIE, LenVIE, ifIndex)) { pApCliEntry->MlmeAux.VarIELen = LenVIE; NdisMoveMemory(pApCliEntry->MlmeAux.VarIEs, pVIE, pApCliEntry->MlmeAux.VarIELen); } else { /* ignore this response */ pApCliEntry->MlmeAux.VarIELen = 0; DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The RSN IE of this received Probe-resp is dis-match !!!!!!!!!! \n")); goto LabelErr; } } else { if (pApCliEntry->wdev.AuthMode >= Ndis802_11AuthModeWPA ) { /* ignore this response */ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The received Probe-resp has empty RSN IE !!!!!!!!!! \n")); goto LabelErr; } pApCliEntry->MlmeAux.VarIELen = 0; } DBGPRINT(RT_DEBUG_TRACE, ("SYNC - receive desired PROBE_RSP at JoinWaitProbeRsp... Channel = %d\n", ie_list->Channel)); /* if the Bssid doesn't be indicated then you need to decide which AP to connect by most strong Rssi signal strength. */ if (bssidEqualFlag == FALSE) { /* caculate real rssi value. */ CHAR Rssi0 = ConvertToRssi(pAd, Elem->Rssi0, RSSI_0); CHAR Rssi1 = ConvertToRssi(pAd, Elem->Rssi1, RSSI_1); CHAR Rssi2 = ConvertToRssi(pAd, Elem->Rssi2, RSSI_2); LONG RealRssi = (LONG)(RTMPMaxRssi(pAd, Rssi0, Rssi1, Rssi2)); DBGPRINT(RT_DEBUG_TRACE, ("SYNC - previous Rssi = %ld current Rssi=%ld\n", pApCliEntry->MlmeAux.Rssi, (LONG)RealRssi)); if (pApCliEntry->MlmeAux.Rssi > (LONG)RealRssi) goto LabelErr; else pApCliEntry->MlmeAux.Rssi = RealRssi; } else { BOOLEAN Cancelled; RTMPCancelTimer(&pApCliEntry->MlmeAux.ProbeTimer, &Cancelled); } NdisMoveMemory(pApCliEntry->MlmeAux.Ssid, ie_list->Ssid, ie_list->SsidLen); pApCliEntry->MlmeAux.SsidLen = ie_list->SsidLen; NdisMoveMemory(pApCliEntry->MlmeAux.Bssid, ie_list->Bssid, MAC_ADDR_LEN); pApCliEntry->MlmeAux.CapabilityInfo = ie_list->CapabilityInfo & SUPPORTED_CAPABILITY_INFO; pApCliEntry->MlmeAux.BssType = ie_list->BssType; pApCliEntry->MlmeAux.BeaconPeriod = ie_list->BeaconPeriod; pApCliEntry->MlmeAux.Channel = ie_list->Channel; pApCliEntry->MlmeAux.AtimWin = ie_list->AtimWin; pApCliEntry->MlmeAux.CfpPeriod = ie_list->CfParm.CfpPeriod; pApCliEntry->MlmeAux.CfpMaxDuration = ie_list->CfParm.CfpMaxDuration; pApCliEntry->MlmeAux.APRalinkIe = ie_list->RalinkIe; /* Copy AP's supported rate to MlmeAux for creating assoication request */ /* Also filter out not supported rate */ pApCliEntry->MlmeAux.SupRateLen = ie_list->SupRateLen; NdisMoveMemory(pApCliEntry->MlmeAux.SupRate, ie_list->SupRate, ie_list->SupRateLen); RTMPCheckRates(pAd, pApCliEntry->MlmeAux.SupRate, &pApCliEntry->MlmeAux.SupRateLen); pApCliEntry->MlmeAux.ExtRateLen = ie_list->ExtRateLen; NdisMoveMemory(pApCliEntry->MlmeAux.ExtRate, ie_list->ExtRate, ie_list->ExtRateLen); RTMPCheckRates(pAd, pApCliEntry->MlmeAux.ExtRate, &pApCliEntry->MlmeAux.ExtRateLen); #ifdef APCLI_CERT_SUPPORT /* Get the ext capability info element */ if (pAd->bApCliCertTest == TRUE #ifdef DOT11N_DRAFT3 && pAd->CommonCfg.bBssCoexEnable == TRUE #endif /* DOT11N_DRAFT3 */ ) { NdisMoveMemory(&pApCliEntry->MlmeAux.ExtCapInfo, &ie_list->ExtCapInfo,sizeof(ie_list->ExtCapInfo)); #ifdef DOT11_N_SUPPORT #ifdef DOT11N_DRAFT3 DBGPRINT(RT_DEBUG_TRACE, ("\x1b[31m ApCliMlmeAux.ExtCapInfo=%d \x1b[m\n", pApCliEntry->MlmeAux.ExtCapInfo.BssCoexistMgmtSupport)); //zero debug 210121122 pAd->CommonCfg.ExtCapIE.BssCoexistMgmtSupport = 1; #endif /* DOT11N_DRAFT3 */ #endif /* DOT11_N_SUPPORT */ } #endif /* APCLI_CERT_SUPPORT */ #ifdef DOT11_N_SUPPORT NdisZeroMemory(pApCliEntry->RxMcsSet,sizeof(pApCliEntry->RxMcsSet)); /* filter out un-supported ht rates */ if ((ie_list->HtCapabilityLen > 0) && (pApCliEntry->wdev.DesiredHtPhyInfo.bHtEnable) && WMODE_CAP_N(pAd->CommonCfg.PhyMode) && /* For Dissallow TKIP rule on STA */ !(pAd->CommonCfg.HT_DisallowTKIP && IS_INVALID_HT_SECURITY(wdev->WepStatus))) { RTMPZeroMemory(&pApCliEntry->MlmeAux.HtCapability, SIZE_HT_CAP_IE); pApCliEntry->MlmeAux.NewExtChannelOffset = ie_list->NewExtChannelOffset; pApCliEntry->MlmeAux.HtCapabilityLen = ie_list->HtCapabilityLen; ApCliCheckHt(pAd, ifIndex, &ie_list->HtCapability, &ie_list->AddHtInfo); if (ie_list->AddHtInfoLen > 0) { CentralChannel = ie_list->AddHtInfo.ControlChan; /* Check again the Bandwidth capability of this AP. */ CentralChannel = get_cent_ch_by_htinfo(pAd, &ie_list->AddHtInfo, &ie_list->HtCapability); DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction HT===>CentralCh = %d, ControlCh = %d\n", CentralChannel, ie_list->AddHtInfo.ControlChan)); } } else #endif /* DOT11_N_SUPPORT */ { RTMPZeroMemory(&pApCliEntry->MlmeAux.HtCapability, SIZE_HT_CAP_IE); RTMPZeroMemory(&pApCliEntry->MlmeAux.AddHtInfo, SIZE_ADD_HT_INFO_IE); pApCliEntry->MlmeAux.HtCapabilityLen = 0; } ApCliUpdateMlmeRate(pAd, ifIndex); #ifdef DOT11_N_SUPPORT /* copy QOS related information */ if (WMODE_CAP_N(pAd->CommonCfg.PhyMode)) { NdisMoveMemory(&pApCliEntry->MlmeAux.APEdcaParm, &ie_list->EdcaParm, sizeof(EDCA_PARM)); NdisMoveMemory(&pApCliEntry->MlmeAux.APQbssLoad, &ie_list->QbssLoad, sizeof(QBSS_LOAD_PARM)); NdisMoveMemory(&pApCliEntry->MlmeAux.APQosCapability, &ie_list->QosCapability, sizeof(QOS_CAPABILITY_PARM)); } else #endif /* DOT11_N_SUPPORT */ { NdisZeroMemory(&pApCliEntry->MlmeAux.APEdcaParm, sizeof(EDCA_PARM)); NdisZeroMemory(&pApCliEntry->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM)); NdisZeroMemory(&pApCliEntry->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM)); } DBGPRINT(RT_DEBUG_TRACE, ("APCLI SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n", pApCliEntry->MlmeAux.SupRateLen, pApCliEntry->MlmeAux.ExtRateLen)); if (ie_list->AironetCellPowerLimit != 0xFF) { /* We need to change our TxPower for CCX 2.0 AP Control of Client Transmit Power */ ChangeToCellPowerLimit(pAd, ie_list->AironetCellPowerLimit); } else /* Used the default TX Power Percentage. */ pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault; if(bssidEqualFlag == TRUE) { *pCurrState = APCLI_SYNC_IDLE; ApCliCtrlMsg.Status = MLME_SUCCESS; MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_PROBE_RSP, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex); } } } LabelErr: if (VarIE != NULL) os_free_mem(NULL, VarIE); if (ie_list != NULL) os_free_mem(NULL, ie_list); return; }
/* ======================================================================== Routine Description: Caller ensures we has 802.11n support. Calls at setting HT from AP/STASetinformation Arguments: pAd - Pointer to our adapter phymode - ======================================================================== */ VOID RTMPSetIndividualHT( IN RTMP_ADAPTER *pAd, IN UCHAR apidx) { RT_PHY_INFO *pDesired_ht_phy = NULL; UCHAR TxStream = pAd->CommonCfg.TxStream; UCHAR DesiredMcs = MCS_AUTO; UCHAR encrypt_mode = Ndis802_11EncryptionDisabled; do { #ifdef CONFIG_AP_SUPPORT #ifdef APCLI_SUPPORT if (apidx >= MIN_NET_DEVICE_FOR_APCLI) { UCHAR idx = apidx - MIN_NET_DEVICE_FOR_APCLI; if (idx < MAX_APCLI_NUM) { pDesired_ht_phy = &pAd->ApCfg.ApCliTab[idx].DesiredHtPhyInfo; DesiredMcs = pAd->ApCfg.ApCliTab[idx].DesiredTransmitSetting.field.MCS; encrypt_mode = pAd->ApCfg.ApCliTab[idx].WepStatus; pAd->ApCfg.ApCliTab[idx].bAutoTxRateSwitch = (DesiredMcs == MCS_AUTO) ? TRUE : FALSE; break; } else { DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetIndividualHT: invalid idx(%d)\n", idx)); return; } } #endif /* APCLI_SUPPORT */ IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { #ifdef WDS_SUPPORT if (apidx >= MIN_NET_DEVICE_FOR_WDS) { UCHAR idx = apidx - MIN_NET_DEVICE_FOR_WDS; if (idx < MAX_WDS_ENTRY) { pDesired_ht_phy = &pAd->WdsTab.WdsEntry[idx].DesiredHtPhyInfo; DesiredMcs = pAd->WdsTab.WdsEntry[idx].DesiredTransmitSetting.field.MCS; /*encrypt_mode = pAd->WdsTab.WdsEntry[idx].WepStatus;*/ pAd->WdsTab.WdsEntry[idx].bAutoTxRateSwitch = (DesiredMcs == MCS_AUTO) ? TRUE : FALSE; break; } else { DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetIndividualHT: invalid apidx(%d)\n", apidx)); return; } } #endif /* WDS_SUPPORT */ if ((apidx < pAd->ApCfg.BssidNum) && (apidx < MAX_MBSSID_NUM(pAd)) && (apidx < HW_BEACON_MAX_NUM)) { pDesired_ht_phy = &pAd->ApCfg.MBSSID[apidx].DesiredHtPhyInfo; DesiredMcs = pAd->ApCfg.MBSSID[apidx].DesiredTransmitSetting.field.MCS; encrypt_mode = pAd->ApCfg.MBSSID[apidx].WepStatus; pAd->ApCfg.MBSSID[apidx].bWmmCapable = TRUE; pAd->ApCfg.MBSSID[apidx].bAutoTxRateSwitch = (DesiredMcs == MCS_AUTO) ? TRUE : FALSE; break; } DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetIndividualHT: invalid apidx(%d)\n", apidx)); return; } #endif /* CONFIG_AP_SUPPORT */ } while (FALSE); if (pDesired_ht_phy == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetIndividualHT: invalid apidx(%d)\n", apidx)); return; } RTMPZeroMemory(pDesired_ht_phy, sizeof(RT_PHY_INFO)); DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetIndividualHT : Desired MCS = %d\n", DesiredMcs)); /* Check the validity of MCS */ if ((TxStream == 1) && ((DesiredMcs >= MCS_8) && (DesiredMcs <= MCS_15))) { DBGPRINT(RT_DEBUG_WARN, ("RTMPSetIndividualHT: MCS(%d) is invalid in 1S, reset it as MCS_7\n", DesiredMcs)); DesiredMcs = MCS_7; } if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_20) && (DesiredMcs == MCS_32)) { DBGPRINT(RT_DEBUG_WARN, ("RTMPSetIndividualHT: MCS_32 is only supported in 40-MHz, reset it as MCS_0\n")); DesiredMcs = MCS_0; } /* WFA recommend to restrict the encryption type in 11n-HT mode. So, the WEP and TKIP are not allowed in HT rate. */ if (pAd->CommonCfg.HT_DisallowTKIP && IS_INVALID_HT_SECURITY(encrypt_mode)) { DBGPRINT(RT_DEBUG_WARN, ("%s : Use legacy rate in WEP/TKIP encryption mode (apidx=%d)\n", __FUNCTION__, apidx)); return; } if (pAd->CommonCfg.HT_Disable) { DBGPRINT(RT_DEBUG_TRACE, ("%s : HT is disabled\n", __FUNCTION__)); return; } pDesired_ht_phy->bHtEnable = TRUE; /* Decide desired Tx MCS*/ switch (TxStream) { case 1: if (DesiredMcs == MCS_AUTO) pDesired_ht_phy->MCSSet[0]= 0xff; else if (DesiredMcs <= MCS_7) pDesired_ht_phy->MCSSet[0]= 1<<DesiredMcs; break; case 2: if (DesiredMcs == MCS_AUTO) { pDesired_ht_phy->MCSSet[0]= 0xff; pDesired_ht_phy->MCSSet[1]= 0xff; } else if (DesiredMcs <= MCS_15) { ULONG mode; mode = DesiredMcs / 8; if (mode < 2) pDesired_ht_phy->MCSSet[mode] = (1 << (DesiredMcs - mode * 8)); } break; case 3: if (DesiredMcs == MCS_AUTO) { /* MCS0 ~ MCS23, 3 bytes */ pDesired_ht_phy->MCSSet[0]= 0xff; pDesired_ht_phy->MCSSet[1]= 0xff; pDesired_ht_phy->MCSSet[2]= 0xff; } else if (DesiredMcs <= MCS_23) { ULONG mode; mode = DesiredMcs / 8; if (mode < 3) pDesired_ht_phy->MCSSet[mode] = (1 << (DesiredMcs - mode * 8)); } break; } if(pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_40) { if (DesiredMcs == MCS_AUTO || DesiredMcs == MCS_32) pDesired_ht_phy->MCSSet[4] = 0x1; } /* update HT Rate setting */ if (pAd->OpMode == OPMODE_STA) { MlmeUpdateHtTxRates(pAd, BSS0); } else MlmeUpdateHtTxRates(pAd, apidx); #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(pAd->CommonCfg.PhyMode)) { pDesired_ht_phy->bVhtEnable = TRUE; rtmp_set_vht(pAd, pDesired_ht_phy); } #endif /* DOT11_VHT_AC */ }
/* ======================================================================== Routine Description: Caller ensures we has 802.11n support. Calls at setting HT from AP/STASetinformation Arguments: pAd - Pointer to our adapter phymode - ======================================================================== */ VOID RTMPSetHT( IN RTMP_ADAPTER *pAd, IN OID_SET_HT_PHYMODE *pHTPhyMode) { UCHAR RxStream = pAd->CommonCfg.RxStream; #ifdef CONFIG_AP_SUPPORT int apidx; #endif /* CONFIG_AP_SUPPORT */ int bw; RT_HT_CAPABILITY *rt_ht_cap = &pAd->CommonCfg.DesiredHtPhy; HT_CAPABILITY_IE *ht_cap= &pAd->CommonCfg.HtCapability; #ifdef CONFIG_AP_SUPPORT /* sanity check for extention channel */ if (CHAN_PropertyCheck(pAd, pAd->CommonCfg.Channel, CHANNEL_NO_FAT_BELOW | CHANNEL_NO_FAT_ABOVE) == TRUE) { /* only 20MHz is allowed */ pHTPhyMode->BW = 0; } else if (pHTPhyMode->ExtOffset == EXTCHA_BELOW) { /* extension channel below this channel is not allowed */ if (CHAN_PropertyCheck(pAd, pAd->CommonCfg.Channel, CHANNEL_NO_FAT_BELOW) == TRUE) { pHTPhyMode->ExtOffset = EXTCHA_ABOVE; } } else if (pHTPhyMode->ExtOffset == EXTCHA_ABOVE) { /* extension channel above this channel is not allowed */ if (CHAN_PropertyCheck(pAd, pAd->CommonCfg.Channel, CHANNEL_NO_FAT_ABOVE) == TRUE) { pHTPhyMode->ExtOffset = EXTCHA_BELOW; } } #endif /* CONFIG_AP_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : HT_mode(%d), ExtOffset(%d), MCS(%d), BW(%d), STBC(%d), SHORTGI(%d)\n", pHTPhyMode->HtMode, pHTPhyMode->ExtOffset, pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->SHORTGI)); /* Don't zero supportedHyPhy structure.*/ RTMPZeroMemory(ht_cap, sizeof(HT_CAPABILITY_IE)); RTMPZeroMemory(&pAd->CommonCfg.AddHTInfo, sizeof(pAd->CommonCfg.AddHTInfo)); RTMPZeroMemory(&pAd->CommonCfg.NewExtChanOffset, sizeof(pAd->CommonCfg.NewExtChanOffset)); RTMPZeroMemory(rt_ht_cap, sizeof(RT_HT_CAPABILITY)); if (pAd->CommonCfg.bRdg) { ht_cap->ExtHtCapInfo.PlusHTC = 1; ht_cap->ExtHtCapInfo.RDGSupport = 1; } else { ht_cap->ExtHtCapInfo.PlusHTC = 0; ht_cap->ExtHtCapInfo.RDGSupport = 0; } if (RxStream == 1) { ht_cap->HtCapParm.MaxRAmpduFactor = 2; rt_ht_cap->MaxRAmpduFactor = 2; } else { ht_cap->HtCapParm.MaxRAmpduFactor = 3; rt_ht_cap->MaxRAmpduFactor = 3; } DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : RxBAWinLimit = %d\n", pAd->CommonCfg.BACapability.field.RxBAWinLimit)); /* Mimo power save, A-MSDU size, */ rt_ht_cap->AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable; rt_ht_cap->AmsduSize = (UCHAR)pAd->CommonCfg.BACapability.field.AmsduSize; rt_ht_cap->MimoPs = (UCHAR)pAd->CommonCfg.BACapability.field.MMPSmode; rt_ht_cap->MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity; ht_cap->HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize; ht_cap->HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode; ht_cap->HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity; DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : AMsduSize = %d, MimoPs = %d, MpduDensity = %d, MaxRAmpduFactor = %d\n", rt_ht_cap->AmsduSize, rt_ht_cap->MimoPs, rt_ht_cap->MpduDensity, rt_ht_cap->MaxRAmpduFactor)); if(pHTPhyMode->HtMode == HTMODE_GF) { ht_cap->HtCapInfo.GF = 1; rt_ht_cap->GF = 1; } else rt_ht_cap->GF = 0; /* Decide Rx MCSSet*/ switch (RxStream) { case 3: ht_cap->MCSSet[2] = 0xff; case 2: ht_cap->MCSSet[1] = 0xff; case 1: default: ht_cap->MCSSet[0] = 0xff; break; } if (pAd->CommonCfg.bForty_Mhz_Intolerant && (pHTPhyMode->BW == BW_40)) { pHTPhyMode->BW = BW_20; ht_cap->HtCapInfo.Forty_Mhz_Intolerant = 1; } // TODO: shiang-6590, how about the "bw" when channel 14 for JP region??? bw = BW_20; if(pHTPhyMode->BW == BW_40) { ht_cap->MCSSet[4] = 0x1; /* MCS 32*/ ht_cap->HtCapInfo.ChannelWidth = 1; if (pAd->CommonCfg.Channel <= 14) ht_cap->HtCapInfo.CCKmodein40 = 1; rt_ht_cap->ChannelWidth = 1; pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 1; pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = (pHTPhyMode->ExtOffset == EXTCHA_BELOW)? (EXTCHA_BELOW): EXTCHA_ABOVE; /* Set Regsiter for extension channel position.*/ rtmp_mac_set_ctrlch(pAd, pHTPhyMode->ExtOffset); /* Turn on BBP 40MHz mode now only as AP . */ /* Sta can turn on BBP 40MHz after connection with 40MHz AP. Sta only broadcast 40MHz capability before connection.*/ if ((pAd->OpMode == OPMODE_AP) || INFRA_ON(pAd) || ADHOC_ON(pAd) ) { rtmp_bbp_set_ctrlch(pAd, pHTPhyMode->ExtOffset); #ifdef GREENAP_SUPPORT if (pAd->ApCfg.bGreenAPActive == 1) bw = BW_20; else #endif /* GREENAP_SUPPORT */ bw = BW_40; } } else { ht_cap->HtCapInfo.ChannelWidth = 0; rt_ht_cap->ChannelWidth = 0; pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 0; pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = EXTCHA_NONE; pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel; /* Turn on BBP 20MHz mode by request here.*/ bw = BW_20; } #ifdef DOT11_VHT_AC if (pHTPhyMode->BW == BW_40 && pAd->CommonCfg.vht_bw == VHT_BW_80 && pAd->CommonCfg.vht_cent_ch) bw = BW_80; #endif /* DOT11_VHT_AC */ rtmp_bbp_set_bw(pAd, bw); if(pHTPhyMode->STBC == STBC_USE) { if (pAd->Antenna.field.TxPath >= 2) { ht_cap->HtCapInfo.TxSTBC = 1; rt_ht_cap->TxSTBC = 1; } else { ht_cap->HtCapInfo.TxSTBC = 0; rt_ht_cap->TxSTBC = 0; } /* RxSTBC 0: not support, 1: support for 1SS 2: support for 1SS, 2SS 3: support for 1SS, 2SS, 3SS */ if (pAd->Antenna.field.RxPath >= 1) { ht_cap->HtCapInfo.RxSTBC = 1; rt_ht_cap->RxSTBC = 1; } else { ht_cap->HtCapInfo.RxSTBC = 0; rt_ht_cap->RxSTBC = 0; } } else { rt_ht_cap->TxSTBC = 0; rt_ht_cap->RxSTBC = 0; } if(pHTPhyMode->SHORTGI == GI_400) { ht_cap->HtCapInfo.ShortGIfor20 = 1; ht_cap->HtCapInfo.ShortGIfor40 = 1; rt_ht_cap->ShortGIfor20 = 1; rt_ht_cap->ShortGIfor40 = 1; } else { ht_cap->HtCapInfo.ShortGIfor20 = 0; ht_cap->HtCapInfo.ShortGIfor40 = 0; rt_ht_cap->ShortGIfor20 = 0; rt_ht_cap->ShortGIfor40 = 0; } /* We support link adaptation for unsolicit MCS feedback, set to 2.*/ pAd->CommonCfg.AddHTInfo.ControlChan = pAd->CommonCfg.Channel; /* 1, the extension channel above the control channel. */ /* EDCA parameters used for AP's own transmission*/ if (pAd->CommonCfg.APEdcaParm.bValid == FALSE) { pAd->CommonCfg.APEdcaParm.bValid = TRUE; pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3; pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7; pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1; pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1; pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4; pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4; pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3; pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2; pAd->CommonCfg.APEdcaParm.Cwmax[0] = 6; pAd->CommonCfg.APEdcaParm.Cwmax[1] = 10; pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4; pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3; pAd->CommonCfg.APEdcaParm.Txop[0] = 0; pAd->CommonCfg.APEdcaParm.Txop[1] = 0; pAd->CommonCfg.APEdcaParm.Txop[2] = 94; pAd->CommonCfg.APEdcaParm.Txop[3] = 47; } AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm); #ifdef TXBF_SUPPORT if (pAd->chipCap.FlgHwTxBfCap) { /* Set ETxBF */ setETxBFCap(pAd, &ht_cap->TxBFCap); /* Check ITxBF */ pAd->CommonCfg.RegTransmitSetting.field.ITxBfEn &= rtmp_chk_itxbf_calibration(pAd); /* Apply to ASIC */ rtmp_asic_set_bf(pAd); } #endif /* TXBF_SUPPORT */ #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++) RTMPSetIndividualHT(pAd, apidx); #ifdef WDS_SUPPORT for (apidx = 0; apidx < MAX_WDS_ENTRY; apidx++) RTMPSetIndividualHT(pAd, apidx + MIN_NET_DEVICE_FOR_WDS); #endif /* WDS_SUPPORT */ #ifdef APCLI_SUPPORT for (apidx = 0; apidx < MAX_APCLI_NUM; apidx++) RTMPSetIndividualHT(pAd, apidx + MIN_NET_DEVICE_FOR_APCLI); #endif /* APCLI_SUPPORT */ } #endif /* CONFIG_AP_SUPPORT */ }