VOID SendNotifyBWActionFrame(RTMP_ADAPTER *pAd, UCHAR Wcid, UCHAR apidx) { UCHAR *pOutBuffer = NULL, *pAddr1; NDIS_STATUS NStatus; FRAME_ACTION_HDR Frame; ULONG FrameLen; struct wifi_dev *wdev; NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /* Get an unused nonpaged memory */ if(NStatus != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_ERROR,("ACT - SendNotifyBWAction() allocate memory failed \n")); return; } pAddr1 = pAd->MacTab.Content[Wcid].Addr; wdev = &pAd->ApCfg.MBSSID[apidx].wdev; ActHeaderInit(pAd, &Frame.Hdr, pAddr1, wdev->if_addr, wdev->bssid); Frame.Category = CATEGORY_HT; Frame.Action = NOTIFY_BW_ACTION; MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(FRAME_ACTION_HDR), &Frame, END_OF_ARGS); *(pOutBuffer + FrameLen) = pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth; FrameLen++; MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); DBGPRINT(RT_DEBUG_TRACE,("ACT - SendNotifyBWAction(NotifyBW= %d)!\n", pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth)); }
VOID SendBSS2040CoexistMgmtAction( IN RTMP_ADAPTER *pAd, IN UCHAR Wcid, IN UCHAR apidx, IN UCHAR InfoReq) { UCHAR *pOutBuffer = NULL; NDIS_STATUS NStatus; FRAME_ACTION_HDR Frame; ULONG FrameLen; BSS_2040_COEXIST_ELEMENT BssCoexistInfo; BSS_2040_INTOLERANT_CH_REPORT BssIntolerantInfo; UCHAR *pAddr1; struct wifi_dev *wdev; DBGPRINT(RT_DEBUG_TRACE, ("SendBSS2040CoexistMgmtAction(): Wcid=%d, apidx=%d, InfoReq=%d!\n", Wcid, apidx, InfoReq)); NdisZeroMemory((PUCHAR)&BssCoexistInfo, sizeof(BSS_2040_COEXIST_ELEMENT)); NdisZeroMemory((PUCHAR)&BssIntolerantInfo, sizeof(BSS_2040_INTOLERANT_CH_REPORT)); BssCoexistInfo.ElementID = IE_2040_BSS_COEXIST; BssCoexistInfo.Len = 1; BssCoexistInfo.BssCoexistIe.word = pAd->CommonCfg.LastBSSCoexist2040.word; BssCoexistInfo.BssCoexistIe.field.InfoReq = InfoReq; BssIntolerantInfo.ElementID = IE_2040_BSS_INTOLERANT_REPORT; BssIntolerantInfo.Len = 1; BssIntolerantInfo.RegulatoryClass = get_regulatory_class(pAd); NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory*/ if(NStatus != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_ERROR,("ACT - SendBSS2040CoexistMgmtAction() allocate memory failed \n")); return; } if (Wcid == MCAST_WCID) pAddr1 = &BROADCAST_ADDR[0]; else pAddr1 = pAd->MacTab.Content[Wcid].Addr; wdev = &pAd->ApCfg.MBSSID[apidx].wdev; ActHeaderInit(pAd, &Frame.Hdr, pAddr1, wdev->if_addr, wdev->bssid); Frame.Category = CATEGORY_PUBLIC; Frame.Action = ACTION_BSS_2040_COEXIST; MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(FRAME_ACTION_HDR), &Frame, sizeof(BSS_2040_COEXIST_ELEMENT), &BssCoexistInfo, sizeof(BSS_2040_INTOLERANT_CH_REPORT), &BssIntolerantInfo, END_OF_ARGS); MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); DBGPRINT(RT_DEBUG_ERROR,("ACT - SendBSS2040CoexistMgmtAction(BSSCoexist2040=0x%x)\n", BssCoexistInfo.BssCoexistIe.word)); }
/* Description : Send PSMP Action frame If PSMP mode switches. */ VOID SendPSMPAction( IN PRTMP_ADAPTER pAd, IN UCHAR Wcid, IN UCHAR Psmp) { PUCHAR pOutBuffer = NULL; NDIS_STATUS NStatus; //ULONG Idx; FRAME_PSMP_ACTION Frame; ULONG FrameLen; NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory if (NStatus != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() allocate memory failed \n")); return; } #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->MacTab.Content[Wcid].Addr); #endif // CONFIG_STA_SUPPORT // Frame.Category = CATEGORY_HT; Frame.Action = SMPS_ACTION; switch (Psmp) { case MMPS_ENABLE: #ifdef RT30xx if (IS_RT30xx(pAd) &&(pAd->Antenna.field.RxPath>1||pAd->Antenna.field.TxPath>1)) { RTMP_ASIC_MMPS_DISABLE(pAd); } #endif // RT30xx // Frame.Psmp = 0; break; case MMPS_DYNAMIC: Frame.Psmp = 3; break; case MMPS_STATIC: #ifdef RT30xx if (IS_RT30xx(pAd) &&(pAd->Antenna.field.RxPath>1||pAd->Antenna.field.TxPath>1)) { RTMP_ASIC_MMPS_ENABLE(pAd); } #endif // RT30xx // Frame.Psmp = 1; break; } MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(FRAME_PSMP_ACTION), &Frame, END_OF_ARGS); MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); DBGPRINT(RT_DEBUG_ERROR,("HT - SendPSMPAction( %d ) \n", Frame.Psmp)); }
/* ========================================================================== Description: P2P Action frame differs only in InBuffer. Others are all common to all ACtion Subtype Parameters: S - pointer to the association state machine Note: The state machine looks like the following as name implies its function ========================================================================== */ VOID MlmeP2pCommonAction( IN PRTMP_ADAPTER pAd, IN UCHAR OUISubType, IN UCHAR Token, IN PUCHAR pInBuffer, IN UCHAR InBufferLen, IN MLME_QUEUE_ELEM *Elem) { PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg; PMLME_P2P_ACTION_STRUCT pGoReq = (PMLME_P2P_ACTION_STRUCT) Elem->Msg; PUCHAR pOutBuffer = NULL; NDIS_STATUS NStatus; ULONG FrameLen = 0; FRAME_P2P_ACTION Frame; ULONG TmpLen; UCHAR i; PUCHAR pDest; NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /* Get an unused nonpaged memory */ if (NStatus != NDIS_STATUS_SUCCESS) { return; } DBGPRINT(RT_DEBUG_ERROR, (" TO= %x %x %x %x %x %x \n", PRINT_MAC(pGoReq->Addr))); DBGPRINT(RT_DEBUG_ERROR, (" Bssid= %x %x %x %x %x %x \n", PRINT_MAC(pP2PCtrl->CurrentAddress))); ActHeaderInit(pAd, &Frame.Hdr, pGoReq->Addr, pP2PCtrl->CurrentAddress, pP2PCtrl->CurrentAddress); Frame.Category = MT2_ACT_VENDOR; /* 0x7F */ RTMPMoveMemory(&Frame.OUI[0], P2POUIBYTE, 4); Frame.OUISubType = OUISubType; Frame.Token = Token; /* No Element */ MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(FRAME_P2P_ACTION), &Frame, END_OF_ARGS); if ((InBufferLen > 0) && (pInBuffer != NULL)) { MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, InBufferLen, pInBuffer, END_OF_ARGS); FrameLen += TmpLen; } MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); pDest = (PUCHAR)&Frame; for (i = 0; i <FrameLen; ) { DBGPRINT(RT_DEBUG_ERROR,(": %x %x %x %x %x %x %x %x %x \n", *(pDest+i), *(pDest+i+1), *(pDest+i+2), *(pDest+i+3), *(pDest+i+4), *(pDest+i+5), *(pDest+i+6), *(pDest+i+7), *(pDest+i+8))); i = i + 9; } DBGPRINT(RT_DEBUG_ERROR, ("Common P2P ACT request. FrameLen = %d. \n", FrameLen)); }
/* Description : Send PSMP Action frame If PSMP mode switches. */ void SendPSMPAction(struct rt_rtmp_adapter *pAd, u8 Wcid, u8 Psmp) { u8 *pOutBuffer = NULL; int NStatus; /*unsigned long Idx; */ struct rt_frame_psmp_action Frame; unsigned long FrameLen; NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ if (NStatus != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_ERROR, ("BA - MlmeADDBAAction() allocate memory failed \n")); return; } ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->MacTab.Content[Wcid].Addr); Frame.Category = CATEGORY_HT; Frame.Action = SMPS_ACTION; switch (Psmp) { case MMPS_ENABLE: #ifdef RT30xx if (IS_RT30xx(pAd) && (pAd->Antenna.field.RxPath > 1 || pAd->Antenna.field.TxPath > 1)) { RTMP_ASIC_MMPS_DISABLE(pAd); } #endif /* RT30xx // */ Frame.Psmp = 0; break; case MMPS_DYNAMIC: Frame.Psmp = 3; break; case MMPS_STATIC: #ifdef RT30xx if (IS_RT30xx(pAd) && (pAd->Antenna.field.RxPath > 1 || pAd->Antenna.field.TxPath > 1)) { RTMP_ASIC_MMPS_ENABLE(pAd); } #endif /* RT30xx // */ Frame.Psmp = 1; break; } MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(struct rt_frame_psmp_action), &Frame, END_OF_ARGS); MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); DBGPRINT(RT_DEBUG_ERROR, ("HT - SendPSMPAction( %d ) \n", Frame.Psmp)); }
VOID MlmeQOSAction(RTMP_ADAPTER *pAd, MLME_QUEUE_ELEM *Elem) { #if defined(CONFIG_AP_SUPPORT) && defined(CONFIG_HOTSPOT_R2) MLME_QOS_ACTION_STRUCT *pInfo; PUCHAR pOutBuffer = NULL; ULONG FrameLen = 0; NDIS_STATUS NStatus; FRAME_ACTION_HDR Frame; pInfo = (MLME_QOS_ACTION_STRUCT *)Elem->Msg; NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory*/ if(NStatus != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_ERROR,("ACT - MlmeQOSAction() allocate memory failed \n")); return; } if (pInfo->ActionField == ACTION_QOSMAP_CONFIG) { UCHAR OosMapIE = IE_QOS_MAP_SET; QOSMAP_SET *pQosMapBuf = &pInfo->QOSMap; BSS_STRUCT *mbss = &pAd->ApCfg.MBSSID[pInfo->apidx]; UCHAR ielen = 0; ActHeaderInit(pAd, &Frame.Hdr, pInfo->Addr, mbss->wdev.bssid, mbss->wdev.bssid); Frame.Category = CATEGORY_QOS; Frame.Action = ACTION_QOSMAP_CONFIG; ielen = pQosMapBuf->DSCP_Field_Len; MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(FRAME_ACTION_HDR), &Frame, 1, &OosMapIE, 1, &ielen, ielen, pQosMapBuf->DSCP_Field, END_OF_ARGS); MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); } MlmeFreeMemory(pAd, pOutBuffer); #endif /* defined(CONFIG_AP_SUPPORT) && defined(CONFIG_HOTSPOT_R2) */ }
/* Description : Send PSMP Action frame If PSMP mode switches. */ VOID SendPSMPAction( IN PRTMP_ADAPTER pAd, IN UCHAR Wcid, IN UCHAR Psmp) { PUCHAR pOutBuffer = NULL; NDIS_STATUS NStatus; //ULONG Idx; FRAME_PSMP_ACTION Frame; ULONG FrameLen; #ifdef RT30xx UCHAR bbpdata=0; UINT32 macdata; #endif // RT30xx // NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory if (NStatus != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() allocate memory failed \n")); return; } #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->MacTab.Content[Wcid].Addr); #endif // CONFIG_STA_SUPPORT // Frame.Category = CATEGORY_HT; Frame.Action = SMPS_ACTION; switch (Psmp) { case MMPS_ENABLE: #ifdef RT30xx if (IS_RT3090(pAd)) { // disable MMPS BBP control register RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpdata); bbpdata &= ~(0x04); //bit 2 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpdata); // disable MMPS MAC control register RTMP_IO_READ32(pAd, 0x1210, &macdata); macdata &= ~(0x09); //bit 0, 3 RTMP_IO_WRITE32(pAd, 0x1210, macdata); } #endif // RT30xx // Frame.Psmp = 0; break; case MMPS_DYNAMIC: #ifdef RT30xx if (IS_RT3090(pAd)) { // enable MMPS BBP control register RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpdata); bbpdata |= 0x04; //bit 2 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpdata); // enable MMPS MAC control register RTMP_IO_READ32(pAd, 0x1210, &macdata); macdata |= 0x09; //bit 0, 3 RTMP_IO_WRITE32(pAd, 0x1210, macdata); } #endif // RT30xx // Frame.Psmp = 3; break; case MMPS_STATIC: #ifdef RT30xx if (IS_RT3090(pAd)) { // enable MMPS BBP control register RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpdata); bbpdata |= 0x04; //bit 2 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpdata); // enable MMPS MAC control register RTMP_IO_READ32(pAd, 0x1210, &macdata); macdata |= 0x09; //bit 0, 3 RTMP_IO_WRITE32(pAd, 0x1210, macdata); } #endif // RT30xx // Frame.Psmp = 1; break; } MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(FRAME_PSMP_ACTION), &Frame, END_OF_ARGS); MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); DBGPRINT(RT_DEBUG_ERROR,("HT - SendPSMPAction( %d ) \n", Frame.Psmp)); }
VOID MlmeADDBAAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { MLME_ADDBA_REQ_STRUCT *pInfo; UCHAR Addr[6]; PUCHAR pOutBuffer = NULL; NDIS_STATUS NStatus; ULONG Idx; FRAME_ADDBA_REQ Frame; ULONG FrameLen; BA_ORI_ENTRY *pBAEntry = NULL; #ifdef CONFIG_AP_SUPPORT UCHAR apidx; #endif /* CONFIG_AP_SUPPORT */ pInfo = (MLME_ADDBA_REQ_STRUCT *)Elem->Msg; NdisZeroMemory(&Frame, sizeof(FRAME_ADDBA_REQ)); if(MlmeAddBAReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr) && VALID_WCID(pInfo->Wcid)) { NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /* Get an unused nonpaged memory*/ if(NStatus != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_TRACE,("BA - MlmeADDBAAction() allocate memory failed \n")); return; } /* 1. find entry */ Idx = pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID]; if (Idx == 0) { MlmeFreeMemory(pAd, pOutBuffer); DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() can't find BAOriEntry \n")); return; } else { pBAEntry =&pAd->BATable.BAOriEntry[Idx]; } #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { #ifdef APCLI_SUPPORT if (IS_ENTRY_APCLI(&pAd->MacTab.Content[pInfo->Wcid])) { #ifdef MAC_REPEATER_SUPPORT MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[pInfo->Wcid]; #endif /* MAC_REPEATER_SUPPORT */ apidx = pAd->MacTab.Content[pInfo->Wcid].MatchAPCLITabIdx; #ifdef MAC_REPEATER_SUPPORT if (pEntry && pEntry->bReptCli) ActHeaderInit(pAd, &Frame.Hdr, pInfo->pAddr, pAd->ApCfg.ApCliTab[apidx].RepeaterCli[pEntry->MatchReptCliIdx].CurrentAddress, pInfo->pAddr); else #endif /* MAC_REPEATER_SUPPORT */ ActHeaderInit(pAd, &Frame.Hdr, pInfo->pAddr, pAd->ApCfg.ApCliTab[apidx].CurrentAddress, pInfo->pAddr); } else #endif /* APCLI_SUPPORT */ { apidx = pAd->MacTab.Content[pInfo->Wcid].apidx; ActHeaderInit(pAd, &Frame.Hdr, pInfo->pAddr, pAd->ApCfg.MBSSID[apidx].Bssid, pAd->ApCfg.MBSSID[apidx].Bssid); } } #endif /* CONFIG_AP_SUPPORT */ Frame.Category = CATEGORY_BA; Frame.Action = ADDBA_REQ; Frame.BaParm.AMSDUSupported = 0; Frame.BaParm.BAPolicy = IMMED_BA; Frame.BaParm.TID = pInfo->TID; Frame.BaParm.BufSize = pInfo->BaBufSize; Frame.Token = pInfo->Token; Frame.TimeOutValue = pInfo->TimeOutValue; Frame.BaStartSeq.field.FragNum = 0; Frame.BaStartSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID]; #ifdef UNALIGNMENT_SUPPORT { BA_PARM tmpBaParm; NdisMoveMemory((PUCHAR)(&tmpBaParm), (PUCHAR)(&Frame.BaParm), sizeof(BA_PARM)); *(USHORT *)(&tmpBaParm) = cpu2le16(*(USHORT *)(&tmpBaParm)); NdisMoveMemory((PUCHAR)(&Frame.BaParm), (PUCHAR)(&tmpBaParm), sizeof(BA_PARM)); } #else *(USHORT *)(&(Frame.BaParm)) = cpu2le16((*(USHORT *)(&(Frame.BaParm)))); #endif /* UNALIGNMENT_SUPPORT */ Frame.TimeOutValue = cpu2le16(Frame.TimeOutValue); Frame.BaStartSeq.word = cpu2le16(Frame.BaStartSeq.word); MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(FRAME_ADDBA_REQ), &Frame, END_OF_ARGS); MiniportMMRequest(pAd, (MGMT_USE_QUEUE_FLAG | MapUserPriorityToAccessCategory[pInfo->TID]), pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); DBGPRINT(RT_DEBUG_TRACE, ("BA - Send ADDBA request. StartSeq = %x, FrameLen = %ld. BufSize = %d\n", Frame.BaStartSeq.field.StartSeq, FrameLen, Frame.BaParm.BufSize)); }
/* ========================================================================== Description: send DELBA and delete BaEntry if any Parametrs: Elem - MLME message MLME_DELBA_REQ_STRUCT IRQL = DISPATCH_LEVEL ========================================================================== */ void MlmeDELBAAction(RTMP_ADAPTER *pAd, MLME_QUEUE_ELEM *Elem) { MLME_DELBA_REQ_STRUCT *pInfo; PUCHAR pOutBuffer = NULL, pOutBuffer2 = NULL; ULONG Idx; FRAME_DELBA_REQ Frame; ULONG FrameLen; FRAME_BAR FrameBar; MAC_TABLE_ENTRY *pEntry = NULL; struct wifi_dev *wdev; pInfo = (MLME_DELBA_REQ_STRUCT *)Elem->Msg; /* must send back DELBA */ NdisZeroMemory(&Frame, sizeof(FRAME_DELBA_REQ)); DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeDELBAAction(), Initiator(%d) \n", pInfo->Initiator)); if (MlmeDelBAReqSanity(pAd, Elem->Msg, Elem->MsgLen) && VALID_WCID(pInfo->Wcid)) { pOutBuffer = MlmeAllocateMemory(); if (!pOutBuffer) { return; } pOutBuffer2 = MlmeAllocateMemory(); if (!pOutBuffer2) { MlmeFreeMemory(pOutBuffer); return; } /* SEND BAR (Send BAR to refresh peer reordering buffer.) */ pEntry = &pAd->MacTab.Content[pInfo->Wcid]; if (!pEntry->wdev) { DBGPRINT(RT_DEBUG_ERROR, ("%s():No binding wdev for wcid(%d)\n", __FUNCTION__, pInfo->Wcid)); MlmeFreeMemory(pOutBuffer); MlmeFreeMemory(pOutBuffer2); return; } wdev = pEntry->wdev; Idx = pEntry->BAOriWcidArray[pInfo->TID]; #ifdef APCLI_SUPPORT #endif /* APCLI_SUPPORT */ BarHeaderInit(pAd, &FrameBar, pEntry->Addr, wdev->if_addr); FrameBar.StartingSeq.field.FragNum = 0; /* make sure sequence not clear in DEL funciton.*/ FrameBar.StartingSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID]; /* make sure sequence not clear in DEL funciton.*/ FrameBar.BarControl.TID = pInfo->TID; /* make sure sequence not clear in DEL funciton.*/ FrameBar.BarControl.ACKPolicy = IMMED_BA; /* make sure sequence not clear in DEL funciton.*/ FrameBar.BarControl.Compressed = 1; /* make sure sequence not clear in DEL funciton.*/ FrameBar.BarControl.MTID = 0; /* make sure sequence not clear in DEL funciton.*/ MakeOutgoingFrame(pOutBuffer2, &FrameLen, sizeof(FRAME_BAR), &FrameBar, END_OF_ARGS); MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer2, FrameLen); MlmeFreeMemory(pOutBuffer2); DBGPRINT(RT_DEBUG_TRACE, ("BA - MlmeDELBAAction() . Send BAR to refresh peer reordering buffer \n")); /* SEND DELBA FRAME*/ FrameLen = 0; //CFG_TODO #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { #ifdef APCLI_SUPPORT #endif /* APCLI_SUPPORT */ ActHeaderInit(pAd, &Frame.Hdr, pEntry->Addr, pEntry->wdev->if_addr, pEntry->wdev->bssid); } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { if (ADHOC_ON(pAd)) ActHeaderInit(pAd, &Frame.Hdr, pEntry->Addr, pAd->StaCfg.wdev.if_addr, pAd->StaCfg.wdev.bssid); else ActHeaderInit(pAd, &Frame.Hdr, pEntry->Addr, pAd->StaCfg.wdev.if_addr, pAd->StaCfg.wdev.bssid); } #endif /* CONFIG_STA_SUPPORT */ Frame.Category = CATEGORY_BA; Frame.Action = DELBA; Frame.DelbaParm.Initiator = pInfo->Initiator; Frame.DelbaParm.TID = pInfo->TID; Frame.ReasonCode = 39; /* Time Out*/ *(USHORT *)(&Frame.DelbaParm) = cpu2le16(*(USHORT *)(&Frame.DelbaParm)); Frame.ReasonCode = cpu2le16(Frame.ReasonCode); MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(FRAME_DELBA_REQ), &Frame, END_OF_ARGS); MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); MlmeFreeMemory(pOutBuffer); DBGPRINT(RT_DEBUG_TRACE, ("BA - MlmeDELBAAction() . 3 DELBA sent. Initiator(%d)\n", pInfo->Initiator)); }
static void MlmeADDBAAction(RTMP_ADAPTER *pAd, MLME_QUEUE_ELEM *Elem) { MLME_ADDBA_REQ_STRUCT *pInfo; UCHAR Addr[6]; PUCHAR pOutBuffer = NULL; ULONG Idx; FRAME_ADDBA_REQ Frame; ULONG FrameLen; BA_ORI_ENTRY *pBAEntry = NULL; MAC_TABLE_ENTRY *pEntry = NULL; struct wifi_dev *wdev; pInfo = (MLME_ADDBA_REQ_STRUCT *)Elem->Msg; NdisZeroMemory(&Frame, sizeof(FRAME_ADDBA_REQ)); if(MlmeAddBAReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr) && VALID_WCID(pInfo->Wcid)) { pOutBuffer = MlmeAllocateMemory(); /* Get an unused nonpaged memory*/ if (!pOutBuffer) { return; } /* 1. find entry */ pEntry = &pAd->MacTab.Content[pInfo->Wcid]; ASSERT((pEntry->wdev != NULL)); wdev = pEntry->wdev; Idx = pEntry->BAOriWcidArray[pInfo->TID]; if (Idx == 0) { MlmeFreeMemory(pOutBuffer); DBGPRINT(RT_DEBUG_ERROR, ("BA - MlmeADDBAAction() can't find BAOriEntry \n")); return; } else { pBAEntry =&pAd->BATable.BAOriEntry[Idx]; } #ifdef APCLI_SUPPORT #endif /* APCLI_SUPPORT */ ActHeaderInit(pAd, &Frame.Hdr, pInfo->pAddr, wdev->if_addr, wdev->bssid); Frame.Category = CATEGORY_BA; Frame.Action = ADDBA_REQ; Frame.BaParm.AMSDUSupported = 0; #ifdef WFA_VHT_PF if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable) Frame.BaParm.AMSDUSupported = 1; #endif /* WFA_VHT_PF */ Frame.BaParm.BAPolicy = IMMED_BA; Frame.BaParm.TID = pInfo->TID; Frame.BaParm.BufSize = pInfo->BaBufSize; Frame.Token = pInfo->Token; Frame.TimeOutValue = pInfo->TimeOutValue; Frame.BaStartSeq.field.FragNum = 0; Frame.BaStartSeq.field.StartSeq = pEntry->TxSeq[pInfo->TID]; #ifdef UNALIGNMENT_SUPPORT { BA_PARM tmpBaParm; NdisMoveMemory((PUCHAR)(&tmpBaParm), (PUCHAR)(&Frame.BaParm), sizeof(BA_PARM)); *(USHORT *)(&tmpBaParm) = cpu2le16(*(USHORT *)(&tmpBaParm)); NdisMoveMemory((PUCHAR)(&Frame.BaParm), (PUCHAR)(&tmpBaParm), sizeof(BA_PARM)); } #else *(USHORT *)(&(Frame.BaParm)) = cpu2le16((*(USHORT *)(&(Frame.BaParm)))); #endif /* UNALIGNMENT_SUPPORT */ Frame.TimeOutValue = cpu2le16(Frame.TimeOutValue); Frame.BaStartSeq.word = cpu2le16(Frame.BaStartSeq.word); MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(FRAME_ADDBA_REQ), &Frame, END_OF_ARGS); MiniportMMRequest(pAd, (MGMT_USE_QUEUE_FLAG | WMM_UP2AC_MAP[pInfo->TID]), pOutBuffer, FrameLen); MlmeFreeMemory(pOutBuffer); DBGPRINT(RT_DEBUG_TRACE, ("BA - Send ADDBA request. StartSeq = %x, FrameLen = %ld. BufSize = %d\n", Frame.BaStartSeq.field.StartSeq, FrameLen, Frame.BaParm.BufSize)); } }
/* ========================================================================== Description: Send Publiac action frame. But with ACtion is GAS_INITIAL_REQ (11). 802.11u. 7.4.7.10 Parameters: Note: ========================================================================== */ VOID MlmeGASIntialReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg; UCHAR Action = Elem->Msg[LENGTH_802_11+1]; PMLME_P2P_ACTION_STRUCT pReq = (PMLME_P2P_ACTION_STRUCT) Elem->Msg; PHEADER_802_11 pHeader; PUCHAR pAdProtocolElem; PUCHAR pQueryReq; PUCHAR pOutBuffer; ULONG FrameLen = 0; PUCHAR pDest; NDIS_STATUS NStatus; PUCHAR pServLen = NULL, pQueryLen = NULL, pTotalQueryLen = NULL; USHORT ServLen = 0, QueryLen = 0, TotalQueryLen = 0; int i, iSubId; UCHAR AnqpQueryInfoId[2] = {0xdd, 0xdd}; ULONG tmpValue = 0; DBGPRINT(RT_DEBUG_TRACE, ("MlmeGASIntialReqAction.Token = %d\n", pAd->P2pCfg.Token)); NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); if (NStatus != NDIS_STATUS_SUCCESS) return; DBGPRINT(RT_DEBUG_TRACE, ("%s:: TO %02x:%02x:%02x:%02x:%02x:%02x.\n", __FUNCTION__, PRINT_MAC(pReq->Addr))); pHeader = (PHEADER_802_11)pOutBuffer; ActHeaderInit(pAd, pHeader, pReq->Addr, pP2PCtrl->CurrentAddress, pReq->Addr); FrameLen += sizeof(HEADER_802_11); DBGPRINT(RT_DEBUG_TRACE, ("Use Token = %d. \n", pP2PCtrl->Token)); pDest = pOutBuffer + sizeof(HEADER_802_11); /* Category */ *pDest = CATEGORY_PUBLIC; /* Action */ *(pDest + 1) = ACTION_GAS_INITIAL_REQ; /* Dialog Token */ *(pDest + 2) = pP2PCtrl->Token; pDest += 3; FrameLen += 3; /* Advertisement Protocol Information Element */ /* Element ID */ *pDest = IE_ADVERTISEMENT_PROTO; /* Length */ *(pDest + 1) = 2; /* Advertisement Protocol Tuple */ /* Query Response Length Limit(7b) + PAME-BI(1b) */ *(pDest+2) = 0; /* Advertisement Protocol ID */ *(pDest + 3) = ACCESS_NETWORK_QUERY_PROTOCOL; /* ANQP */ pDest += 4; FrameLen += 4; /* Query Request Length */ pTotalQueryLen = pDest; pDest += 2; FrameLen += 2; /* ANQP Query Request */ /* Info ID (56797) */ RTMPMoveMemory(pDest, AnqpQueryInfoId, 2); /* Length */ pQueryLen = (pDest + 2); /* Vendor Specific OUI for P2P defined by WFA. */ RTMPMoveMemory(pDest + 4, P2POUIBYTE, 4); pDest += 8; FrameLen += 8; /* Service Update Indicator */ *pDest = 0; *(pDest + 1) = 0; /* Length */ pDest += 2; FrameLen += 2; #ifdef WFD_SUPPORT if (pAd->StaCfg.WfdCfg.bWfdEnable) { for (i = 0; i < WFD_DEVICE_TYPE_END; i++) { ServLen = 0; pServLen = pDest; pDest += 2; FrameLen += 2; /* Service Protocol Type */ *pDest = SERVICE_PROTOCOL_TYPE_WFD; /* WiFi-Display */ pDest += 1; /* Service Transaction ID */ *pDest = 0; pDest += 1; /* Requested Device Role, add for WFD Spec. D1.38 and above */ switch (i) { case 0: *pDest = WFD_SOURCE; break; case 1: *pDest = WFD_PRIMARY_SINK; break; case 2: *pDest = WFD_SECONDARY_SINK; break; case 3: *pDest = WFD_SOURCE_PRIMARY_SINK; break; } pDest += 1; FrameLen += 3; ServLen += 3; /* Including Requested Device Role */ /* List of WFD Subelement IDs */ for (iSubId = 0; iSubId < SUBID_WFD_END; iSubId++) { if (pAd->StaCfg.WfdCfg.WfdSerDiscCapable & (0x01 << iSubId)) { *pDest = iSubId; FrameLen += 1; ServLen += 1; pDest += 1; } } tmpValue = cpu2le16(ServLen); RTMPMoveMemory(pServLen, &tmpValue, 2); QueryLen += ServLen + 2; } } #endif /* WFD_SUPPORT */ QueryLen += 6; tmpValue = cpu2le16(QueryLen); RTMPMoveMemory(pQueryLen, &tmpValue, 2); TotalQueryLen = QueryLen + 4; tmpValue = cpu2le16(TotalQueryLen); RTMPMoveMemory(pTotalQueryLen, &tmpValue, 2); MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); }
/* ========================================================================== Description: send DELBA and delete BaEntry if any Parametrs: Elem - MLME message MLME_DELBA_REQ_STRUCT IRQL = DISPATCH_LEVEL ========================================================================== */ VOID MlmeDELBAAction(RTMP_ADAPTER *pAd, MLME_QUEUE_ELEM *Elem) { MLME_DELBA_REQ_STRUCT *pInfo; PUCHAR pOutBuffer = NULL, pOutBuffer2 = NULL; //ULONG Idx; FRAME_DELBA_REQ Frame; ULONG FrameLen; #if defined(RTMP_MAC) || defined(RTL_MAC) FRAME_BAR FrameBar; #endif MAC_TABLE_ENTRY *pEntry = NULL; struct wifi_dev *wdev; UCHAR *src_addr = NULL; pInfo = (MLME_DELBA_REQ_STRUCT *)Elem->Msg; /* must send back DELBA */ NdisZeroMemory(&Frame, sizeof(FRAME_DELBA_REQ)); DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeDELBAAction(), Initiator(%d) \n", pInfo->Initiator)); if(MlmeDelBAReqSanity(pAd, Elem->Msg, Elem->MsgLen) && VALID_WCID(pInfo->Wcid)) { if(MlmeAllocateMemory(pAd, &pOutBuffer) != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeDELBAAction() allocate memory failed 1. \n")); return; } if(MlmeAllocateMemory(pAd, &pOutBuffer2) != NDIS_STATUS_SUCCESS) { MlmeFreeMemory(pAd, pOutBuffer); DBGPRINT(RT_DEBUG_ERROR, ("BA - MlmeDELBAAction() allocate memory failed 2. \n")); return; } /* SEND BAR (Send BAR to refresh peer reordering buffer.) */ pEntry = &pAd->MacTab.Content[pInfo->Wcid]; if (!pEntry->wdev) { DBGPRINT(RT_DEBUG_ERROR, ("%s():No binding wdev for wcid(%d)\n", __FUNCTION__, pInfo->Wcid)); MlmeFreeMemory(pAd, pOutBuffer); MlmeFreeMemory(pAd, pOutBuffer2); return; } wdev = pEntry->wdev; //Idx = pEntry->BAOriWcidArray[pInfo->TID]; #ifdef APCLI_SUPPORT #ifdef MAC_REPEATER_SUPPORT if (IS_ENTRY_APCLI(pEntry) && pEntry->bReptCli) { UINT apidx = pEntry->func_tb_idx; src_addr = &pAd->ApCfg.ApCliTab[apidx].RepeaterCli[pEntry->MatchReptCliIdx].CurrentAddress[0]; } else #endif /* MAC_REPEATER_SUPPORT */ #endif /* APCLI_SUPPORT */ src_addr = wdev->if_addr; #if defined(RTMP_MAC) || defined(RTL_MAC) if ((pAd->chipCap.hif_type == HIF_RTMP) || (pAd->chipCap.hif_type == HIF_RLT)) { BarHeaderInit(pAd, &FrameBar, pEntry->Addr, src_addr); FrameBar.StartingSeq.field.FragNum = 0; /* make sure sequence not clear in DEL funciton.*/ FrameBar.StartingSeq.field.StartSeq = pAd->MacTab.tr_entry[pInfo->Wcid].TxSeq[pInfo->TID]; /* make sure sequence not clear in DEL funciton.*/ FrameBar.BarControl.TID = pInfo->TID; /* make sure sequence not clear in DEL funciton.*/ FrameBar.BarControl.ACKPolicy = IMMED_BA; /* make sure sequence not clear in DEL funciton.*/ FrameBar.BarControl.Compressed = 1; /* make sure sequence not clear in DEL funciton.*/ FrameBar.BarControl.MTID = 0; /* make sure sequence not clear in DEL funciton.*/ MakeOutgoingFrame(pOutBuffer2, &FrameLen, sizeof(FRAME_BAR), &FrameBar, END_OF_ARGS); MiniportMMRequest(pAd, (MGMT_USE_QUEUE_FLAG & QID_AC_BE), pOutBuffer2, FrameLen); DBGPRINT(RT_DEBUG_TRACE,("BA - MlmeDELBAAction() . Send BAR to refresh peer reordering buffer \n")); } #endif /* SEND DELBA FRAME*/ FrameLen = 0; ActHeaderInit(pAd, &Frame.Hdr, pEntry->Addr, src_addr, pEntry->wdev->bssid); Frame.Category = CATEGORY_BA; Frame.Action = DELBA; Frame.DelbaParm.Initiator = pInfo->Initiator; Frame.DelbaParm.TID = pInfo->TID; Frame.ReasonCode = 39; /* Time Out*/ *(USHORT *)(&Frame.DelbaParm) = cpu2le16(*(USHORT *)(&Frame.DelbaParm)); Frame.ReasonCode = cpu2le16(Frame.ReasonCode); MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(FRAME_DELBA_REQ), &Frame, END_OF_ARGS); MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); MlmeFreeMemory(pAd, pOutBuffer2); DBGPRINT(RT_DEBUG_TRACE, ("BA - MlmeDELBAAction() . 3 DELBA sent. Initiator(%d)\n", pInfo->Initiator)); } }
/* ========================================================================== Description: IRQL = DISPATCH_LEVEL ========================================================================== */ VOID FT_OTD_ReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { PUCHAR pOutBuffer = NULL; NDIS_STATUS NStatus; ULONG FrameLen = 0; HEADER_802_11 FtReqHdr; FT_MDIE MdIe; UCHAR Snonce[32]; UCHAR R0KhIdLen; UCHAR R0KhId[FT_ROKH_ID_LEN + 1]; UCHAR Category = FT_CATEGORY_BSS_TRANSITION; UCHAR Action = FT_ACTION_BT_REQ; ULONG Timeout = 0; USHORT Status; UCHAR TargetAddr[6]; NDIS_802_11_VARIABLE_IEs *pRsnIE = NULL; USHORT LenRsnIE; if (!MlmeFtReqSanity (pAd, Elem->Msg, Elem->MsgLen, TargetAddr, &Timeout, &MdIe, Snonce, &R0KhIdLen, R0KhId, &LenRsnIE, pRsnIE)) { DBGPRINT_ERR(("FT_OTD_ACTION - FT_OTD_ReqAction() sanity check failed\n")); pAd->Mlme.AuthMachine.CurrState = FT_OTD_IDLE; Status = MLME_INVALID_FORMAT; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status, 0); return; } DBGPRINT(RT_DEBUG_TRACE, ("FT_OTD_ACTION :FT_OTD_ReqAction() \n")); NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ if (NStatus != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_ERROR, ("FT_OTD_ACTION :FT_OTD_ReqAction() allocate memory failed \n")); return; } ActHeaderInit(pAd, &FtReqHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid); /* Build basic frame first */ MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof (HEADER_802_11), &FtReqHdr, 1, &Category, 1, &Action, 6, pAd->CurrentAddress, 6, TargetAddr, END_OF_ARGS); /* MDIE */ FT_InsertMdIE(pAd, pOutBuffer + FrameLen, &FrameLen, MdIe.MdId, MdIe.FtCapPlc); /* Process with RSN */ if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) { FT_ConstructAuthReqInRsn(pAd, pOutBuffer, &FrameLen); } MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); RTMPSetTimer(&pAd->MlmeAux.FtOtdActTimer, Timeout); pAd->Mlme.FtOtdActMachine.CurrState = FT_OTD_WAIT_SEQ2; }
/* ========================================================================== Description: Send Publiac action frame. But with ACtion is GAS_INITIAL_RSP (12). 802.11u. 7.4.7.10 Parameters: Note: ========================================================================== */ VOID MlmeGASIntialRspAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { UCHAR Action = Elem->Msg[LENGTH_802_11+1]; PMLME_P2P_ACTION_STRUCT pReq = (PMLME_P2P_ACTION_STRUCT) Elem->Msg; PHEADER_802_11 pHeader; PUCHAR pAdProtocolElem; PUCHAR pQueryRsp; PUCHAR pOutBuffer; ULONG FrameLen = 0; PUCHAR pDest; NDIS_STATUS NStatus; PUCHAR pServLen = NULL, pQueryLen = NULL, pTotalQueryLen = NULL; USHORT ServLen = 0, QueryLen = 0, TotalQueryLen = 0; PRT_P2P_CLIENT_ENTRY pP2pEntry = NULL; UCHAR AnqpQueryInfoId[2] = {0xdd, 0xdd}; UINT32 TempLen = 0; ULONG tmpValue = 0; DBGPRINT(RT_DEBUG_TRACE, ("MlmeGASIntialRspAction. \n")); NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); if (NStatus != NDIS_STATUS_SUCCESS) return; pP2pEntry = &pAd->P2pTable.Client[pReq->TabIndex]; DBGPRINT(RT_DEBUG_TRACE, ("MlmeGASIntialRspAction. TO %02x:%02x:%02x:%02x:%02x:%02x.\n", PRINT_MAC(pReq->Addr))); pHeader = (PHEADER_802_11)pOutBuffer; ActHeaderInit(pAd, pHeader, pReq->Addr, pAd->P2PCurrentAddress, pAd->P2PCurrentAddress); FrameLen = sizeof(HEADER_802_11); pDest = pOutBuffer + sizeof(HEADER_802_11); /* Category */ *pDest = CATEGORY_PUBLIC; /* Action */ *(pDest+1) = ACTION_GAS_INITIAL_RSP; /* Dialog Token */ *(pDest+2) = pP2pEntry->DialogToken; /* Status Code */ *(pDest+3) = 0; *(pDest+4) = 0; /* GAS Comeback Delay */ *(pDest+5) = 0; *(pDest+6) = 0; pDest += 7; FrameLen += 7; /* Advertisement Protocol information element */ /* Element ID */ *pDest = IE_ADVERTISEMENT_PROTO; /* Length */ *(pDest+1) = 2; /* Advertisement Protocol Tuple */ /* Query Response Length Limit(7b) + PAME-BI(1b) */ *(pDest+2) = 0; /* Advertisement Protol ID */ *(pDest + 3) = ACCESS_NETWORK_QUERY_PROTOCOL; /* ANQP */ FrameLen += 4; pDest += 4; /* Query Request Length */ pTotalQueryLen = pDest; FrameLen += 2; pDest += 2; /* ANQP Query Response */ /* Info ID (56797) */ RTMPMoveMemory(pDest, AnqpQueryInfoId, 2); /* Length */ pQueryLen = (pDest + 2); /* Vendor Specific OUI for P2P defined by WFA. */ RTMPMoveMemory(pDest + 4, P2POUIBYTE, 4); pDest += 8; FrameLen += 8; /* Service Update Indicator */ *pDest = 0; *(pDest + 1) = 0; /* Length */ pServLen = (pDest + 2); /* Service Protocol Type */ *(pDest + 4) = SERVICE_PROTOCOL_TYPE_WFD; /* WiFi-Display */ /* Service Transaction ID */ *(pDest + 5) = pAd->P2pCfg.ServiceTransac; /* Status Code */ *(pDest + 6) = 0; pDest += 7; FrameLen += 7; #ifdef WFD_SUPPORT if (pAd->StaCfg.WfdCfg.bWfdEnable) { /* Response Data */ if (pP2pEntry->WfdEntryInfo.wfd_serv_disc_query_info.bWfd_device_info_ie) { TempLen = InsertWfdSubelmtTlv(pAd, SUBID_WFD_DEVICE_INFO, NULL, pDest, ACTION_GAS_INITIAL_RSP); FrameLen += TempLen; ServLen += TempLen; pDest += TempLen; } if (pP2pEntry->WfdEntryInfo.wfd_serv_disc_query_info.bWfd_associate_bssid_ie) { TempLen = InsertWfdSubelmtTlv(pAd, SUBID_WFD_ASSOCIATED_BSSID, NULL, pDest, ACTION_GAS_INITIAL_RSP); FrameLen += TempLen; ServLen += TempLen; pDest += TempLen; } if (pP2pEntry->WfdEntryInfo.wfd_serv_disc_query_info.bWfd_audio_format_ie) { TempLen = InsertWfdSubelmtTlv(pAd, SUBID_WFD_AUDIO_FORMATS, NULL, pDest, ACTION_GAS_INITIAL_RSP); FrameLen += TempLen; ServLen += TempLen; pDest += TempLen; } if (pP2pEntry->WfdEntryInfo.wfd_serv_disc_query_info.bWfd_video_format_ie) { TempLen = InsertWfdSubelmtTlv(pAd, SUBID_WFD_VIDEO_FORMATS, NULL, pDest, ACTION_GAS_INITIAL_RSP); FrameLen += TempLen; ServLen += TempLen; pDest += TempLen; } if (pP2pEntry->WfdEntryInfo.wfd_serv_disc_query_info.bWfd_3d_video_format_ie) { TempLen = InsertWfdSubelmtTlv(pAd, SUBID_WFD_3D_VIDEO_FORMATS, NULL, pDest, ACTION_GAS_INITIAL_RSP); FrameLen += TempLen; ServLen += TempLen; pDest += TempLen; } if (pP2pEntry->WfdEntryInfo.wfd_serv_disc_query_info.bWfd_content_proctection) { TempLen = InsertWfdSubelmtTlv(pAd, SUBID_WFD_CONTENT_PROTECTION, NULL, pDest, ACTION_GAS_INITIAL_RSP); FrameLen += TempLen; ServLen += TempLen; pDest += TempLen; } if (pP2pEntry->WfdEntryInfo.wfd_serv_disc_query_info.bWfd_couple_sink_info_ie) { TempLen = InsertWfdSubelmtTlv(pAd, SUBID_WFD_COUPLED_SINK_INFO, NULL, pDest, ACTION_GAS_INITIAL_RSP); FrameLen += TempLen; ServLen += TempLen; pDest += TempLen; } if (pP2pEntry->WfdEntryInfo.wfd_serv_disc_query_info.bWfd_extent_capability_ie) { TempLen = InsertWfdSubelmtTlv(pAd, SUBID_WFD_EXTENDED_CAP, NULL, pDest, ACTION_GAS_INITIAL_RSP); FrameLen += TempLen; ServLen += TempLen; pDest += TempLen; } if (pP2pEntry->WfdEntryInfo.wfd_serv_disc_query_info.bWfd_local_ip_ie) { TempLen = InsertWfdSubelmtTlv(pAd, SUBID_WFD_LOCAL_IP_ADDR, NULL, pDest, ACTION_GAS_INITIAL_RSP); FrameLen += TempLen; ServLen += TempLen; pDest += TempLen; } if (pP2pEntry->WfdEntryInfo.wfd_serv_disc_query_info.bWfd_session_info_ie) { TempLen = InsertWfdSubelmtTlv(pAd, SUBID_WFD_SESSION_INFO, NULL, pDest, ACTION_GAS_INITIAL_RSP); FrameLen += TempLen; ServLen += TempLen; pDest += TempLen; } if (pP2pEntry->WfdEntryInfo.wfd_serv_disc_query_info.bWfd_alternate_mac_addr_ie) { TempLen = InsertWfdSubelmtTlv(pAd, SUBID_WFD_ALTERNATE_MAC_ADDR, NULL, pDest, ACTION_GAS_INITIAL_RSP); FrameLen += TempLen; ServLen += TempLen; pDest += TempLen; } } #endif /* WFD_SUPPORT */ //ServLen += 2; ServLen += 3; /* Including Status Code */ tmpValue = cpu2le16(ServLen); RTMPMoveMemory(pServLen, &tmpValue, 2); QueryLen = ServLen + 8; tmpValue = cpu2le16(QueryLen); RTMPMoveMemory(pQueryLen, &tmpValue, 2); TotalQueryLen = QueryLen + 4; tmpValue = cpu2le16(TotalQueryLen); RTMPMoveMemory(pTotalQueryLen, &tmpValue, 2); MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); }
VOID MlmeADDBAAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { MLME_ADDBA_REQ_STRUCT *pInfo; UCHAR Addr[6]; PUCHAR pOutBuffer = NULL; NDIS_STATUS NStatus; ULONG Idx; FRAME_ADDBA_REQ Frame; ULONG FrameLen; BA_ORI_ENTRY *pBAEntry = NULL; pInfo = (MLME_ADDBA_REQ_STRUCT *)Elem->Msg; NdisZeroMemory(&Frame, sizeof(FRAME_ADDBA_REQ)); if(MlmeAddBAReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr)) { NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory if(NStatus != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_TRACE,("BA - MlmeADDBAAction() allocate memory failed \n")); return; } // 1. find entry Idx = pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID]; if (Idx == 0) { MlmeFreeMemory(pAd, pOutBuffer); DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() can't find BAOriEntry \n")); return; } else { pBAEntry =&pAd->BATable.BAOriEntry[Idx]; } #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { if (ADHOC_ON(pAd) #ifdef QOS_DLS_SUPPORT || (IS_ENTRY_DLS(&pAd->MacTab.Content[pInfo->Wcid])) #endif // QOS_DLS_SUPPORT // ) ActHeaderInit(pAd, &Frame.Hdr, pInfo->pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid); else ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pInfo->pAddr); } #endif // CONFIG_STA_SUPPORT // Frame.Category = CATEGORY_BA; Frame.Action = ADDBA_REQ; Frame.BaParm.AMSDUSupported = 0; Frame.BaParm.BAPolicy = IMMED_BA; Frame.BaParm.TID = pInfo->TID; Frame.BaParm.BufSize = pInfo->BaBufSize; Frame.Token = pInfo->Token; Frame.TimeOutValue = pInfo->TimeOutValue; Frame.BaStartSeq.field.FragNum = 0; Frame.BaStartSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID]; *(USHORT *)(&Frame.BaParm) = cpu2le16(*(USHORT *)(&Frame.BaParm)); Frame.TimeOutValue = cpu2le16(Frame.TimeOutValue); Frame.BaStartSeq.word = cpu2le16(Frame.BaStartSeq.word); MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(FRAME_ADDBA_REQ), &Frame, END_OF_ARGS); MiniportMMRequest(pAd, (MGMT_USE_QUEUE_FLAG | MapUserPriorityToAccessCategory[pInfo->TID]), pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); DBGPRINT(RT_DEBUG_TRACE, ("BA - Send ADDBA request. StartSeq = %x, FrameLen = %ld. BufSize = %d\n", Frame.BaStartSeq.field.StartSeq, FrameLen, Frame.BaParm.BufSize)); }
VOID PeerAddBAReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { // 7.4.4.1 //ULONG Idx; UCHAR Status = 1; UCHAR pAddr[6]; FRAME_ADDBA_RSP ADDframe; PUCHAR pOutBuffer = NULL; NDIS_STATUS NStatus; PFRAME_ADDBA_REQ pAddreqFrame = NULL; //UCHAR BufSize; ULONG FrameLen; PULONG ptemp; PMAC_TABLE_ENTRY pMacEntry; DBGPRINT(RT_DEBUG_TRACE, ("%s ==> (Wcid = %d)\n", __FUNCTION__, Elem->Wcid)); //hex_dump("AddBAReq", Elem->Msg, Elem->MsgLen); //ADDBA Request from unknown peer, ignore this. if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE) return; pMacEntry = &pAd->MacTab.Content[Elem->Wcid]; DBGPRINT(RT_DEBUG_TRACE,("BA - PeerAddBAReqAction----> \n")); ptemp = (PULONG)Elem->Msg; //DBGPRINT_RAW(RT_DEBUG_EMU, ("%08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x\n", *(ptemp), *(ptemp+1), *(ptemp+2), *(ptemp+3), *(ptemp+4), *(ptemp+5), *(ptemp+6), *(ptemp+7), *(ptemp+8))); if (PeerAddBAReqActionSanity(pAd, Elem->Msg, Elem->MsgLen, pAddr)) { if ((pAd->CommonCfg.bBADecline == FALSE) && IS_HT_STA(pMacEntry)) { pAddreqFrame = (PFRAME_ADDBA_REQ)(&Elem->Msg[0]); DBGPRINT(RT_DEBUG_OFF, ("Rcv Wcid(%d) AddBAReq\n", Elem->Wcid)); if (BARecSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid], pAddreqFrame)) Status = 0; else Status = 38; // more parameters have invalid values } else { Status = 37; // the request has been declined. } } if (pAd->MacTab.Content[Elem->Wcid].ValidAsCLI) ASSERT(pAd->MacTab.Content[Elem->Wcid].Sst == SST_ASSOC); pAddreqFrame = (PFRAME_ADDBA_REQ)(&Elem->Msg[0]); // 2. Always send back ADDBA Response NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory if (NStatus != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_TRACE,("ACTION - PeerBAAction() allocate memory failed \n")); return; } NdisZeroMemory(&ADDframe, sizeof(FRAME_ADDBA_RSP)); // 2-1. Prepare ADDBA Response frame. #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { if (ADHOC_ON(pAd)) ActHeaderInit(pAd, &ADDframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid); else #ifdef QOS_DLS_SUPPORT if (pAd->MacTab.Content[Elem->Wcid].ValidAsDls) ActHeaderInit(pAd, &ADDframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid); else #endif // QOS_DLS_SUPPORT // ActHeaderInit(pAd, &ADDframe.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAddr); } #endif // CONFIG_STA_SUPPORT // ADDframe.Category = CATEGORY_BA; ADDframe.Action = ADDBA_RESP; ADDframe.Token = pAddreqFrame->Token; // What is the Status code?? need to check. ADDframe.StatusCode = Status; ADDframe.BaParm.BAPolicy = IMMED_BA; ADDframe.BaParm.AMSDUSupported = 0; ADDframe.BaParm.TID = pAddreqFrame->BaParm.TID; ADDframe.BaParm.BufSize = min(((UCHAR)pAddreqFrame->BaParm.BufSize), (UCHAR)pAd->CommonCfg.BACapability.field.RxBAWinLimit); if (ADDframe.BaParm.BufSize == 0) { ADDframe.BaParm.BufSize = 64; } ADDframe.TimeOutValue = 0; //pAddreqFrame->TimeOutValue; *(USHORT *)(&ADDframe.BaParm) = cpu2le16(*(USHORT *)(&ADDframe.BaParm)); ADDframe.StatusCode = cpu2le16(ADDframe.StatusCode); ADDframe.TimeOutValue = cpu2le16(ADDframe.TimeOutValue); MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(FRAME_ADDBA_RSP), &ADDframe, END_OF_ARGS); MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); DBGPRINT(RT_DEBUG_TRACE, ("%s(%d): TID(%d), BufSize(%d) <== \n", __FUNCTION__, Elem->Wcid, ADDframe.BaParm.TID, ADDframe.BaParm.BufSize)); }
void PeerAddBAReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) { /* 7.4.4.1 */ /*unsigned long Idx; */ u8 Status = 1; u8 pAddr[6]; struct rt_frame_addba_rsp ADDframe; u8 *pOutBuffer = NULL; int NStatus; struct rt_frame_addba_req * pAddreqFrame = NULL; /*u8 BufSize; */ unsigned long FrameLen; unsigned long *ptemp; struct rt_mac_table_entry *pMacEntry; DBGPRINT(RT_DEBUG_TRACE, ("%s ==> (Wcid = %d)\n", __func__, Elem->Wcid)); /*hex_dump("AddBAReq", Elem->Msg, Elem->MsgLen); */ /*ADDBA Request from unknown peer, ignore this. */ if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE) return; pMacEntry = &pAd->MacTab.Content[Elem->Wcid]; DBGPRINT(RT_DEBUG_TRACE, ("BA - PeerAddBAReqAction----> \n")); ptemp = (unsigned long *)Elem->Msg; /*DBGPRINT_RAW(RT_DEBUG_EMU, ("%08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x\n", *(ptemp), *(ptemp+1), *(ptemp+2), *(ptemp+3), *(ptemp+4), *(ptemp+5), *(ptemp+6), *(ptemp+7), *(ptemp+8))); */ if (PeerAddBAReqActionSanity(pAd, Elem->Msg, Elem->MsgLen, pAddr)) { if ((pAd->CommonCfg.bBADecline == FALSE) && IS_HT_STA(pMacEntry)) { pAddreqFrame = (struct rt_frame_addba_req *) (&Elem->Msg[0]); DBGPRINT(RT_DEBUG_OFF, ("Rcv Wcid(%d) AddBAReq\n", Elem->Wcid)); if (BARecSessionAdd (pAd, &pAd->MacTab.Content[Elem->Wcid], pAddreqFrame)) Status = 0; else Status = 38; /* more parameters have invalid values */ } else { Status = 37; /* the request has been declined. */ } } if (pAd->MacTab.Content[Elem->Wcid].ValidAsCLI) ASSERT(pAd->MacTab.Content[Elem->Wcid].Sst == SST_ASSOC); pAddreqFrame = (struct rt_frame_addba_req *) (&Elem->Msg[0]); /* 2. Always send back ADDBA Response */ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ if (NStatus != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_TRACE, ("ACTION - PeerBAAction() allocate memory failed \n")); return; } NdisZeroMemory(&ADDframe, sizeof(struct rt_frame_addba_rsp)); /* 2-1. Prepare ADDBA Response frame. */ { if (ADHOC_ON(pAd)) ActHeaderInit(pAd, &ADDframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid); else ActHeaderInit(pAd, &ADDframe.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAddr); } ADDframe.Category = CATEGORY_BA; ADDframe.Action = ADDBA_RESP; ADDframe.Token = pAddreqFrame->Token; /* What is the Status code?? need to check. */ ADDframe.StatusCode = Status; ADDframe.BaParm.BAPolicy = IMMED_BA; ADDframe.BaParm.AMSDUSupported = 0; ADDframe.BaParm.TID = pAddreqFrame->BaParm.TID; ADDframe.BaParm.BufSize = min(((u8)pAddreqFrame->BaParm.BufSize), (u8)pAd->CommonCfg.BACapability.field.RxBAWinLimit); if (ADDframe.BaParm.BufSize == 0) { ADDframe.BaParm.BufSize = 64; } ADDframe.TimeOutValue = 0; /*pAddreqFrame->TimeOutValue; */ *(u16 *) (&ADDframe.BaParm) = cpu2le16(*(u16 *) (&ADDframe.BaParm)); ADDframe.StatusCode = cpu2le16(ADDframe.StatusCode); ADDframe.TimeOutValue = cpu2le16(ADDframe.TimeOutValue); MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(struct rt_frame_addba_rsp), &ADDframe, END_OF_ARGS); MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); DBGPRINT(RT_DEBUG_TRACE, ("%s(%d): TID(%d), BufSize(%d) <== \n", __func__, Elem->Wcid, ADDframe.BaParm.TID, ADDframe.BaParm.BufSize)); }
VOID APMakeBssTimFrame(RTMP_ADAPTER *pAd, INT apidx) { BSS_STRUCT *pMbss = &pAd->ApCfg.MBSSID[apidx]; HEADER_802_11 TimHdr; LARGE_INTEGER FakeTimestamp; ULONG FrameLen = 0; UCHAR *pTimFrame, *ptr, *tmac_info; HTTRANSMIT_SETTING TimTransmit = {.word = 0}; /* MGMT frame PHY rate setting when operatin at HT rate. */ UINT8 tx_hw_hdr_len = pAd->chipCap.tx_hw_hdr_len; UCHAR Cat = 11;//Tim Category field UCHAR Act = 0;//Tim Action field UCHAR ChkBcn = 0;//Check Beacon field init from 0. if(!TimTransmitRequired(pAd, apidx, pMbss)) return; if (pMbss->tim_buf.TimPkt == NULL) { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s():Invalid TimPkt for MBSS[%d]\n", __func__, apidx)); return; } tmac_info = (UCHAR *)GET_OS_PKT_DATAPTR(pMbss->tim_buf.TimPkt); pTimFrame = (UCHAR *)(tmac_info + tx_hw_hdr_len); ActHeaderInit(pAd, &TimHdr, BROADCAST_ADDR, pMbss->wdev.if_addr, pMbss->wdev.bssid); MakeOutgoingFrame(pTimFrame, &FrameLen, sizeof(HEADER_802_11), &TimHdr, 1, &Cat, 1, &Act, 1, &ChkBcn, TIMESTAMP_LEN, &FakeTimestamp, END_OF_ARGS); TimTransmit.word = 0; pMbss->TimIELocationInTim = (UCHAR)FrameLen; /* step 2 - update TIM IE TODO: enlarge TIM bitmap to support up to 64 STAs TODO: re-measure if RT2600 TBTT interrupt happens faster than BEACON sent out time */ ptr = pTimFrame + (UCHAR)FrameLen; *ptr = IE_TIM; *(ptr+1) = 0x0e; *(ptr + 2) = pAd->ApCfg.DtimCount; *(ptr + 3) = pAd->ApCfg.DtimPeriod; *(ptr + 4) = 0xa0; *(ptr + 5) = 0xa0; *(ptr + 6) = 0xa0; *(ptr + 7) = 0xa0; *(ptr + 8) = 0xa0; *(ptr + 9) = 0xa0; *(ptr + 10) = 0xa0; *(ptr + 11) = 0xa0; *(ptr + 12) = 0xa0; *(ptr + 13) = 0xa0; *(ptr + 14) = 0xa0; *(ptr + 15) = 0xa0; // /* find the smallest AID (PS mode) */ // TimFirst = 0; /* record first TIM byte != 0x00 */ // TimLast = 0; /* record last TIM byte != 0x00 */ // pTim = pMbss->TimBitmaps; // // for(ID_1B=0; ID_1B<WLAN_MAX_NUM_OF_TIM; ID_1B++) // { // /* get the TIM indicating PS packets for 8 stations */ // UCHAR tim_1B = pTim[ID_1B]; // // if (ID_1B == 0) // tim_1B &= 0xfe; /* skip bit0 bc/mc */ // // if (tim_1B == 0) // continue; /* find next 1B */ // // if (TimFirst == 0) // TimFirst = ID_1B; // // TimLast = ID_1B; // } // // /* fill TIM content to beacon buffer */ // if (TimFirst & 0x01) // TimFirst --; /* find the even offset byte */ // // *(ptr + 1) = 3+(TimLast-TimFirst+1); /* TIM IE length */ // *(ptr + 4) = TimFirst; // // for(i=TimFirst; i<=TimLast; i++) // *(ptr + 5 + i - TimFirst) = pTim[i]; // // /* bit0 means backlogged mcast/bcast */ // /* per spec, this bit in TIM frame shall always 0. */ // //TODO: MTK proprietary mechanism. // //if (pAd->ApCfg.DtimCount == 0) // //*(ptr + 4) |= (pMbss->TimBitmaps[WLAN_CT_TIM_BCMC_OFFSET] & 0x01); // *(ptr + 4) = 0; /* adjust TIM length according to the new TIM */ FrameLen += 16;//(2 + *(ptr+1)); /* When Beacon is use CCK to send, TIM shall use OFDM to send. and it's mandatory. */ if (pAd->CommonCfg.Channel <= 14) { TimTransmit.field.MODE = MODE_OFDM; TimTransmit.field.MCS = MCS_RATE_6; } write_tmac_info_tim(pAd, apidx, tmac_info, &TimTransmit, FrameLen); // asic_write_bcn_buf(pAd, // tmac_info, TXWISize, // pTimFrame, FrameLen, // pAd->BeaconOffset[pMbss->bcn_buf.BcnBufIdx]); RT28xx_UpdateTimToAsic(pAd, apidx, FrameLen); //+++Add by shiang for debug MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s(): Dump the Beacon Packet of BSS%d!\n", __FUNCTION__, apidx)); hex_dump("Initial BeaconBuf", tmac_info, FrameLen + tx_hw_hdr_len); //---Add by shiang for debug } static UCHAR GetTimNum(RTMP_ADAPTER *pAd) { int i; int NumTim; TIM_BUF_STRUC *tim_info; NumTim = 0; for (i=0; i<pAd->ApCfg.BssidNum; i++) { tim_info = &pAd->ApCfg.MBSSID[i].tim_buf; if (tim_info->bTimSntReq) { tim_info->TimBufIdx = NumTim; NumTim ++; } } return NumTim; }
/* Description : Send 20/40 BSS Coexistence Action frame If one trigger event is triggered. */ VOID Send2040CoexistAction( IN RTMP_ADAPTER *pAd, IN UCHAR Wcid, IN BOOLEAN bAddIntolerantCha) { UCHAR *pOutBuffer = NULL; NDIS_STATUS NStatus; FRAME_ACTION_HDR Frame; ULONG FrameLen; UINT32 IntolerantChaRepLen; UCHAR HtLen = 1; IntolerantChaRepLen = 0; NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory*/ if(NStatus != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_ERROR,("ACT - Send2040CoexistAction() allocate memory failed \n")); return; } #ifdef DOT11V_WNM_SUPPORT /* Not complete yet. Ignore for compliing successfully.*/ #else #ifdef APCLI_SUPPORT if(IS_ENTRY_APCLI(&pAd->MacTab.Content[Wcid])) { PMAC_TABLE_ENTRY pEntry = NULL; struct wifi_dev *wdev; pEntry = &pAd->MacTab.Content[Wcid]; wdev = pEntry->wdev; ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[Wcid].Addr, wdev->if_addr, pAd->CommonCfg.Bssid); } else #endif /* APCLI_SUPPORT */ ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[Wcid].Addr, pAd->CurrentAddress, pAd->CommonCfg.Bssid); #endif /* DOT11V_WNM_SUPPORT */ Frame.Category = CATEGORY_PUBLIC; Frame.Action = ACTION_BSS_2040_COEXIST; /*COEXIST_2040_ACTION;*/ MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(FRAME_ACTION_HDR), &Frame, 1, &BssCoexistIe, 1, &HtLen, 1, &pAd->CommonCfg.BSSCoexist2040.word, END_OF_ARGS); if (bAddIntolerantCha == TRUE) IntolerantChaRepLen = BuildIntolerantChannelRep(pAd, pOutBuffer + FrameLen); /*2009 PF#3: IOT issue with Motorola AP. It will not check the field of BSSCoexist2040.*/ /*11.14.12 Switching between 40 MHz and 20 MHz*/ DBGPRINT(RT_DEBUG_TRACE, ("IntolerantChaRepLen=%d, BSSCoexist2040=0x%x!\n", IntolerantChaRepLen, pAd->CommonCfg.BSSCoexist2040.word)); if (!((IntolerantChaRepLen == 0) && (pAd->CommonCfg.BSSCoexist2040.word == 0))) MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen + IntolerantChaRepLen); MlmeFreeMemory(pAd, pOutBuffer); DBGPRINT(RT_DEBUG_TRACE,("ACT - Send2040CoexistAction( BSSCoexist2040 = 0x%x ) \n", pAd->CommonCfg.BSSCoexist2040.word)); }