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 MODULE_LICENSE("GPL");
51 MODULE_VERSION(STA_DRIVER_VERSION);
54 /* Kernel thread and vars, which handles packets that are completed. Only
55 * packets that have a "complete" function are sent here. This way, the
56 * completion is run out of kernel context, and doesn't block the rest of
58 //static int mlme_kill = 0; // Mlme kernel thread
59 //static int RTUSBCmd_kill = 0; // Command kernel thread
60 //static int TimerFunc_kill = 0; // TimerQ kernel thread
62 //static wait_queue_head_t timerWaitQ;
63 //static wait_queue_t waitQ;
65 extern INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p,
66 IN UINT argc, OUT PRTMP_ADAPTER *ppAd);
70 struct usb_device_id rtusb_usb_id[] = RT2870_USB_DEVICES;
71 INT const rtusb_usb_id_len = sizeof(rtusb_usb_id) / sizeof(struct usb_device_id);
72 MODULE_DEVICE_TABLE(usb, rtusb_usb_id);
80 static int rt2870_suspend(struct usb_interface *intf, pm_message_t state);
81 static int rt2870_resume(struct usb_interface *intf);
82 #endif // CONFIG_PM //
84 /**************************************************************************/
85 /**************************************************************************/
86 //tested for kernel 2.6series
87 /**************************************************************************/
88 /**************************************************************************/
89 static int rtusb_probe (struct usb_interface *intf,
90 const struct usb_device_id *id);
91 static void rtusb_disconnect(struct usb_interface *intf);
93 struct usb_driver rtusb_driver = {
96 .disconnect=rtusb_disconnect,
97 .id_table=rtusb_usb_id,
100 suspend: rt2870_suspend,
101 resume: rt2870_resume,
107 VOID RT2860RejectPendingPackets(
108 IN PRTMP_ADAPTER pAd)
111 // clear TxSw packets
114 static int rt2870_suspend(
115 struct usb_interface *intf,
118 struct net_device *net_dev;
119 PRTMP_ADAPTER pAd = usb_get_intfdata(intf);
122 DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_suspend()\n"));
123 net_dev = pAd->net_dev;
124 netif_device_detach(net_dev);
126 pAd->PM_FlgSuspend = 1;
127 if (netif_running(net_dev)) {
128 RTUSBCancelPendingBulkInIRP(pAd);
129 RTUSBCancelPendingBulkOutIRP(pAd);
131 DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_suspend()\n"));
135 static int rt2870_resume(
136 struct usb_interface *intf)
138 struct net_device *net_dev;
139 PRTMP_ADAPTER pAd = usb_get_intfdata(intf);
142 DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_resume()\n"));
144 pAd->PM_FlgSuspend = 0;
145 net_dev = pAd->net_dev;
146 netif_device_attach(net_dev);
147 netif_start_queue(net_dev);
148 netif_carrier_on(net_dev);
149 netif_wake_queue(net_dev);
151 DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_resume()\n"));
154 #endif // CONFIG_PM //
157 // Init driver module
158 INT __init rtusb_init(void)
160 printk("rtusb init --->\n");
161 return usb_register(&rtusb_driver);
164 // Deinit driver module
165 VOID __exit rtusb_exit(void)
167 usb_deregister(&rtusb_driver);
168 printk("<--- rtusb exit\n");
171 module_init(rtusb_init);
172 module_exit(rtusb_exit);
177 /*--------------------------------------------------------------------- */
178 /* function declarations */
179 /*--------------------------------------------------------------------- */
182 ========================================================================
187 *Context the pAd, driver control block pointer
193 ========================================================================
198 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)Context;
202 pObj = (POS_COOKIE)pAd->OS_Cookie;
204 rtmp_os_thread_init("rt2870MlmeThread", (PVOID)&(pAd->mlmeComplete));
206 while (pAd->mlme_kill == 0)
208 /* lock the device pointers */
209 //down(&(pAd->mlme_semaphore));
210 status = down_interruptible(&(pAd->mlme_semaphore));
212 /* lock the device pointers , need to check if required*/
213 //down(&(pAd->usbdev_semaphore));
215 if (!pAd->PM_FlgSuspend)
218 /* unlock the device pointers */
219 //up(&(pAd->usbdev_semaphore));
222 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
227 /* notify the exit routine that we're actually exiting now
229 * complete()/wait_for_completion() is similar to up()/down(),
230 * except that complete() is safe in the case where the structure
231 * is getting deleted in a parallel mode of execution (i.e. just
232 * after the down() -- that's necessary for the thread-shutdown
235 * complete_and_exit() goes even further than this -- it is safe in
236 * the case that the thread of the caller is going away (not just
237 * the structure) -- this is necessary for the module-remove case.
238 * This is important in preemption kernels, which transfer the flow
239 * of execution immediately upon a complete().
241 DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__func__));
243 pObj->MLMEThr_pid = NULL;
245 complete_and_exit (&pAd->mlmeComplete, 0);
252 ========================================================================
254 USB command kernel thread.
257 *Context the pAd, driver control block pointer
263 ========================================================================
268 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)Context;
272 pObj = (POS_COOKIE)pAd->OS_Cookie;
274 rtmp_os_thread_init("rt2870CmdThread", (PVOID)&(pAd->CmdQComplete));
276 NdisAcquireSpinLock(&pAd->CmdQLock);
277 pAd->CmdQ.CmdQState = RT2870_THREAD_RUNNING;
278 NdisReleaseSpinLock(&pAd->CmdQLock);
280 while (pAd->CmdQ.CmdQState == RT2870_THREAD_RUNNING)
282 /* lock the device pointers */
283 //down(&(pAd->RTUSBCmd_semaphore));
284 status = down_interruptible(&(pAd->RTUSBCmd_semaphore));
286 if (pAd->CmdQ.CmdQState == RT2870_THREAD_STOPED)
291 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
294 /* lock the device pointers , need to check if required*/
295 //down(&(pAd->usbdev_semaphore));
297 if (!pAd->PM_FlgSuspend)
300 /* unlock the device pointers */
301 //up(&(pAd->usbdev_semaphore));
304 if (!pAd->PM_FlgSuspend)
305 { // Clear the CmdQElements.
306 CmdQElmt *pCmdQElmt = NULL;
308 NdisAcquireSpinLock(&pAd->CmdQLock);
309 pAd->CmdQ.CmdQState = RT2870_THREAD_STOPED;
310 while(pAd->CmdQ.size)
312 RTUSBDequeueCmd(&pAd->CmdQ, &pCmdQElmt);
315 if (pCmdQElmt->CmdFromNdis == TRUE)
317 if (pCmdQElmt->buffer != NULL)
318 NdisFreeMemory(pCmdQElmt->buffer, pCmdQElmt->bufferlength, 0);
320 NdisFreeMemory(pCmdQElmt, sizeof(CmdQElmt), 0);
324 if ((pCmdQElmt->buffer != NULL) && (pCmdQElmt->bufferlength != 0))
325 NdisFreeMemory(pCmdQElmt->buffer, pCmdQElmt->bufferlength, 0);
327 NdisFreeMemory(pCmdQElmt, sizeof(CmdQElmt), 0);
333 NdisReleaseSpinLock(&pAd->CmdQLock);
335 /* notify the exit routine that we're actually exiting now
337 * complete()/wait_for_completion() is similar to up()/down(),
338 * except that complete() is safe in the case where the structure
339 * is getting deleted in a parallel mode of execution (i.e. just
340 * after the down() -- that's necessary for the thread-shutdown
343 * complete_and_exit() goes even further than this -- it is safe in
344 * the case that the thread of the caller is going away (not just
345 * the structure) -- this is necessary for the module-remove case.
346 * This is important in preemption kernels, which transfer the flow
347 * of execution immediately upon a complete().
349 DBGPRINT(RT_DEBUG_TRACE,( "<---RTUSBCmdThread\n"));
351 pObj->RTUSBCmdThr_pid = NULL;
353 complete_and_exit (&pAd->CmdQComplete, 0);
359 static void RT2870_TimerQ_Handle(RTMP_ADAPTER *pAd)
362 RALINK_TIMER_STRUCT *pTimer;
363 RT2870_TIMER_ENTRY *pEntry;
364 unsigned long irqFlag;
366 while(!pAd->TimerFunc_kill)
368 // printk("waiting for event!\n");
371 status = down_interruptible(&(pAd->RTUSBTimer_semaphore));
373 if (pAd->TimerQ.status == RT2870_THREAD_STOPED)
377 while(pAd->TimerQ.pQHead)
379 RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlag);
380 pEntry = pAd->TimerQ.pQHead;
383 pTimer = pEntry->pRaTimer;
386 pAd->TimerQ.pQHead = pEntry->pNext;
387 if (pEntry == pAd->TimerQ.pQTail)
388 pAd->TimerQ.pQTail = NULL;
390 // return this queue entry to timerQFreeList.
391 pEntry->pNext = pAd->TimerQ.pQPollFreeList;
392 pAd->TimerQ.pQPollFreeList = pEntry;
394 RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlag);
398 if (pTimer->handle != NULL)
399 if (!pAd->PM_FlgSuspend)
400 pTimer->handle(NULL, (PVOID) pTimer->cookie, NULL, pTimer);
401 if ((pTimer->Repeat) && (pTimer->State == FALSE))
402 RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue);
408 pAd->TimerQ.status = RT2870_THREAD_STOPED;
409 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
417 IN OUT PVOID Context)
422 pAd = (PRTMP_ADAPTER)Context;
423 pObj = (POS_COOKIE) pAd->OS_Cookie;
425 rtmp_os_thread_init("rt2870TimerQHandle", (PVOID)&(pAd->TimerQComplete));
427 RT2870_TimerQ_Handle(pAd);
429 /* notify the exit routine that we're actually exiting now
431 * complete()/wait_for_completion() is similar to up()/down(),
432 * except that complete() is safe in the case where the structure
433 * is getting deleted in a parallel mode of execution (i.e. just
434 * after the down() -- that's necessary for the thread-shutdown
437 * complete_and_exit() goes even further than this -- it is safe in
438 * the case that the thread of the caller is going away (not just
439 * the structure) -- this is necessary for the module-remove case.
440 * This is important in preemption kernels, which transfer the flow
441 * of execution immediately upon a complete().
443 DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__func__));
445 pObj->TimerQThr_pid = NULL;
447 complete_and_exit(&pAd->TimerQComplete, 0);
453 RT2870_TIMER_ENTRY *RT2870_TimerQ_Insert(
454 IN RTMP_ADAPTER *pAd,
455 IN RALINK_TIMER_STRUCT *pTimer)
457 RT2870_TIMER_ENTRY *pQNode = NULL, *pQTail;
458 unsigned long irqFlags;
461 RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
462 if (pAd->TimerQ.status & RT2870_THREAD_CAN_DO_INSERT)
464 if(pAd->TimerQ.pQPollFreeList)
466 pQNode = pAd->TimerQ.pQPollFreeList;
467 pAd->TimerQ.pQPollFreeList = pQNode->pNext;
469 pQNode->pRaTimer = pTimer;
470 pQNode->pNext = NULL;
472 pQTail = pAd->TimerQ.pQTail;
473 if (pAd->TimerQ.pQTail != NULL)
474 pQTail->pNext = pQNode;
475 pAd->TimerQ.pQTail = pQNode;
476 if (pAd->TimerQ.pQHead == NULL)
477 pAd->TimerQ.pQHead = pQNode;
479 RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
482 up(&pAd->RTUSBTimer_semaphore);
483 //wake_up(&timerWaitQ);
487 RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
493 BOOLEAN RT2870_TimerQ_Remove(
494 IN RTMP_ADAPTER *pAd,
495 IN RALINK_TIMER_STRUCT *pTimer)
497 RT2870_TIMER_ENTRY *pNode, *pPrev = NULL;
498 unsigned long irqFlags;
500 RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
501 if (pAd->TimerQ.status >= RT2870_THREAD_INITED)
503 pNode = pAd->TimerQ.pQHead;
506 if (pNode->pRaTimer == pTimer)
509 pNode = pNode->pNext;
512 // Now move it to freeList queue.
515 if (pNode == pAd->TimerQ.pQHead)
516 pAd->TimerQ.pQHead = pNode->pNext;
517 if (pNode == pAd->TimerQ.pQTail)
518 pAd->TimerQ.pQTail = pPrev;
520 pPrev->pNext = pNode->pNext;
522 // return this queue entry to timerQFreeList.
523 pNode->pNext = pAd->TimerQ.pQPollFreeList;
524 pAd->TimerQ.pQPollFreeList = pNode;
527 RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
533 void RT2870_TimerQ_Exit(RTMP_ADAPTER *pAd)
535 RT2870_TIMER_ENTRY *pTimerQ;
536 unsigned long irqFlags;
538 RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
539 while (pAd->TimerQ.pQHead)
541 pTimerQ = pAd->TimerQ.pQHead;
542 pAd->TimerQ.pQHead = pTimerQ->pNext;
545 pAd->TimerQ.pQPollFreeList = NULL;
546 os_free_mem(pAd, pAd->TimerQ.pTimerQPoll);
547 pAd->TimerQ.pQTail = NULL;
548 pAd->TimerQ.pQHead = NULL;
549 pAd->TimerQ.status = RT2870_THREAD_STOPED;
550 RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
555 void RT2870_TimerQ_Init(RTMP_ADAPTER *pAd)
558 RT2870_TIMER_ENTRY *pQNode, *pEntry;
559 unsigned long irqFlags;
561 NdisAllocateSpinLock(&pAd->TimerQLock);
563 RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
564 NdisZeroMemory(&pAd->TimerQ, sizeof(pAd->TimerQ));
565 //InterlockedExchange(&pAd->TimerQ.count, 0);
567 /* Initialise the wait q head */
568 //init_waitqueue_head(&timerWaitQ);
570 os_alloc_mem(pAd, &pAd->TimerQ.pTimerQPoll, sizeof(RT2870_TIMER_ENTRY) * TIMER_QUEUE_SIZE_MAX);
571 if (pAd->TimerQ.pTimerQPoll)
574 pQNode = (RT2870_TIMER_ENTRY *)pAd->TimerQ.pTimerQPoll;
575 for (i = 0 ;i <TIMER_QUEUE_SIZE_MAX; i++)
577 pQNode->pNext = pEntry;
581 pAd->TimerQ.pQPollFreeList = pEntry;
582 pAd->TimerQ.pQHead = NULL;
583 pAd->TimerQ.pQTail = NULL;
584 pAd->TimerQ.status = RT2870_THREAD_INITED;
586 RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
590 VOID RT2870_WatchDog(IN RTMP_ADAPTER *pAd)
592 PHT_TX_CONTEXT pHTTXContext;
596 BOOLEAN needDumpSeq = FALSE;
601 RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
602 if ((MACValue & 0xff) !=0 )
604 DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 0 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue));
605 RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40012);
606 while((MACValue &0xff) != 0 && (idx++ < 10))
608 RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
611 RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006);
614 //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
615 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
618 if ((MACValue & 0xff00) !=0 )
620 DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 1 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue));
621 RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf4000a);
622 while((MACValue &0xff00) != 0 && (idx++ < 10))
624 RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
627 RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006);
631 if (pAd->watchDogRxOverFlowCnt >= 2)
633 DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Rx Bulk-In hanged! Cancel the pending Rx bulks request!\n"));
634 if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
635 fRTMP_ADAPTER_BULKIN_RESET |
636 fRTMP_ADAPTER_HALT_IN_PROGRESS |
637 fRTMP_ADAPTER_NIC_NOT_EXIST))))
639 DBGPRINT(RT_DEBUG_TRACE, ("Call CMDTHREAD_RESET_BULK_IN to cancel the pending Rx Bulk!\n"));
640 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
641 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0);
644 pAd->watchDogRxOverFlowCnt = 0;
648 for (idx = 0; idx < NUM_OF_TX_RING; idx++)
652 RTMP_IRQ_LOCK(&pAd->BulkOutLock[idx], irqFlags);
653 if ((pAd->BulkOutPending[idx] == TRUE) && pAd->watchDogTxPendingCnt)
655 pAd->watchDogTxPendingCnt[idx]++;
657 if ((pAd->watchDogTxPendingCnt[idx] > 2) &&
658 (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_BULKOUT_RESET)))
661 // FIXME: Following code just support single bulk out. If you wanna support multiple bulk out. Modify it!
662 pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[idx]);
663 if (pHTTXContext->IRPPending)
664 { // Check TxContext.
665 pUrb = pHTTXContext->pUrb;
667 else if (idx == MGMTPIPEIDX)
669 PTX_CONTEXT pMLMEContext, pNULLContext, pPsPollContext;
672 pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa);
673 pPsPollContext = (PTX_CONTEXT)(&pAd->PsPollContext);
674 pNULLContext = (PTX_CONTEXT)(&pAd->NullContext);
676 if (pMLMEContext->IRPPending)
678 ASSERT(pMLMEContext->IRPPending);
679 pUrb = pMLMEContext->pUrb;
681 else if (pNULLContext->IRPPending)
683 ASSERT(pNULLContext->IRPPending);
684 pUrb = pNULLContext->pUrb;
686 else if (pPsPollContext->IRPPending)
688 ASSERT(pPsPollContext->IRPPending);
689 pUrb = pPsPollContext->pUrb;
693 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
695 DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Tx Bulk-Out hanged! Cancel the pending Tx bulks request of idx(%d)!\n", idx));
698 DBGPRINT(RT_DEBUG_TRACE, ("Unlink the pending URB!\n"));
700 RTUSB_UNLINK_URB(pUrb);
701 // Sleep 200 microseconds to give cancellation time to work
707 DBGPRINT(RT_DEBUG_ERROR, ("Unkonw bulkOut URB maybe hanged!!!!!!!!!!!!\n"));
712 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
717 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
721 #ifdef DOT11_N_SUPPORT
722 // For Sigma debug, dump the ba_reordering sequence.
723 if((needDumpSeq == TRUE) && (pAd->CommonCfg.bDisableReordering == 0))
726 PBA_REC_ENTRY pBAEntry = NULL;
728 struct reordering_mpdu *mpdu_blk;
730 Idx = pAd->MacTab.Content[BSSID_WCID].BARecWcidArray[0];
732 pBAEntry = &pAd->BATable.BARecEntry[Idx];
733 if((pBAEntry->list.qlen > 0) && (pBAEntry->list.next != NULL))
735 DBGPRINT(RT_DEBUG_TRACE, ("NICUpdateRawCounters():The Queueing pkt in reordering buffer:\n"));
736 NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
737 mpdu_blk = pBAEntry->list.next;
740 DBGPRINT(RT_DEBUG_TRACE, ("\t%d:Seq-%d, bAMSDU-%d!\n", count, mpdu_blk->Sequence, mpdu_blk->bAMSDU));
741 mpdu_blk = mpdu_blk->next;
745 DBGPRINT(RT_DEBUG_TRACE, ("\npBAEntry->LastIndSeq=%d!\n", pBAEntry->LastIndSeq));
746 NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
749 #endif // DOT11_N_SUPPORT //
753 ========================================================================
755 Release allocated resources.
758 *dev Point to the PCI or USB device
759 pAd driver control block pointer
765 ========================================================================
767 static void _rtusb_disconnect(struct usb_device *dev, PRTMP_ADAPTER pAd)
769 struct net_device *net_dev = NULL;
772 DBGPRINT(RT_DEBUG_ERROR, ("rtusb_disconnect: unregister usbnet usb-%s-%s\n",
773 dev->bus->bus_name, dev->devpath));
778 printk("rtusb_disconnect: pAd == NULL!\n");
781 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
785 // for debug, wait to show some messages to /proc system
791 net_dev = pAd->net_dev;
792 if (pAd->net_dev != NULL)
794 printk("rtusb_disconnect: unregister_netdev(), dev->name=%s!\n", net_dev->name);
795 unregister_netdev (pAd->net_dev);
798 flush_scheduled_work();
801 // free net_device memory
802 free_netdev(net_dev);
804 // free adapter memory
805 RTMPFreeAdapter(pAd);
807 // release a use of the usb device structure
811 DBGPRINT(RT_DEBUG_ERROR, (" RTUSB disconnect successfully\n"));
816 ========================================================================
818 Probe RT28XX chipset.
821 *dev Point to the PCI or USB device
823 *id_table Point to the PCI or USB device ID
829 ========================================================================
831 static int rtusb_probe (struct usb_interface *intf,
832 const struct usb_device_id *id)
835 return (int)rt28xx_probe((void *)intf, (void *)id, 0, &pAd);
839 static void rtusb_disconnect(struct usb_interface *intf)
841 struct usb_device *dev = interface_to_usbdev(intf);
845 pAd = usb_get_intfdata(intf);
846 usb_set_intfdata(intf, NULL);
848 _rtusb_disconnect(dev, pAd);
853 ========================================================================
855 Close kernel threads.
858 *pAd the raxx interface data pointer
864 ========================================================================
866 VOID RT28xxThreadTerminate(
867 IN RTMP_ADAPTER *pAd)
869 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
873 // Sleep 50 milliseconds so pending io might finish normally
874 RTMPusecDelay(50000);
876 // We want to wait until all pending receives and sends to the
877 // device object. We cancel any
878 // irps. Wait until sends and receives have stopped.
879 RTUSBCancelPendingIRPs(pAd);
882 if (pObj->MLMEThr_pid)
884 printk("Terminate the MLMEThr_pid=%d!\n", pid_nr(pObj->MLMEThr_pid));
887 //RT28XX_MLME_HANDLER(pAd);
889 ret = kill_pid(pObj->MLMEThr_pid, SIGTERM, 1);
892 printk (KERN_WARNING "%s: unable to Mlme thread, pid=%d, ret=%d!\n",
893 pAd->net_dev->name, pid_nr(pObj->MLMEThr_pid), ret);
897 //wait_for_completion (&pAd->notify);
898 wait_for_completion (&pAd->mlmeComplete);
899 pObj->MLMEThr_pid = NULL;
903 if (pObj->RTUSBCmdThr_pid >= 0)
905 printk("Terminate the RTUSBCmdThr_pid=%d!\n", pid_nr(pObj->RTUSBCmdThr_pid));
907 NdisAcquireSpinLock(&pAd->CmdQLock);
908 pAd->CmdQ.CmdQState = RT2870_THREAD_STOPED;
909 NdisReleaseSpinLock(&pAd->CmdQLock);
912 ret = kill_pid(pObj->RTUSBCmdThr_pid, SIGTERM, 1);
915 printk(KERN_WARNING "%s: unable to RTUSBCmd thread, pid=%d, ret=%d!\n",
916 pAd->net_dev->name, pid_nr(pObj->RTUSBCmdThr_pid), ret);
920 //wait_for_completion (&pAd->notify);
921 wait_for_completion (&pAd->CmdQComplete);
922 pObj->RTUSBCmdThr_pid = NULL;
925 if (pObj->TimerQThr_pid >= 0)
927 POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
929 printk("Terminate the TimerQThr_pid=%d!\n", pid_nr(pObj->TimerQThr_pid));
931 pAd->TimerFunc_kill = 1;
933 ret = kill_pid(pObj->TimerQThr_pid, SIGTERM, 1);
936 printk(KERN_WARNING "%s: unable to stop TimerQThread, pid=%d, ret=%d!\n",
937 pAd->net_dev->name, pid_nr(pObj->TimerQThr_pid), ret);
941 printk("wait_for_completion TimerQThr\n");
942 wait_for_completion(&pAd->TimerQComplete);
943 pObj->TimerQThr_pid = NULL;
948 pAd->CmdQ.CmdQState = RT2870_THREAD_UNKNOWN;
949 pAd->TimerFunc_kill = 0;
953 void kill_thread_task(IN PRTMP_ADAPTER pAd)
957 pObj = (POS_COOKIE) pAd->OS_Cookie;
959 tasklet_kill(&pObj->rx_done_task);
960 tasklet_kill(&pObj->mgmt_dma_done_task);
961 tasklet_kill(&pObj->ac0_dma_done_task);
962 tasklet_kill(&pObj->ac1_dma_done_task);
963 tasklet_kill(&pObj->ac2_dma_done_task);
964 tasklet_kill(&pObj->ac3_dma_done_task);
965 tasklet_kill(&pObj->hcca_dma_done_task);
966 tasklet_kill(&pObj->tbtt_task);
972 ========================================================================
974 Check the chipset vendor/product ID.
977 _dev_p Point to the PCI or USB device
984 ========================================================================
986 BOOLEAN RT28XXChipsetCheck(
989 struct usb_interface *intf = (struct usb_interface *)_dev_p;
990 struct usb_device *dev_p = interface_to_usbdev(intf);
994 for(i=0; i<rtusb_usb_id_len; i++)
996 if (dev_p->descriptor.idVendor == rtusb_usb_id[i].idVendor &&
997 dev_p->descriptor.idProduct == rtusb_usb_id[i].idProduct)
999 printk("rt2870: idVendor = 0x%x, idProduct = 0x%x\n",
1000 dev_p->descriptor.idVendor, dev_p->descriptor.idProduct);
1005 if (i == rtusb_usb_id_len)
1007 printk("rt2870: Error! Device Descriptor not matching!\n");
1016 ========================================================================
1017 Routine Description:
1018 Init net device structure.
1021 _dev_p Point to the PCI or USB device
1022 *net_dev Point to the net device
1023 *pAd the raxx interface data pointer
1030 ========================================================================
1032 BOOLEAN RT28XXNetDevInit(
1034 IN struct net_device *net_dev,
1035 IN RTMP_ADAPTER *pAd)
1037 struct usb_interface *intf = (struct usb_interface *)_dev_p;
1038 struct usb_device *dev_p = interface_to_usbdev(intf);
1041 pAd->config = &dev_p->config->desc;
1047 ========================================================================
1048 Routine Description:
1049 Init net device structure.
1052 _dev_p Point to the PCI or USB device
1053 *pAd the raxx interface data pointer
1060 ========================================================================
1062 BOOLEAN RT28XXProbePostConfig(
1064 IN RTMP_ADAPTER *pAd,
1067 struct usb_interface *intf = (struct usb_interface *)_dev_p;
1068 struct usb_host_interface *iface_desc;
1073 /* get the active interface descriptor */
1074 iface_desc = intf->cur_altsetting;
1076 /* get # of enpoints */
1077 pAd->NumberOfPipes = iface_desc->desc.bNumEndpoints;
1078 DBGPRINT(RT_DEBUG_TRACE,
1079 ("NumEndpoints=%d\n", iface_desc->desc.bNumEndpoints));
1081 /* Configure Pipes */
1084 for(i=0; i<pAd->NumberOfPipes; i++)
1086 if ((iface_desc->endpoint[i].desc.bmAttributes ==
1087 USB_ENDPOINT_XFER_BULK) &&
1088 ((iface_desc->endpoint[i].desc.bEndpointAddress &
1089 USB_ENDPOINT_DIR_MASK) == USB_DIR_IN))
1091 pAd->BulkInEpAddr = iface_desc->endpoint[i].desc.bEndpointAddress;
1092 pAd->BulkInMaxPacketSize = iface_desc->endpoint[i].desc.wMaxPacketSize;
1094 DBGPRINT_RAW(RT_DEBUG_TRACE,
1095 ("BULK IN MaximumPacketSize = %d\n", pAd->BulkInMaxPacketSize));
1096 DBGPRINT_RAW(RT_DEBUG_TRACE,
1097 ("EP address = 0x%2x\n", iface_desc->endpoint[i].desc.bEndpointAddress));
1099 else if ((iface_desc->endpoint[i].desc.bmAttributes ==
1100 USB_ENDPOINT_XFER_BULK) &&
1101 ((iface_desc->endpoint[i].desc.bEndpointAddress &
1102 USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT))
1104 // there are 6 bulk out EP. EP6 highest priority.
1105 // EP1-4 is EDCA. EP5 is HCCA.
1106 pAd->BulkOutEpAddr[BulkOutIdx++] = iface_desc->endpoint[i].desc.bEndpointAddress;
1107 pAd->BulkOutMaxPacketSize = iface_desc->endpoint[i].desc.wMaxPacketSize;
1109 DBGPRINT_RAW(RT_DEBUG_TRACE,
1110 ("BULK OUT MaximumPacketSize = %d\n", pAd->BulkOutMaxPacketSize));
1111 DBGPRINT_RAW(RT_DEBUG_TRACE,
1112 ("EP address = 0x%2x \n", iface_desc->endpoint[i].desc.bEndpointAddress));
1116 if (!(pAd->BulkInEpAddr && pAd->BulkOutEpAddr[0]))
1118 printk("%s: Could not find both bulk-in and bulk-out endpoints\n", __func__);
1127 ========================================================================
1128 Routine Description:
1132 *pAd the raxx interface data pointer
1138 ========================================================================
1140 VOID RT28XXDMADisable(
1141 IN RTMP_ADAPTER *pAd)
1149 ========================================================================
1150 Routine Description:
1154 *pAd the raxx interface data pointer
1160 ========================================================================
1162 VOID RT28XXDMAEnable(
1163 IN RTMP_ADAPTER *pAd)
1165 WPDMA_GLO_CFG_STRUC GloCfg;
1166 USB_DMA_CFG_STRUC UsbCfg;
1170 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
1173 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
1174 if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
1177 DBGPRINT(RT_DEBUG_TRACE, ("==> DMABusy\n"));
1178 RTMPusecDelay(1000);
1184 GloCfg.field.EnTXWriteBackDDONE = 1;
1185 GloCfg.field.EnableRxDMA = 1;
1186 GloCfg.field.EnableTxDMA = 1;
1187 DBGPRINT(RT_DEBUG_TRACE, ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word));
1188 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
1191 UsbCfg.field.phyclear = 0;
1192 /* usb version is 1.1,do not use bulk in aggregation */
1193 if (pAd->BulkInMaxPacketSize == 512)
1194 UsbCfg.field.RxBulkAggEn = 1;
1195 /* for last packet, PBF might use more than limited, so minus 2 to prevent from error */
1196 UsbCfg.field.RxBulkAggLmt = (MAX_RXBULK_SIZE /1024)-3;
1197 UsbCfg.field.RxBulkAggTOut = 0x80; /* 2006-10-18 */
1198 UsbCfg.field.RxBulkEn = 1;
1199 UsbCfg.field.TxBulkEn = 1;
1201 RTUSBWriteMACRegister(pAd, USB_DMA_CFG, UsbCfg.word);
1206 ========================================================================
1207 Routine Description:
1208 Write Beacon buffer to Asic.
1211 *pAd the raxx interface data pointer
1217 ========================================================================
1219 VOID RT28xx_UpdateBeaconToAsic(
1220 IN RTMP_ADAPTER *pAd,
1225 PUCHAR pBeaconFrame = NULL;
1228 BEACON_SYNC_STRUCT *pBeaconSync = pAd->CommonCfg.pBeaconSync;
1230 // USHORT shortValue;
1231 BOOLEAN bBcnReq = FALSE;
1235 if (pBeaconFrame == NULL)
1237 DBGPRINT(RT_DEBUG_ERROR,("pBeaconFrame is NULL!\n"));
1241 if (pBeaconSync == NULL)
1243 DBGPRINT(RT_DEBUG_ERROR,("pBeaconSync is NULL!\n"));
1247 //if ((pAd->WdsTab.Mode == WDS_BRIDGE_MODE) ||
1248 // ((pAd->ApCfg.MBSSID[apidx].MSSIDDev == NULL) || !(pAd->ApCfg.MBSSID[apidx].MSSIDDev->flags & IFF_UP))
1250 if (bBcnReq == FALSE)
1252 /* when the ra interface is down, do not send its beacon frame */
1253 /* clear all zero */
1254 for(i=0; i<TXWI_SIZE; i+=4) {
1255 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, 0x00);
1257 pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
1258 NdisZeroMemory(pBeaconSync->BeaconTxWI[bcn_idx], TXWI_SIZE);
1262 ptr = (PUCHAR)&pAd->BeaconTxWI;
1264 if (NdisEqualMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE) == FALSE)
1265 { // If BeaconTxWI changed, we need to rewrite the TxWI for the Beacon frames.
1266 pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
1267 NdisMoveMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE);
1270 if ((pBeaconSync->BeaconBitMap & (1 << bcn_idx)) != (1 << bcn_idx))
1272 for (i=0; i<TXWI_SIZE; i+=4) // 16-byte TXWI field
1274 longValue = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
1275 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, longValue);
1280 ptr = pBeaconSync->BeaconBuf[bcn_idx];
1281 padding = (FrameLen & 0x01);
1282 NdisZeroMemory((PUCHAR)(pBeaconFrame + FrameLen), padding);
1283 FrameLen += padding;
1284 for (i = 0 ; i < FrameLen /*HW_BEACON_OFFSET*/; i += 2)
1286 if (NdisEqualMemory(ptr, pBeaconFrame, 2) == FALSE)
1288 NdisMoveMemory(ptr, pBeaconFrame, 2);
1289 //shortValue = *ptr + (*(ptr+1)<<8);
1290 //RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, shortValue);
1291 RTUSBMultiWrite(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, ptr, 2);
1297 pBeaconSync->BeaconBitMap |= (1 << bcn_idx);
1299 // For AP interface, set the DtimBitOn so that we can send Bcast/Mcast frame out after this beacon frame.
1305 VOID RT2870_BssBeaconStop(
1306 IN RTMP_ADAPTER *pAd)
1308 BEACON_SYNC_STRUCT *pBeaconSync;
1310 BOOLEAN Cancelled = TRUE;
1312 pBeaconSync = pAd->CommonCfg.pBeaconSync;
1313 if (pBeaconSync && pBeaconSync->EnableBeacon)
1317 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1319 NumOfBcn = MAX_MESH_NUM;
1322 RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
1324 for(i=0; i<NumOfBcn; i++)
1326 NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
1327 NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
1329 for (offset=0; offset<HW_BEACON_OFFSET; offset+=4)
1330 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[i] + offset, 0x00);
1332 pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
1333 pBeaconSync->TimIELocationInBeacon[i] = 0;
1335 pBeaconSync->BeaconBitMap = 0;
1336 pBeaconSync->DtimBitOn = 0;
1341 VOID RT2870_BssBeaconStart(
1342 IN RTMP_ADAPTER *pAd)
1345 BEACON_SYNC_STRUCT *pBeaconSync;
1346 // LARGE_INTEGER tsfTime, deltaTime;
1348 pBeaconSync = pAd->CommonCfg.pBeaconSync;
1349 if (pBeaconSync && pBeaconSync->EnableBeacon)
1353 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1355 NumOfBcn = MAX_MESH_NUM;
1358 for(apidx=0; apidx<NumOfBcn; apidx++)
1360 UCHAR CapabilityInfoLocationInBeacon = 0;
1361 UCHAR TimIELocationInBeacon = 0;
1363 NdisZeroMemory(pBeaconSync->BeaconBuf[apidx], HW_BEACON_OFFSET);
1364 pBeaconSync->CapabilityInfoLocationInBeacon[apidx] = CapabilityInfoLocationInBeacon;
1365 pBeaconSync->TimIELocationInBeacon[apidx] = TimIELocationInBeacon;
1366 NdisZeroMemory(pBeaconSync->BeaconTxWI[apidx], TXWI_SIZE);
1368 pBeaconSync->BeaconBitMap = 0;
1369 pBeaconSync->DtimBitOn = 0;
1370 pAd->CommonCfg.BeaconUpdateTimer.Repeat = TRUE;
1372 pAd->CommonCfg.BeaconAdjust = 0;
1373 pAd->CommonCfg.BeaconFactor = 0xffffffff / (pAd->CommonCfg.BeaconPeriod << 10);
1374 pAd->CommonCfg.BeaconRemain = (0xffffffff % (pAd->CommonCfg.BeaconPeriod << 10)) + 1;
1375 printk("RT2870_BssBeaconStart:BeaconFactor=%d, BeaconRemain=%d!\n", pAd->CommonCfg.BeaconFactor, pAd->CommonCfg.BeaconRemain);
1376 RTMPSetTimer(&pAd->CommonCfg.BeaconUpdateTimer, pAd->CommonCfg.BeaconPeriod);
1382 VOID RT2870_BssBeaconInit(
1383 IN RTMP_ADAPTER *pAd)
1385 BEACON_SYNC_STRUCT *pBeaconSync;
1388 NdisAllocMemory(pAd->CommonCfg.pBeaconSync, sizeof(BEACON_SYNC_STRUCT), MEM_ALLOC_FLAG);
1389 if (pAd->CommonCfg.pBeaconSync)
1391 pBeaconSync = pAd->CommonCfg.pBeaconSync;
1392 NdisZeroMemory(pBeaconSync, sizeof(BEACON_SYNC_STRUCT));
1393 for(i=0; i < HW_BEACON_MAX_COUNT; i++)
1395 NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
1396 pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
1397 pBeaconSync->TimIELocationInBeacon[i] = 0;
1398 NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
1400 pBeaconSync->BeaconBitMap = 0;
1402 //RTMPInitTimer(pAd, &pAd->CommonCfg.BeaconUpdateTimer, GET_TIMER_FUNCTION(BeaconUpdateExec), pAd, TRUE);
1403 pBeaconSync->EnableBeacon = TRUE;
1408 VOID RT2870_BssBeaconExit(
1409 IN RTMP_ADAPTER *pAd)
1411 BEACON_SYNC_STRUCT *pBeaconSync;
1412 BOOLEAN Cancelled = TRUE;
1415 if (pAd->CommonCfg.pBeaconSync)
1417 pBeaconSync = pAd->CommonCfg.pBeaconSync;
1418 pBeaconSync->EnableBeacon = FALSE;
1419 RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
1420 pBeaconSync->BeaconBitMap = 0;
1422 for(i=0; i<HW_BEACON_MAX_COUNT; i++)
1424 NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
1425 pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
1426 pBeaconSync->TimIELocationInBeacon[i] = 0;
1427 NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
1430 NdisFreeMemory(pAd->CommonCfg.pBeaconSync, HW_BEACON_OFFSET * HW_BEACON_MAX_COUNT, 0);
1431 pAd->CommonCfg.pBeaconSync = NULL;
1435 VOID BeaconUpdateExec(
1436 IN PVOID SystemSpecific1,
1437 IN PVOID FunctionContext,
1438 IN PVOID SystemSpecific2,
1439 IN PVOID SystemSpecific3)
1441 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)FunctionContext;
1442 LARGE_INTEGER tsfTime_a;//, tsfTime_b, deltaTime_exp, deltaTime_ab;
1443 UINT32 delta, remain, remain_low, remain_high;
1444 // BOOLEAN positive;
1446 ReSyncBeaconTime(pAd);
1450 RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &tsfTime_a.u.LowPart);
1451 RTMP_IO_READ32(pAd, TSF_TIMER_DW1, &tsfTime_a.u.HighPart);
1454 //positive=getDeltaTime(tsfTime_a, expectedTime, &deltaTime_exp);
1455 remain_high = pAd->CommonCfg.BeaconRemain * tsfTime_a.u.HighPart;
1456 remain_low = tsfTime_a.u.LowPart % (pAd->CommonCfg.BeaconPeriod << 10);
1457 remain = (remain_high + remain_low)%(pAd->CommonCfg.BeaconPeriod << 10);
1458 delta = (pAd->CommonCfg.BeaconPeriod << 10) - remain;
1460 pAd->CommonCfg.BeaconUpdateTimer.TimerValue = (delta >> 10) + 10;