2 *************************************************************************
4 * 5F., No.36, Taiyuan St., Jhubei City,
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
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. *
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. *
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. *
25 *************************************************************************
31 main initialization routines
35 -------- ---------- ----------------------------------------------
36 Name Date Modification logs
37 Jan Lee 01-10-2005 modified
38 Sample Jun/01/07 Merge RT2870 and RT2860 drivers.
41 #include "rt_config.h"
44 // Following information will be show when you run 'modinfo'
45 // *** If you have a solution for the bug in current version of driver, please mail to me.
46 // Otherwise post to forum in ralinktech's web site(www.ralinktech.com) and let all users help you. ***
47 MODULE_AUTHOR("Paul Lin <paul_lin@ralinktech.com>");
48 MODULE_DESCRIPTION("RT2870 Wireless Lan Linux Driver");
49 #ifdef CONFIG_STA_SUPPORT
50 MODULE_LICENSE("GPL");
52 MODULE_VERSION(STA_DRIVER_VERSION);
54 #endif // CONFIG_STA_SUPPORT //
56 #ifdef MULTIPLE_CARD_SUPPORT
57 // record whether the card in the card list is used in the card file
58 extern UINT8 MC_CardUsed[];
59 #endif // MULTIPLE_CARD_SUPPORT //
61 /* Kernel thread and vars, which handles packets that are completed. Only
62 * packets that have a "complete" function are sent here. This way, the
63 * completion is run out of kernel context, and doesn't block the rest of
65 //static int mlme_kill = 0; // Mlme kernel thread
66 //static int RTUSBCmd_kill = 0; // Command kernel thread
67 //static int TimerFunc_kill = 0; // TimerQ kernel thread
69 //static wait_queue_head_t timerWaitQ;
70 //static wait_queue_t waitQ;
72 extern INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p,
73 IN UINT argc, OUT PRTMP_ADAPTER *ppAd);
77 struct usb_device_id rtusb_usb_id[] = RT2870_USB_DEVICES;
78 INT const rtusb_usb_id_len = sizeof(rtusb_usb_id) / sizeof(struct usb_device_id);
79 MODULE_DEVICE_TABLE(usb, rtusb_usb_id);
87 static int rt2870_suspend(struct usb_interface *intf, pm_message_t state);
88 static int rt2870_resume(struct usb_interface *intf);
89 #endif // CONFIG_PM //
91 /**************************************************************************/
92 /**************************************************************************/
93 //tested for kernel 2.6series
94 /**************************************************************************/
95 /**************************************************************************/
96 static int rtusb_probe (struct usb_interface *intf,
97 const struct usb_device_id *id);
98 static void rtusb_disconnect(struct usb_interface *intf);
100 struct usb_driver rtusb_driver = {
103 .disconnect=rtusb_disconnect,
104 .id_table=rtusb_usb_id,
107 suspend: rt2870_suspend,
108 resume: rt2870_resume,
114 VOID RT2860RejectPendingPackets(
115 IN PRTMP_ADAPTER pAd)
118 // clear TxSw packets
121 static int rt2870_suspend(
122 struct usb_interface *intf,
125 struct net_device *net_dev;
126 PRTMP_ADAPTER pAd = usb_get_intfdata(intf);
129 DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_suspend()\n"));
130 net_dev = pAd->net_dev;
131 netif_device_detach(net_dev);
133 pAd->PM_FlgSuspend = 1;
134 if (netif_running(net_dev)) {
135 RTUSBCancelPendingBulkInIRP(pAd);
136 RTUSBCancelPendingBulkOutIRP(pAd);
138 DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_suspend()\n"));
142 static int rt2870_resume(
143 struct usb_interface *intf)
145 struct net_device *net_dev;
146 PRTMP_ADAPTER pAd = usb_get_intfdata(intf);
149 DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_resume()\n"));
151 pAd->PM_FlgSuspend = 0;
152 net_dev = pAd->net_dev;
153 netif_device_attach(net_dev);
154 netif_start_queue(net_dev);
155 netif_carrier_on(net_dev);
156 netif_wake_queue(net_dev);
158 DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_resume()\n"));
161 #endif // CONFIG_PM //
164 // Init driver module
165 INT __init rtusb_init(void)
167 printk("rtusb init --->\n");
168 return usb_register(&rtusb_driver);
171 // Deinit driver module
172 VOID __exit rtusb_exit(void)
174 usb_deregister(&rtusb_driver);
175 printk("<--- rtusb exit\n");
178 module_init(rtusb_init);
179 module_exit(rtusb_exit);
184 /*--------------------------------------------------------------------- */
185 /* function declarations */
186 /*--------------------------------------------------------------------- */
189 ========================================================================
194 *Context the pAd, driver control block pointer
200 ========================================================================
205 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)Context;
209 pObj = (POS_COOKIE)pAd->OS_Cookie;
211 rtmp_os_thread_init("rt2870MlmeThread", (PVOID)&(pAd->mlmeComplete));
213 while (pAd->mlme_kill == 0)
215 /* lock the device pointers */
216 //down(&(pAd->mlme_semaphore));
217 status = down_interruptible(&(pAd->mlme_semaphore));
219 /* lock the device pointers , need to check if required*/
220 //down(&(pAd->usbdev_semaphore));
222 if (!pAd->PM_FlgSuspend)
225 /* unlock the device pointers */
226 //up(&(pAd->usbdev_semaphore));
229 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
234 /* notify the exit routine that we're actually exiting now
236 * complete()/wait_for_completion() is similar to up()/down(),
237 * except that complete() is safe in the case where the structure
238 * is getting deleted in a parallel mode of execution (i.e. just
239 * after the down() -- that's necessary for the thread-shutdown
242 * complete_and_exit() goes even further than this -- it is safe in
243 * the case that the thread of the caller is going away (not just
244 * the structure) -- this is necessary for the module-remove case.
245 * This is important in preemption kernels, which transfer the flow
246 * of execution immediately upon a complete().
248 DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__func__));
250 pObj->MLMEThr_pid = NULL;
252 complete_and_exit (&pAd->mlmeComplete, 0);
259 ========================================================================
261 USB command kernel thread.
264 *Context the pAd, driver control block pointer
270 ========================================================================
275 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)Context;
279 pObj = (POS_COOKIE)pAd->OS_Cookie;
281 rtmp_os_thread_init("rt2870CmdThread", (PVOID)&(pAd->CmdQComplete));
283 NdisAcquireSpinLock(&pAd->CmdQLock);
284 pAd->CmdQ.CmdQState = RT2870_THREAD_RUNNING;
285 NdisReleaseSpinLock(&pAd->CmdQLock);
287 while (pAd->CmdQ.CmdQState == RT2870_THREAD_RUNNING)
289 /* lock the device pointers */
290 //down(&(pAd->RTUSBCmd_semaphore));
291 status = down_interruptible(&(pAd->RTUSBCmd_semaphore));
293 if (pAd->CmdQ.CmdQState == RT2870_THREAD_STOPED)
298 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
301 /* lock the device pointers , need to check if required*/
302 //down(&(pAd->usbdev_semaphore));
304 if (!pAd->PM_FlgSuspend)
307 /* unlock the device pointers */
308 //up(&(pAd->usbdev_semaphore));
311 if (!pAd->PM_FlgSuspend)
312 { // Clear the CmdQElements.
313 CmdQElmt *pCmdQElmt = NULL;
315 NdisAcquireSpinLock(&pAd->CmdQLock);
316 pAd->CmdQ.CmdQState = RT2870_THREAD_STOPED;
317 while(pAd->CmdQ.size)
319 RTUSBDequeueCmd(&pAd->CmdQ, &pCmdQElmt);
322 if (pCmdQElmt->CmdFromNdis == TRUE)
324 if (pCmdQElmt->buffer != NULL)
325 NdisFreeMemory(pCmdQElmt->buffer, pCmdQElmt->bufferlength, 0);
327 NdisFreeMemory(pCmdQElmt, sizeof(CmdQElmt), 0);
331 if ((pCmdQElmt->buffer != NULL) && (pCmdQElmt->bufferlength != 0))
332 NdisFreeMemory(pCmdQElmt->buffer, pCmdQElmt->bufferlength, 0);
334 NdisFreeMemory(pCmdQElmt, sizeof(CmdQElmt), 0);
340 NdisReleaseSpinLock(&pAd->CmdQLock);
342 /* notify the exit routine that we're actually exiting now
344 * complete()/wait_for_completion() is similar to up()/down(),
345 * except that complete() is safe in the case where the structure
346 * is getting deleted in a parallel mode of execution (i.e. just
347 * after the down() -- that's necessary for the thread-shutdown
350 * complete_and_exit() goes even further than this -- it is safe in
351 * the case that the thread of the caller is going away (not just
352 * the structure) -- this is necessary for the module-remove case.
353 * This is important in preemption kernels, which transfer the flow
354 * of execution immediately upon a complete().
356 DBGPRINT(RT_DEBUG_TRACE,( "<---RTUSBCmdThread\n"));
358 pObj->RTUSBCmdThr_pid = NULL;
360 complete_and_exit (&pAd->CmdQComplete, 0);
366 static void RT2870_TimerQ_Handle(RTMP_ADAPTER *pAd)
369 RALINK_TIMER_STRUCT *pTimer;
370 RT2870_TIMER_ENTRY *pEntry;
371 unsigned long irqFlag;
373 while(!pAd->TimerFunc_kill)
375 // printk("waiting for event!\n");
378 status = down_interruptible(&(pAd->RTUSBTimer_semaphore));
380 if (pAd->TimerQ.status == RT2870_THREAD_STOPED)
384 while(pAd->TimerQ.pQHead)
386 RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlag);
387 pEntry = pAd->TimerQ.pQHead;
390 pTimer = pEntry->pRaTimer;
393 pAd->TimerQ.pQHead = pEntry->pNext;
394 if (pEntry == pAd->TimerQ.pQTail)
395 pAd->TimerQ.pQTail = NULL;
397 // return this queue entry to timerQFreeList.
398 pEntry->pNext = pAd->TimerQ.pQPollFreeList;
399 pAd->TimerQ.pQPollFreeList = pEntry;
401 RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlag);
405 if (pTimer->handle != NULL)
406 if (!pAd->PM_FlgSuspend)
407 pTimer->handle(NULL, (PVOID) pTimer->cookie, NULL, pTimer);
408 if ((pTimer->Repeat) && (pTimer->State == FALSE))
409 RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue);
415 pAd->TimerQ.status = RT2870_THREAD_STOPED;
416 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
424 IN OUT PVOID Context)
429 pAd = (PRTMP_ADAPTER)Context;
430 pObj = (POS_COOKIE) pAd->OS_Cookie;
432 rtmp_os_thread_init("rt2870TimerQHandle", (PVOID)&(pAd->TimerQComplete));
434 RT2870_TimerQ_Handle(pAd);
436 /* notify the exit routine that we're actually exiting now
438 * complete()/wait_for_completion() is similar to up()/down(),
439 * except that complete() is safe in the case where the structure
440 * is getting deleted in a parallel mode of execution (i.e. just
441 * after the down() -- that's necessary for the thread-shutdown
444 * complete_and_exit() goes even further than this -- it is safe in
445 * the case that the thread of the caller is going away (not just
446 * the structure) -- this is necessary for the module-remove case.
447 * This is important in preemption kernels, which transfer the flow
448 * of execution immediately upon a complete().
450 DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__func__));
452 pObj->TimerQThr_pid = NULL;
454 complete_and_exit(&pAd->TimerQComplete, 0);
460 RT2870_TIMER_ENTRY *RT2870_TimerQ_Insert(
461 IN RTMP_ADAPTER *pAd,
462 IN RALINK_TIMER_STRUCT *pTimer)
464 RT2870_TIMER_ENTRY *pQNode = NULL, *pQTail;
465 unsigned long irqFlags;
468 RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
469 if (pAd->TimerQ.status & RT2870_THREAD_CAN_DO_INSERT)
471 if(pAd->TimerQ.pQPollFreeList)
473 pQNode = pAd->TimerQ.pQPollFreeList;
474 pAd->TimerQ.pQPollFreeList = pQNode->pNext;
476 pQNode->pRaTimer = pTimer;
477 pQNode->pNext = NULL;
479 pQTail = pAd->TimerQ.pQTail;
480 if (pAd->TimerQ.pQTail != NULL)
481 pQTail->pNext = pQNode;
482 pAd->TimerQ.pQTail = pQNode;
483 if (pAd->TimerQ.pQHead == NULL)
484 pAd->TimerQ.pQHead = pQNode;
486 RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
489 up(&pAd->RTUSBTimer_semaphore);
490 //wake_up(&timerWaitQ);
494 RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
500 BOOLEAN RT2870_TimerQ_Remove(
501 IN RTMP_ADAPTER *pAd,
502 IN RALINK_TIMER_STRUCT *pTimer)
504 RT2870_TIMER_ENTRY *pNode, *pPrev = NULL;
505 unsigned long irqFlags;
507 RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
508 if (pAd->TimerQ.status >= RT2870_THREAD_INITED)
510 pNode = pAd->TimerQ.pQHead;
513 if (pNode->pRaTimer == pTimer)
516 pNode = pNode->pNext;
519 // Now move it to freeList queue.
522 if (pNode == pAd->TimerQ.pQHead)
523 pAd->TimerQ.pQHead = pNode->pNext;
524 if (pNode == pAd->TimerQ.pQTail)
525 pAd->TimerQ.pQTail = pPrev;
527 pPrev->pNext = pNode->pNext;
529 // return this queue entry to timerQFreeList.
530 pNode->pNext = pAd->TimerQ.pQPollFreeList;
531 pAd->TimerQ.pQPollFreeList = pNode;
534 RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
540 void RT2870_TimerQ_Exit(RTMP_ADAPTER *pAd)
542 RT2870_TIMER_ENTRY *pTimerQ;
543 unsigned long irqFlags;
545 RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
546 while (pAd->TimerQ.pQHead)
548 pTimerQ = pAd->TimerQ.pQHead;
549 pAd->TimerQ.pQHead = pTimerQ->pNext;
552 pAd->TimerQ.pQPollFreeList = NULL;
553 os_free_mem(pAd, pAd->TimerQ.pTimerQPoll);
554 pAd->TimerQ.pQTail = NULL;
555 pAd->TimerQ.pQHead = NULL;
556 pAd->TimerQ.status = RT2870_THREAD_STOPED;
557 RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
562 void RT2870_TimerQ_Init(RTMP_ADAPTER *pAd)
565 RT2870_TIMER_ENTRY *pQNode, *pEntry;
566 unsigned long irqFlags;
568 NdisAllocateSpinLock(&pAd->TimerQLock);
570 RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
571 NdisZeroMemory(&pAd->TimerQ, sizeof(pAd->TimerQ));
572 //InterlockedExchange(&pAd->TimerQ.count, 0);
574 /* Initialise the wait q head */
575 //init_waitqueue_head(&timerWaitQ);
577 os_alloc_mem(pAd, &pAd->TimerQ.pTimerQPoll, sizeof(RT2870_TIMER_ENTRY) * TIMER_QUEUE_SIZE_MAX);
578 if (pAd->TimerQ.pTimerQPoll)
581 pQNode = (RT2870_TIMER_ENTRY *)pAd->TimerQ.pTimerQPoll;
582 for (i = 0 ;i <TIMER_QUEUE_SIZE_MAX; i++)
584 pQNode->pNext = pEntry;
588 pAd->TimerQ.pQPollFreeList = pEntry;
589 pAd->TimerQ.pQHead = NULL;
590 pAd->TimerQ.pQTail = NULL;
591 pAd->TimerQ.status = RT2870_THREAD_INITED;
593 RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
597 VOID RT2870_WatchDog(IN RTMP_ADAPTER *pAd)
599 PHT_TX_CONTEXT pHTTXContext;
603 BOOLEAN needDumpSeq = FALSE;
608 RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
609 if ((MACValue & 0xff) !=0 )
611 DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 0 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue));
612 RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40012);
613 while((MACValue &0xff) != 0 && (idx++ < 10))
615 RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
618 RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006);
621 //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
622 #ifdef CONFIG_STA_SUPPORT
623 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
626 if ((MACValue & 0xff00) !=0 )
628 DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 1 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue));
629 RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf4000a);
630 while((MACValue &0xff00) != 0 && (idx++ < 10))
632 RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
635 RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006);
638 #endif // CONFIG_STA_SUPPORT //
640 if (pAd->watchDogRxOverFlowCnt >= 2)
642 DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Rx Bulk-In hanged! Cancel the pending Rx bulks request!\n"));
643 if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
644 fRTMP_ADAPTER_BULKIN_RESET |
645 fRTMP_ADAPTER_HALT_IN_PROGRESS |
646 fRTMP_ADAPTER_NIC_NOT_EXIST))))
648 DBGPRINT(RT_DEBUG_TRACE, ("Call CMDTHREAD_RESET_BULK_IN to cancel the pending Rx Bulk!\n"));
649 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
650 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0);
653 pAd->watchDogRxOverFlowCnt = 0;
657 for (idx = 0; idx < NUM_OF_TX_RING; idx++)
661 RTMP_IRQ_LOCK(&pAd->BulkOutLock[idx], irqFlags);
662 if ((pAd->BulkOutPending[idx] == TRUE) && pAd->watchDogTxPendingCnt)
664 pAd->watchDogTxPendingCnt[idx]++;
666 if ((pAd->watchDogTxPendingCnt[idx] > 2) &&
667 (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_BULKOUT_RESET)))
670 // FIXME: Following code just support single bulk out. If you wanna support multiple bulk out. Modify it!
671 pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[idx]);
672 if (pHTTXContext->IRPPending)
673 { // Check TxContext.
674 pUrb = pHTTXContext->pUrb;
676 else if (idx == MGMTPIPEIDX)
678 PTX_CONTEXT pMLMEContext, pNULLContext, pPsPollContext;
681 pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa);
682 pPsPollContext = (PTX_CONTEXT)(&pAd->PsPollContext);
683 pNULLContext = (PTX_CONTEXT)(&pAd->NullContext);
685 if (pMLMEContext->IRPPending)
687 ASSERT(pMLMEContext->IRPPending);
688 pUrb = pMLMEContext->pUrb;
690 else if (pNULLContext->IRPPending)
692 ASSERT(pNULLContext->IRPPending);
693 pUrb = pNULLContext->pUrb;
695 else if (pPsPollContext->IRPPending)
697 ASSERT(pPsPollContext->IRPPending);
698 pUrb = pPsPollContext->pUrb;
702 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
704 DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Tx Bulk-Out hanged! Cancel the pending Tx bulks request of idx(%d)!\n", idx));
707 DBGPRINT(RT_DEBUG_TRACE, ("Unlink the pending URB!\n"));
709 RTUSB_UNLINK_URB(pUrb);
710 // Sleep 200 microseconds to give cancellation time to work
716 DBGPRINT(RT_DEBUG_ERROR, ("Unkonw bulkOut URB maybe hanged!!!!!!!!!!!!\n"));
721 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
726 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
730 #ifdef DOT11_N_SUPPORT
731 // For Sigma debug, dump the ba_reordering sequence.
732 if((needDumpSeq == TRUE) && (pAd->CommonCfg.bDisableReordering == 0))
735 PBA_REC_ENTRY pBAEntry = NULL;
737 struct reordering_mpdu *mpdu_blk;
739 Idx = pAd->MacTab.Content[BSSID_WCID].BARecWcidArray[0];
741 pBAEntry = &pAd->BATable.BARecEntry[Idx];
742 if((pBAEntry->list.qlen > 0) && (pBAEntry->list.next != NULL))
744 DBGPRINT(RT_DEBUG_TRACE, ("NICUpdateRawCounters():The Queueing pkt in reordering buffer:\n"));
745 NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
746 mpdu_blk = pBAEntry->list.next;
749 DBGPRINT(RT_DEBUG_TRACE, ("\t%d:Seq-%d, bAMSDU-%d!\n", count, mpdu_blk->Sequence, mpdu_blk->bAMSDU));
750 mpdu_blk = mpdu_blk->next;
754 DBGPRINT(RT_DEBUG_TRACE, ("\npBAEntry->LastIndSeq=%d!\n", pBAEntry->LastIndSeq));
755 NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
758 #endif // DOT11_N_SUPPORT //
762 ========================================================================
764 Release allocated resources.
767 *dev Point to the PCI or USB device
768 pAd driver control block pointer
774 ========================================================================
776 static void _rtusb_disconnect(struct usb_device *dev, PRTMP_ADAPTER pAd)
778 struct net_device *net_dev = NULL;
781 DBGPRINT(RT_DEBUG_ERROR, ("rtusb_disconnect: unregister usbnet usb-%s-%s\n",
782 dev->bus->bus_name, dev->devpath));
785 #ifdef MULTIPLE_CARD_SUPPORT
786 if ((pAd->MC_RowID >= 0) && (pAd->MC_RowID <= MAX_NUM_OF_MULTIPLE_CARD))
787 MC_CardUsed[pAd->MC_RowID] = 0; // not clear MAC address
788 #endif // MULTIPLE_CARD_SUPPORT //
792 printk("rtusb_disconnect: pAd == NULL!\n");
795 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
799 // for debug, wait to show some messages to /proc system
805 net_dev = pAd->net_dev;
806 if (pAd->net_dev != NULL)
808 printk("rtusb_disconnect: unregister_netdev(), dev->name=%s!\n", net_dev->name);
809 unregister_netdev (pAd->net_dev);
812 flush_scheduled_work();
815 // free net_device memory
816 free_netdev(net_dev);
818 // free adapter memory
819 RTMPFreeAdapter(pAd);
821 // release a use of the usb device structure
825 DBGPRINT(RT_DEBUG_ERROR, (" RTUSB disconnect successfully\n"));
830 ========================================================================
832 Probe RT28XX chipset.
835 *dev Point to the PCI or USB device
837 *id_table Point to the PCI or USB device ID
843 ========================================================================
845 static int rtusb_probe (struct usb_interface *intf,
846 const struct usb_device_id *id)
849 return (int)rt28xx_probe((void *)intf, (void *)id, 0, &pAd);
853 static void rtusb_disconnect(struct usb_interface *intf)
855 struct usb_device *dev = interface_to_usbdev(intf);
859 pAd = usb_get_intfdata(intf);
860 usb_set_intfdata(intf, NULL);
862 _rtusb_disconnect(dev, pAd);
867 ========================================================================
869 Close kernel threads.
872 *pAd the raxx interface data pointer
878 ========================================================================
880 VOID RT28xxThreadTerminate(
881 IN RTMP_ADAPTER *pAd)
883 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
887 // Sleep 50 milliseconds so pending io might finish normally
888 RTMPusecDelay(50000);
890 // We want to wait until all pending receives and sends to the
891 // device object. We cancel any
892 // irps. Wait until sends and receives have stopped.
893 RTUSBCancelPendingIRPs(pAd);
896 if (pObj->MLMEThr_pid)
898 printk("Terminate the MLMEThr_pid=%d!\n", pid_nr(pObj->MLMEThr_pid));
901 //RT28XX_MLME_HANDLER(pAd);
903 ret = kill_pid(pObj->MLMEThr_pid, SIGTERM, 1);
906 printk (KERN_WARNING "%s: unable to Mlme thread, pid=%d, ret=%d!\n",
907 pAd->net_dev->name, pid_nr(pObj->MLMEThr_pid), ret);
911 //wait_for_completion (&pAd->notify);
912 wait_for_completion (&pAd->mlmeComplete);
913 pObj->MLMEThr_pid = NULL;
917 if (pObj->RTUSBCmdThr_pid >= 0)
919 printk("Terminate the RTUSBCmdThr_pid=%d!\n", pid_nr(pObj->RTUSBCmdThr_pid));
921 NdisAcquireSpinLock(&pAd->CmdQLock);
922 pAd->CmdQ.CmdQState = RT2870_THREAD_STOPED;
923 NdisReleaseSpinLock(&pAd->CmdQLock);
926 ret = kill_pid(pObj->RTUSBCmdThr_pid, SIGTERM, 1);
929 printk(KERN_WARNING "%s: unable to RTUSBCmd thread, pid=%d, ret=%d!\n",
930 pAd->net_dev->name, pid_nr(pObj->RTUSBCmdThr_pid), ret);
934 //wait_for_completion (&pAd->notify);
935 wait_for_completion (&pAd->CmdQComplete);
936 pObj->RTUSBCmdThr_pid = NULL;
939 if (pObj->TimerQThr_pid >= 0)
941 POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
943 printk("Terminate the TimerQThr_pid=%d!\n", pid_nr(pObj->TimerQThr_pid));
945 pAd->TimerFunc_kill = 1;
947 ret = kill_pid(pObj->TimerQThr_pid, SIGTERM, 1);
950 printk(KERN_WARNING "%s: unable to stop TimerQThread, pid=%d, ret=%d!\n",
951 pAd->net_dev->name, pid_nr(pObj->TimerQThr_pid), ret);
955 printk("wait_for_completion TimerQThr\n");
956 wait_for_completion(&pAd->TimerQComplete);
957 pObj->TimerQThr_pid = NULL;
962 pAd->CmdQ.CmdQState = RT2870_THREAD_UNKNOWN;
963 pAd->TimerFunc_kill = 0;
967 void kill_thread_task(IN PRTMP_ADAPTER pAd)
971 pObj = (POS_COOKIE) pAd->OS_Cookie;
973 tasklet_kill(&pObj->rx_done_task);
974 tasklet_kill(&pObj->mgmt_dma_done_task);
975 tasklet_kill(&pObj->ac0_dma_done_task);
976 tasklet_kill(&pObj->ac1_dma_done_task);
977 tasklet_kill(&pObj->ac2_dma_done_task);
978 tasklet_kill(&pObj->ac3_dma_done_task);
979 tasklet_kill(&pObj->hcca_dma_done_task);
980 tasklet_kill(&pObj->tbtt_task);
986 ========================================================================
988 Check the chipset vendor/product ID.
991 _dev_p Point to the PCI or USB device
998 ========================================================================
1000 BOOLEAN RT28XXChipsetCheck(
1003 struct usb_interface *intf = (struct usb_interface *)_dev_p;
1004 struct usb_device *dev_p = interface_to_usbdev(intf);
1008 for(i=0; i<rtusb_usb_id_len; i++)
1010 if (dev_p->descriptor.idVendor == rtusb_usb_id[i].idVendor &&
1011 dev_p->descriptor.idProduct == rtusb_usb_id[i].idProduct)
1013 printk("rt2870: idVendor = 0x%x, idProduct = 0x%x\n",
1014 dev_p->descriptor.idVendor, dev_p->descriptor.idProduct);
1019 if (i == rtusb_usb_id_len)
1021 printk("rt2870: Error! Device Descriptor not matching!\n");
1030 ========================================================================
1031 Routine Description:
1032 Init net device structure.
1035 _dev_p Point to the PCI or USB device
1036 *net_dev Point to the net device
1037 *pAd the raxx interface data pointer
1044 ========================================================================
1046 BOOLEAN RT28XXNetDevInit(
1048 IN struct net_device *net_dev,
1049 IN RTMP_ADAPTER *pAd)
1051 struct usb_interface *intf = (struct usb_interface *)_dev_p;
1052 struct usb_device *dev_p = interface_to_usbdev(intf);
1055 pAd->config = &dev_p->config->desc;
1061 ========================================================================
1062 Routine Description:
1063 Init net device structure.
1066 _dev_p Point to the PCI or USB device
1067 *pAd the raxx interface data pointer
1074 ========================================================================
1076 BOOLEAN RT28XXProbePostConfig(
1078 IN RTMP_ADAPTER *pAd,
1081 struct usb_interface *intf = (struct usb_interface *)_dev_p;
1082 struct usb_host_interface *iface_desc;
1087 /* get the active interface descriptor */
1088 iface_desc = intf->cur_altsetting;
1090 /* get # of enpoints */
1091 pAd->NumberOfPipes = iface_desc->desc.bNumEndpoints;
1092 DBGPRINT(RT_DEBUG_TRACE,
1093 ("NumEndpoints=%d\n", iface_desc->desc.bNumEndpoints));
1095 /* Configure Pipes */
1098 for(i=0; i<pAd->NumberOfPipes; i++)
1100 if ((iface_desc->endpoint[i].desc.bmAttributes ==
1101 USB_ENDPOINT_XFER_BULK) &&
1102 ((iface_desc->endpoint[i].desc.bEndpointAddress &
1103 USB_ENDPOINT_DIR_MASK) == USB_DIR_IN))
1105 pAd->BulkInEpAddr = iface_desc->endpoint[i].desc.bEndpointAddress;
1106 pAd->BulkInMaxPacketSize = iface_desc->endpoint[i].desc.wMaxPacketSize;
1108 DBGPRINT_RAW(RT_DEBUG_TRACE,
1109 ("BULK IN MaximumPacketSize = %d\n", pAd->BulkInMaxPacketSize));
1110 DBGPRINT_RAW(RT_DEBUG_TRACE,
1111 ("EP address = 0x%2x\n", iface_desc->endpoint[i].desc.bEndpointAddress));
1113 else if ((iface_desc->endpoint[i].desc.bmAttributes ==
1114 USB_ENDPOINT_XFER_BULK) &&
1115 ((iface_desc->endpoint[i].desc.bEndpointAddress &
1116 USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT))
1118 // there are 6 bulk out EP. EP6 highest priority.
1119 // EP1-4 is EDCA. EP5 is HCCA.
1120 pAd->BulkOutEpAddr[BulkOutIdx++] = iface_desc->endpoint[i].desc.bEndpointAddress;
1121 pAd->BulkOutMaxPacketSize = iface_desc->endpoint[i].desc.wMaxPacketSize;
1123 DBGPRINT_RAW(RT_DEBUG_TRACE,
1124 ("BULK OUT MaximumPacketSize = %d\n", pAd->BulkOutMaxPacketSize));
1125 DBGPRINT_RAW(RT_DEBUG_TRACE,
1126 ("EP address = 0x%2x \n", iface_desc->endpoint[i].desc.bEndpointAddress));
1130 if (!(pAd->BulkInEpAddr && pAd->BulkOutEpAddr[0]))
1132 printk("%s: Could not find both bulk-in and bulk-out endpoints\n", __func__);
1141 ========================================================================
1142 Routine Description:
1146 *pAd the raxx interface data pointer
1152 ========================================================================
1154 VOID RT28XXDMADisable(
1155 IN RTMP_ADAPTER *pAd)
1163 ========================================================================
1164 Routine Description:
1168 *pAd the raxx interface data pointer
1174 ========================================================================
1176 VOID RT28XXDMAEnable(
1177 IN RTMP_ADAPTER *pAd)
1179 WPDMA_GLO_CFG_STRUC GloCfg;
1180 USB_DMA_CFG_STRUC UsbCfg;
1184 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
1187 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
1188 if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
1191 DBGPRINT(RT_DEBUG_TRACE, ("==> DMABusy\n"));
1192 RTMPusecDelay(1000);
1198 GloCfg.field.EnTXWriteBackDDONE = 1;
1199 GloCfg.field.EnableRxDMA = 1;
1200 GloCfg.field.EnableTxDMA = 1;
1201 DBGPRINT(RT_DEBUG_TRACE, ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word));
1202 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
1205 UsbCfg.field.phyclear = 0;
1206 /* usb version is 1.1,do not use bulk in aggregation */
1207 if (pAd->BulkInMaxPacketSize == 512)
1208 UsbCfg.field.RxBulkAggEn = 1;
1209 /* for last packet, PBF might use more than limited, so minus 2 to prevent from error */
1210 UsbCfg.field.RxBulkAggLmt = (MAX_RXBULK_SIZE /1024)-3;
1211 UsbCfg.field.RxBulkAggTOut = 0x80; /* 2006-10-18 */
1212 UsbCfg.field.RxBulkEn = 1;
1213 UsbCfg.field.TxBulkEn = 1;
1215 RTUSBWriteMACRegister(pAd, USB_DMA_CFG, UsbCfg.word);
1220 ========================================================================
1221 Routine Description:
1222 Write Beacon buffer to Asic.
1225 *pAd the raxx interface data pointer
1231 ========================================================================
1233 VOID RT28xx_UpdateBeaconToAsic(
1234 IN RTMP_ADAPTER *pAd,
1239 PUCHAR pBeaconFrame = NULL;
1242 BEACON_SYNC_STRUCT *pBeaconSync = pAd->CommonCfg.pBeaconSync;
1244 // USHORT shortValue;
1245 BOOLEAN bBcnReq = FALSE;
1249 if (pBeaconFrame == NULL)
1251 DBGPRINT(RT_DEBUG_ERROR,("pBeaconFrame is NULL!\n"));
1255 if (pBeaconSync == NULL)
1257 DBGPRINT(RT_DEBUG_ERROR,("pBeaconSync is NULL!\n"));
1261 //if ((pAd->WdsTab.Mode == WDS_BRIDGE_MODE) ||
1262 // ((pAd->ApCfg.MBSSID[apidx].MSSIDDev == NULL) || !(pAd->ApCfg.MBSSID[apidx].MSSIDDev->flags & IFF_UP))
1264 if (bBcnReq == FALSE)
1266 /* when the ra interface is down, do not send its beacon frame */
1267 /* clear all zero */
1268 for(i=0; i<TXWI_SIZE; i+=4) {
1269 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, 0x00);
1271 pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
1272 NdisZeroMemory(pBeaconSync->BeaconTxWI[bcn_idx], TXWI_SIZE);
1276 ptr = (PUCHAR)&pAd->BeaconTxWI;
1277 #ifdef RT_BIG_ENDIAN
1278 RTMPWIEndianChange(ptr, TYPE_TXWI);
1280 if (NdisEqualMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE) == FALSE)
1281 { // If BeaconTxWI changed, we need to rewrite the TxWI for the Beacon frames.
1282 pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
1283 NdisMoveMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE);
1286 if ((pBeaconSync->BeaconBitMap & (1 << bcn_idx)) != (1 << bcn_idx))
1288 for (i=0; i<TXWI_SIZE; i+=4) // 16-byte TXWI field
1290 longValue = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
1291 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, longValue);
1296 ptr = pBeaconSync->BeaconBuf[bcn_idx];
1297 padding = (FrameLen & 0x01);
1298 NdisZeroMemory((PUCHAR)(pBeaconFrame + FrameLen), padding);
1299 FrameLen += padding;
1300 for (i = 0 ; i < FrameLen /*HW_BEACON_OFFSET*/; i += 2)
1302 if (NdisEqualMemory(ptr, pBeaconFrame, 2) == FALSE)
1304 NdisMoveMemory(ptr, pBeaconFrame, 2);
1305 //shortValue = *ptr + (*(ptr+1)<<8);
1306 //RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, shortValue);
1307 RTUSBMultiWrite(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, ptr, 2);
1313 pBeaconSync->BeaconBitMap |= (1 << bcn_idx);
1315 // For AP interface, set the DtimBitOn so that we can send Bcast/Mcast frame out after this beacon frame.
1321 VOID RT2870_BssBeaconStop(
1322 IN RTMP_ADAPTER *pAd)
1324 BEACON_SYNC_STRUCT *pBeaconSync;
1326 BOOLEAN Cancelled = TRUE;
1328 pBeaconSync = pAd->CommonCfg.pBeaconSync;
1329 if (pBeaconSync && pBeaconSync->EnableBeacon)
1334 #ifdef CONFIG_STA_SUPPORT
1335 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1337 NumOfBcn = MAX_MESH_NUM;
1339 #endif // CONFIG_STA_SUPPORT //
1341 RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
1343 for(i=0; i<NumOfBcn; i++)
1345 NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
1346 NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
1348 for (offset=0; offset<HW_BEACON_OFFSET; offset+=4)
1349 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[i] + offset, 0x00);
1351 pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
1352 pBeaconSync->TimIELocationInBeacon[i] = 0;
1354 pBeaconSync->BeaconBitMap = 0;
1355 pBeaconSync->DtimBitOn = 0;
1360 VOID RT2870_BssBeaconStart(
1361 IN RTMP_ADAPTER *pAd)
1364 BEACON_SYNC_STRUCT *pBeaconSync;
1365 // LARGE_INTEGER tsfTime, deltaTime;
1367 pBeaconSync = pAd->CommonCfg.pBeaconSync;
1368 if (pBeaconSync && pBeaconSync->EnableBeacon)
1373 #ifdef CONFIG_STA_SUPPORT
1374 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1376 NumOfBcn = MAX_MESH_NUM;
1378 #endif // CONFIG_STA_SUPPORT //
1380 for(apidx=0; apidx<NumOfBcn; apidx++)
1382 UCHAR CapabilityInfoLocationInBeacon = 0;
1383 UCHAR TimIELocationInBeacon = 0;
1385 #ifdef CONFIG_STA_SUPPORT
1386 #endif // CONFIG_STA_SUPPORT //
1388 NdisZeroMemory(pBeaconSync->BeaconBuf[apidx], HW_BEACON_OFFSET);
1389 pBeaconSync->CapabilityInfoLocationInBeacon[apidx] = CapabilityInfoLocationInBeacon;
1390 pBeaconSync->TimIELocationInBeacon[apidx] = TimIELocationInBeacon;
1391 NdisZeroMemory(pBeaconSync->BeaconTxWI[apidx], TXWI_SIZE);
1393 pBeaconSync->BeaconBitMap = 0;
1394 pBeaconSync->DtimBitOn = 0;
1395 pAd->CommonCfg.BeaconUpdateTimer.Repeat = TRUE;
1397 pAd->CommonCfg.BeaconAdjust = 0;
1398 pAd->CommonCfg.BeaconFactor = 0xffffffff / (pAd->CommonCfg.BeaconPeriod << 10);
1399 pAd->CommonCfg.BeaconRemain = (0xffffffff % (pAd->CommonCfg.BeaconPeriod << 10)) + 1;
1400 printk("RT2870_BssBeaconStart:BeaconFactor=%d, BeaconRemain=%d!\n", pAd->CommonCfg.BeaconFactor, pAd->CommonCfg.BeaconRemain);
1401 RTMPSetTimer(&pAd->CommonCfg.BeaconUpdateTimer, pAd->CommonCfg.BeaconPeriod);
1407 VOID RT2870_BssBeaconInit(
1408 IN RTMP_ADAPTER *pAd)
1410 BEACON_SYNC_STRUCT *pBeaconSync;
1413 NdisAllocMemory(pAd->CommonCfg.pBeaconSync, sizeof(BEACON_SYNC_STRUCT), MEM_ALLOC_FLAG);
1414 if (pAd->CommonCfg.pBeaconSync)
1416 pBeaconSync = pAd->CommonCfg.pBeaconSync;
1417 NdisZeroMemory(pBeaconSync, sizeof(BEACON_SYNC_STRUCT));
1418 for(i=0; i < HW_BEACON_MAX_COUNT; i++)
1420 NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
1421 pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
1422 pBeaconSync->TimIELocationInBeacon[i] = 0;
1423 NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
1425 pBeaconSync->BeaconBitMap = 0;
1427 //RTMPInitTimer(pAd, &pAd->CommonCfg.BeaconUpdateTimer, GET_TIMER_FUNCTION(BeaconUpdateExec), pAd, TRUE);
1428 pBeaconSync->EnableBeacon = TRUE;
1433 VOID RT2870_BssBeaconExit(
1434 IN RTMP_ADAPTER *pAd)
1436 BEACON_SYNC_STRUCT *pBeaconSync;
1437 BOOLEAN Cancelled = TRUE;
1440 if (pAd->CommonCfg.pBeaconSync)
1442 pBeaconSync = pAd->CommonCfg.pBeaconSync;
1443 pBeaconSync->EnableBeacon = FALSE;
1444 RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
1445 pBeaconSync->BeaconBitMap = 0;
1447 for(i=0; i<HW_BEACON_MAX_COUNT; i++)
1449 NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
1450 pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
1451 pBeaconSync->TimIELocationInBeacon[i] = 0;
1452 NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
1455 NdisFreeMemory(pAd->CommonCfg.pBeaconSync, HW_BEACON_OFFSET * HW_BEACON_MAX_COUNT, 0);
1456 pAd->CommonCfg.pBeaconSync = NULL;
1460 VOID BeaconUpdateExec(
1461 IN PVOID SystemSpecific1,
1462 IN PVOID FunctionContext,
1463 IN PVOID SystemSpecific2,
1464 IN PVOID SystemSpecific3)
1466 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)FunctionContext;
1467 LARGE_INTEGER tsfTime_a;//, tsfTime_b, deltaTime_exp, deltaTime_ab;
1468 UINT32 delta, remain, remain_low, remain_high;
1469 // BOOLEAN positive;
1471 ReSyncBeaconTime(pAd);
1475 RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &tsfTime_a.u.LowPart);
1476 RTMP_IO_READ32(pAd, TSF_TIMER_DW1, &tsfTime_a.u.HighPart);
1479 //positive=getDeltaTime(tsfTime_a, expectedTime, &deltaTime_exp);
1480 remain_high = pAd->CommonCfg.BeaconRemain * tsfTime_a.u.HighPart;
1481 remain_low = tsfTime_a.u.LowPart % (pAd->CommonCfg.BeaconPeriod << 10);
1482 remain = (remain_high + remain_low)%(pAd->CommonCfg.BeaconPeriod << 10);
1483 delta = (pAd->CommonCfg.BeaconPeriod << 10) - remain;
1485 pAd->CommonCfg.BeaconUpdateTimer.TimerValue = (delta >> 10) + 10;