| /* |
| ************************************************************************* |
| * Ralink Tech Inc. |
| * 5F., No.36, Taiyuan St., Jhubei City, |
| * Hsinchu County 302, |
| * Taiwan, R.O.C. |
| * |
| * (c) Copyright 2002-2007, Ralink Technology, Inc. |
| * |
| * This program is free software; you can redistribute it and/or modify * |
| * it under the terms of the GNU General Public License as published by * |
| * the Free Software Foundation; either version 2 of the License, or * |
| * (at your option) any later version. * |
| * * |
| * This program is distributed in the hope that it will be useful, * |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of * |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * |
| * GNU General Public License for more details. * |
| * * |
| * You should have received a copy of the GNU General Public License * |
| * along with this program; if not, write to the * |
| * Free Software Foundation, Inc., * |
| * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * |
| * * |
| ************************************************************************* |
| |
| Module Name: |
| action.c |
| |
| Abstract: |
| Handle association related requests either from WSTA or from local MLME |
| |
| Revision History: |
| Who When What |
| -------- ---------- ---------------------------------------------- |
| Jan Lee 2006 created for rt2860 |
| */ |
| |
| #include "../rt_config.h" |
| #include "action.h" |
| |
| static void ReservedAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); |
| |
| /* |
| ========================================================================== |
| Description: |
| association state machine init, including state transition and timer init |
| Parameters: |
| S - pointer to the association state machine |
| Note: |
| The state machine looks like the following |
| |
| ASSOC_IDLE |
| MT2_MLME_DISASSOC_REQ mlme_disassoc_req_action |
| MT2_PEER_DISASSOC_REQ peer_disassoc_action |
| MT2_PEER_ASSOC_REQ drop |
| MT2_PEER_REASSOC_REQ drop |
| MT2_CLS3ERR cls3err_action |
| ========================================================================== |
| */ |
| void ActionStateMachineInit(struct rt_rtmp_adapter *pAd, |
| struct rt_state_machine *S, |
| OUT STATE_MACHINE_FUNC Trans[]) |
| { |
| StateMachineInit(S, (STATE_MACHINE_FUNC *) Trans, MAX_ACT_STATE, |
| MAX_ACT_MSG, (STATE_MACHINE_FUNC) Drop, ACT_IDLE, |
| ACT_MACHINE_BASE); |
| |
| StateMachineSetAction(S, ACT_IDLE, MT2_PEER_SPECTRUM_CATE, |
| (STATE_MACHINE_FUNC) PeerSpectrumAction); |
| StateMachineSetAction(S, ACT_IDLE, MT2_PEER_QOS_CATE, |
| (STATE_MACHINE_FUNC) PeerQOSAction); |
| |
| StateMachineSetAction(S, ACT_IDLE, MT2_PEER_DLS_CATE, |
| (STATE_MACHINE_FUNC) ReservedAction); |
| |
| StateMachineSetAction(S, ACT_IDLE, MT2_PEER_BA_CATE, |
| (STATE_MACHINE_FUNC) PeerBAAction); |
| StateMachineSetAction(S, ACT_IDLE, MT2_PEER_HT_CATE, |
| (STATE_MACHINE_FUNC) PeerHTAction); |
| StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ADD_BA_CATE, |
| (STATE_MACHINE_FUNC) MlmeADDBAAction); |
| StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ORI_DELBA_CATE, |
| (STATE_MACHINE_FUNC) MlmeDELBAAction); |
| StateMachineSetAction(S, ACT_IDLE, MT2_MLME_REC_DELBA_CATE, |
| (STATE_MACHINE_FUNC) MlmeDELBAAction); |
| |
| StateMachineSetAction(S, ACT_IDLE, MT2_PEER_PUBLIC_CATE, |
| (STATE_MACHINE_FUNC) PeerPublicAction); |
| StateMachineSetAction(S, ACT_IDLE, MT2_PEER_RM_CATE, |
| (STATE_MACHINE_FUNC) PeerRMAction); |
| |
| StateMachineSetAction(S, ACT_IDLE, MT2_MLME_QOS_CATE, |
| (STATE_MACHINE_FUNC) MlmeQOSAction); |
| StateMachineSetAction(S, ACT_IDLE, MT2_MLME_DLS_CATE, |
| (STATE_MACHINE_FUNC) MlmeDLSAction); |
| StateMachineSetAction(S, ACT_IDLE, MT2_ACT_INVALID, |
| (STATE_MACHINE_FUNC) MlmeInvalidAction); |
| } |
| |
| void MlmeADDBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) |
| { |
| struct rt_mlme_addba_req *pInfo; |
| u8 Addr[6]; |
| u8 *pOutBuffer = NULL; |
| int NStatus; |
| unsigned long Idx; |
| struct rt_frame_addba_req Frame; |
| unsigned long FrameLen; |
| struct rt_ba_ori_entry *pBAEntry = NULL; |
| |
| pInfo = (struct rt_mlme_addba_req *)Elem->Msg; |
| NdisZeroMemory(&Frame, sizeof(struct rt_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]; |
| } |
| |
| { |
| if (ADHOC_ON(pAd)) |
| ActHeaderInit(pAd, &Frame.Hdr, pInfo->pAddr, |
| pAd->CurrentAddress, |
| pAd->CommonCfg.Bssid); |
| else |
| ActHeaderInit(pAd, &Frame.Hdr, |
| pAd->CommonCfg.Bssid, |
| pAd->CurrentAddress, |
| pInfo->pAddr); |
| } |
| |
| 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]; |
| |
| *(u16 *) (&Frame.BaParm) = |
| cpu2le16(*(u16 *) (&Frame.BaParm)); |
| Frame.TimeOutValue = cpu2le16(Frame.TimeOutValue); |
| Frame.BaStartSeq.word = cpu2le16(Frame.BaStartSeq.word); |
| |
| MakeOutgoingFrame(pOutBuffer, &FrameLen, |
| sizeof(struct rt_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 struct rt_mlme_delba_req |
| |
| IRQL = DISPATCH_LEVEL |
| |
| ========================================================================== |
| */ |
| void MlmeDELBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) |
| { |
| struct rt_mlme_delba_req *pInfo; |
| u8 *pOutBuffer = NULL; |
| u8 *pOutBuffer2 = NULL; |
| int NStatus; |
| unsigned long Idx; |
| struct rt_frame_delba_req Frame; |
| unsigned long FrameLen; |
| struct rt_frame_bar FrameBar; |
| |
| pInfo = (struct rt_mlme_delba_req *)Elem->Msg; |
| /* must send back DELBA */ |
| NdisZeroMemory(&Frame, sizeof(struct rt_frame_delba_req)); |
| DBGPRINT(RT_DEBUG_TRACE, |
| ("==> MlmeDELBAAction(), Initiator(%d) \n", pInfo->Initiator)); |
| |
| if (MlmeDelBAReqSanity(pAd, Elem->Msg, Elem->MsgLen)) { |
| NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ |
| if (NStatus != NDIS_STATUS_SUCCESS) { |
| DBGPRINT(RT_DEBUG_ERROR, |
| ("BA - MlmeDELBAAction() allocate memory failed 1. \n")); |
| return; |
| } |
| |
| NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2); /*Get an unused nonpaged memory */ |
| if (NStatus != 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.) */ |
| Idx = |
| pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID]; |
| |
| BarHeaderInit(pAd, &FrameBar, |
| pAd->MacTab.Content[pInfo->Wcid].Addr, |
| pAd->CurrentAddress); |
| |
| 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(struct rt_frame_bar), &FrameBar, END_OF_ARGS); |
| MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer2, FrameLen); |
| MlmeFreeMemory(pAd, pOutBuffer2); |
| DBGPRINT(RT_DEBUG_TRACE, |
| ("BA - MlmeDELBAAction() . Send BAR to refresh peer reordering buffer \n")); |
| |
| /* SEND DELBA FRAME */ |
| FrameLen = 0; |
| |
| { |
| if (ADHOC_ON(pAd)) |
| ActHeaderInit(pAd, &Frame.Hdr, |
| pAd->MacTab.Content[pInfo->Wcid]. |
| Addr, pAd->CurrentAddress, |
| pAd->CommonCfg.Bssid); |
| else |
| ActHeaderInit(pAd, &Frame.Hdr, |
| pAd->CommonCfg.Bssid, |
| pAd->CurrentAddress, |
| pAd->MacTab.Content[pInfo->Wcid]. |
| Addr); |
| } |
| |
| Frame.Category = CATEGORY_BA; |
| Frame.Action = DELBA; |
| Frame.DelbaParm.Initiator = pInfo->Initiator; |
| Frame.DelbaParm.TID = pInfo->TID; |
| Frame.ReasonCode = 39; /* Time Out */ |
| *(u16 *) (&Frame.DelbaParm) = |
| cpu2le16(*(u16 *) (&Frame.DelbaParm)); |
| Frame.ReasonCode = cpu2le16(Frame.ReasonCode); |
| |
| MakeOutgoingFrame(pOutBuffer, &FrameLen, |
| sizeof(struct rt_frame_delba_req), &Frame, END_OF_ARGS); |
| MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); |
| MlmeFreeMemory(pAd, pOutBuffer); |
| DBGPRINT(RT_DEBUG_TRACE, |
| ("BA - MlmeDELBAAction() . 3 DELBA sent. Initiator(%d)\n", |
| pInfo->Initiator)); |
| } |
| } |
| |
| void MlmeQOSAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) |
| { |
| } |
| |
| void MlmeDLSAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) |
| { |
| } |
| |
| void MlmeInvalidAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) |
| { |
| /*u8 * pOutBuffer = NULL; */ |
| /*Return the receiving frame except the MSB of category filed set to 1. 7.3.1.11 */ |
| } |
| |
| void PeerQOSAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) |
| { |
| } |
| |
| void PeerBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) |
| { |
| u8 Action = Elem->Msg[LENGTH_802_11 + 1]; |
| |
| switch (Action) { |
| case ADDBA_REQ: |
| PeerAddBAReqAction(pAd, Elem); |
| break; |
| case ADDBA_RESP: |
| PeerAddBARspAction(pAd, Elem); |
| break; |
| case DELBA: |
| PeerDelBAAction(pAd, Elem); |
| break; |
| } |
| } |
| |
| void PeerPublicAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) |
| { |
| if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE) |
| return; |
| } |
| |
| static void ReservedAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) |
| { |
| u8 Category; |
| |
| if (Elem->MsgLen <= LENGTH_802_11) { |
| return; |
| } |
| |
| Category = Elem->Msg[LENGTH_802_11]; |
| DBGPRINT(RT_DEBUG_TRACE, |
| ("Rcv reserved category(%d) Action Frame\n", Category)); |
| hex_dump("Reserved Action Frame", &Elem->Msg[0], Elem->MsgLen); |
| } |
| |
| void PeerRMAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) |
| { |
| return; |
| } |
| |
| static void respond_ht_information_exchange_action(struct rt_rtmp_adapter *pAd, |
| struct rt_mlme_queue_elem *Elem) |
| { |
| u8 *pOutBuffer = NULL; |
| int NStatus; |
| unsigned long FrameLen; |
| struct rt_frame_ht_info HTINFOframe, *pFrame; |
| u8 *pAddr; |
| |
| /* 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 - respond_ht_information_exchange_action() allocate memory failed \n")); |
| return; |
| } |
| /* get RA */ |
| pFrame = (struct rt_frame_ht_info *) & Elem->Msg[0]; |
| pAddr = pFrame->Hdr.Addr2; |
| |
| NdisZeroMemory(&HTINFOframe, sizeof(struct rt_frame_ht_info)); |
| /* 2-1. Prepare ADDBA Response frame. */ |
| { |
| if (ADHOC_ON(pAd)) |
| ActHeaderInit(pAd, &HTINFOframe.Hdr, pAddr, |
| pAd->CurrentAddress, |
| pAd->CommonCfg.Bssid); |
| else |
| ActHeaderInit(pAd, &HTINFOframe.Hdr, |
| pAd->CommonCfg.Bssid, pAd->CurrentAddress, |
| pAddr); |
| } |
| |
| HTINFOframe.Category = CATEGORY_HT; |
| HTINFOframe.Action = HT_INFO_EXCHANGE; |
| HTINFOframe.HT_Info.Request = 0; |
| HTINFOframe.HT_Info.Forty_MHz_Intolerant = |
| pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant; |
| HTINFOframe.HT_Info.STA_Channel_Width = |
| pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth; |
| |
| MakeOutgoingFrame(pOutBuffer, &FrameLen, |
| sizeof(struct rt_frame_ht_info), &HTINFOframe, END_OF_ARGS); |
| |
| MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); |
| MlmeFreeMemory(pAd, pOutBuffer); |
| } |
| |
| void PeerHTAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) |
| { |
| u8 Action = Elem->Msg[LENGTH_802_11 + 1]; |
| |
| if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE) |
| return; |
| |
| switch (Action) { |
| case NOTIFY_BW_ACTION: |
| DBGPRINT(RT_DEBUG_TRACE, |
| ("ACTION - HT Notify Channel bandwidth action----> \n")); |
| |
| if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) { |
| /* Note, this is to patch DIR-1353 AP. When the AP set to Wep, it will use legacy mode. But AP still keeps */ |
| /* sending BW_Notify Action frame, and cause us to linkup and linkdown. */ |
| /* In legacy mode, don't need to parse HT action frame. */ |
| DBGPRINT(RT_DEBUG_TRACE, |
| ("ACTION -Ignore HT Notify Channel BW when link as legacy mode. BW = %d---> \n", |
| Elem->Msg[LENGTH_802_11 + 2])); |
| break; |
| } |
| |
| if (Elem->Msg[LENGTH_802_11 + 2] == 0) /* 7.4.8.2. if value is 1, keep the same as supported channel bandwidth. */ |
| pAd->MacTab.Content[Elem->Wcid].HTPhyMode.field.BW = 0; |
| |
| break; |
| case SMPS_ACTION: |
| /* 7.3.1.25 */ |
| DBGPRINT(RT_DEBUG_TRACE, ("ACTION - SMPS action----> \n")); |
| if (((Elem->Msg[LENGTH_802_11 + 2] & 0x1) == 0)) { |
| pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_ENABLE; |
| } else if (((Elem->Msg[LENGTH_802_11 + 2] & 0x2) == 0)) { |
| pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_STATIC; |
| } else { |
| pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_DYNAMIC; |
| } |
| |
| DBGPRINT(RT_DEBUG_TRACE, |
| ("Aid(%d) MIMO PS = %d\n", Elem->Wcid, |
| pAd->MacTab.Content[Elem->Wcid].MmpsMode)); |
| /* rt2860c : add something for smps change. */ |
| break; |
| |
| case SETPCO_ACTION: |
| break; |
| case MIMO_CHA_MEASURE_ACTION: |
| break; |
| case HT_INFO_EXCHANGE: |
| { |
| struct rt_ht_information_octet *pHT_info; |
| |
| pHT_info = |
| (struct rt_ht_information_octet *) & Elem->Msg[LENGTH_802_11 + |
| 2]; |
| /* 7.4.8.10 */ |
| DBGPRINT(RT_DEBUG_TRACE, |
| ("ACTION - HT Information Exchange action----> \n")); |
| if (pHT_info->Request) { |
| respond_ht_information_exchange_action(pAd, |
| Elem); |
| } |
| } |
| break; |
| } |
| } |
| |
| /* |
| ========================================================================== |
| Description: |
| Retry sending ADDBA Reqest. |
| |
| IRQL = DISPATCH_LEVEL |
| |
| Parametrs: |
| p8023Header: if this is already 802.3 format, p8023Header is NULL |
| |
| Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere. |
| FALSE , then continue indicaterx at this moment. |
| ========================================================================== |
| */ |
| void ORIBATimerTimeout(struct rt_rtmp_adapter *pAd) |
| { |
| struct rt_mac_table_entry *pEntry; |
| int i, total; |
| u8 TID; |
| |
| total = pAd->MacTab.Size * NUM_OF_TID; |
| |
| for (i = 1; ((i < MAX_LEN_OF_BA_ORI_TABLE) && (total > 0)); i++) { |
| if (pAd->BATable.BAOriEntry[i].ORI_BA_Status == Originator_Done) { |
| pEntry = |
| &pAd->MacTab.Content[pAd->BATable.BAOriEntry[i]. |
| Wcid]; |
| TID = pAd->BATable.BAOriEntry[i].TID; |
| |
| ASSERT(pAd->BATable.BAOriEntry[i].Wcid < |
| MAX_LEN_OF_MAC_TABLE); |
| } |
| total--; |
| } |
| } |
| |
| void SendRefreshBAR(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry) |
| { |
| struct rt_frame_bar FrameBar; |
| unsigned long FrameLen; |
| int NStatus; |
| u8 *pOutBuffer = NULL; |
| u16 Sequence; |
| u8 i, TID; |
| u16 idx; |
| struct rt_ba_ori_entry *pBAEntry; |
| |
| for (i = 0; i < NUM_OF_TID; i++) { |
| idx = pEntry->BAOriWcidArray[i]; |
| if (idx == 0) { |
| continue; |
| } |
| pBAEntry = &pAd->BATable.BAOriEntry[idx]; |
| |
| if (pBAEntry->ORI_BA_Status == Originator_Done) { |
| TID = pBAEntry->TID; |
| |
| ASSERT(pBAEntry->Wcid < MAX_LEN_OF_MAC_TABLE); |
| |
| 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; |
| } |
| |
| Sequence = pEntry->TxSeq[TID]; |
| |
| BarHeaderInit(pAd, &FrameBar, pEntry->Addr, |
| pAd->CurrentAddress); |
| |
| FrameBar.StartingSeq.field.FragNum = 0; /* make sure sequence not clear in DEL function. */ |
| FrameBar.StartingSeq.field.StartSeq = Sequence; /* make sure sequence not clear in DEL funciton. */ |
| FrameBar.BarControl.TID = TID; /* make sure sequence not clear in DEL funciton. */ |
| |
| MakeOutgoingFrame(pOutBuffer, &FrameLen, |
| sizeof(struct rt_frame_bar), &FrameBar, |
| END_OF_ARGS); |
| /*if (!(CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET))) */ |
| if (1) /* Now we always send BAR. */ |
| { |
| /*MiniportMMRequestUnlock(pAd, 0, pOutBuffer, FrameLen); */ |
| MiniportMMRequest(pAd, |
| (MGMT_USE_QUEUE_FLAG | |
| MapUserPriorityToAccessCategory |
| [TID]), pOutBuffer, |
| FrameLen); |
| |
| } |
| MlmeFreeMemory(pAd, pOutBuffer); |
| } |
| } |
| } |
| |
| void ActHeaderInit(struct rt_rtmp_adapter *pAd, |
| struct rt_header_802_11 * pHdr80211, |
| u8 *Addr1, u8 *Addr2, u8 *Addr3) |
| { |
| NdisZeroMemory(pHdr80211, sizeof(struct rt_header_802_11)); |
| pHdr80211->FC.Type = BTYPE_MGMT; |
| pHdr80211->FC.SubType = SUBTYPE_ACTION; |
| |
| COPY_MAC_ADDR(pHdr80211->Addr1, Addr1); |
| COPY_MAC_ADDR(pHdr80211->Addr2, Addr2); |
| COPY_MAC_ADDR(pHdr80211->Addr3, Addr3); |
| } |
| |
| void BarHeaderInit(struct rt_rtmp_adapter *pAd, |
| struct rt_frame_bar * pCntlBar, u8 *pDA, u8 *pSA) |
| { |
| NdisZeroMemory(pCntlBar, sizeof(struct rt_frame_bar)); |
| pCntlBar->FC.Type = BTYPE_CNTL; |
| pCntlBar->FC.SubType = SUBTYPE_BLOCK_ACK_REQ; |
| pCntlBar->BarControl.MTID = 0; |
| pCntlBar->BarControl.Compressed = 1; |
| pCntlBar->BarControl.ACKPolicy = 0; |
| |
| pCntlBar->Duration = |
| 16 + RTMPCalcDuration(pAd, RATE_1, sizeof(struct rt_frame_ba)); |
| |
| COPY_MAC_ADDR(pCntlBar->Addr1, pDA); |
| COPY_MAC_ADDR(pCntlBar->Addr2, pSA); |
| } |
| |
| /* |
| ========================================================================== |
| Description: |
| Insert Category and action code into the action frame. |
| |
| Parametrs: |
| 1. frame buffer pointer. |
| 2. frame length. |
| 3. category code of the frame. |
| 4. action code of the frame. |
| |
| Return : None. |
| ========================================================================== |
| */ |
| void InsertActField(struct rt_rtmp_adapter *pAd, |
| u8 *pFrameBuf, |
| unsigned long *pFrameLen, u8 Category, u8 ActCode) |
| { |
| unsigned long TempLen; |
| |
| MakeOutgoingFrame(pFrameBuf, &TempLen, |
| 1, &Category, 1, &ActCode, END_OF_ARGS); |
| |
| *pFrameLen = *pFrameLen + TempLen; |
| |
| return; |
| } |