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 28#ifdef RTMP_MAC_USB 29 30#include "../rt_config.h" 31 32/* 33======================================================================== 34Routine Description: 35 Initialize receive data structures. 36 37Arguments: 38 pAd Pointer to our adapter 39 40Return Value: 41 NDIS_STATUS_SUCCESS 42 NDIS_STATUS_RESOURCES 43 44Note: 45 Initialize all receive releated private buffer, include those define 46 in struct rt_rtmp_adapter structure and all private data structures. The mahor 47 work is to allocate buffer for each packet and chain buffer to 48 NDIS packet descriptor. 49======================================================================== 50*/ 51int NICInitRecv(struct rt_rtmp_adapter *pAd) 52{ 53 u8 i; 54 int Status = NDIS_STATUS_SUCCESS; 55 struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie; 56 57 DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitRecv\n")); 58 pObj = pObj; 59 60 /*InterlockedExchange(&pAd->PendingRx, 0); */ 61 pAd->PendingRx = 0; 62 pAd->NextRxBulkInReadIndex = 0; /* Next Rx Read index */ 63 pAd->NextRxBulkInIndex = 0; /*RX_RING_SIZE -1; // Rx Bulk pointer */ 64 pAd->NextRxBulkInPosition = 0; 65 66 for (i = 0; i < (RX_RING_SIZE); i++) { 67 struct rt_rx_context *pRxContext = &(pAd->RxContext[i]); 68 69 /*Allocate URB */ 70 pRxContext->pUrb = RTUSB_ALLOC_URB(0); 71 if (pRxContext->pUrb == NULL) { 72 Status = NDIS_STATUS_RESOURCES; 73 goto out1; 74 } 75 /* Allocate transfer buffer */ 76 pRxContext->TransferBuffer = 77 RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE, 78 &pRxContext->data_dma); 79 if (pRxContext->TransferBuffer == NULL) { 80 Status = NDIS_STATUS_RESOURCES; 81 goto out1; 82 } 83 84 NdisZeroMemory(pRxContext->TransferBuffer, MAX_RXBULK_SIZE); 85 86 pRxContext->pAd = pAd; 87 pRxContext->pIrp = NULL; 88 pRxContext->InUse = FALSE; 89 pRxContext->IRPPending = FALSE; 90 pRxContext->Readable = FALSE; 91 /*pRxContext->ReorderInUse = FALSE; */ 92 pRxContext->bRxHandling = FALSE; 93 pRxContext->BulkInOffset = 0; 94 } 95 96 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitRecv(Status=%d)\n", Status)); 97 return Status; 98 99out1: 100 for (i = 0; i < (RX_RING_SIZE); i++) { 101 struct rt_rx_context *pRxContext = &(pAd->RxContext[i]); 102 103 if (NULL != pRxContext->TransferBuffer) { 104 RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE, 105 pRxContext->TransferBuffer, 106 pRxContext->data_dma); 107 pRxContext->TransferBuffer = NULL; 108 } 109 110 if (NULL != pRxContext->pUrb) { 111 RTUSB_UNLINK_URB(pRxContext->pUrb); 112 RTUSB_FREE_URB(pRxContext->pUrb); 113 pRxContext->pUrb = NULL; 114 } 115 } 116 117 return Status; 118} 119 120/* 121======================================================================== 122Routine Description: 123 Initialize transmit data structures. 124 125Arguments: 126 pAd Pointer to our adapter 127 128Return Value: 129 NDIS_STATUS_SUCCESS 130 NDIS_STATUS_RESOURCES 131 132Note: 133======================================================================== 134*/ 135int NICInitTransmit(struct rt_rtmp_adapter *pAd) 136{ 137#define LM_USB_ALLOC(pObj, Context, TB_Type, BufferSize, Status, msg1, err1, msg2, err2) \ 138 Context->pUrb = RTUSB_ALLOC_URB(0); \ 139 if (Context->pUrb == NULL) { \ 140 DBGPRINT(RT_DEBUG_ERROR, msg1); \ 141 Status = NDIS_STATUS_RESOURCES; \ 142 goto err1; } \ 143 \ 144 Context->TransferBuffer = \ 145 (TB_Type)RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, BufferSize, &Context->data_dma); \ 146 if (Context->TransferBuffer == NULL) { \ 147 DBGPRINT(RT_DEBUG_ERROR, msg2); \ 148 Status = NDIS_STATUS_RESOURCES; \ 149 goto err2; } 150 151#define LM_URB_FREE(pObj, Context, BufferSize) \ 152 if (NULL != Context->pUrb) { \ 153 RTUSB_UNLINK_URB(Context->pUrb); \ 154 RTUSB_FREE_URB(Context->pUrb); \ 155 Context->pUrb = NULL; } \ 156 if (NULL != Context->TransferBuffer) { \ 157 RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize, \ 158 Context->TransferBuffer, \ 159 Context->data_dma); \ 160 Context->TransferBuffer = NULL; } 161 162 u8 i, acidx; 163 int Status = NDIS_STATUS_SUCCESS; 164 struct rt_tx_context *pNullContext = &(pAd->NullContext); 165 struct rt_tx_context *pPsPollContext = &(pAd->PsPollContext); 166 struct rt_tx_context *pRTSContext = &(pAd->RTSContext); 167 struct rt_tx_context *pMLMEContext = NULL; 168/* struct rt_ht_tx_context *pHTTXContext = NULL; */ 169 struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie; 170 void *RingBaseVa; 171/* struct rt_rtmp_tx_ring *pTxRing; */ 172 struct rt_rtmp_mgmt_ring *pMgmtRing; 173 174 DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitTransmit\n")); 175 pObj = pObj; 176 177 /* Init 4 set of Tx parameters */ 178 for (acidx = 0; acidx < NUM_OF_TX_RING; acidx++) { 179 /* Initialize all Transmit releated queues */ 180 InitializeQueueHeader(&pAd->TxSwQueue[acidx]); 181 182 /* Next Local tx ring pointer waiting for buck out */ 183 pAd->NextBulkOutIndex[acidx] = acidx; 184 pAd->BulkOutPending[acidx] = FALSE; /* Buck Out control flag */ 185 /*pAd->DataBulkDoneIdx[acidx] = 0; */ 186 } 187 188 /*pAd->NextMLMEIndex = 0; */ 189 /*pAd->PushMgmtIndex = 0; */ 190 /*pAd->PopMgmtIndex = 0; */ 191 /*InterlockedExchange(&pAd->MgmtQueueSize, 0); */ 192 /*InterlockedExchange(&pAd->TxCount, 0); */ 193 194 /*pAd->PrioRingFirstIndex = 0; */ 195 /*pAd->PrioRingTxCnt = 0; */ 196 197 do { 198 /* */ 199 /* TX_RING_SIZE, 4 ACs */ 200 /* */ 201 for (acidx = 0; acidx < 4; acidx++) { 202 struct rt_ht_tx_context *pHTTXContext = &(pAd->TxContext[acidx]); 203 204 NdisZeroMemory(pHTTXContext, sizeof(struct rt_ht_tx_context)); 205 /*Allocate URB */ 206 LM_USB_ALLOC(pObj, pHTTXContext, struct rt_httx_buffer *, 207 sizeof(struct rt_httx_buffer), Status, 208 ("<-- ERROR in Alloc TX TxContext[%d] urb!\n", 209 acidx), done, 210 ("<-- ERROR in Alloc TX TxContext[%d] struct rt_httx_buffer!\n", 211 acidx), out1); 212 213 NdisZeroMemory(pHTTXContext->TransferBuffer-> 214 Aggregation, 4); 215 pHTTXContext->pAd = pAd; 216 pHTTXContext->pIrp = NULL; 217 pHTTXContext->IRPPending = FALSE; 218 pHTTXContext->NextBulkOutPosition = 0; 219 pHTTXContext->ENextBulkOutPosition = 0; 220 pHTTXContext->CurWritePosition = 0; 221 pHTTXContext->CurWriteRealPos = 0; 222 pHTTXContext->BulkOutSize = 0; 223 pHTTXContext->BulkOutPipeId = acidx; 224 pHTTXContext->bRingEmpty = TRUE; 225 pHTTXContext->bCopySavePad = FALSE; 226 pAd->BulkOutPending[acidx] = FALSE; 227 } 228 229 /* */ 230 /* MGMT_RING_SIZE */ 231 /* */ 232 233 /* Allocate MGMT ring descriptor's memory */ 234 pAd->MgmtDescRing.AllocSize = 235 MGMT_RING_SIZE * sizeof(struct rt_tx_context); 236 os_alloc_mem(pAd, (u8 **) (&pAd->MgmtDescRing.AllocVa), 237 pAd->MgmtDescRing.AllocSize); 238 if (pAd->MgmtDescRing.AllocVa == NULL) { 239 DBGPRINT_ERR(("Failed to allocate a big buffer for MgmtDescRing!\n")); 240 Status = NDIS_STATUS_RESOURCES; 241 goto out1; 242 } 243 NdisZeroMemory(pAd->MgmtDescRing.AllocVa, 244 pAd->MgmtDescRing.AllocSize); 245 RingBaseVa = pAd->MgmtDescRing.AllocVa; 246 247 /* Initialize MGMT Ring and associated buffer memory */ 248 pMgmtRing = &pAd->MgmtRing; 249 for (i = 0; i < MGMT_RING_SIZE; i++) { 250 /* link the pre-allocated Mgmt buffer to MgmtRing.Cell */ 251 pMgmtRing->Cell[i].AllocSize = sizeof(struct rt_tx_context); 252 pMgmtRing->Cell[i].AllocVa = RingBaseVa; 253 pMgmtRing->Cell[i].pNdisPacket = NULL; 254 pMgmtRing->Cell[i].pNextNdisPacket = NULL; 255 256 /*Allocate URB for MLMEContext */ 257 pMLMEContext = 258 (struct rt_tx_context *)pAd->MgmtRing.Cell[i].AllocVa; 259 pMLMEContext->pUrb = RTUSB_ALLOC_URB(0); 260 if (pMLMEContext->pUrb == NULL) { 261 DBGPRINT(RT_DEBUG_ERROR, 262 ("<-- ERROR in Alloc TX MLMEContext[%d] urb!\n", 263 i)); 264 Status = NDIS_STATUS_RESOURCES; 265 goto out2; 266 } 267 pMLMEContext->pAd = pAd; 268 pMLMEContext->pIrp = NULL; 269 pMLMEContext->TransferBuffer = NULL; 270 pMLMEContext->InUse = FALSE; 271 pMLMEContext->IRPPending = FALSE; 272 pMLMEContext->bWaitingBulkOut = FALSE; 273 pMLMEContext->BulkOutSize = 0; 274 pMLMEContext->SelfIdx = i; 275 276 /* Offset to next ring descriptor address */ 277 RingBaseVa = (u8 *)RingBaseVa + sizeof(struct rt_tx_context); 278 } 279 DBGPRINT(RT_DEBUG_TRACE, 280 ("MGMT Ring: total %d entry allocated\n", i)); 281 282 /*pAd->MgmtRing.TxSwFreeIdx = (MGMT_RING_SIZE - 1); */ 283 pAd->MgmtRing.TxSwFreeIdx = MGMT_RING_SIZE; 284 pAd->MgmtRing.TxCpuIdx = 0; 285 pAd->MgmtRing.TxDmaIdx = 0; 286 287 /* */ 288 /* BEACON_RING_SIZE */ 289 /* */ 290 for (i = 0; i < BEACON_RING_SIZE; i++) /* 2 */ 291 { 292 struct rt_tx_context *pBeaconContext = &(pAd->BeaconContext[i]); 293 294 NdisZeroMemory(pBeaconContext, sizeof(struct rt_tx_context)); 295 296 /*Allocate URB */ 297 LM_USB_ALLOC(pObj, pBeaconContext, struct rt_tx_buffer *, 298 sizeof(struct rt_tx_buffer), Status, 299 ("<-- ERROR in Alloc TX BeaconContext[%d] urb!\n", 300 i), out2, 301 ("<-- ERROR in Alloc TX BeaconContext[%d] struct rt_tx_buffer!\n", 302 i), out3); 303 304 pBeaconContext->pAd = pAd; 305 pBeaconContext->pIrp = NULL; 306 pBeaconContext->InUse = FALSE; 307 pBeaconContext->IRPPending = FALSE; 308 } 309 310 /* */ 311 /* NullContext */ 312 /* */ 313 NdisZeroMemory(pNullContext, sizeof(struct rt_tx_context)); 314 315 /*Allocate URB */ 316 LM_USB_ALLOC(pObj, pNullContext, struct rt_tx_buffer *, sizeof(struct rt_tx_buffer), 317 Status, 318 ("<-- ERROR in Alloc TX NullContext urb!\n"), 319 out3, 320 ("<-- ERROR in Alloc TX NullContext struct rt_tx_buffer!\n"), 321 out4); 322 323 pNullContext->pAd = pAd; 324 pNullContext->pIrp = NULL; 325 pNullContext->InUse = FALSE; 326 pNullContext->IRPPending = FALSE; 327 328 /* */ 329 /* RTSContext */ 330 /* */ 331 NdisZeroMemory(pRTSContext, sizeof(struct rt_tx_context)); 332 333 /*Allocate URB */ 334 LM_USB_ALLOC(pObj, pRTSContext, struct rt_tx_buffer *, sizeof(struct rt_tx_buffer), 335 Status, 336 ("<-- ERROR in Alloc TX RTSContext urb!\n"), 337 out4, 338 ("<-- ERROR in Alloc TX RTSContext struct rt_tx_buffer!\n"), 339 out5); 340 341 pRTSContext->pAd = pAd; 342 pRTSContext->pIrp = NULL; 343 pRTSContext->InUse = FALSE; 344 pRTSContext->IRPPending = FALSE; 345 346 /* */ 347 /* PsPollContext */ 348 /* */ 349 /*NdisZeroMemory(pPsPollContext, sizeof(struct rt_tx_context)); */ 350 /*Allocate URB */ 351 LM_USB_ALLOC(pObj, pPsPollContext, struct rt_tx_buffer *, 352 sizeof(struct rt_tx_buffer), Status, 353 ("<-- ERROR in Alloc TX PsPollContext urb!\n"), 354 out5, 355 ("<-- ERROR in Alloc TX PsPollContext struct rt_tx_buffer!\n"), 356 out6); 357 358 pPsPollContext->pAd = pAd; 359 pPsPollContext->pIrp = NULL; 360 pPsPollContext->InUse = FALSE; 361 pPsPollContext->IRPPending = FALSE; 362 pPsPollContext->bAggregatible = FALSE; 363 pPsPollContext->LastOne = TRUE; 364 365 } while (FALSE); 366 367done: 368 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitTransmit(Status=%d)\n", Status)); 369 370 return Status; 371 372 /* --------------------------- ERROR HANDLE --------------------------- */ 373out6: 374 LM_URB_FREE(pObj, pPsPollContext, sizeof(struct rt_tx_buffer)); 375 376out5: 377 LM_URB_FREE(pObj, pRTSContext, sizeof(struct rt_tx_buffer)); 378 379out4: 380 LM_URB_FREE(pObj, pNullContext, sizeof(struct rt_tx_buffer)); 381 382out3: 383 for (i = 0; i < BEACON_RING_SIZE; i++) { 384 struct rt_tx_context *pBeaconContext = &(pAd->BeaconContext[i]); 385 if (pBeaconContext) 386 LM_URB_FREE(pObj, pBeaconContext, sizeof(struct rt_tx_buffer)); 387 } 388 389out2: 390 if (pAd->MgmtDescRing.AllocVa) { 391 pMgmtRing = &pAd->MgmtRing; 392 for (i = 0; i < MGMT_RING_SIZE; i++) { 393 pMLMEContext = 394 (struct rt_tx_context *)pAd->MgmtRing.Cell[i].AllocVa; 395 if (pMLMEContext) 396 LM_URB_FREE(pObj, pMLMEContext, 397 sizeof(struct rt_tx_buffer)); 398 } 399 os_free_mem(pAd, pAd->MgmtDescRing.AllocVa); 400 pAd->MgmtDescRing.AllocVa = NULL; 401 } 402 403out1: 404 for (acidx = 0; acidx < 4; acidx++) { 405 struct rt_ht_tx_context *pTxContext = &(pAd->TxContext[acidx]); 406 if (pTxContext) 407 LM_URB_FREE(pObj, pTxContext, sizeof(struct rt_httx_buffer)); 408 } 409 410 /* Here we didn't have any pre-allocated memory need to free. */ 411 412 return Status; 413} 414 415/* 416======================================================================== 417Routine Description: 418 Allocate DMA memory blocks for send, receive. 419 420Arguments: 421 pAd Pointer to our adapter 422 423Return Value: 424 NDIS_STATUS_SUCCESS 425 NDIS_STATUS_FAILURE 426 NDIS_STATUS_RESOURCES 427 428Note: 429======================================================================== 430*/ 431int RTMPAllocTxRxRingMemory(struct rt_rtmp_adapter *pAd) 432{ 433/* struct rt_counter_802_11 pCounter = &pAd->WlanCounters; */ 434 int Status; 435 int num; 436 437 DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n")); 438 439 do { 440 /* Init the struct rt_cmdq and CmdQLock */ 441 NdisAllocateSpinLock(&pAd->CmdQLock); 442 NdisAcquireSpinLock(&pAd->CmdQLock); 443 RTUSBInitializeCmdQ(&pAd->CmdQ); 444 NdisReleaseSpinLock(&pAd->CmdQLock); 445 446 NdisAllocateSpinLock(&pAd->MLMEBulkOutLock); 447 /*NdisAllocateSpinLock(&pAd->MLMEWaitQueueLock); */ 448 NdisAllocateSpinLock(&pAd->BulkOutLock[0]); 449 NdisAllocateSpinLock(&pAd->BulkOutLock[1]); 450 NdisAllocateSpinLock(&pAd->BulkOutLock[2]); 451 NdisAllocateSpinLock(&pAd->BulkOutLock[3]); 452 NdisAllocateSpinLock(&pAd->BulkOutLock[4]); 453 NdisAllocateSpinLock(&pAd->BulkOutLock[5]); 454 NdisAllocateSpinLock(&pAd->BulkInLock); 455 456 for (num = 0; num < NUM_OF_TX_RING; num++) { 457 NdisAllocateSpinLock(&pAd->TxContextQueueLock[num]); 458 } 459 460/* NdisAllocateSpinLock(&pAd->MemLock); // Not used in RT28XX */ 461 462/* NdisAllocateSpinLock(&pAd->MacTabLock); // init it in UserCfgInit() */ 463/* NdisAllocateSpinLock(&pAd->BATabLock); // init it in BATableInit() */ 464 465/* for(num=0; num<MAX_LEN_OF_BA_REC_TABLE; num++) */ 466/* { */ 467/* NdisAllocateSpinLock(&pAd->BATable.BARecEntry[num].RxReRingLock); */ 468/* } */ 469 470 /* */ 471 /* Init Mac Table */ 472 /* */ 473/* MacTableInitialize(pAd); */ 474 475 /* */ 476 /* Init send data structures and related parameters */ 477 /* */ 478 Status = NICInitTransmit(pAd); 479 if (Status != NDIS_STATUS_SUCCESS) 480 break; 481 482 /* */ 483 /* Init receive data structures and related parameters */ 484 /* */ 485 Status = NICInitRecv(pAd); 486 if (Status != NDIS_STATUS_SUCCESS) 487 break; 488 489 pAd->PendingIoCount = 1; 490 491 } while (FALSE); 492 493 NdisZeroMemory(&pAd->FragFrame, sizeof(struct rt_fragment_frame)); 494 pAd->FragFrame.pFragPacket = 495 RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE); 496 497 if (pAd->FragFrame.pFragPacket == NULL) { 498 Status = NDIS_STATUS_RESOURCES; 499 } 500 501 DBGPRINT_S(Status, 502 ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status)); 503 return Status; 504} 505 506/* 507======================================================================== 508Routine Description: 509 Calls USB_InterfaceStop and frees memory allocated for the URBs 510 calls NdisMDeregisterDevice and frees the memory 511 allocated in VNetInitialize for the Adapter Object 512 513Arguments: 514 *pAd the raxx interface data pointer 515 516Return Value: 517 None 518 519Note: 520======================================================================== 521*/ 522void RTMPFreeTxRxRingMemory(struct rt_rtmp_adapter *pAd) 523{ 524#define LM_URB_FREE(pObj, Context, BufferSize) \ 525 if (NULL != Context->pUrb) { \ 526 RTUSB_UNLINK_URB(Context->pUrb); \ 527 RTUSB_FREE_URB(Context->pUrb); \ 528 Context->pUrb = NULL; } \ 529 if (NULL != Context->TransferBuffer) { \ 530 RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize, \ 531 Context->TransferBuffer, \ 532 Context->data_dma); \ 533 Context->TransferBuffer = NULL; } 534 535 u32 i, acidx; 536 struct rt_tx_context *pNullContext = &pAd->NullContext; 537 struct rt_tx_context *pPsPollContext = &pAd->PsPollContext; 538 struct rt_tx_context *pRTSContext = &pAd->RTSContext; 539/* struct rt_ht_tx_context *pHTTXContext; */ 540 /*PRTMP_REORDERBUF pReorderBuf; */ 541 struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie; 542/* struct rt_rtmp_tx_ring *pTxRing; */ 543 544 DBGPRINT(RT_DEBUG_ERROR, ("---> RTMPFreeTxRxRingMemory\n")); 545 pObj = pObj; 546 547 /* Free all resources for the RECEIVE buffer queue. */ 548 for (i = 0; i < (RX_RING_SIZE); i++) { 549 struct rt_rx_context *pRxContext = &(pAd->RxContext[i]); 550 if (pRxContext) 551 LM_URB_FREE(pObj, pRxContext, MAX_RXBULK_SIZE); 552 } 553 554 /* Free PsPoll frame resource */ 555 LM_URB_FREE(pObj, pPsPollContext, sizeof(struct rt_tx_buffer)); 556 557 /* Free NULL frame resource */ 558 LM_URB_FREE(pObj, pNullContext, sizeof(struct rt_tx_buffer)); 559 560 /* Free RTS frame resource */ 561 LM_URB_FREE(pObj, pRTSContext, sizeof(struct rt_tx_buffer)); 562 563 /* Free beacon frame resource */ 564 for (i = 0; i < BEACON_RING_SIZE; i++) { 565 struct rt_tx_context *pBeaconContext = &(pAd->BeaconContext[i]); 566 if (pBeaconContext) 567 LM_URB_FREE(pObj, pBeaconContext, sizeof(struct rt_tx_buffer)); 568 } 569 570 /* Free mgmt frame resource */ 571 for (i = 0; i < MGMT_RING_SIZE; i++) { 572 struct rt_tx_context *pMLMEContext = 573 (struct rt_tx_context *)pAd->MgmtRing.Cell[i].AllocVa; 574 /*LM_URB_FREE(pObj, pMLMEContext, sizeof(struct rt_tx_buffer)); */ 575 if (NULL != pAd->MgmtRing.Cell[i].pNdisPacket) { 576 RTMPFreeNdisPacket(pAd, 577 pAd->MgmtRing.Cell[i].pNdisPacket); 578 pAd->MgmtRing.Cell[i].pNdisPacket = NULL; 579 pMLMEContext->TransferBuffer = NULL; 580 } 581 582 if (pMLMEContext) { 583 if (NULL != pMLMEContext->pUrb) { 584 RTUSB_UNLINK_URB(pMLMEContext->pUrb); 585 RTUSB_FREE_URB(pMLMEContext->pUrb); 586 pMLMEContext->pUrb = NULL; 587 } 588 } 589 } 590 if (pAd->MgmtDescRing.AllocVa) 591 os_free_mem(pAd, pAd->MgmtDescRing.AllocVa); 592 593 /* Free Tx frame resource */ 594 for (acidx = 0; acidx < 4; acidx++) { 595 struct rt_ht_tx_context *pHTTXContext = &(pAd->TxContext[acidx]); 596 if (pHTTXContext) 597 LM_URB_FREE(pObj, pHTTXContext, sizeof(struct rt_httx_buffer)); 598 } 599 600 if (pAd->FragFrame.pFragPacket) 601 RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, 602 NDIS_STATUS_SUCCESS); 603 604 for (i = 0; i < 6; i++) { 605 NdisFreeSpinLock(&pAd->BulkOutLock[i]); 606 } 607 608 NdisFreeSpinLock(&pAd->BulkInLock); 609 NdisFreeSpinLock(&pAd->MLMEBulkOutLock); 610 611 NdisFreeSpinLock(&pAd->CmdQLock); 612 /* Clear all pending bulk-out request flags. */ 613 RTUSB_CLEAR_BULK_FLAG(pAd, 0xffffffff); 614 615/* NdisFreeSpinLock(&pAd->MacTabLock); */ 616 617/* for(i=0; i<MAX_LEN_OF_BA_REC_TABLE; i++) */ 618/* { */ 619/* NdisFreeSpinLock(&pAd->BATable.BARecEntry[i].RxReRingLock); */ 620/* } */ 621 622 DBGPRINT(RT_DEBUG_ERROR, ("<--- RTMPFreeTxRxRingMemory\n")); 623} 624 625/* 626======================================================================== 627Routine Description: 628 Write WLAN MAC address to USB 2870. 629 630Arguments: 631 pAd Pointer to our adapter 632 633Return Value: 634 NDIS_STATUS_SUCCESS 635 636Note: 637======================================================================== 638*/ 639int RTUSBWriteHWMACAddress(struct rt_rtmp_adapter *pAd) 640{ 641 MAC_DW0_STRUC StaMacReg0; 642 MAC_DW1_STRUC StaMacReg1; 643 int Status = NDIS_STATUS_SUCCESS; 644 LARGE_INTEGER NOW; 645 646 /* initialize the random number generator */ 647 RTMP_GetCurrentSystemTime(&NOW); 648 649 if (pAd->bLocalAdminMAC != TRUE) { 650 pAd->CurrentAddress[0] = pAd->PermanentAddress[0]; 651 pAd->CurrentAddress[1] = pAd->PermanentAddress[1]; 652 pAd->CurrentAddress[2] = pAd->PermanentAddress[2]; 653 pAd->CurrentAddress[3] = pAd->PermanentAddress[3]; 654 pAd->CurrentAddress[4] = pAd->PermanentAddress[4]; 655 pAd->CurrentAddress[5] = pAd->PermanentAddress[5]; 656 } 657 /* Write New MAC address to MAC_CSR2 & MAC_CSR3 & let ASIC know our new MAC */ 658 StaMacReg0.field.Byte0 = pAd->CurrentAddress[0]; 659 StaMacReg0.field.Byte1 = pAd->CurrentAddress[1]; 660 StaMacReg0.field.Byte2 = pAd->CurrentAddress[2]; 661 StaMacReg0.field.Byte3 = pAd->CurrentAddress[3]; 662 StaMacReg1.field.Byte4 = pAd->CurrentAddress[4]; 663 StaMacReg1.field.Byte5 = pAd->CurrentAddress[5]; 664 StaMacReg1.field.U2MeMask = 0xff; 665 DBGPRINT_RAW(RT_DEBUG_TRACE, 666 ("Local MAC = %02x:%02x:%02x:%02x:%02x:%02x\n", 667 pAd->CurrentAddress[0], pAd->CurrentAddress[1], 668 pAd->CurrentAddress[2], pAd->CurrentAddress[3], 669 pAd->CurrentAddress[4], pAd->CurrentAddress[5])); 670 671 RTUSBWriteMACRegister(pAd, MAC_ADDR_DW0, StaMacReg0.word); 672 RTUSBWriteMACRegister(pAd, MAC_ADDR_DW1, StaMacReg1.word); 673 return Status; 674} 675 676/* 677======================================================================== 678Routine Description: 679 Disable DMA. 680 681Arguments: 682 *pAd the raxx interface data pointer 683 684Return Value: 685 None 686 687Note: 688======================================================================== 689*/ 690void RT28XXDMADisable(struct rt_rtmp_adapter *pAd) 691{ 692 /* no use */ 693} 694 695/* 696======================================================================== 697Routine Description: 698 Enable DMA. 699 700Arguments: 701 *pAd the raxx interface data pointer 702 703Return Value: 704 None 705 706Note: 707======================================================================== 708*/ 709void RT28XXDMAEnable(struct rt_rtmp_adapter *pAd) 710{ 711 WPDMA_GLO_CFG_STRUC GloCfg; 712 USB_DMA_CFG_STRUC UsbCfg; 713 int i = 0; 714 715 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4); 716 do { 717 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word); 718 if ((GloCfg.field.TxDMABusy == 0) 719 && (GloCfg.field.RxDMABusy == 0)) 720 break; 721 722 DBGPRINT(RT_DEBUG_TRACE, ("==> DMABusy\n")); 723 RTMPusecDelay(1000); 724 i++; 725 } while (i < 200); 726 727 RTMPusecDelay(50); 728 GloCfg.field.EnTXWriteBackDDONE = 1; 729 GloCfg.field.EnableRxDMA = 1; 730 GloCfg.field.EnableTxDMA = 1; 731 DBGPRINT(RT_DEBUG_TRACE, 732 ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word)); 733 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word); 734 735 UsbCfg.word = 0; 736 UsbCfg.field.phyclear = 0; 737 /* usb version is 1.1,do not use bulk in aggregation */ 738 if (pAd->BulkInMaxPacketSize == 512) 739 UsbCfg.field.RxBulkAggEn = 1; 740 /* for last packet, PBF might use more than limited, so minus 2 to prevent from error */ 741 UsbCfg.field.RxBulkAggLmt = (MAX_RXBULK_SIZE / 1024) - 3; 742 UsbCfg.field.RxBulkAggTOut = 0x80; /* 2006-10-18 */ 743 UsbCfg.field.RxBulkEn = 1; 744 UsbCfg.field.TxBulkEn = 1; 745 746 RTUSBWriteMACRegister(pAd, USB_DMA_CFG, UsbCfg.word); 747 748} 749 750/******************************************************************** 751 * 752 * 2870 Beacon Update Related functions. 753 * 754 ********************************************************************/ 755 756/* 757======================================================================== 758Routine Description: 759 Write Beacon buffer to Asic. 760 761Arguments: 762 *pAd the raxx interface data pointer 763 764Return Value: 765 None 766 767Note: 768======================================================================== 769*/ 770void RT28xx_UpdateBeaconToAsic(struct rt_rtmp_adapter *pAd, 771 int apidx, 772 unsigned long FrameLen, unsigned long UpdatePos) 773{ 774 u8 *pBeaconFrame = NULL; 775 u8 *ptr; 776 u32 i, padding; 777 struct rt_beacon_sync *pBeaconSync = pAd->CommonCfg.pBeaconSync; 778 u32 longValue; 779/* u16 shortValue; */ 780 BOOLEAN bBcnReq = FALSE; 781 u8 bcn_idx = 0; 782 783 if (pBeaconFrame == NULL) { 784 DBGPRINT(RT_DEBUG_ERROR, ("pBeaconFrame is NULL!\n")); 785 return; 786 } 787 788 if (pBeaconSync == NULL) { 789 DBGPRINT(RT_DEBUG_ERROR, ("pBeaconSync is NULL!\n")); 790 return; 791 } 792 /*if ((pAd->WdsTab.Mode == WDS_BRIDGE_MODE) || */ 793 /* ((pAd->ApCfg.MBSSID[apidx].MSSIDDev == NULL) || !(pAd->ApCfg.MBSSID[apidx].MSSIDDev->flags & IFF_UP)) */ 794 /* ) */ 795 if (bBcnReq == FALSE) { 796 /* when the ra interface is down, do not send its beacon frame */ 797 /* clear all zero */ 798 for (i = 0; i < TXWI_SIZE; i += 4) { 799 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, 800 0x00); 801 } 802 pBeaconSync->BeaconBitMap &= 803 (~(BEACON_BITMAP_MASK & (1 << bcn_idx))); 804 NdisZeroMemory(pBeaconSync->BeaconTxWI[bcn_idx], TXWI_SIZE); 805 } else { 806 ptr = (u8 *)& pAd->BeaconTxWI; 807 if (NdisEqualMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE) == FALSE) { /* If BeaconTxWI changed, we need to rewrite the TxWI for the Beacon frames. */ 808 pBeaconSync->BeaconBitMap &= 809 (~(BEACON_BITMAP_MASK & (1 << bcn_idx))); 810 NdisMoveMemory(pBeaconSync->BeaconTxWI[bcn_idx], 811 &pAd->BeaconTxWI, TXWI_SIZE); 812 } 813 814 if ((pBeaconSync->BeaconBitMap & (1 << bcn_idx)) != 815 (1 << bcn_idx)) { 816 for (i = 0; i < TXWI_SIZE; i += 4) /* 16-byte TXWI field */ 817 { 818 longValue = 819 *ptr + (*(ptr + 1) << 8) + 820 (*(ptr + 2) << 16) + (*(ptr + 3) << 24); 821 RTMP_IO_WRITE32(pAd, 822 pAd->BeaconOffset[bcn_idx] + i, 823 longValue); 824 ptr += 4; 825 } 826 } 827 828 ptr = pBeaconSync->BeaconBuf[bcn_idx]; 829 padding = (FrameLen & 0x01); 830 NdisZeroMemory((u8 *)(pBeaconFrame + FrameLen), padding); 831 FrameLen += padding; 832 for (i = 0; i < FrameLen /*HW_BEACON_OFFSET */ ; i += 2) { 833 if (NdisEqualMemory(ptr, pBeaconFrame, 2) == FALSE) { 834 NdisMoveMemory(ptr, pBeaconFrame, 2); 835 /*shortValue = *ptr + (*(ptr+1)<<8); */ 836 /*RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, shortValue); */ 837 RTUSBMultiWrite(pAd, 838 pAd->BeaconOffset[bcn_idx] + 839 TXWI_SIZE + i, ptr, 2); 840 } 841 ptr += 2; 842 pBeaconFrame += 2; 843 } 844 845 pBeaconSync->BeaconBitMap |= (1 << bcn_idx); 846 847 /* For AP interface, set the DtimBitOn so that we can send Bcast/Mcast frame out after this beacon frame. */ 848 } 849 850} 851 852void RTUSBBssBeaconStop(struct rt_rtmp_adapter *pAd) 853{ 854 struct rt_beacon_sync *pBeaconSync; 855 int i, offset; 856 BOOLEAN Cancelled = TRUE; 857 858 pBeaconSync = pAd->CommonCfg.pBeaconSync; 859 if (pBeaconSync && pBeaconSync->EnableBeacon) { 860 int NumOfBcn; 861 862 { 863 NumOfBcn = MAX_MESH_NUM; 864 } 865 866 RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled); 867 868 for (i = 0; i < NumOfBcn; i++) { 869 NdisZeroMemory(pBeaconSync->BeaconBuf[i], 870 HW_BEACON_OFFSET); 871 NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE); 872 873 for (offset = 0; offset < HW_BEACON_OFFSET; offset += 4) 874 RTMP_IO_WRITE32(pAd, 875 pAd->BeaconOffset[i] + offset, 876 0x00); 877 878 pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0; 879 pBeaconSync->TimIELocationInBeacon[i] = 0; 880 } 881 pBeaconSync->BeaconBitMap = 0; 882 pBeaconSync->DtimBitOn = 0; 883 } 884} 885 886void RTUSBBssBeaconStart(struct rt_rtmp_adapter *pAd) 887{ 888 int apidx; 889 struct rt_beacon_sync *pBeaconSync; 890/* LARGE_INTEGER tsfTime, deltaTime; */ 891 892 pBeaconSync = pAd->CommonCfg.pBeaconSync; 893 if (pBeaconSync && pBeaconSync->EnableBeacon) { 894 int NumOfBcn; 895 896 { 897 NumOfBcn = MAX_MESH_NUM; 898 } 899 900 for (apidx = 0; apidx < NumOfBcn; apidx++) { 901 u8 CapabilityInfoLocationInBeacon = 0; 902 u8 TimIELocationInBeacon = 0; 903 904 NdisZeroMemory(pBeaconSync->BeaconBuf[apidx], 905 HW_BEACON_OFFSET); 906 pBeaconSync->CapabilityInfoLocationInBeacon[apidx] = 907 CapabilityInfoLocationInBeacon; 908 pBeaconSync->TimIELocationInBeacon[apidx] = 909 TimIELocationInBeacon; 910 NdisZeroMemory(pBeaconSync->BeaconTxWI[apidx], 911 TXWI_SIZE); 912 } 913 pBeaconSync->BeaconBitMap = 0; 914 pBeaconSync->DtimBitOn = 0; 915 pAd->CommonCfg.BeaconUpdateTimer.Repeat = TRUE; 916 917 pAd->CommonCfg.BeaconAdjust = 0; 918 pAd->CommonCfg.BeaconFactor = 919 0xffffffff / (pAd->CommonCfg.BeaconPeriod << 10); 920 pAd->CommonCfg.BeaconRemain = 921 (0xffffffff % (pAd->CommonCfg.BeaconPeriod << 10)) + 1; 922 DBGPRINT(RT_DEBUG_TRACE, 923 ("RTUSBBssBeaconStart:BeaconFactor=%d, BeaconRemain=%d!\n", 924 pAd->CommonCfg.BeaconFactor, 925 pAd->CommonCfg.BeaconRemain)); 926 RTMPSetTimer(&pAd->CommonCfg.BeaconUpdateTimer, 927 10 /*pAd->CommonCfg.BeaconPeriod */ ); 928 929 } 930} 931 932void RTUSBBssBeaconInit(struct rt_rtmp_adapter *pAd) 933{ 934 struct rt_beacon_sync *pBeaconSync; 935 int i; 936 937 os_alloc_mem(pAd, (u8 **) (&pAd->CommonCfg.pBeaconSync), 938 sizeof(struct rt_beacon_sync)); 939 /*NdisAllocMemory(pAd->CommonCfg.pBeaconSync, sizeof(struct rt_beacon_sync), MEM_ALLOC_FLAG); */ 940 if (pAd->CommonCfg.pBeaconSync) { 941 pBeaconSync = pAd->CommonCfg.pBeaconSync; 942 NdisZeroMemory(pBeaconSync, sizeof(struct rt_beacon_sync)); 943 for (i = 0; i < HW_BEACON_MAX_COUNT; i++) { 944 NdisZeroMemory(pBeaconSync->BeaconBuf[i], 945 HW_BEACON_OFFSET); 946 pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0; 947 pBeaconSync->TimIELocationInBeacon[i] = 0; 948 NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE); 949 } 950 pBeaconSync->BeaconBitMap = 0; 951 952 /*RTMPInitTimer(pAd, &pAd->CommonCfg.BeaconUpdateTimer, GET_TIMER_FUNCTION(BeaconUpdateExec), pAd, TRUE); */ 953 pBeaconSync->EnableBeacon = TRUE; 954 } 955} 956 957void RTUSBBssBeaconExit(struct rt_rtmp_adapter *pAd) 958{ 959 struct rt_beacon_sync *pBeaconSync; 960 BOOLEAN Cancelled = TRUE; 961 int i; 962 963 if (pAd->CommonCfg.pBeaconSync) { 964 pBeaconSync = pAd->CommonCfg.pBeaconSync; 965 pBeaconSync->EnableBeacon = FALSE; 966 RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled); 967 pBeaconSync->BeaconBitMap = 0; 968 969 for (i = 0; i < HW_BEACON_MAX_COUNT; i++) { 970 NdisZeroMemory(pBeaconSync->BeaconBuf[i], 971 HW_BEACON_OFFSET); 972 pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0; 973 pBeaconSync->TimIELocationInBeacon[i] = 0; 974 NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE); 975 } 976 977 os_free_mem(pAd, pAd->CommonCfg.pBeaconSync); 978 pAd->CommonCfg.pBeaconSync = NULL; 979 } 980} 981 982/* 983 ======================================================================== 984 Routine Description: 985 For device work as AP mode but didn't have TBTT interrupt event, we need a mechanism 986 to update the beacon context in each Beacon interval. Here we use a periodical timer 987 to simulate the TBTT interrupt to handle the beacon context update. 988 989 Arguments: 990 SystemSpecific1 - Not used. 991 FunctionContext - Pointer to our Adapter context. 992 SystemSpecific2 - Not used. 993 SystemSpecific3 - Not used. 994 995 Return Value: 996 None 997 998 ======================================================================== 999*/ 1000void BeaconUpdateExec(void *SystemSpecific1, 1001 void *FunctionContext, 1002 void *SystemSpecific2, void *SystemSpecific3) 1003{ 1004 struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext; 1005 LARGE_INTEGER tsfTime_a; /*, tsfTime_b, deltaTime_exp, deltaTime_ab; */ 1006 u32 delta, delta2MS, period2US, remain, remain_low, remain_high; 1007/* BOOLEAN positive; */ 1008 1009 if (pAd->CommonCfg.IsUpdateBeacon == TRUE) { 1010 ReSyncBeaconTime(pAd); 1011 1012 } 1013 1014 RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &tsfTime_a.u.LowPart); 1015 RTMP_IO_READ32(pAd, TSF_TIMER_DW1, &tsfTime_a.u.HighPart); 1016 1017 /*positive=getDeltaTime(tsfTime_a, expectedTime, &deltaTime_exp); */ 1018 period2US = (pAd->CommonCfg.BeaconPeriod << 10); 1019 remain_high = pAd->CommonCfg.BeaconRemain * tsfTime_a.u.HighPart; 1020 remain_low = tsfTime_a.u.LowPart % (pAd->CommonCfg.BeaconPeriod << 10); 1021 remain = 1022 (remain_high + remain_low) % (pAd->CommonCfg.BeaconPeriod << 10); 1023 delta = (pAd->CommonCfg.BeaconPeriod << 10) - remain; 1024 1025 delta2MS = (delta >> 10); 1026 if (delta2MS > 150) { 1027 pAd->CommonCfg.BeaconUpdateTimer.TimerValue = 100; 1028 pAd->CommonCfg.IsUpdateBeacon = FALSE; 1029 } else { 1030 pAd->CommonCfg.BeaconUpdateTimer.TimerValue = delta2MS + 10; 1031 pAd->CommonCfg.IsUpdateBeacon = TRUE; 1032 } 1033 1034} 1035 1036/******************************************************************** 1037 * 1038 * 2870 Radio on/off Related functions. 1039 * 1040 ********************************************************************/ 1041void RT28xxUsbMlmeRadioOn(struct rt_rtmp_adapter *pAd) 1042{ 1043 struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps; 1044 1045 DBGPRINT(RT_DEBUG_TRACE, ("RT28xxUsbMlmeRadioOn()\n")); 1046 1047 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) 1048 return; 1049 1050 { 1051 AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02); 1052 RTMPusecDelay(10000); 1053 } 1054 /*NICResetFromError(pAd); */ 1055 1056 /* Enable Tx/Rx */ 1057 RTMPEnableRxTx(pAd); 1058 1059 if (pChipOps->AsicReverseRfFromSleepMode) 1060 pChipOps->AsicReverseRfFromSleepMode(pAd); 1061 1062 /* Clear Radio off flag */ 1063 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); 1064 1065 RTUSBBulkReceive(pAd); 1066 1067 /* Set LED */ 1068 RTMPSetLED(pAd, LED_RADIO_ON); 1069} 1070 1071void RT28xxUsbMlmeRadioOFF(struct rt_rtmp_adapter *pAd) 1072{ 1073 WPDMA_GLO_CFG_STRUC GloCfg; 1074 u32 Value, i; 1075 1076 DBGPRINT(RT_DEBUG_TRACE, ("RT28xxUsbMlmeRadioOFF()\n")); 1077 1078 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) 1079 return; 1080 1081 /* Clear PMKID cache. */ 1082 pAd->StaCfg.SavedPMKNum = 0; 1083 RTMPZeroMemory(pAd->StaCfg.SavedPMK, (PMKID_NO * sizeof(struct rt_bssid_info))); 1084 1085 /* Link down first if any association exists */ 1086 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) { 1087 if (INFRA_ON(pAd) || ADHOC_ON(pAd)) { 1088 struct rt_mlme_disassoc_req DisReq; 1089 struct rt_mlme_queue_elem *pMsgElem = 1090 kmalloc(sizeof(struct rt_mlme_queue_elem), 1091 MEM_ALLOC_FLAG); 1092 1093 if (pMsgElem) { 1094 COPY_MAC_ADDR(&DisReq.Addr, 1095 pAd->CommonCfg.Bssid); 1096 DisReq.Reason = REASON_DISASSOC_STA_LEAVING; 1097 1098 pMsgElem->Machine = ASSOC_STATE_MACHINE; 1099 pMsgElem->MsgType = MT2_MLME_DISASSOC_REQ; 1100 pMsgElem->MsgLen = 1101 sizeof(struct rt_mlme_disassoc_req); 1102 NdisMoveMemory(pMsgElem->Msg, &DisReq, 1103 sizeof 1104 (struct rt_mlme_disassoc_req)); 1105 1106 MlmeDisassocReqAction(pAd, pMsgElem); 1107 kfree(pMsgElem); 1108 1109 RTMPusecDelay(1000); 1110 } 1111 } 1112 } 1113 /* Set Radio off flag */ 1114 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); 1115 1116 { 1117 /* Link down first if any association exists */ 1118 if (INFRA_ON(pAd) || ADHOC_ON(pAd)) 1119 LinkDown(pAd, FALSE); 1120 RTMPusecDelay(10000); 1121 1122 /*========================================== */ 1123 /* Clean up old bss table */ 1124 BssTableInit(&pAd->ScanTab); 1125 } 1126 1127 /* Set LED */ 1128 RTMPSetLED(pAd, LED_RADIO_OFF); 1129 1130 if (pAd->CommonCfg.BBPCurrentBW == BW_40) { 1131 /* Must using 40MHz. */ 1132 AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel); 1133 } else { 1134 /* Must using 20MHz. */ 1135 AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel); 1136 } 1137 1138 /* Disable Tx/Rx DMA */ 1139 RTUSBReadMACRegister(pAd, WPDMA_GLO_CFG, &GloCfg.word); /* disable DMA */ 1140 GloCfg.field.EnableTxDMA = 0; 1141 GloCfg.field.EnableRxDMA = 0; 1142 RTUSBWriteMACRegister(pAd, WPDMA_GLO_CFG, GloCfg.word); /* abort all TX rings */ 1143 1144 /* Waiting for DMA idle */ 1145 i = 0; 1146 do { 1147 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word); 1148 if ((GloCfg.field.TxDMABusy == 0) 1149 && (GloCfg.field.RxDMABusy == 0)) 1150 break; 1151 1152 RTMPusecDelay(1000); 1153 } while (i++ < 100); 1154 1155 /* Disable MAC Tx/Rx */ 1156 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value); 1157 Value &= (0xfffffff3); 1158 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value); 1159 1160 { 1161 AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02); 1162 } 1163} 1164 1165#endif /* RTMP_MAC_USB // */ 1166