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
66 extern INT __devinit
rt28xx_probe(IN
void *_dev_p
, IN
void *_dev_id_p
,
67 IN UINT argc
, OUT PRTMP_ADAPTER
*ppAd
);
71 struct usb_device_id rtusb_usb_id
[] = RT2870_USB_DEVICES
;
72 INT
const rtusb_usb_id_len
= sizeof(rtusb_usb_id
) / sizeof(struct usb_device_id
);
73 MODULE_DEVICE_TABLE(usb
, rtusb_usb_id
);
80 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
82 /**************************************************************************/
83 /**************************************************************************/
84 //tested for kernel 2.4 series
85 /**************************************************************************/
86 /**************************************************************************/
87 static void *rtusb_probe(struct usb_device
*dev
, UINT interface
,
88 const struct usb_device_id
*id_table
);
89 static void rtusb_disconnect(struct usb_device
*dev
, void *ptr
);
91 struct usb_driver rtusb_driver
= {
94 disconnect
:rtusb_disconnect
,
95 id_table
:rtusb_usb_id
,
101 static int rt2870_suspend(struct usb_interface
*intf
, pm_message_t state
);
102 static int rt2870_resume(struct usb_interface
*intf
);
103 #endif // CONFIG_PM //
105 /**************************************************************************/
106 /**************************************************************************/
107 //tested for kernel 2.6series
108 /**************************************************************************/
109 /**************************************************************************/
110 static int rtusb_probe (struct usb_interface
*intf
,
111 const struct usb_device_id
*id
);
112 static void rtusb_disconnect(struct usb_interface
*intf
);
114 struct usb_driver rtusb_driver
= {
115 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
116 .owner
= THIS_MODULE
,
120 .disconnect
=rtusb_disconnect
,
121 .id_table
=rtusb_usb_id
,
124 suspend
: rt2870_suspend
,
125 resume
: rt2870_resume
,
131 VOID
RT2860RejectPendingPackets(
132 IN PRTMP_ADAPTER pAd
)
135 // clear TxSw packets
138 static int rt2870_suspend(
139 struct usb_interface
*intf
,
142 struct net_device
*net_dev
;
143 PRTMP_ADAPTER pAd
= usb_get_intfdata(intf
);
146 DBGPRINT(RT_DEBUG_TRACE
, ("===> rt2870_suspend()\n"));
147 net_dev
= pAd
->net_dev
;
148 netif_device_detach (net_dev
);
150 pAd
->PM_FlgSuspend
= 1;
151 if (netif_running(net_dev
)) {
152 RTUSBCancelPendingBulkInIRP(pAd
);
153 RTUSBCancelPendingBulkOutIRP(pAd
);
155 DBGPRINT(RT_DEBUG_TRACE
, ("<=== rt2870_suspend()\n"));
159 static int rt2870_resume(
160 struct usb_interface
*intf
)
162 struct net_device
*net_dev
;
163 PRTMP_ADAPTER pAd
= usb_get_intfdata(intf
);
166 DBGPRINT(RT_DEBUG_TRACE
, ("===> rt2870_resume()\n"));
168 pAd
->PM_FlgSuspend
= 0;
169 net_dev
= pAd
->net_dev
;
170 netif_device_attach (net_dev
);
171 netif_start_queue(net_dev
);
172 netif_carrier_on(net_dev
);
173 netif_wake_queue(net_dev
);
175 DBGPRINT(RT_DEBUG_TRACE
, ("<=== rt2870_resume()\n"));
178 #endif // CONFIG_PM //
179 #endif // LINUX_VERSION_CODE //
182 // Init driver module
183 INT __init
rtusb_init(void)
185 printk("rtusb init --->\n");
186 return usb_register(&rtusb_driver
);
189 // Deinit driver module
190 VOID __exit
rtusb_exit(void)
192 usb_deregister(&rtusb_driver
);
193 printk("<--- rtusb exit\n");
196 module_init(rtusb_init
);
197 module_exit(rtusb_exit
);
202 /*--------------------------------------------------------------------- */
203 /* function declarations */
204 /*--------------------------------------------------------------------- */
207 ========================================================================
212 *Context the pAd, driver control block pointer
218 ========================================================================
223 PRTMP_ADAPTER pAd
= (PRTMP_ADAPTER
)Context
;
227 pObj
= (POS_COOKIE
)pAd
->OS_Cookie
;
229 rtmp_os_thread_init("rt2870MlmeThread", (PVOID
)&(pAd
->mlmeComplete
));
231 while (pAd
->mlme_kill
== 0)
233 /* lock the device pointers */
234 //down(&(pAd->mlme_semaphore));
235 status
= down_interruptible(&(pAd
->mlme_semaphore
));
237 /* lock the device pointers , need to check if required*/
238 //down(&(pAd->usbdev_semaphore));
240 if (!pAd
->PM_FlgSuspend
)
243 /* unlock the device pointers */
244 //up(&(pAd->usbdev_semaphore));
247 RTMP_SET_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
);
252 /* notify the exit routine that we're actually exiting now
254 * complete()/wait_for_completion() is similar to up()/down(),
255 * except that complete() is safe in the case where the structure
256 * is getting deleted in a parallel mode of execution (i.e. just
257 * after the down() -- that's necessary for the thread-shutdown
260 * complete_and_exit() goes even further than this -- it is safe in
261 * the case that the thread of the caller is going away (not just
262 * the structure) -- this is necessary for the module-remove case.
263 * This is important in preemption kernels, which transfer the flow
264 * of execution immediately upon a complete().
266 DBGPRINT(RT_DEBUG_TRACE
,( "<---%s\n",__FUNCTION__
));
268 pObj
->MLMEThr_pid
= THREAD_PID_INIT_VALUE
;
270 complete_and_exit (&pAd
->mlmeComplete
, 0);
277 ========================================================================
279 USB command kernel thread.
282 *Context the pAd, driver control block pointer
288 ========================================================================
293 PRTMP_ADAPTER pAd
= (PRTMP_ADAPTER
)Context
;
297 pObj
= (POS_COOKIE
)pAd
->OS_Cookie
;
299 rtmp_os_thread_init("rt2870CmdThread", (PVOID
)&(pAd
->CmdQComplete
));
301 NdisAcquireSpinLock(&pAd
->CmdQLock
);
302 pAd
->CmdQ
.CmdQState
= RT2870_THREAD_RUNNING
;
303 NdisReleaseSpinLock(&pAd
->CmdQLock
);
305 while (pAd
->CmdQ
.CmdQState
== RT2870_THREAD_RUNNING
)
307 /* lock the device pointers */
308 //down(&(pAd->RTUSBCmd_semaphore));
309 status
= down_interruptible(&(pAd
->RTUSBCmd_semaphore
));
311 if (pAd
->CmdQ
.CmdQState
== RT2870_THREAD_STOPED
)
316 RTMP_SET_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
);
319 /* lock the device pointers , need to check if required*/
320 //down(&(pAd->usbdev_semaphore));
322 if (!pAd
->PM_FlgSuspend
)
325 /* unlock the device pointers */
326 //up(&(pAd->usbdev_semaphore));
329 if (!pAd
->PM_FlgSuspend
)
330 { // Clear the CmdQElements.
331 CmdQElmt
*pCmdQElmt
= NULL
;
333 NdisAcquireSpinLock(&pAd
->CmdQLock
);
334 pAd
->CmdQ
.CmdQState
= RT2870_THREAD_STOPED
;
335 while(pAd
->CmdQ
.size
)
337 RTUSBDequeueCmd(&pAd
->CmdQ
, &pCmdQElmt
);
340 if (pCmdQElmt
->CmdFromNdis
== TRUE
)
342 if (pCmdQElmt
->buffer
!= NULL
)
343 NdisFreeMemory(pCmdQElmt
->buffer
, pCmdQElmt
->bufferlength
, 0);
345 NdisFreeMemory(pCmdQElmt
, sizeof(CmdQElmt
), 0);
349 if ((pCmdQElmt
->buffer
!= NULL
) && (pCmdQElmt
->bufferlength
!= 0))
350 NdisFreeMemory(pCmdQElmt
->buffer
, pCmdQElmt
->bufferlength
, 0);
352 NdisFreeMemory(pCmdQElmt
, sizeof(CmdQElmt
), 0);
358 NdisReleaseSpinLock(&pAd
->CmdQLock
);
360 /* notify the exit routine that we're actually exiting now
362 * complete()/wait_for_completion() is similar to up()/down(),
363 * except that complete() is safe in the case where the structure
364 * is getting deleted in a parallel mode of execution (i.e. just
365 * after the down() -- that's necessary for the thread-shutdown
368 * complete_and_exit() goes even further than this -- it is safe in
369 * the case that the thread of the caller is going away (not just
370 * the structure) -- this is necessary for the module-remove case.
371 * This is important in preemption kernels, which transfer the flow
372 * of execution immediately upon a complete().
374 DBGPRINT(RT_DEBUG_TRACE
,( "<---RTUSBCmdThread\n"));
376 pObj
->RTUSBCmdThr_pid
= THREAD_PID_INIT_VALUE
;
378 complete_and_exit (&pAd
->CmdQComplete
, 0);
384 static void RT2870_TimerQ_Handle(RTMP_ADAPTER
*pAd
)
387 RALINK_TIMER_STRUCT
*pTimer
;
388 RT2870_TIMER_ENTRY
*pEntry
;
389 unsigned long irqFlag
;
391 while(!pAd
->TimerFunc_kill
)
393 // printk("waiting for event!\n");
396 status
= down_interruptible(&(pAd
->RTUSBTimer_semaphore
));
398 if (pAd
->TimerQ
.status
== RT2870_THREAD_STOPED
)
402 while(pAd
->TimerQ
.pQHead
)
404 RTMP_IRQ_LOCK(&pAd
->TimerQLock
, irqFlag
);
405 pEntry
= pAd
->TimerQ
.pQHead
;
408 pTimer
= pEntry
->pRaTimer
;
411 pAd
->TimerQ
.pQHead
= pEntry
->pNext
;
412 if (pEntry
== pAd
->TimerQ
.pQTail
)
413 pAd
->TimerQ
.pQTail
= NULL
;
415 // return this queue entry to timerQFreeList.
416 pEntry
->pNext
= pAd
->TimerQ
.pQPollFreeList
;
417 pAd
->TimerQ
.pQPollFreeList
= pEntry
;
419 RTMP_IRQ_UNLOCK(&pAd
->TimerQLock
, irqFlag
);
423 if (pTimer
->handle
!= NULL
)
424 if (!pAd
->PM_FlgSuspend
)
425 pTimer
->handle(NULL
, (PVOID
) pTimer
->cookie
, NULL
, pTimer
);
426 if ((pTimer
->Repeat
) && (pTimer
->State
== FALSE
))
427 RTMP_OS_Add_Timer(&pTimer
->TimerObj
, pTimer
->TimerValue
);
433 pAd
->TimerQ
.status
= RT2870_THREAD_STOPED
;
434 RTMP_SET_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
);
442 IN OUT PVOID Context
)
447 pAd
= (PRTMP_ADAPTER
)Context
;
448 pObj
= (POS_COOKIE
) pAd
->OS_Cookie
;
450 rtmp_os_thread_init("rt2870TimerQHandle", (PVOID
)&(pAd
->TimerQComplete
));
452 RT2870_TimerQ_Handle(pAd
);
454 /* notify the exit routine that we're actually exiting now
456 * complete()/wait_for_completion() is similar to up()/down(),
457 * except that complete() is safe in the case where the structure
458 * is getting deleted in a parallel mode of execution (i.e. just
459 * after the down() -- that's necessary for the thread-shutdown
462 * complete_and_exit() goes even further than this -- it is safe in
463 * the case that the thread of the caller is going away (not just
464 * the structure) -- this is necessary for the module-remove case.
465 * This is important in preemption kernels, which transfer the flow
466 * of execution immediately upon a complete().
468 DBGPRINT(RT_DEBUG_TRACE
,( "<---%s\n",__FUNCTION__
));
470 pObj
->TimerQThr_pid
= THREAD_PID_INIT_VALUE
;
472 complete_and_exit(&pAd
->TimerQComplete
, 0);
478 RT2870_TIMER_ENTRY
*RT2870_TimerQ_Insert(
479 IN RTMP_ADAPTER
*pAd
,
480 IN RALINK_TIMER_STRUCT
*pTimer
)
482 RT2870_TIMER_ENTRY
*pQNode
= NULL
, *pQTail
;
483 unsigned long irqFlags
;
486 RTMP_IRQ_LOCK(&pAd
->TimerQLock
, irqFlags
);
487 if (pAd
->TimerQ
.status
& RT2870_THREAD_CAN_DO_INSERT
)
489 if(pAd
->TimerQ
.pQPollFreeList
)
491 pQNode
= pAd
->TimerQ
.pQPollFreeList
;
492 pAd
->TimerQ
.pQPollFreeList
= pQNode
->pNext
;
494 pQNode
->pRaTimer
= pTimer
;
495 pQNode
->pNext
= NULL
;
497 pQTail
= pAd
->TimerQ
.pQTail
;
498 if (pAd
->TimerQ
.pQTail
!= NULL
)
499 pQTail
->pNext
= pQNode
;
500 pAd
->TimerQ
.pQTail
= pQNode
;
501 if (pAd
->TimerQ
.pQHead
== NULL
)
502 pAd
->TimerQ
.pQHead
= pQNode
;
504 RTMP_IRQ_UNLOCK(&pAd
->TimerQLock
, irqFlags
);
507 up(&pAd
->RTUSBTimer_semaphore
);
508 //wake_up(&timerWaitQ);
512 RTMP_IRQ_UNLOCK(&pAd
->TimerQLock
, irqFlags
);
518 BOOLEAN
RT2870_TimerQ_Remove(
519 IN RTMP_ADAPTER
*pAd
,
520 IN RALINK_TIMER_STRUCT
*pTimer
)
522 RT2870_TIMER_ENTRY
*pNode
, *pPrev
= NULL
;
523 unsigned long irqFlags
;
525 RTMP_IRQ_LOCK(&pAd
->TimerQLock
, irqFlags
);
526 if (pAd
->TimerQ
.status
>= RT2870_THREAD_INITED
)
528 pNode
= pAd
->TimerQ
.pQHead
;
531 if (pNode
->pRaTimer
== pTimer
)
534 pNode
= pNode
->pNext
;
537 // Now move it to freeList queue.
540 if (pNode
== pAd
->TimerQ
.pQHead
)
541 pAd
->TimerQ
.pQHead
= pNode
->pNext
;
542 if (pNode
== pAd
->TimerQ
.pQTail
)
543 pAd
->TimerQ
.pQTail
= pPrev
;
545 pPrev
->pNext
= pNode
->pNext
;
547 // return this queue entry to timerQFreeList.
548 pNode
->pNext
= pAd
->TimerQ
.pQPollFreeList
;
549 pAd
->TimerQ
.pQPollFreeList
= pNode
;
552 RTMP_IRQ_UNLOCK(&pAd
->TimerQLock
, irqFlags
);
558 void RT2870_TimerQ_Exit(RTMP_ADAPTER
*pAd
)
560 RT2870_TIMER_ENTRY
*pTimerQ
;
561 unsigned long irqFlags
;
563 RTMP_IRQ_LOCK(&pAd
->TimerQLock
, irqFlags
);
564 while (pAd
->TimerQ
.pQHead
)
566 pTimerQ
= pAd
->TimerQ
.pQHead
;
567 pAd
->TimerQ
.pQHead
= pTimerQ
->pNext
;
570 pAd
->TimerQ
.pQPollFreeList
= NULL
;
571 os_free_mem(pAd
, pAd
->TimerQ
.pTimerQPoll
);
572 pAd
->TimerQ
.pQTail
= NULL
;
573 pAd
->TimerQ
.pQHead
= NULL
;
574 pAd
->TimerQ
.status
= RT2870_THREAD_STOPED
;
575 RTMP_IRQ_UNLOCK(&pAd
->TimerQLock
, irqFlags
);
580 void RT2870_TimerQ_Init(RTMP_ADAPTER
*pAd
)
583 RT2870_TIMER_ENTRY
*pQNode
, *pEntry
;
584 unsigned long irqFlags
;
586 NdisAllocateSpinLock(&pAd
->TimerQLock
);
588 RTMP_IRQ_LOCK(&pAd
->TimerQLock
, irqFlags
);
589 NdisZeroMemory(&pAd
->TimerQ
, sizeof(pAd
->TimerQ
));
590 //InterlockedExchange(&pAd->TimerQ.count, 0);
592 /* Initialise the wait q head */
593 //init_waitqueue_head(&timerWaitQ);
595 os_alloc_mem(pAd
, &pAd
->TimerQ
.pTimerQPoll
, sizeof(RT2870_TIMER_ENTRY
) * TIMER_QUEUE_SIZE_MAX
);
596 if (pAd
->TimerQ
.pTimerQPoll
)
599 pQNode
= (RT2870_TIMER_ENTRY
*)pAd
->TimerQ
.pTimerQPoll
;
600 for (i
= 0 ;i
<TIMER_QUEUE_SIZE_MAX
; i
++)
602 pQNode
->pNext
= pEntry
;
606 pAd
->TimerQ
.pQPollFreeList
= pEntry
;
607 pAd
->TimerQ
.pQHead
= NULL
;
608 pAd
->TimerQ
.pQTail
= NULL
;
609 pAd
->TimerQ
.status
= RT2870_THREAD_INITED
;
611 RTMP_IRQ_UNLOCK(&pAd
->TimerQLock
, irqFlags
);
615 VOID
RT2870_WatchDog(IN RTMP_ADAPTER
*pAd
)
617 PHT_TX_CONTEXT pHTTXContext
;
621 BOOLEAN needDumpSeq
= FALSE
;
626 RTMP_IO_READ32(pAd
, TXRXQ_PCNT
, &MACValue
);
627 if ((MACValue
& 0xff) !=0 )
629 DBGPRINT(RT_DEBUG_TRACE
, ("TX QUEUE 0 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue
));
630 RTMP_IO_WRITE32(pAd
, PBF_CFG
, 0xf40012);
631 while((MACValue
&0xff) != 0 && (idx
++ < 10))
633 RTMP_IO_READ32(pAd
, TXRXQ_PCNT
, &MACValue
);
636 RTMP_IO_WRITE32(pAd
, PBF_CFG
, 0xf40006);
640 if ((MACValue
& 0xff00) !=0 )
642 DBGPRINT(RT_DEBUG_TRACE
, ("TX QUEUE 1 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue
));
643 RTMP_IO_WRITE32(pAd
, PBF_CFG
, 0xf4000a);
644 while((MACValue
&0xff00) != 0 && (idx
++ < 10))
646 RTMP_IO_READ32(pAd
, TXRXQ_PCNT
, &MACValue
);
649 RTMP_IO_WRITE32(pAd
, PBF_CFG
, 0xf40006);
653 if (pAd
->watchDogRxOverFlowCnt
>= 2)
655 DBGPRINT(RT_DEBUG_TRACE
, ("Maybe the Rx Bulk-In hanged! Cancel the pending Rx bulks request!\n"));
656 if ((!RTMP_TEST_FLAG(pAd
, (fRTMP_ADAPTER_RESET_IN_PROGRESS
|
657 fRTMP_ADAPTER_BULKIN_RESET
|
658 fRTMP_ADAPTER_HALT_IN_PROGRESS
|
659 fRTMP_ADAPTER_NIC_NOT_EXIST
))))
661 DBGPRINT(RT_DEBUG_TRACE
, ("Call CMDTHREAD_RESET_BULK_IN to cancel the pending Rx Bulk!\n"));
662 RTMP_SET_FLAG(pAd
, fRTMP_ADAPTER_BULKIN_RESET
);
663 RTUSBEnqueueInternalCmd(pAd
, CMDTHREAD_RESET_BULK_IN
, NULL
, 0);
666 pAd
->watchDogRxOverFlowCnt
= 0;
670 for (idx
= 0; idx
< NUM_OF_TX_RING
; idx
++)
674 RTMP_IRQ_LOCK(&pAd
->BulkOutLock
[idx
], irqFlags
);
675 if ((pAd
->BulkOutPending
[idx
] == TRUE
) && pAd
->watchDogTxPendingCnt
)
677 pAd
->watchDogTxPendingCnt
[idx
]++;
679 if ((pAd
->watchDogTxPendingCnt
[idx
] > 2) &&
680 (!RTMP_TEST_FLAG(pAd
, (fRTMP_ADAPTER_RESET_IN_PROGRESS
| fRTMP_ADAPTER_HALT_IN_PROGRESS
| fRTMP_ADAPTER_NIC_NOT_EXIST
| fRTMP_ADAPTER_BULKOUT_RESET
)))
683 // FIXME: Following code just support single bulk out. If you wanna support multiple bulk out. Modify it!
684 pHTTXContext
= (PHT_TX_CONTEXT
)(&pAd
->TxContext
[idx
]);
685 if (pHTTXContext
->IRPPending
)
686 { // Check TxContext.
687 pUrb
= pHTTXContext
->pUrb
;
689 else if (idx
== MGMTPIPEIDX
)
691 PTX_CONTEXT pMLMEContext
, pNULLContext
, pPsPollContext
;
694 pMLMEContext
= (PTX_CONTEXT
)(pAd
->MgmtRing
.Cell
[pAd
->MgmtRing
.TxDmaIdx
].AllocVa
);
695 pPsPollContext
= (PTX_CONTEXT
)(&pAd
->PsPollContext
);
696 pNULLContext
= (PTX_CONTEXT
)(&pAd
->NullContext
);
698 if (pMLMEContext
->IRPPending
)
700 ASSERT(pMLMEContext
->IRPPending
);
701 pUrb
= pMLMEContext
->pUrb
;
703 else if (pNULLContext
->IRPPending
)
705 ASSERT(pNULLContext
->IRPPending
);
706 pUrb
= pNULLContext
->pUrb
;
708 else if (pPsPollContext
->IRPPending
)
710 ASSERT(pPsPollContext
->IRPPending
);
711 pUrb
= pPsPollContext
->pUrb
;
715 RTMP_IRQ_UNLOCK(&pAd
->BulkOutLock
[idx
], irqFlags
);
717 DBGPRINT(RT_DEBUG_TRACE
, ("Maybe the Tx Bulk-Out hanged! Cancel the pending Tx bulks request of idx(%d)!\n", idx
));
720 DBGPRINT(RT_DEBUG_TRACE
, ("Unlink the pending URB!\n"));
722 RTUSB_UNLINK_URB(pUrb
);
723 // Sleep 200 microseconds to give cancellation time to work
729 DBGPRINT(RT_DEBUG_ERROR
, ("Unkonw bulkOut URB maybe hanged!!!!!!!!!!!!\n"));
734 RTMP_IRQ_UNLOCK(&pAd
->BulkOutLock
[idx
], irqFlags
);
739 RTMP_IRQ_UNLOCK(&pAd
->BulkOutLock
[idx
], irqFlags
);
743 #ifdef DOT11_N_SUPPORT
744 // For Sigma debug, dump the ba_reordering sequence.
745 if((needDumpSeq
== TRUE
) && (pAd
->CommonCfg
.bDisableReordering
== 0))
748 PBA_REC_ENTRY pBAEntry
= NULL
;
750 struct reordering_mpdu
*mpdu_blk
;
752 Idx
= pAd
->MacTab
.Content
[BSSID_WCID
].BARecWcidArray
[0];
754 pBAEntry
= &pAd
->BATable
.BARecEntry
[Idx
];
755 if((pBAEntry
->list
.qlen
> 0) && (pBAEntry
->list
.next
!= NULL
))
757 DBGPRINT(RT_DEBUG_TRACE
, ("NICUpdateRawCounters():The Queueing pkt in reordering buffer:\n"));
758 NdisAcquireSpinLock(&pBAEntry
->RxReRingLock
);
759 mpdu_blk
= pBAEntry
->list
.next
;
762 DBGPRINT(RT_DEBUG_TRACE
, ("\t%d:Seq-%d, bAMSDU-%d!\n", count
, mpdu_blk
->Sequence
, mpdu_blk
->bAMSDU
));
763 mpdu_blk
= mpdu_blk
->next
;
767 DBGPRINT(RT_DEBUG_TRACE
, ("\npBAEntry->LastIndSeq=%d!\n", pBAEntry
->LastIndSeq
));
768 NdisReleaseSpinLock(&pBAEntry
->RxReRingLock
);
771 #endif // DOT11_N_SUPPORT //
775 ========================================================================
777 Release allocated resources.
780 *dev Point to the PCI or USB device
781 pAd driver control block pointer
787 ========================================================================
789 static void _rtusb_disconnect(struct usb_device
*dev
, PRTMP_ADAPTER pAd
)
791 struct net_device
*net_dev
= NULL
;
794 DBGPRINT(RT_DEBUG_ERROR
, ("rtusb_disconnect: unregister usbnet usb-%s-%s\n",
795 dev
->bus
->bus_name
, dev
->devpath
));
798 #ifdef MULTIPLE_CARD_SUPPORT
799 if ((pAd
->MC_RowID
>= 0) && (pAd
->MC_RowID
<= MAX_NUM_OF_MULTIPLE_CARD
))
800 MC_CardUsed
[pAd
->MC_RowID
] = 0; // not clear MAC address
801 #endif // MULTIPLE_CARD_SUPPORT //
803 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
804 while(MOD_IN_USE
> 0)
810 #endif // LINUX_VERSION_CODE //
812 printk("rtusb_disconnect: pAd == NULL!\n");
815 RTMP_SET_FLAG(pAd
, fRTMP_ADAPTER_NIC_NOT_EXIST
);
819 // for debug, wait to show some messages to /proc system
825 net_dev
= pAd
->net_dev
;
826 if (pAd
->net_dev
!= NULL
)
828 printk("rtusb_disconnect: unregister_netdev(), dev->name=%s!\n", net_dev
->name
);
829 unregister_netdev (pAd
->net_dev
);
832 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
834 flush_scheduled_work();
835 #endif // LINUX_VERSION_CODE //
838 // free net_device memory
839 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
842 free_netdev(net_dev
);
843 #endif // LINUX_VERSION_CODE //
845 // free adapter memory
846 RTMPFreeAdapter(pAd
);
848 // release a use of the usb device structure
849 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
850 while(MOD_IN_USE
> 0)
856 #endif // LINUX_VERSION_CODE //
859 DBGPRINT(RT_DEBUG_ERROR
, (" RTUSB disconnect successfully\n"));
864 ========================================================================
866 Probe RT28XX chipset.
869 *dev Point to the PCI or USB device
871 *id_table Point to the PCI or USB device ID
877 ========================================================================
879 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
880 static void *rtusb_probe(struct usb_device
*dev
, UINT interface
,
881 const struct usb_device_id
*id
)
884 rt28xx_probe((void *)dev
, (void *)id
, interface
, &pAd
);
888 //Disconnect function is called within exit routine
889 static void rtusb_disconnect(struct usb_device
*dev
, void *ptr
)
891 _rtusb_disconnect(dev
, ((PRTMP_ADAPTER
)ptr
));
894 #else /* kernel 2.6 series */
895 static int rtusb_probe (struct usb_interface
*intf
,
896 const struct usb_device_id
*id
)
899 return (int)rt28xx_probe((void *)intf
, (void *)id
, 0, &pAd
);
903 static void rtusb_disconnect(struct usb_interface
*intf
)
905 struct usb_device
*dev
= interface_to_usbdev(intf
);
909 pAd
= usb_get_intfdata(intf
);
910 usb_set_intfdata(intf
, NULL
);
912 _rtusb_disconnect(dev
, pAd
);
914 #endif // LINUX_VERSION_CODE //
918 ========================================================================
920 Close kernel threads.
923 *pAd the raxx interface data pointer
929 ========================================================================
931 VOID
RT28xxThreadTerminate(
932 IN RTMP_ADAPTER
*pAd
)
934 POS_COOKIE pObj
= (POS_COOKIE
) pAd
->OS_Cookie
;
938 // Sleep 50 milliseconds so pending io might finish normally
939 RTMPusecDelay(50000);
941 // We want to wait until all pending receives and sends to the
942 // device object. We cancel any
943 // irps. Wait until sends and receives have stopped.
944 RTUSBCancelPendingIRPs(pAd
);
947 CHECK_PID_LEGALITY(pObj
->TimerQThr_pid
)
949 POS_COOKIE pObj
= (POS_COOKIE
)pAd
->OS_Cookie
;
951 printk("Terminate the TimerQThr_pid=%d!\n", GET_PID_NUMBER(pObj
->TimerQThr_pid
));
953 pAd
->TimerFunc_kill
= 1;
955 ret
= KILL_THREAD_PID(pObj
->TimerQThr_pid
, SIGTERM
, 1);
958 printk(KERN_WARNING
"%s: unable to stop TimerQThread, pid=%d, ret=%d!\n",
959 pAd
->net_dev
->name
, GET_PID_NUMBER(pObj
->TimerQThr_pid
), ret
);
963 wait_for_completion(&pAd
->TimerQComplete
);
964 pObj
->TimerQThr_pid
= THREAD_PID_INIT_VALUE
;
968 CHECK_PID_LEGALITY(pObj
->MLMEThr_pid
)
970 printk("Terminate the MLMEThr_pid=%d!\n", GET_PID_NUMBER(pObj
->MLMEThr_pid
));
973 //RT28XX_MLME_HANDLER(pAd);
975 ret
= KILL_THREAD_PID(pObj
->MLMEThr_pid
, SIGTERM
, 1);
978 printk (KERN_WARNING
"%s: unable to Mlme thread, pid=%d, ret=%d!\n",
979 pAd
->net_dev
->name
, GET_PID_NUMBER(pObj
->MLMEThr_pid
), ret
);
983 //wait_for_completion (&pAd->notify);
984 wait_for_completion (&pAd
->mlmeComplete
);
985 pObj
->MLMEThr_pid
= THREAD_PID_INIT_VALUE
;
989 CHECK_PID_LEGALITY(pObj
->RTUSBCmdThr_pid
)
991 printk("Terminate the RTUSBCmdThr_pid=%d!\n", GET_PID_NUMBER(pObj
->RTUSBCmdThr_pid
));
993 NdisAcquireSpinLock(&pAd
->CmdQLock
);
994 pAd
->CmdQ
.CmdQState
= RT2870_THREAD_STOPED
;
995 NdisReleaseSpinLock(&pAd
->CmdQLock
);
998 ret
= KILL_THREAD_PID(pObj
->RTUSBCmdThr_pid
, SIGTERM
, 1);
1001 printk(KERN_WARNING
"%s: unable to RTUSBCmd thread, pid=%d, ret=%d!\n",
1002 pAd
->net_dev
->name
, GET_PID_NUMBER(pObj
->RTUSBCmdThr_pid
), ret
);
1006 //wait_for_completion (&pAd->notify);
1007 wait_for_completion (&pAd
->CmdQComplete
);
1008 pObj
->RTUSBCmdThr_pid
= THREAD_PID_INIT_VALUE
;
1015 pAd
->CmdQ
.CmdQState
= RT2870_THREAD_UNKNOWN
;
1016 pAd
->TimerFunc_kill
= 0;
1020 void kill_thread_task(IN PRTMP_ADAPTER pAd
)
1024 pObj
= (POS_COOKIE
) pAd
->OS_Cookie
;
1026 tasklet_kill(&pObj
->rx_done_task
);
1027 tasklet_kill(&pObj
->mgmt_dma_done_task
);
1028 tasklet_kill(&pObj
->ac0_dma_done_task
);
1029 tasklet_kill(&pObj
->ac1_dma_done_task
);
1030 tasklet_kill(&pObj
->ac2_dma_done_task
);
1031 tasklet_kill(&pObj
->ac3_dma_done_task
);
1032 tasklet_kill(&pObj
->hcca_dma_done_task
);
1033 tasklet_kill(&pObj
->tbtt_task
);
1039 ========================================================================
1040 Routine Description:
1041 Check the chipset vendor/product ID.
1044 _dev_p Point to the PCI or USB device
1051 ========================================================================
1053 BOOLEAN
RT28XXChipsetCheck(
1056 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
1057 struct usb_device
*dev_p
= (struct usb_device
*)_dev_p
;
1059 struct usb_interface
*intf
= (struct usb_interface
*)_dev_p
;
1060 struct usb_device
*dev_p
= interface_to_usbdev(intf
);
1061 #endif // LINUX_VERSION_CODE //
1065 for(i
=0; i
<rtusb_usb_id_len
; i
++)
1067 if (dev_p
->descriptor
.idVendor
== rtusb_usb_id
[i
].idVendor
&&
1068 dev_p
->descriptor
.idProduct
== rtusb_usb_id
[i
].idProduct
)
1070 printk("rt2870: idVendor = 0x%x, idProduct = 0x%x\n",
1071 dev_p
->descriptor
.idVendor
, dev_p
->descriptor
.idProduct
);
1076 if (i
== rtusb_usb_id_len
)
1078 printk("rt2870: Error! Device Descriptor not matching!\n");
1087 ========================================================================
1088 Routine Description:
1089 Init net device structure.
1092 _dev_p Point to the PCI or USB device
1093 *net_dev Point to the net device
1094 *pAd the raxx interface data pointer
1101 ========================================================================
1103 BOOLEAN
RT28XXNetDevInit(
1105 IN
struct net_device
*net_dev
,
1106 IN RTMP_ADAPTER
*pAd
)
1108 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
1109 struct usb_device
*dev_p
= (struct usb_device
*)_dev_p
;
1111 struct usb_interface
*intf
= (struct usb_interface
*)_dev_p
;
1112 struct usb_device
*dev_p
= interface_to_usbdev(intf
);
1113 #endif // LINUX_VERSION_CODE //
1116 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
1117 pAd
->config
= dev_p
->config
;
1119 pAd
->config
= &dev_p
->config
->desc
;
1120 #endif // LINUX_VERSION_CODE //
1126 ========================================================================
1127 Routine Description:
1128 Init net device structure.
1131 _dev_p Point to the PCI or USB device
1132 *pAd the raxx interface data pointer
1139 ========================================================================
1141 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
1142 BOOLEAN
RT28XXProbePostConfig(
1144 IN RTMP_ADAPTER
*pAd
,
1147 struct usb_device
*dev_p
= (struct usb_device
*)_dev_p
;
1148 struct usb_interface
*intf
;
1149 struct usb_interface_descriptor
*iface_desc
;
1150 struct usb_endpoint_descriptor
*endpoint
;
1155 /* get the active interface descriptor */
1156 intf
= &dev_p
->actconfig
->interface
[interface
];
1157 iface_desc
= &intf
->altsetting
[0];
1159 /* get # of enpoints */
1160 pAd
->NumberOfPipes
= iface_desc
->bNumEndpoints
;
1161 DBGPRINT(RT_DEBUG_TRACE
, ("NumEndpoints=%d\n", iface_desc
->bNumEndpoints
));
1163 /* Configure Pipes */
1164 endpoint
= &iface_desc
->endpoint
[0];
1167 for(i
=0; i
<pAd
->NumberOfPipes
; i
++)
1169 if ((endpoint
[i
].bmAttributes
== USB_ENDPOINT_XFER_BULK
) &&
1170 ((endpoint
[i
].bEndpointAddress
& USB_ENDPOINT_DIR_MASK
) == USB_DIR_IN
))
1172 pAd
->BulkInEpAddr
= endpoint
[i
].bEndpointAddress
;
1173 pAd
->BulkInMaxPacketSize
= endpoint
[i
].wMaxPacketSize
;
1175 DBGPRINT_RAW(RT_DEBUG_TRACE
,
1176 ("BULK IN MaximumPacketSize = %d\n", pAd
->BulkInMaxPacketSize
));
1177 DBGPRINT_RAW(RT_DEBUG_TRACE
,
1178 ("EP address = 0x%2x \n", endpoint
[i
].bEndpointAddress
));
1180 else if ((endpoint
[i
].bmAttributes
== USB_ENDPOINT_XFER_BULK
) &&
1181 ((endpoint
[i
].bEndpointAddress
& USB_ENDPOINT_DIR_MASK
) == USB_DIR_OUT
))
1183 // There are 6 bulk out EP. EP6 highest priority.
1184 // EP1-4 is EDCA. EP5 is HCCA.
1185 pAd
->BulkOutEpAddr
[BulkOutIdx
++] = endpoint
[i
].bEndpointAddress
;
1186 pAd
->BulkOutMaxPacketSize
= endpoint
[i
].wMaxPacketSize
;
1188 DBGPRINT_RAW(RT_DEBUG_TRACE
,
1189 ("BULK OUT MaximumPacketSize = %d\n", pAd
->BulkOutMaxPacketSize
));
1190 DBGPRINT_RAW(RT_DEBUG_TRACE
,
1191 ("EP address = 0x%2x \n", endpoint
[i
].bEndpointAddress
));
1195 if (!(pAd
->BulkInEpAddr
&& pAd
->BulkOutEpAddr
[0]))
1197 printk("Could not find both bulk-in and bulk-out endpoints\n");
1205 BOOLEAN
RT28XXProbePostConfig(
1207 IN RTMP_ADAPTER
*pAd
,
1210 struct usb_interface
*intf
= (struct usb_interface
*)_dev_p
;
1211 struct usb_host_interface
*iface_desc
;
1216 /* get the active interface descriptor */
1217 iface_desc
= intf
->cur_altsetting
;
1219 /* get # of enpoints */
1220 pAd
->NumberOfPipes
= iface_desc
->desc
.bNumEndpoints
;
1221 DBGPRINT(RT_DEBUG_TRACE
,
1222 ("NumEndpoints=%d\n", iface_desc
->desc
.bNumEndpoints
));
1224 /* Configure Pipes */
1227 for(i
=0; i
<pAd
->NumberOfPipes
; i
++)
1229 if ((iface_desc
->endpoint
[i
].desc
.bmAttributes
==
1230 USB_ENDPOINT_XFER_BULK
) &&
1231 ((iface_desc
->endpoint
[i
].desc
.bEndpointAddress
&
1232 USB_ENDPOINT_DIR_MASK
) == USB_DIR_IN
))
1234 pAd
->BulkInEpAddr
= iface_desc
->endpoint
[i
].desc
.bEndpointAddress
;
1235 pAd
->BulkInMaxPacketSize
= iface_desc
->endpoint
[i
].desc
.wMaxPacketSize
;
1237 DBGPRINT_RAW(RT_DEBUG_TRACE
,
1238 ("BULK IN MaximumPacketSize = %d\n", pAd
->BulkInMaxPacketSize
));
1239 DBGPRINT_RAW(RT_DEBUG_TRACE
,
1240 ("EP address = 0x%2x\n", iface_desc
->endpoint
[i
].desc
.bEndpointAddress
));
1242 else if ((iface_desc
->endpoint
[i
].desc
.bmAttributes
==
1243 USB_ENDPOINT_XFER_BULK
) &&
1244 ((iface_desc
->endpoint
[i
].desc
.bEndpointAddress
&
1245 USB_ENDPOINT_DIR_MASK
) == USB_DIR_OUT
))
1247 // there are 6 bulk out EP. EP6 highest priority.
1248 // EP1-4 is EDCA. EP5 is HCCA.
1249 pAd
->BulkOutEpAddr
[BulkOutIdx
++] = iface_desc
->endpoint
[i
].desc
.bEndpointAddress
;
1250 pAd
->BulkOutMaxPacketSize
= iface_desc
->endpoint
[i
].desc
.wMaxPacketSize
;
1252 DBGPRINT_RAW(RT_DEBUG_TRACE
,
1253 ("BULK OUT MaximumPacketSize = %d\n", pAd
->BulkOutMaxPacketSize
));
1254 DBGPRINT_RAW(RT_DEBUG_TRACE
,
1255 ("EP address = 0x%2x \n", iface_desc
->endpoint
[i
].desc
.bEndpointAddress
));
1259 if (!(pAd
->BulkInEpAddr
&& pAd
->BulkOutEpAddr
[0]))
1261 printk("%s: Could not find both bulk-in and bulk-out endpoints\n", __FUNCTION__
);
1267 #endif // LINUX_VERSION_CODE //
1271 ========================================================================
1272 Routine Description:
1276 *pAd the raxx interface data pointer
1282 ========================================================================
1284 VOID
RT28XXDMADisable(
1285 IN RTMP_ADAPTER
*pAd
)
1293 ========================================================================
1294 Routine Description:
1298 *pAd the raxx interface data pointer
1304 ========================================================================
1306 VOID
RT28XXDMAEnable(
1307 IN RTMP_ADAPTER
*pAd
)
1309 WPDMA_GLO_CFG_STRUC GloCfg
;
1310 USB_DMA_CFG_STRUC UsbCfg
;
1314 RTMP_IO_WRITE32(pAd
, MAC_SYS_CTRL
, 0x4);
1317 RTMP_IO_READ32(pAd
, WPDMA_GLO_CFG
, &GloCfg
.word
);
1318 if ((GloCfg
.field
.TxDMABusy
== 0) && (GloCfg
.field
.RxDMABusy
== 0))
1321 DBGPRINT(RT_DEBUG_TRACE
, ("==> DMABusy\n"));
1322 RTMPusecDelay(1000);
1328 GloCfg
.field
.EnTXWriteBackDDONE
= 1;
1329 GloCfg
.field
.EnableRxDMA
= 1;
1330 GloCfg
.field
.EnableTxDMA
= 1;
1331 DBGPRINT(RT_DEBUG_TRACE
, ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg
.word
));
1332 RTMP_IO_WRITE32(pAd
, WPDMA_GLO_CFG
, GloCfg
.word
);
1335 UsbCfg
.field
.phyclear
= 0;
1336 /* usb version is 1.1,do not use bulk in aggregation */
1337 if (pAd
->BulkInMaxPacketSize
== 512)
1338 UsbCfg
.field
.RxBulkAggEn
= 1;
1339 /* for last packet, PBF might use more than limited, so minus 2 to prevent from error */
1340 UsbCfg
.field
.RxBulkAggLmt
= (MAX_RXBULK_SIZE
/1024)-3;
1341 UsbCfg
.field
.RxBulkAggTOut
= 0x80; /* 2006-10-18 */
1342 UsbCfg
.field
.RxBulkEn
= 1;
1343 UsbCfg
.field
.TxBulkEn
= 1;
1345 RTUSBWriteMACRegister(pAd
, USB_DMA_CFG
, UsbCfg
.word
);
1350 ========================================================================
1351 Routine Description:
1352 Write Beacon buffer to Asic.
1355 *pAd the raxx interface data pointer
1361 ========================================================================
1363 VOID
RT28xx_UpdateBeaconToAsic(
1364 IN RTMP_ADAPTER
*pAd
,
1369 PUCHAR pBeaconFrame
= NULL
;
1372 BEACON_SYNC_STRUCT
*pBeaconSync
= pAd
->CommonCfg
.pBeaconSync
;
1374 BOOLEAN bBcnReq
= FALSE
;
1378 if (pBeaconFrame
== NULL
)
1380 DBGPRINT(RT_DEBUG_ERROR
,("pBeaconFrame is NULL!\n"));
1384 if (pBeaconSync
== NULL
)
1386 DBGPRINT(RT_DEBUG_ERROR
,("pBeaconSync is NULL!\n"));
1390 //if ((pAd->WdsTab.Mode == WDS_BRIDGE_MODE) ||
1391 // ((pAd->ApCfg.MBSSID[apidx].MSSIDDev == NULL) || !(pAd->ApCfg.MBSSID[apidx].MSSIDDev->flags & IFF_UP))
1393 if (bBcnReq
== FALSE
)
1395 /* when the ra interface is down, do not send its beacon frame */
1396 /* clear all zero */
1397 for(i
=0; i
<TXWI_SIZE
; i
+=4) {
1398 RTMP_IO_WRITE32(pAd
, pAd
->BeaconOffset
[bcn_idx
] + i
, 0x00);
1400 pBeaconSync
->BeaconBitMap
&= (~(BEACON_BITMAP_MASK
& (1 << bcn_idx
)));
1401 NdisZeroMemory(pBeaconSync
->BeaconTxWI
[bcn_idx
], TXWI_SIZE
);
1405 ptr
= (PUCHAR
)&pAd
->BeaconTxWI
;
1406 #ifdef RT_BIG_ENDIAN
1407 RTMPWIEndianChange(ptr
, TYPE_TXWI
);
1409 if (NdisEqualMemory(pBeaconSync
->BeaconTxWI
[bcn_idx
], &pAd
->BeaconTxWI
, TXWI_SIZE
) == FALSE
)
1410 { // If BeaconTxWI changed, we need to rewrite the TxWI for the Beacon frames.
1411 pBeaconSync
->BeaconBitMap
&= (~(BEACON_BITMAP_MASK
& (1 << bcn_idx
)));
1412 NdisMoveMemory(pBeaconSync
->BeaconTxWI
[bcn_idx
], &pAd
->BeaconTxWI
, TXWI_SIZE
);
1415 if ((pBeaconSync
->BeaconBitMap
& (1 << bcn_idx
)) != (1 << bcn_idx
))
1417 for (i
=0; i
<TXWI_SIZE
; i
+=4) // 16-byte TXWI field
1419 longValue
= *ptr
+ (*(ptr
+1)<<8) + (*(ptr
+2)<<16) + (*(ptr
+3)<<24);
1420 RTMP_IO_WRITE32(pAd
, pAd
->BeaconOffset
[bcn_idx
] + i
, longValue
);
1425 ptr
= pBeaconSync
->BeaconBuf
[bcn_idx
];
1426 padding
= (FrameLen
& 0x01);
1427 NdisZeroMemory((PUCHAR
)(pBeaconFrame
+ FrameLen
), padding
);
1428 FrameLen
+= padding
;
1429 for (i
= 0 ; i
< FrameLen
/*HW_BEACON_OFFSET*/; i
+= 2)
1431 if (NdisEqualMemory(ptr
, pBeaconFrame
, 2) == FALSE
)
1433 NdisMoveMemory(ptr
, pBeaconFrame
, 2);
1434 //shortValue = *ptr + (*(ptr+1)<<8);
1435 //RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, shortValue);
1436 RTUSBMultiWrite(pAd
, pAd
->BeaconOffset
[bcn_idx
] + TXWI_SIZE
+ i
, ptr
, 2);
1442 pBeaconSync
->BeaconBitMap
|= (1 << bcn_idx
);
1448 VOID
RT2870_BssBeaconStop(
1449 IN RTMP_ADAPTER
*pAd
)
1451 BEACON_SYNC_STRUCT
*pBeaconSync
;
1453 BOOLEAN Cancelled
= TRUE
;
1455 pBeaconSync
= pAd
->CommonCfg
.pBeaconSync
;
1456 if (pBeaconSync
&& pBeaconSync
->EnableBeacon
)
1461 #ifdef CONFIG_STA_SUPPORT
1462 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
1464 NumOfBcn
= MAX_MESH_NUM
;
1466 #endif // CONFIG_STA_SUPPORT //
1468 RTMPCancelTimer(&pAd
->CommonCfg
.BeaconUpdateTimer
, &Cancelled
);
1470 for(i
=0; i
<NumOfBcn
; i
++)
1472 NdisZeroMemory(pBeaconSync
->BeaconBuf
[i
], HW_BEACON_OFFSET
);
1473 NdisZeroMemory(pBeaconSync
->BeaconTxWI
[i
], TXWI_SIZE
);
1475 for (offset
=0; offset
<HW_BEACON_OFFSET
; offset
+=4)
1476 RTMP_IO_WRITE32(pAd
, pAd
->BeaconOffset
[i
] + offset
, 0x00);
1478 pBeaconSync
->CapabilityInfoLocationInBeacon
[i
] = 0;
1479 pBeaconSync
->TimIELocationInBeacon
[i
] = 0;
1481 pBeaconSync
->BeaconBitMap
= 0;
1482 pBeaconSync
->DtimBitOn
= 0;
1487 VOID
RT2870_BssBeaconStart(
1488 IN RTMP_ADAPTER
*pAd
)
1491 BEACON_SYNC_STRUCT
*pBeaconSync
;
1492 // LARGE_INTEGER tsfTime, deltaTime;
1494 pBeaconSync
= pAd
->CommonCfg
.pBeaconSync
;
1495 if (pBeaconSync
&& pBeaconSync
->EnableBeacon
)
1500 #ifdef CONFIG_STA_SUPPORT
1501 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
1503 NumOfBcn
= MAX_MESH_NUM
;
1505 #endif // CONFIG_STA_SUPPORT //
1507 for(apidx
=0; apidx
<NumOfBcn
; apidx
++)
1509 UCHAR CapabilityInfoLocationInBeacon
= 0;
1510 UCHAR TimIELocationInBeacon
= 0;
1512 NdisZeroMemory(pBeaconSync
->BeaconBuf
[apidx
], HW_BEACON_OFFSET
);
1513 pBeaconSync
->CapabilityInfoLocationInBeacon
[apidx
] = CapabilityInfoLocationInBeacon
;
1514 pBeaconSync
->TimIELocationInBeacon
[apidx
] = TimIELocationInBeacon
;
1515 NdisZeroMemory(pBeaconSync
->BeaconTxWI
[apidx
], TXWI_SIZE
);
1517 pBeaconSync
->BeaconBitMap
= 0;
1518 pBeaconSync
->DtimBitOn
= 0;
1519 pAd
->CommonCfg
.BeaconUpdateTimer
.Repeat
= TRUE
;
1521 pAd
->CommonCfg
.BeaconAdjust
= 0;
1522 pAd
->CommonCfg
.BeaconFactor
= 0xffffffff / (pAd
->CommonCfg
.BeaconPeriod
<< 10);
1523 pAd
->CommonCfg
.BeaconRemain
= (0xffffffff % (pAd
->CommonCfg
.BeaconPeriod
<< 10)) + 1;
1524 printk("RT2870_BssBeaconStart:BeaconFactor=%d, BeaconRemain=%d!\n", pAd
->CommonCfg
.BeaconFactor
, pAd
->CommonCfg
.BeaconRemain
);
1525 RTMPSetTimer(&pAd
->CommonCfg
.BeaconUpdateTimer
, pAd
->CommonCfg
.BeaconPeriod
);
1531 VOID
RT2870_BssBeaconInit(
1532 IN RTMP_ADAPTER
*pAd
)
1534 BEACON_SYNC_STRUCT
*pBeaconSync
;
1537 NdisAllocMemory(pAd
->CommonCfg
.pBeaconSync
, sizeof(BEACON_SYNC_STRUCT
), MEM_ALLOC_FLAG
);
1538 if (pAd
->CommonCfg
.pBeaconSync
)
1540 pBeaconSync
= pAd
->CommonCfg
.pBeaconSync
;
1541 NdisZeroMemory(pBeaconSync
, sizeof(BEACON_SYNC_STRUCT
));
1542 for(i
=0; i
< HW_BEACON_MAX_COUNT
; i
++)
1544 NdisZeroMemory(pBeaconSync
->BeaconBuf
[i
], HW_BEACON_OFFSET
);
1545 pBeaconSync
->CapabilityInfoLocationInBeacon
[i
] = 0;
1546 pBeaconSync
->TimIELocationInBeacon
[i
] = 0;
1547 NdisZeroMemory(pBeaconSync
->BeaconTxWI
[i
], TXWI_SIZE
);
1549 pBeaconSync
->BeaconBitMap
= 0;
1551 //RTMPInitTimer(pAd, &pAd->CommonCfg.BeaconUpdateTimer, GET_TIMER_FUNCTION(BeaconUpdateExec), pAd, TRUE);
1552 pBeaconSync
->EnableBeacon
= TRUE
;
1557 VOID
RT2870_BssBeaconExit(
1558 IN RTMP_ADAPTER
*pAd
)
1560 BEACON_SYNC_STRUCT
*pBeaconSync
;
1561 BOOLEAN Cancelled
= TRUE
;
1564 if (pAd
->CommonCfg
.pBeaconSync
)
1566 pBeaconSync
= pAd
->CommonCfg
.pBeaconSync
;
1567 pBeaconSync
->EnableBeacon
= FALSE
;
1568 RTMPCancelTimer(&pAd
->CommonCfg
.BeaconUpdateTimer
, &Cancelled
);
1569 pBeaconSync
->BeaconBitMap
= 0;
1571 for(i
=0; i
<HW_BEACON_MAX_COUNT
; i
++)
1573 NdisZeroMemory(pBeaconSync
->BeaconBuf
[i
], HW_BEACON_OFFSET
);
1574 pBeaconSync
->CapabilityInfoLocationInBeacon
[i
] = 0;
1575 pBeaconSync
->TimIELocationInBeacon
[i
] = 0;
1576 NdisZeroMemory(pBeaconSync
->BeaconTxWI
[i
], TXWI_SIZE
);
1579 NdisFreeMemory(pAd
->CommonCfg
.pBeaconSync
, HW_BEACON_OFFSET
* HW_BEACON_MAX_COUNT
, 0);
1580 pAd
->CommonCfg
.pBeaconSync
= NULL
;
1584 VOID
BeaconUpdateExec(
1585 IN PVOID SystemSpecific1
,
1586 IN PVOID FunctionContext
,
1587 IN PVOID SystemSpecific2
,
1588 IN PVOID SystemSpecific3
)
1590 PRTMP_ADAPTER pAd
= (PRTMP_ADAPTER
)FunctionContext
;
1591 LARGE_INTEGER tsfTime_a
;//, tsfTime_b, deltaTime_exp, deltaTime_ab;
1592 UINT32 delta
, remain
, remain_low
, remain_high
;
1593 // BOOLEAN positive;
1595 ReSyncBeaconTime(pAd
);
1599 RTMP_IO_READ32(pAd
, TSF_TIMER_DW0
, &tsfTime_a
.u
.LowPart
);
1600 RTMP_IO_READ32(pAd
, TSF_TIMER_DW1
, &tsfTime_a
.u
.HighPart
);
1603 //positive=getDeltaTime(tsfTime_a, expectedTime, &deltaTime_exp);
1604 remain_high
= pAd
->CommonCfg
.BeaconRemain
* tsfTime_a
.u
.HighPart
;
1605 remain_low
= tsfTime_a
.u
.LowPart
% (pAd
->CommonCfg
.BeaconPeriod
<< 10);
1606 remain
= (remain_high
+ remain_low
)%(pAd
->CommonCfg
.BeaconPeriod
<< 10);
1607 delta
= (pAd
->CommonCfg
.BeaconPeriod
<< 10) - remain
;
1609 pAd
->CommonCfg
.BeaconUpdateTimer
.TimerValue
= (delta
>> 10) + 10;