1/* 2 ************************************************************************* 3 * Ralink Tech Inc. 4 * 5F., No.36, Taiyuan St., Jhubei City, 5 * Hsinchu County 302, 6 * Taiwan, R.O.C. 7 * 8 * (c) Copyright 2002-2007, Ralink Technology, Inc. 9 * 10 * This program is free software; you can redistribute it and/or modify * 11 * it under the terms of the GNU General Public License as published by * 12 * the Free Software Foundation; either version 2 of the License, or * 13 * (at your option) any later version. * 14 * * 15 * This program is distributed in the hope that it will be useful, * 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 18 * GNU General Public License for more details. * 19 * * 20 * You should have received a copy of the GNU General Public License * 21 * along with this program; if not, write to the * 22 * Free Software Foundation, Inc., * 23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 24 * * 25 ************************************************************************* 26 27 Module Name: 28 action.c 29 30 Abstract: 31 Handle association related requests either from WSTA or from local MLME 32 33 Revision History: 34 Who When What 35 -------- ---------- ---------------------------------------------- 36 Jan Lee 2006 created for rt2860 37 */ 38 39#include "../rt_config.h" 40#include "action.h" 41 42static void ReservedAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); 43 44/* 45 ========================================================================== 46 Description: 47 association state machine init, including state transition and timer init 48 Parameters: 49 S - pointer to the association state machine 50 Note: 51 The state machine looks like the following 52 53 ASSOC_IDLE 54 MT2_MLME_DISASSOC_REQ mlme_disassoc_req_action 55 MT2_PEER_DISASSOC_REQ peer_disassoc_action 56 MT2_PEER_ASSOC_REQ drop 57 MT2_PEER_REASSOC_REQ drop 58 MT2_CLS3ERR cls3err_action 59 ========================================================================== 60 */ 61void ActionStateMachineInit(struct rt_rtmp_adapter *pAd, 62 struct rt_state_machine *S, 63 OUT STATE_MACHINE_FUNC Trans[]) 64{ 65 StateMachineInit(S, (STATE_MACHINE_FUNC *) Trans, MAX_ACT_STATE, 66 MAX_ACT_MSG, (STATE_MACHINE_FUNC) Drop, ACT_IDLE, 67 ACT_MACHINE_BASE); 68 69 StateMachineSetAction(S, ACT_IDLE, MT2_PEER_SPECTRUM_CATE, 70 (STATE_MACHINE_FUNC) PeerSpectrumAction); 71 StateMachineSetAction(S, ACT_IDLE, MT2_PEER_QOS_CATE, 72 (STATE_MACHINE_FUNC) PeerQOSAction); 73 74 StateMachineSetAction(S, ACT_IDLE, MT2_PEER_DLS_CATE, 75 (STATE_MACHINE_FUNC) ReservedAction); 76 77 StateMachineSetAction(S, ACT_IDLE, MT2_PEER_BA_CATE, 78 (STATE_MACHINE_FUNC) PeerBAAction); 79 StateMachineSetAction(S, ACT_IDLE, MT2_PEER_HT_CATE, 80 (STATE_MACHINE_FUNC) PeerHTAction); 81 StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ADD_BA_CATE, 82 (STATE_MACHINE_FUNC) MlmeADDBAAction); 83 StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ORI_DELBA_CATE, 84 (STATE_MACHINE_FUNC) MlmeDELBAAction); 85 StateMachineSetAction(S, ACT_IDLE, MT2_MLME_REC_DELBA_CATE, 86 (STATE_MACHINE_FUNC) MlmeDELBAAction); 87 88 StateMachineSetAction(S, ACT_IDLE, MT2_PEER_PUBLIC_CATE, 89 (STATE_MACHINE_FUNC) PeerPublicAction); 90 StateMachineSetAction(S, ACT_IDLE, MT2_PEER_RM_CATE, 91 (STATE_MACHINE_FUNC) PeerRMAction); 92 93 StateMachineSetAction(S, ACT_IDLE, MT2_MLME_QOS_CATE, 94 (STATE_MACHINE_FUNC) MlmeQOSAction); 95 StateMachineSetAction(S, ACT_IDLE, MT2_MLME_DLS_CATE, 96 (STATE_MACHINE_FUNC) MlmeDLSAction); 97 StateMachineSetAction(S, ACT_IDLE, MT2_ACT_INVALID, 98 (STATE_MACHINE_FUNC) MlmeInvalidAction); 99} 100 101void MlmeADDBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) 102{ 103 struct rt_mlme_addba_req *pInfo; 104 u8 Addr[6]; 105 u8 *pOutBuffer = NULL; 106 int NStatus; 107 unsigned long Idx; 108 struct rt_frame_addba_req Frame; 109 unsigned long FrameLen; 110 struct rt_ba_ori_entry *pBAEntry = NULL; 111 112 pInfo = (struct rt_mlme_addba_req *)Elem->Msg; 113 NdisZeroMemory(&Frame, sizeof(struct rt_frame_addba_req)); 114 115 if (MlmeAddBAReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr)) { 116 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ 117 if (NStatus != NDIS_STATUS_SUCCESS) { 118 DBGPRINT(RT_DEBUG_TRACE, 119 ("BA - MlmeADDBAAction() allocate memory failed \n")); 120 return; 121 } 122 /* 1. find entry */ 123 Idx = 124 pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID]; 125 if (Idx == 0) { 126 MlmeFreeMemory(pAd, pOutBuffer); 127 DBGPRINT(RT_DEBUG_ERROR, 128 ("BA - MlmeADDBAAction() can't find BAOriEntry \n")); 129 return; 130 } else { 131 pBAEntry = &pAd->BATable.BAOriEntry[Idx]; 132 } 133 134 { 135 if (ADHOC_ON(pAd)) 136 ActHeaderInit(pAd, &Frame.Hdr, pInfo->pAddr, 137 pAd->CurrentAddress, 138 pAd->CommonCfg.Bssid); 139 else 140 ActHeaderInit(pAd, &Frame.Hdr, 141 pAd->CommonCfg.Bssid, 142 pAd->CurrentAddress, 143 pInfo->pAddr); 144 } 145 146 Frame.Category = CATEGORY_BA; 147 Frame.Action = ADDBA_REQ; 148 Frame.BaParm.AMSDUSupported = 0; 149 Frame.BaParm.BAPolicy = IMMED_BA; 150 Frame.BaParm.TID = pInfo->TID; 151 Frame.BaParm.BufSize = pInfo->BaBufSize; 152 Frame.Token = pInfo->Token; 153 Frame.TimeOutValue = pInfo->TimeOutValue; 154 Frame.BaStartSeq.field.FragNum = 0; 155 Frame.BaStartSeq.field.StartSeq = 156 pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID]; 157 158 *(u16 *) (&Frame.BaParm) = 159 cpu2le16(*(u16 *) (&Frame.BaParm)); 160 Frame.TimeOutValue = cpu2le16(Frame.TimeOutValue); 161 Frame.BaStartSeq.word = cpu2le16(Frame.BaStartSeq.word); 162 163 MakeOutgoingFrame(pOutBuffer, &FrameLen, 164 sizeof(struct rt_frame_addba_req), &Frame, END_OF_ARGS); 165 166 MiniportMMRequest(pAd, 167 (MGMT_USE_QUEUE_FLAG | 168 MapUserPriorityToAccessCategory[pInfo->TID]), 169 pOutBuffer, FrameLen); 170 171 MlmeFreeMemory(pAd, pOutBuffer); 172 173 DBGPRINT(RT_DEBUG_TRACE, 174 ("BA - Send ADDBA request. StartSeq = %x, FrameLen = %ld. BufSize = %d\n", 175 Frame.BaStartSeq.field.StartSeq, FrameLen, 176 Frame.BaParm.BufSize)); 177 } 178} 179 180/* 181 ========================================================================== 182 Description: 183 send DELBA and delete BaEntry if any 184 Parametrs: 185 Elem - MLME message struct rt_mlme_delba_req 186 187 IRQL = DISPATCH_LEVEL 188 189 ========================================================================== 190 */ 191void MlmeDELBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) 192{ 193 struct rt_mlme_delba_req *pInfo; 194 u8 *pOutBuffer = NULL; 195 u8 *pOutBuffer2 = NULL; 196 int NStatus; 197 unsigned long Idx; 198 struct rt_frame_delba_req Frame; 199 unsigned long FrameLen; 200 struct rt_frame_bar FrameBar; 201 202 pInfo = (struct rt_mlme_delba_req *)Elem->Msg; 203 /* must send back DELBA */ 204 NdisZeroMemory(&Frame, sizeof(struct rt_frame_delba_req)); 205 DBGPRINT(RT_DEBUG_TRACE, 206 ("==> MlmeDELBAAction(), Initiator(%d) \n", pInfo->Initiator)); 207 208 if (MlmeDelBAReqSanity(pAd, Elem->Msg, Elem->MsgLen)) { 209 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ 210 if (NStatus != NDIS_STATUS_SUCCESS) { 211 DBGPRINT(RT_DEBUG_ERROR, 212 ("BA - MlmeDELBAAction() allocate memory failed 1. \n")); 213 return; 214 } 215 216 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2); /*Get an unused nonpaged memory */ 217 if (NStatus != NDIS_STATUS_SUCCESS) { 218 MlmeFreeMemory(pAd, pOutBuffer); 219 DBGPRINT(RT_DEBUG_ERROR, 220 ("BA - MlmeDELBAAction() allocate memory failed 2. \n")); 221 return; 222 } 223 /* SEND BAR (Send BAR to refresh peer reordering buffer.) */ 224 Idx = 225 pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID]; 226 227 BarHeaderInit(pAd, &FrameBar, 228 pAd->MacTab.Content[pInfo->Wcid].Addr, 229 pAd->CurrentAddress); 230 231 FrameBar.StartingSeq.field.FragNum = 0; /* make sure sequence not clear in DEL funciton. */ 232 FrameBar.StartingSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID]; /* make sure sequence not clear in DEL funciton. */ 233 FrameBar.BarControl.TID = pInfo->TID; /* make sure sequence not clear in DEL funciton. */ 234 FrameBar.BarControl.ACKPolicy = IMMED_BA; /* make sure sequence not clear in DEL funciton. */ 235 FrameBar.BarControl.Compressed = 1; /* make sure sequence not clear in DEL funciton. */ 236 FrameBar.BarControl.MTID = 0; /* make sure sequence not clear in DEL funciton. */ 237 238 MakeOutgoingFrame(pOutBuffer2, &FrameLen, 239 sizeof(struct rt_frame_bar), &FrameBar, END_OF_ARGS); 240 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer2, FrameLen); 241 MlmeFreeMemory(pAd, pOutBuffer2); 242 DBGPRINT(RT_DEBUG_TRACE, 243 ("BA - MlmeDELBAAction() . Send BAR to refresh peer reordering buffer \n")); 244 245 /* SEND DELBA FRAME */ 246 FrameLen = 0; 247 248 { 249 if (ADHOC_ON(pAd)) 250 ActHeaderInit(pAd, &Frame.Hdr, 251 pAd->MacTab.Content[pInfo->Wcid]. 252 Addr, pAd->CurrentAddress, 253 pAd->CommonCfg.Bssid); 254 else 255 ActHeaderInit(pAd, &Frame.Hdr, 256 pAd->CommonCfg.Bssid, 257 pAd->CurrentAddress, 258 pAd->MacTab.Content[pInfo->Wcid]. 259 Addr); 260 } 261 262 Frame.Category = CATEGORY_BA; 263 Frame.Action = DELBA; 264 Frame.DelbaParm.Initiator = pInfo->Initiator; 265 Frame.DelbaParm.TID = pInfo->TID; 266 Frame.ReasonCode = 39; /* Time Out */ 267 *(u16 *) (&Frame.DelbaParm) = 268 cpu2le16(*(u16 *) (&Frame.DelbaParm)); 269 Frame.ReasonCode = cpu2le16(Frame.ReasonCode); 270 271 MakeOutgoingFrame(pOutBuffer, &FrameLen, 272 sizeof(struct rt_frame_delba_req), &Frame, END_OF_ARGS); 273 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); 274 MlmeFreeMemory(pAd, pOutBuffer); 275 DBGPRINT(RT_DEBUG_TRACE, 276 ("BA - MlmeDELBAAction() . 3 DELBA sent. Initiator(%d)\n", 277 pInfo->Initiator)); 278 } 279} 280 281void MlmeQOSAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) 282{ 283} 284 285void MlmeDLSAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) 286{ 287} 288 289void MlmeInvalidAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) 290{ 291 /*u8 * pOutBuffer = NULL; */ 292 /*Return the receiving frame except the MSB of category filed set to 1. 7.3.1.11 */ 293} 294 295void PeerQOSAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) 296{ 297} 298 299void PeerBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) 300{ 301 u8 Action = Elem->Msg[LENGTH_802_11 + 1]; 302 303 switch (Action) { 304 case ADDBA_REQ: 305 PeerAddBAReqAction(pAd, Elem); 306 break; 307 case ADDBA_RESP: 308 PeerAddBARspAction(pAd, Elem); 309 break; 310 case DELBA: 311 PeerDelBAAction(pAd, Elem); 312 break; 313 } 314} 315 316void PeerPublicAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) 317{ 318 if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE) 319 return; 320} 321 322static void ReservedAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) 323{ 324 u8 Category; 325 326 if (Elem->MsgLen <= LENGTH_802_11) { 327 return; 328 } 329 330 Category = Elem->Msg[LENGTH_802_11]; 331 DBGPRINT(RT_DEBUG_TRACE, 332 ("Rcv reserved category(%d) Action Frame\n", Category)); 333 hex_dump("Reserved Action Frame", &Elem->Msg[0], Elem->MsgLen); 334} 335 336void PeerRMAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) 337{ 338 return; 339} 340 341static void respond_ht_information_exchange_action(struct rt_rtmp_adapter *pAd, 342 struct rt_mlme_queue_elem *Elem) 343{ 344 u8 *pOutBuffer = NULL; 345 int NStatus; 346 unsigned long FrameLen; 347 struct rt_frame_ht_info HTINFOframe, *pFrame; 348 u8 *pAddr; 349 350 /* 2. Always send back ADDBA Response */ 351 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ 352 353 if (NStatus != NDIS_STATUS_SUCCESS) { 354 DBGPRINT(RT_DEBUG_TRACE, 355 ("ACTION - respond_ht_information_exchange_action() allocate memory failed \n")); 356 return; 357 } 358 /* get RA */ 359 pFrame = (struct rt_frame_ht_info *) & Elem->Msg[0]; 360 pAddr = pFrame->Hdr.Addr2; 361 362 NdisZeroMemory(&HTINFOframe, sizeof(struct rt_frame_ht_info)); 363 /* 2-1. Prepare ADDBA Response frame. */ 364 { 365 if (ADHOC_ON(pAd)) 366 ActHeaderInit(pAd, &HTINFOframe.Hdr, pAddr, 367 pAd->CurrentAddress, 368 pAd->CommonCfg.Bssid); 369 else 370 ActHeaderInit(pAd, &HTINFOframe.Hdr, 371 pAd->CommonCfg.Bssid, pAd->CurrentAddress, 372 pAddr); 373 } 374 375 HTINFOframe.Category = CATEGORY_HT; 376 HTINFOframe.Action = HT_INFO_EXCHANGE; 377 HTINFOframe.HT_Info.Request = 0; 378 HTINFOframe.HT_Info.Forty_MHz_Intolerant = 379 pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant; 380 HTINFOframe.HT_Info.STA_Channel_Width = 381 pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth; 382 383 MakeOutgoingFrame(pOutBuffer, &FrameLen, 384 sizeof(struct rt_frame_ht_info), &HTINFOframe, END_OF_ARGS); 385 386 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); 387 MlmeFreeMemory(pAd, pOutBuffer); 388} 389 390void PeerHTAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) 391{ 392 u8 Action = Elem->Msg[LENGTH_802_11 + 1]; 393 394 if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE) 395 return; 396 397 switch (Action) { 398 case NOTIFY_BW_ACTION: 399 DBGPRINT(RT_DEBUG_TRACE, 400 ("ACTION - HT Notify Channel bandwidth action----> \n")); 401 402 if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) { 403 /* Note, this is to patch DIR-1353 AP. When the AP set to Wep, it will use legacy mode. But AP still keeps */ 404 /* sending BW_Notify Action frame, and cause us to linkup and linkdown. */ 405 /* In legacy mode, don't need to parse HT action frame. */ 406 DBGPRINT(RT_DEBUG_TRACE, 407 ("ACTION -Ignore HT Notify Channel BW when link as legacy mode. BW = %d---> \n", 408 Elem->Msg[LENGTH_802_11 + 2])); 409 break; 410 } 411 412 if (Elem->Msg[LENGTH_802_11 + 2] == 0) /* 7.4.8.2. if value is 1, keep the same as supported channel bandwidth. */ 413 pAd->MacTab.Content[Elem->Wcid].HTPhyMode.field.BW = 0; 414 415 break; 416 case SMPS_ACTION: 417 /* 7.3.1.25 */ 418 DBGPRINT(RT_DEBUG_TRACE, ("ACTION - SMPS action----> \n")); 419 if (((Elem->Msg[LENGTH_802_11 + 2] & 0x1) == 0)) { 420 pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_ENABLE; 421 } else if (((Elem->Msg[LENGTH_802_11 + 2] & 0x2) == 0)) { 422 pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_STATIC; 423 } else { 424 pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_DYNAMIC; 425 } 426 427 DBGPRINT(RT_DEBUG_TRACE, 428 ("Aid(%d) MIMO PS = %d\n", Elem->Wcid, 429 pAd->MacTab.Content[Elem->Wcid].MmpsMode)); 430 /* rt2860c : add something for smps change. */ 431 break; 432 433 case SETPCO_ACTION: 434 break; 435 case MIMO_CHA_MEASURE_ACTION: 436 break; 437 case HT_INFO_EXCHANGE: 438 { 439 struct rt_ht_information_octet *pHT_info; 440 441 pHT_info = 442 (struct rt_ht_information_octet *) & Elem->Msg[LENGTH_802_11 + 443 2]; 444 /* 7.4.8.10 */ 445 DBGPRINT(RT_DEBUG_TRACE, 446 ("ACTION - HT Information Exchange action----> \n")); 447 if (pHT_info->Request) { 448 respond_ht_information_exchange_action(pAd, 449 Elem); 450 } 451 } 452 break; 453 } 454} 455 456/* 457 ========================================================================== 458 Description: 459 Retry sending ADDBA Reqest. 460 461 IRQL = DISPATCH_LEVEL 462 463 Parametrs: 464 p8023Header: if this is already 802.3 format, p8023Header is NULL 465 466 Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere. 467 FALSE , then continue indicaterx at this moment. 468 ========================================================================== 469 */ 470void ORIBATimerTimeout(struct rt_rtmp_adapter *pAd) 471{ 472 struct rt_mac_table_entry *pEntry; 473 int i, total; 474 u8 TID; 475 476 total = pAd->MacTab.Size * NUM_OF_TID; 477 478 for (i = 1; ((i < MAX_LEN_OF_BA_ORI_TABLE) && (total > 0)); i++) { 479 if (pAd->BATable.BAOriEntry[i].ORI_BA_Status == Originator_Done) { 480 pEntry = 481 &pAd->MacTab.Content[pAd->BATable.BAOriEntry[i]. 482 Wcid]; 483 TID = pAd->BATable.BAOriEntry[i].TID; 484 485 ASSERT(pAd->BATable.BAOriEntry[i].Wcid < 486 MAX_LEN_OF_MAC_TABLE); 487 } 488 total--; 489 } 490} 491 492void SendRefreshBAR(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry) 493{ 494 struct rt_frame_bar FrameBar; 495 unsigned long FrameLen; 496 int NStatus; 497 u8 *pOutBuffer = NULL; 498 u16 Sequence; 499 u8 i, TID; 500 u16 idx; 501 struct rt_ba_ori_entry *pBAEntry; 502 503 for (i = 0; i < NUM_OF_TID; i++) { 504 idx = pEntry->BAOriWcidArray[i]; 505 if (idx == 0) { 506 continue; 507 } 508 pBAEntry = &pAd->BATable.BAOriEntry[idx]; 509 510 if (pBAEntry->ORI_BA_Status == Originator_Done) { 511 TID = pBAEntry->TID; 512 513 ASSERT(pBAEntry->Wcid < MAX_LEN_OF_MAC_TABLE); 514 515 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ 516 if (NStatus != NDIS_STATUS_SUCCESS) { 517 DBGPRINT(RT_DEBUG_ERROR, 518 ("BA - MlmeADDBAAction() allocate memory failed \n")); 519 return; 520 } 521 522 Sequence = pEntry->TxSeq[TID]; 523 524 BarHeaderInit(pAd, &FrameBar, pEntry->Addr, 525 pAd->CurrentAddress); 526 527 FrameBar.StartingSeq.field.FragNum = 0; /* make sure sequence not clear in DEL function. */ 528 FrameBar.StartingSeq.field.StartSeq = Sequence; /* make sure sequence not clear in DEL funciton. */ 529 FrameBar.BarControl.TID = TID; /* make sure sequence not clear in DEL funciton. */ 530 531 MakeOutgoingFrame(pOutBuffer, &FrameLen, 532 sizeof(struct rt_frame_bar), &FrameBar, 533 END_OF_ARGS); 534 /*if (!(CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET))) */ 535 if (1) /* Now we always send BAR. */ 536 { 537 /*MiniportMMRequestUnlock(pAd, 0, pOutBuffer, FrameLen); */ 538 MiniportMMRequest(pAd, 539 (MGMT_USE_QUEUE_FLAG | 540 MapUserPriorityToAccessCategory 541 [TID]), pOutBuffer, 542 FrameLen); 543 544 } 545 MlmeFreeMemory(pAd, pOutBuffer); 546 } 547 } 548} 549 550void ActHeaderInit(struct rt_rtmp_adapter *pAd, 551 struct rt_header_802_11 * pHdr80211, 552 u8 *Addr1, u8 *Addr2, u8 *Addr3) 553{ 554 NdisZeroMemory(pHdr80211, sizeof(struct rt_header_802_11)); 555 pHdr80211->FC.Type = BTYPE_MGMT; 556 pHdr80211->FC.SubType = SUBTYPE_ACTION; 557 558 COPY_MAC_ADDR(pHdr80211->Addr1, Addr1); 559 COPY_MAC_ADDR(pHdr80211->Addr2, Addr2); 560 COPY_MAC_ADDR(pHdr80211->Addr3, Addr3); 561} 562 563void BarHeaderInit(struct rt_rtmp_adapter *pAd, 564 struct rt_frame_bar * pCntlBar, u8 *pDA, u8 *pSA) 565{ 566 NdisZeroMemory(pCntlBar, sizeof(struct rt_frame_bar)); 567 pCntlBar->FC.Type = BTYPE_CNTL; 568 pCntlBar->FC.SubType = SUBTYPE_BLOCK_ACK_REQ; 569 pCntlBar->BarControl.MTID = 0; 570 pCntlBar->BarControl.Compressed = 1; 571 pCntlBar->BarControl.ACKPolicy = 0; 572 573 pCntlBar->Duration = 574 16 + RTMPCalcDuration(pAd, RATE_1, sizeof(struct rt_frame_ba)); 575 576 COPY_MAC_ADDR(pCntlBar->Addr1, pDA); 577 COPY_MAC_ADDR(pCntlBar->Addr2, pSA); 578} 579 580/* 581 ========================================================================== 582 Description: 583 Insert Category and action code into the action frame. 584 585 Parametrs: 586 1. frame buffer pointer. 587 2. frame length. 588 3. category code of the frame. 589 4. action code of the frame. 590 591 Return : None. 592 ========================================================================== 593 */ 594void InsertActField(struct rt_rtmp_adapter *pAd, 595 u8 *pFrameBuf, 596 unsigned long *pFrameLen, u8 Category, u8 ActCode) 597{ 598 unsigned long TempLen; 599 600 MakeOutgoingFrame(pFrameBuf, &TempLen, 601 1, &Category, 1, &ActCode, END_OF_ARGS); 602 603 *pFrameLen = *pFrameLen + TempLen; 604 605 return; 606} 607