Staging: rt2870: remove dead EXT_BUILD_CHANNEL_LIST code
[safe/jmp/linux-2.6] / drivers / staging / rt2870 / 2870_main_dev.c
1 /*
2  *************************************************************************
3  * Ralink Tech Inc.
4  * 5F., No.36, Taiyuan St., Jhubei City,
5  * Hsinchu County 302,
6  * Taiwan, R.O.C.
7  *
8  * (c) Copyright 2002-2007, Ralink Technology, Inc.
9  *
10  * This program is free software; you can redistribute it and/or modify  *
11  * it under the terms of the GNU General Public License as published by  *
12  * the Free Software Foundation; either version 2 of the License, or     *
13  * (at your option) any later version.                                   *
14  *                                                                       *
15  * This program is distributed in the hope that it will be useful,       *
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
18  * GNU General Public License for more details.                          *
19  *                                                                       *
20  * You should have received a copy of the GNU General Public License     *
21  * along with this program; if not, write to the                         *
22  * Free Software Foundation, Inc.,                                       *
23  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
24  *                                                                       *
25  *************************************************************************
26
27     Module Name:
28     rtmp_main.c
29
30     Abstract:
31     main initialization routines
32
33     Revision History:
34     Who         When            What
35     --------    ----------      ----------------------------------------------
36     Name        Date            Modification logs
37     Jan Lee             01-10-2005          modified
38         Sample          Jun/01/07               Merge RT2870 and RT2860 drivers.
39 */
40
41 #include "rt_config.h"
42
43
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");
51 #ifdef MODULE_VERSION
52 MODULE_VERSION(STA_DRIVER_VERSION);
53 #endif
54 #endif // CONFIG_STA_SUPPORT //
55
56 /* Kernel thread and vars, which handles packets that are completed. Only
57  * packets that have a "complete" function are sent here. This way, the
58  * completion is run out of kernel context, and doesn't block the rest of
59  * the stack. */
60
61 extern INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p,
62                                                                         IN UINT argc, OUT PRTMP_ADAPTER *ppAd);
63
64
65 /* module table */
66 struct usb_device_id    rtusb_usb_id[] = RT2870_USB_DEVICES;
67 INT const               rtusb_usb_id_len = sizeof(rtusb_usb_id) / sizeof(struct usb_device_id);
68 MODULE_DEVICE_TABLE(usb, rtusb_usb_id);
69
70 #ifndef PF_NOFREEZE
71 #define PF_NOFREEZE  0
72 #endif
73
74
75 #ifdef CONFIG_PM
76 static int rt2870_suspend(struct usb_interface *intf, pm_message_t state);
77 static int rt2870_resume(struct usb_interface *intf);
78 #endif // CONFIG_PM //
79
80 /**************************************************************************/
81 /**************************************************************************/
82 //tested for kernel 2.6series
83 /**************************************************************************/
84 /**************************************************************************/
85 static int rtusb_probe (struct usb_interface *intf,
86                                                 const struct usb_device_id *id);
87 static void rtusb_disconnect(struct usb_interface *intf);
88
89 struct usb_driver rtusb_driver = {
90         .name="rt2870",
91         .probe=rtusb_probe,
92         .disconnect=rtusb_disconnect,
93         .id_table=rtusb_usb_id,
94
95 #ifdef CONFIG_PM
96         suspend:        rt2870_suspend,
97         resume:         rt2870_resume,
98 #endif
99         };
100
101 #ifdef CONFIG_PM
102
103 VOID RT2860RejectPendingPackets(
104         IN      PRTMP_ADAPTER   pAd)
105 {
106         // clear PS packets
107         // clear TxSw packets
108 }
109
110 static int rt2870_suspend(
111         struct usb_interface *intf,
112         pm_message_t state)
113 {
114         struct net_device *net_dev;
115         PRTMP_ADAPTER pAd = usb_get_intfdata(intf);
116
117
118         DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_suspend()\n"));
119         net_dev = pAd->net_dev;
120         netif_device_detach (net_dev);
121
122         pAd->PM_FlgSuspend = 1;
123         if (netif_running(net_dev)) {
124                 RTUSBCancelPendingBulkInIRP(pAd);
125                 RTUSBCancelPendingBulkOutIRP(pAd);
126         }
127         DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_suspend()\n"));
128         return 0;
129 }
130
131 static int rt2870_resume(
132         struct usb_interface *intf)
133 {
134         struct net_device *net_dev;
135         PRTMP_ADAPTER pAd = usb_get_intfdata(intf);
136
137
138         DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_resume()\n"));
139
140         pAd->PM_FlgSuspend = 0;
141         net_dev = pAd->net_dev;
142         netif_device_attach (net_dev);
143         netif_start_queue(net_dev);
144         netif_carrier_on(net_dev);
145         netif_wake_queue(net_dev);
146
147         DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_resume()\n"));
148         return 0;
149 }
150 #endif // CONFIG_PM //
151
152
153 // Init driver module
154 INT __init rtusb_init(void)
155 {
156         printk("rtusb init --->\n");
157         return usb_register(&rtusb_driver);
158 }
159
160 // Deinit driver module
161 VOID __exit rtusb_exit(void)
162 {
163         usb_deregister(&rtusb_driver);
164         printk("<--- rtusb exit\n");
165 }
166
167 module_init(rtusb_init);
168 module_exit(rtusb_exit);
169
170
171
172
173 /*--------------------------------------------------------------------- */
174 /* function declarations                                                                                                */
175 /*--------------------------------------------------------------------- */
176
177 /*
178 ========================================================================
179 Routine Description:
180     MLME kernel thread.
181
182 Arguments:
183         *Context                        the pAd, driver control block pointer
184
185 Return Value:
186     0                                   close the thread
187
188 Note:
189 ========================================================================
190 */
191 INT MlmeThread(
192         IN void *Context)
193 {
194         PRTMP_ADAPTER   pAd = (PRTMP_ADAPTER)Context;
195         POS_COOKIE      pObj;
196         int status;
197
198         pObj = (POS_COOKIE)pAd->OS_Cookie;
199
200         rtmp_os_thread_init("rt2870MlmeThread", (PVOID)&(pAd->mlmeComplete));
201
202         while (pAd->mlme_kill == 0)
203         {
204                 /* lock the device pointers */
205                 //down(&(pAd->mlme_semaphore));
206                 status = down_interruptible(&(pAd->mlme_semaphore));
207
208                 /* lock the device pointers , need to check if required*/
209                 //down(&(pAd->usbdev_semaphore));
210
211                 if (!pAd->PM_FlgSuspend)
212                 MlmeHandler(pAd);
213
214                 /* unlock the device pointers */
215                 //up(&(pAd->usbdev_semaphore));
216                 if (status != 0)
217                 {
218                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
219                         break;
220                 }
221         }
222
223         /* notify the exit routine that we're actually exiting now
224          *
225          * complete()/wait_for_completion() is similar to up()/down(),
226          * except that complete() is safe in the case where the structure
227          * is getting deleted in a parallel mode of execution (i.e. just
228          * after the down() -- that's necessary for the thread-shutdown
229          * case.
230          *
231          * complete_and_exit() goes even further than this -- it is safe in
232          * the case that the thread of the caller is going away (not just
233          * the structure) -- this is necessary for the module-remove case.
234          * This is important in preemption kernels, which transfer the flow
235          * of execution immediately upon a complete().
236          */
237         DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__func__));
238
239         pObj->MLMEThr_task = NULL;
240
241         complete_and_exit (&pAd->mlmeComplete, 0);
242         return 0;
243
244 }
245
246
247 /*
248 ========================================================================
249 Routine Description:
250     USB command kernel thread.
251
252 Arguments:
253         *Context                        the pAd, driver control block pointer
254
255 Return Value:
256     0                                   close the thread
257
258 Note:
259 ========================================================================
260 */
261 INT RTUSBCmdThread(
262         IN void * Context)
263 {
264         PRTMP_ADAPTER   pAd = (PRTMP_ADAPTER)Context;
265         POS_COOKIE              pObj;
266         int status;
267
268         pObj = (POS_COOKIE)pAd->OS_Cookie;
269
270         rtmp_os_thread_init("rt2870CmdThread", (PVOID)&(pAd->CmdQComplete));
271
272         NdisAcquireSpinLock(&pAd->CmdQLock);
273         pAd->CmdQ.CmdQState = RT2870_THREAD_RUNNING;
274         NdisReleaseSpinLock(&pAd->CmdQLock);
275
276         while (pAd->CmdQ.CmdQState == RT2870_THREAD_RUNNING)
277         {
278                 /* lock the device pointers */
279                 //down(&(pAd->RTUSBCmd_semaphore));
280                 status = down_interruptible(&(pAd->RTUSBCmd_semaphore));
281
282                 if (pAd->CmdQ.CmdQState == RT2870_THREAD_STOPED)
283                         break;
284
285                 if (status != 0)
286                 {
287                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
288                         break;
289                 }
290                 /* lock the device pointers , need to check if required*/
291                 //down(&(pAd->usbdev_semaphore));
292
293                 if (!pAd->PM_FlgSuspend)
294                 CMDHandler(pAd);
295
296                 /* unlock the device pointers */
297                 //up(&(pAd->usbdev_semaphore));
298         }
299
300         if (!pAd->PM_FlgSuspend)
301         {       // Clear the CmdQElements.
302                 CmdQElmt        *pCmdQElmt = NULL;
303
304                 NdisAcquireSpinLock(&pAd->CmdQLock);
305                 pAd->CmdQ.CmdQState = RT2870_THREAD_STOPED;
306                 while(pAd->CmdQ.size)
307                 {
308                         RTUSBDequeueCmd(&pAd->CmdQ, &pCmdQElmt);
309                         if (pCmdQElmt)
310                         {
311                                 if (pCmdQElmt->CmdFromNdis == TRUE)
312                                 {
313                                         if (pCmdQElmt->buffer != NULL)
314                                                 NdisFreeMemory(pCmdQElmt->buffer, pCmdQElmt->bufferlength, 0);
315
316                                         NdisFreeMemory(pCmdQElmt, sizeof(CmdQElmt), 0);
317                                 }
318                                 else
319                                 {
320                                         if ((pCmdQElmt->buffer != NULL) && (pCmdQElmt->bufferlength != 0))
321                                                 NdisFreeMemory(pCmdQElmt->buffer, pCmdQElmt->bufferlength, 0);
322                             {
323                                                 NdisFreeMemory(pCmdQElmt, sizeof(CmdQElmt), 0);
324                                         }
325                                 }
326                         }
327                 }
328
329                 NdisReleaseSpinLock(&pAd->CmdQLock);
330         }
331         /* notify the exit routine that we're actually exiting now
332          *
333          * complete()/wait_for_completion() is similar to up()/down(),
334          * except that complete() is safe in the case where the structure
335          * is getting deleted in a parallel mode of execution (i.e. just
336          * after the down() -- that's necessary for the thread-shutdown
337          * case.
338          *
339          * complete_and_exit() goes even further than this -- it is safe in
340          * the case that the thread of the caller is going away (not just
341          * the structure) -- this is necessary for the module-remove case.
342          * This is important in preemption kernels, which transfer the flow
343          * of execution immediately upon a complete().
344          */
345         DBGPRINT(RT_DEBUG_TRACE,( "<---RTUSBCmdThread\n"));
346
347         pObj->RTUSBCmdThr_task = NULL;
348
349         complete_and_exit (&pAd->CmdQComplete, 0);
350         return 0;
351
352 }
353
354
355 static void RT2870_TimerQ_Handle(RTMP_ADAPTER *pAd)
356 {
357         int status;
358         RALINK_TIMER_STRUCT     *pTimer;
359         RT2870_TIMER_ENTRY      *pEntry;
360         unsigned long   irqFlag;
361
362         while(!pAd->TimerFunc_kill)
363         {
364 //              printk("waiting for event!\n");
365                 pTimer = NULL;
366
367                 status = down_interruptible(&(pAd->RTUSBTimer_semaphore));
368
369                 if (pAd->TimerQ.status == RT2870_THREAD_STOPED)
370                         break;
371
372                 // event happened.
373                 while(pAd->TimerQ.pQHead)
374                 {
375                         RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlag);
376                         pEntry = pAd->TimerQ.pQHead;
377                         if (pEntry)
378                         {
379                                 pTimer = pEntry->pRaTimer;
380
381                                 // update pQHead
382                                 pAd->TimerQ.pQHead = pEntry->pNext;
383                                 if (pEntry == pAd->TimerQ.pQTail)
384                                         pAd->TimerQ.pQTail = NULL;
385
386                                 // return this queue entry to timerQFreeList.
387                                 pEntry->pNext = pAd->TimerQ.pQPollFreeList;
388                                 pAd->TimerQ.pQPollFreeList = pEntry;
389                         }
390                         RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlag);
391
392                         if (pTimer)
393                         {
394                                 if (pTimer->handle != NULL)
395                                 if (!pAd->PM_FlgSuspend)
396                                         pTimer->handle(NULL, (PVOID) pTimer->cookie, NULL, pTimer);
397                                 if ((pTimer->Repeat) && (pTimer->State == FALSE))
398                                         RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue);
399                         }
400                 }
401
402                 if (status != 0)
403                 {
404                         pAd->TimerQ.status = RT2870_THREAD_STOPED;
405                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
406                         break;
407                 }
408         }
409 }
410
411
412 INT TimerQThread(
413         IN OUT PVOID Context)
414 {
415         PRTMP_ADAPTER   pAd;
416         POS_COOKIE      pObj;
417
418         pAd = (PRTMP_ADAPTER)Context;
419         pObj = (POS_COOKIE) pAd->OS_Cookie;
420
421         rtmp_os_thread_init("rt2870TimerQHandle", (PVOID)&(pAd->TimerQComplete));
422
423         RT2870_TimerQ_Handle(pAd);
424
425         /* notify the exit routine that we're actually exiting now
426          *
427          * complete()/wait_for_completion() is similar to up()/down(),
428          * except that complete() is safe in the case where the structure
429          * is getting deleted in a parallel mode of execution (i.e. just
430          * after the down() -- that's necessary for the thread-shutdown
431          * case.
432          *
433          * complete_and_exit() goes even further than this -- it is safe in
434          * the case that the thread of the caller is going away (not just
435          * the structure) -- this is necessary for the module-remove case.
436          * This is important in preemption kernels, which transfer the flow
437          * of execution immediately upon a complete().
438          */
439         DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__func__));
440
441         pObj->TimerQThr_task = NULL;
442
443         complete_and_exit(&pAd->TimerQComplete, 0);
444         return 0;
445
446 }
447
448
449 RT2870_TIMER_ENTRY *RT2870_TimerQ_Insert(
450         IN RTMP_ADAPTER *pAd,
451         IN RALINK_TIMER_STRUCT *pTimer)
452 {
453         RT2870_TIMER_ENTRY *pQNode = NULL, *pQTail;
454         unsigned long irqFlags;
455
456
457         RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
458         if (pAd->TimerQ.status & RT2870_THREAD_CAN_DO_INSERT)
459         {
460                 if(pAd->TimerQ.pQPollFreeList)
461                 {
462                         pQNode = pAd->TimerQ.pQPollFreeList;
463                         pAd->TimerQ.pQPollFreeList = pQNode->pNext;
464
465                         pQNode->pRaTimer = pTimer;
466                         pQNode->pNext = NULL;
467
468                         pQTail = pAd->TimerQ.pQTail;
469                         if (pAd->TimerQ.pQTail != NULL)
470                                 pQTail->pNext = pQNode;
471                         pAd->TimerQ.pQTail = pQNode;
472                         if (pAd->TimerQ.pQHead == NULL)
473                                 pAd->TimerQ.pQHead = pQNode;
474                 }
475                 RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
476
477                 if (pQNode)
478                         up(&pAd->RTUSBTimer_semaphore);
479                         //wake_up(&timerWaitQ);
480         }
481         else
482         {
483                 RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
484         }
485         return pQNode;
486 }
487
488
489 BOOLEAN RT2870_TimerQ_Remove(
490         IN RTMP_ADAPTER *pAd,
491         IN RALINK_TIMER_STRUCT *pTimer)
492 {
493         RT2870_TIMER_ENTRY *pNode, *pPrev = NULL;
494         unsigned long irqFlags;
495
496         RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
497         if (pAd->TimerQ.status >= RT2870_THREAD_INITED)
498         {
499                 pNode = pAd->TimerQ.pQHead;
500                 while (pNode)
501                 {
502                         if (pNode->pRaTimer == pTimer)
503                                 break;
504                         pPrev = pNode;
505                         pNode = pNode->pNext;
506                 }
507
508                 // Now move it to freeList queue.
509                 if (pNode)
510                 {
511                         if (pNode == pAd->TimerQ.pQHead)
512                                 pAd->TimerQ.pQHead = pNode->pNext;
513                         if (pNode == pAd->TimerQ.pQTail)
514                                 pAd->TimerQ.pQTail = pPrev;
515                         if (pPrev != NULL)
516                                 pPrev->pNext = pNode->pNext;
517
518                         // return this queue entry to timerQFreeList.
519                         pNode->pNext = pAd->TimerQ.pQPollFreeList;
520                         pAd->TimerQ.pQPollFreeList = pNode;
521                 }
522         }
523         RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
524
525         return TRUE;
526 }
527
528
529 void RT2870_TimerQ_Exit(RTMP_ADAPTER *pAd)
530 {
531         RT2870_TIMER_ENTRY *pTimerQ;
532         unsigned long irqFlags;
533
534         RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
535         while (pAd->TimerQ.pQHead)
536         {
537                 pTimerQ = pAd->TimerQ.pQHead;
538                 pAd->TimerQ.pQHead = pTimerQ->pNext;
539                 // remove the timeQ
540         }
541         pAd->TimerQ.pQPollFreeList = NULL;
542         os_free_mem(pAd, pAd->TimerQ.pTimerQPoll);
543         pAd->TimerQ.pQTail = NULL;
544         pAd->TimerQ.pQHead = NULL;
545         pAd->TimerQ.status = RT2870_THREAD_STOPED;
546         RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
547
548 }
549
550
551 void RT2870_TimerQ_Init(RTMP_ADAPTER *pAd)
552 {
553         int     i;
554         RT2870_TIMER_ENTRY *pQNode, *pEntry;
555         unsigned long irqFlags;
556
557         NdisAllocateSpinLock(&pAd->TimerQLock);
558
559         RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
560         NdisZeroMemory(&pAd->TimerQ, sizeof(pAd->TimerQ));
561         //InterlockedExchange(&pAd->TimerQ.count, 0);
562
563         /* Initialise the wait q head */
564         //init_waitqueue_head(&timerWaitQ);
565
566         os_alloc_mem(pAd, &pAd->TimerQ.pTimerQPoll, sizeof(RT2870_TIMER_ENTRY) * TIMER_QUEUE_SIZE_MAX);
567         if (pAd->TimerQ.pTimerQPoll)
568         {
569                 pEntry = NULL;
570                 pQNode = (RT2870_TIMER_ENTRY *)pAd->TimerQ.pTimerQPoll;
571                 for (i = 0 ;i <TIMER_QUEUE_SIZE_MAX; i++)
572                 {
573                         pQNode->pNext = pEntry;
574                         pEntry = pQNode;
575                         pQNode++;
576                 }
577                 pAd->TimerQ.pQPollFreeList = pEntry;
578                 pAd->TimerQ.pQHead = NULL;
579                 pAd->TimerQ.pQTail = NULL;
580                 pAd->TimerQ.status = RT2870_THREAD_INITED;
581         }
582         RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
583 }
584
585
586 VOID RT2870_WatchDog(IN RTMP_ADAPTER *pAd)
587 {
588         PHT_TX_CONTEXT          pHTTXContext;
589         int                                     idx;
590         ULONG                           irqFlags;
591         PURB                            pUrb;
592         BOOLEAN                         needDumpSeq = FALSE;
593         UINT32                  MACValue;
594
595
596         idx = 0;
597         RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
598         if ((MACValue & 0xff) !=0 )
599         {
600                 DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 0 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue));
601                 RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40012);
602                 while((MACValue &0xff) != 0 && (idx++ < 10))
603                 {
604                         RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
605                         NdisMSleep(1);
606                 }
607                 RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006);
608         }
609
610         idx = 0;
611         if ((MACValue & 0xff00) !=0 )
612         {
613                 DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 1 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue));
614                 RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf4000a);
615                 while((MACValue &0xff00) != 0 && (idx++ < 10))
616                 {
617                         RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
618                         NdisMSleep(1);
619                 }
620                 RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006);
621         }
622
623
624         if (pAd->watchDogRxOverFlowCnt >= 2)
625         {
626                 DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Rx Bulk-In hanged! Cancel the pending Rx bulks request!\n"));
627                 if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
628                                                                         fRTMP_ADAPTER_BULKIN_RESET |
629                                                                         fRTMP_ADAPTER_HALT_IN_PROGRESS |
630                                                                         fRTMP_ADAPTER_NIC_NOT_EXIST))))
631                 {
632                         DBGPRINT(RT_DEBUG_TRACE, ("Call CMDTHREAD_RESET_BULK_IN to cancel the pending Rx Bulk!\n"));
633                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
634                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0);
635                         needDumpSeq = TRUE;
636                 }
637                 pAd->watchDogRxOverFlowCnt = 0;
638         }
639
640
641         for (idx = 0; idx < NUM_OF_TX_RING; idx++)
642         {
643                 pUrb = NULL;
644
645                 RTMP_IRQ_LOCK(&pAd->BulkOutLock[idx], irqFlags);
646                 if ((pAd->BulkOutPending[idx] == TRUE) && pAd->watchDogTxPendingCnt)
647                 {
648                         pAd->watchDogTxPendingCnt[idx]++;
649
650                         if ((pAd->watchDogTxPendingCnt[idx] > 2) &&
651                                  (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_BULKOUT_RESET)))
652                                 )
653                         {
654                                 // FIXME: Following code just support single bulk out. If you wanna support multiple bulk out. Modify it!
655                                 pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[idx]);
656                                 if (pHTTXContext->IRPPending)
657                                 {       // Check TxContext.
658                                         pUrb = pHTTXContext->pUrb;
659                                 }
660                                 else if (idx == MGMTPIPEIDX)
661                                 {
662                                         PTX_CONTEXT pMLMEContext, pNULLContext, pPsPollContext;
663
664                                         //Check MgmtContext.
665                                         pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa);
666                                         pPsPollContext = (PTX_CONTEXT)(&pAd->PsPollContext);
667                                         pNULLContext = (PTX_CONTEXT)(&pAd->NullContext);
668
669                                         if (pMLMEContext->IRPPending)
670                                         {
671                                                 ASSERT(pMLMEContext->IRPPending);
672                                                 pUrb = pMLMEContext->pUrb;
673                                         }
674                                         else if (pNULLContext->IRPPending)
675                                         {
676                                                 ASSERT(pNULLContext->IRPPending);
677                                                 pUrb = pNULLContext->pUrb;
678                                         }
679                                         else if (pPsPollContext->IRPPending)
680                                         {
681                                                 ASSERT(pPsPollContext->IRPPending);
682                                                 pUrb = pPsPollContext->pUrb;
683                                         }
684                                 }
685
686                                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
687
688                                 DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Tx Bulk-Out hanged! Cancel the pending Tx bulks request of idx(%d)!\n", idx));
689                                 if (pUrb)
690                                 {
691                                         DBGPRINT(RT_DEBUG_TRACE, ("Unlink the pending URB!\n"));
692                                         // unlink it now
693                                         RTUSB_UNLINK_URB(pUrb);
694                                         // Sleep 200 microseconds to give cancellation time to work
695                                         RTMPusecDelay(200);
696                                         needDumpSeq = TRUE;
697                                 }
698                                 else
699                                 {
700                                         DBGPRINT(RT_DEBUG_ERROR, ("Unkonw bulkOut URB maybe hanged!!!!!!!!!!!!\n"));
701                                 }
702                         }
703                         else
704                         {
705                                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
706                         }
707                 }
708                 else
709                 {
710                         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
711                 }
712         }
713
714 #ifdef DOT11_N_SUPPORT
715         // For Sigma debug, dump the ba_reordering sequence.
716         if((needDumpSeq == TRUE) && (pAd->CommonCfg.bDisableReordering == 0))
717         {
718                 USHORT                          Idx;
719                 PBA_REC_ENTRY           pBAEntry = NULL;
720                 UCHAR                           count = 0;
721                 struct reordering_mpdu *mpdu_blk;
722
723                 Idx = pAd->MacTab.Content[BSSID_WCID].BARecWcidArray[0];
724
725                 pBAEntry = &pAd->BATable.BARecEntry[Idx];
726                 if((pBAEntry->list.qlen > 0) && (pBAEntry->list.next != NULL))
727                 {
728                         DBGPRINT(RT_DEBUG_TRACE, ("NICUpdateRawCounters():The Queueing pkt in reordering buffer:\n"));
729                         NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
730                         mpdu_blk = pBAEntry->list.next;
731                         while (mpdu_blk)
732                         {
733                                 DBGPRINT(RT_DEBUG_TRACE, ("\t%d:Seq-%d, bAMSDU-%d!\n", count, mpdu_blk->Sequence, mpdu_blk->bAMSDU));
734                                 mpdu_blk = mpdu_blk->next;
735                                 count++;
736                         }
737
738                         DBGPRINT(RT_DEBUG_TRACE, ("\npBAEntry->LastIndSeq=%d!\n", pBAEntry->LastIndSeq));
739                         NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
740                 }
741         }
742 #endif // DOT11_N_SUPPORT //
743 }
744
745 /*
746 ========================================================================
747 Routine Description:
748     Release allocated resources.
749
750 Arguments:
751     *dev                                Point to the PCI or USB device
752         pAd                                     driver control block pointer
753
754 Return Value:
755     None
756
757 Note:
758 ========================================================================
759 */
760 static void _rtusb_disconnect(struct usb_device *dev, PRTMP_ADAPTER pAd)
761 {
762         struct net_device       *net_dev = NULL;
763
764
765         DBGPRINT(RT_DEBUG_ERROR, ("rtusb_disconnect: unregister usbnet usb-%s-%s\n",
766                                 dev->bus->bus_name, dev->devpath));
767         if (!pAd)
768         {
769                 usb_put_dev(dev);
770
771                 printk("rtusb_disconnect: pAd == NULL!\n");
772                 return;
773         }
774         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
775
776
777
778         // for debug, wait to show some messages to /proc system
779         udelay(1);
780
781
782
783
784         net_dev = pAd->net_dev;
785         if (pAd->net_dev != NULL)
786         {
787                 printk("rtusb_disconnect: unregister_netdev(), dev->name=%s!\n", net_dev->name);
788                 unregister_netdev (pAd->net_dev);
789         }
790         udelay(1);
791         flush_scheduled_work();
792         udelay(1);
793
794         // free net_device memory
795         free_netdev(net_dev);
796
797         // free adapter memory
798         RTMPFreeAdapter(pAd);
799
800         // release a use of the usb device structure
801         usb_put_dev(dev);
802         udelay(1);
803
804         DBGPRINT(RT_DEBUG_ERROR, (" RTUSB disconnect successfully\n"));
805 }
806
807
808 /*
809 ========================================================================
810 Routine Description:
811     Probe RT28XX chipset.
812
813 Arguments:
814     *dev                                Point to the PCI or USB device
815         interface
816         *id_table                       Point to the PCI or USB device ID
817
818 Return Value:
819     None
820
821 Note:
822 ========================================================================
823 */
824 static int rtusb_probe (struct usb_interface *intf,
825                                                 const struct usb_device_id *id)
826 {
827         PRTMP_ADAPTER pAd;
828         return (int)rt28xx_probe((void *)intf, (void *)id, 0, &pAd);
829 }
830
831
832 static void rtusb_disconnect(struct usb_interface *intf)
833 {
834         struct usb_device   *dev = interface_to_usbdev(intf);
835         PRTMP_ADAPTER       pAd;
836
837
838         pAd = usb_get_intfdata(intf);
839         usb_set_intfdata(intf, NULL);
840
841         _rtusb_disconnect(dev, pAd);
842 }
843
844
845 /*
846 ========================================================================
847 Routine Description:
848     Close kernel threads.
849
850 Arguments:
851         *pAd                            the raxx interface data pointer
852
853 Return Value:
854     NONE
855
856 Note:
857 ========================================================================
858 */
859 VOID RT28xxThreadTerminate(
860         IN RTMP_ADAPTER *pAd)
861 {
862         POS_COOKIE      pObj = (POS_COOKIE) pAd->OS_Cookie;
863         INT                     ret;
864
865
866         // Sleep 50 milliseconds so pending io might finish normally
867         RTMPusecDelay(50000);
868
869         // We want to wait until all pending receives and sends to the
870         // device object. We cancel any
871         // irps. Wait until sends and receives have stopped.
872         RTUSBCancelPendingIRPs(pAd);
873
874         // Terminate Threads
875         BUG_ON(pObj->TimerQThr_task == NULL);
876         CHECK_PID_LEGALITY(task_pid(pObj->TimerQThr_task))
877         {
878                 POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
879
880                 printk(KERN_DEBUG "Terminate the TimerQThr pid=%d!\n",
881                         pid_nr(task_pid(pObj->TimerQThr_task)));
882                 mb();
883                 pAd->TimerFunc_kill = 1;
884                 mb();
885                 kthread_stop(pObj->TimerQThr_task);
886                 pObj->TimerQThr_task = NULL;
887         }
888
889         BUG_ON(pObj->MLMEThr_task == NULL);
890         CHECK_PID_LEGALITY(task_pid(pObj->MLMEThr_task))
891         {
892                 printk(KERN_DEBUG "Terminate the MLMEThr pid=%d!\n",
893                         pid_nr(task_pid(pObj->MLMEThr_task)));
894                 mb();
895                 pAd->mlme_kill = 1;
896                 //RT28XX_MLME_HANDLER(pAd);
897                 mb();
898                 kthread_stop(pObj->MLMEThr_task);
899                 pObj->MLMEThr_task = NULL;
900         }
901
902         BUG_ON(pObj->RTUSBCmdThr_task == NULL);
903         CHECK_PID_LEGALITY(task_pid(pObj->RTUSBCmdThr_task))
904         {
905                 printk(KERN_DEBUG "Terminate the RTUSBCmdThr pid=%d!\n",
906                         pid_nr(task_pid(pObj->RTUSBCmdThr_task)));
907                 mb();
908                 NdisAcquireSpinLock(&pAd->CmdQLock);
909                 pAd->CmdQ.CmdQState = RT2870_THREAD_STOPED;
910                 NdisReleaseSpinLock(&pAd->CmdQLock);
911                 mb();
912                 //RTUSBCMDUp(pAd);
913                 kthread_stop(pObj->RTUSBCmdThr_task);
914                 pObj->RTUSBCmdThr_task = NULL;
915         }
916
917
918         // Kill tasklets
919         pAd->mlme_kill = 0;
920         pAd->CmdQ.CmdQState = RT2870_THREAD_UNKNOWN;
921         pAd->TimerFunc_kill = 0;
922 }
923
924
925 void kill_thread_task(IN PRTMP_ADAPTER pAd)
926 {
927         POS_COOKIE pObj;
928
929         pObj = (POS_COOKIE) pAd->OS_Cookie;
930
931         tasklet_kill(&pObj->rx_done_task);
932         tasklet_kill(&pObj->mgmt_dma_done_task);
933         tasklet_kill(&pObj->ac0_dma_done_task);
934         tasklet_kill(&pObj->ac1_dma_done_task);
935         tasklet_kill(&pObj->ac2_dma_done_task);
936         tasklet_kill(&pObj->ac3_dma_done_task);
937         tasklet_kill(&pObj->hcca_dma_done_task);
938         tasklet_kill(&pObj->tbtt_task);
939
940 }
941
942
943 /*
944 ========================================================================
945 Routine Description:
946     Check the chipset vendor/product ID.
947
948 Arguments:
949     _dev_p                              Point to the PCI or USB device
950
951 Return Value:
952     TRUE                                Check ok
953         FALSE                           Check fail
954
955 Note:
956 ========================================================================
957 */
958 BOOLEAN RT28XXChipsetCheck(
959         IN void *_dev_p)
960 {
961         struct usb_interface *intf = (struct usb_interface *)_dev_p;
962         struct usb_device *dev_p = interface_to_usbdev(intf);
963         UINT32 i;
964
965
966         for(i=0; i<rtusb_usb_id_len; i++)
967         {
968                 if (dev_p->descriptor.idVendor == rtusb_usb_id[i].idVendor &&
969                         dev_p->descriptor.idProduct == rtusb_usb_id[i].idProduct)
970                 {
971                         printk(KERN_DEBUG "rt2870: idVendor = 0x%x, idProduct = 0x%x\n",
972                                         dev_p->descriptor.idVendor, dev_p->descriptor.idProduct);
973                         break;
974                 }
975         }
976
977         if (i == rtusb_usb_id_len)
978         {
979                 printk("rt2870: Error! Device Descriptor not matching!\n");
980                 return FALSE;
981         }
982
983         return TRUE;
984 }
985
986
987 /*
988 ========================================================================
989 Routine Description:
990     Init net device structure.
991
992 Arguments:
993     _dev_p                              Point to the PCI or USB device
994     *net_dev                    Point to the net device
995         *pAd                            the raxx interface data pointer
996
997 Return Value:
998     TRUE                                Init ok
999         FALSE                           Init fail
1000
1001 Note:
1002 ========================================================================
1003 */
1004 BOOLEAN RT28XXNetDevInit(
1005         IN void                                 *_dev_p,
1006         IN struct  net_device   *net_dev,
1007         IN RTMP_ADAPTER                 *pAd)
1008 {
1009         struct usb_interface *intf = (struct usb_interface *)_dev_p;
1010         struct usb_device *dev_p = interface_to_usbdev(intf);
1011
1012
1013         pAd->config = &dev_p->config->desc;
1014         return TRUE;
1015 }
1016
1017
1018 /*
1019 ========================================================================
1020 Routine Description:
1021     Init net device structure.
1022
1023 Arguments:
1024     _dev_p                              Point to the PCI or USB device
1025         *pAd                            the raxx interface data pointer
1026
1027 Return Value:
1028     TRUE                                Config ok
1029         FALSE                           Config fail
1030
1031 Note:
1032 ========================================================================
1033 */
1034 BOOLEAN RT28XXProbePostConfig(
1035         IN void                                 *_dev_p,
1036         IN RTMP_ADAPTER                 *pAd,
1037         IN INT32                                interface)
1038 {
1039         struct usb_interface *intf = (struct usb_interface *)_dev_p;
1040         struct usb_host_interface *iface_desc;
1041         ULONG BulkOutIdx;
1042         UINT32 i;
1043
1044
1045         /* get the active interface descriptor */
1046         iface_desc = intf->cur_altsetting;
1047
1048         /* get # of enpoints  */
1049         pAd->NumberOfPipes = iface_desc->desc.bNumEndpoints;
1050         DBGPRINT(RT_DEBUG_TRACE,
1051                         ("NumEndpoints=%d\n", iface_desc->desc.bNumEndpoints));
1052
1053         /* Configure Pipes */
1054         BulkOutIdx = 0;
1055
1056         for(i=0; i<pAd->NumberOfPipes; i++)
1057         {
1058                 if ((iface_desc->endpoint[i].desc.bmAttributes ==
1059                                 USB_ENDPOINT_XFER_BULK) &&
1060                         ((iface_desc->endpoint[i].desc.bEndpointAddress &
1061                                 USB_ENDPOINT_DIR_MASK) == USB_DIR_IN))
1062                 {
1063                         pAd->BulkInEpAddr = iface_desc->endpoint[i].desc.bEndpointAddress;
1064                         pAd->BulkInMaxPacketSize = iface_desc->endpoint[i].desc.wMaxPacketSize;
1065
1066                         DBGPRINT_RAW(RT_DEBUG_TRACE,
1067                                 ("BULK IN MaximumPacketSize = %d\n", pAd->BulkInMaxPacketSize));
1068                         DBGPRINT_RAW(RT_DEBUG_TRACE,
1069                                 ("EP address = 0x%2x\n", iface_desc->endpoint[i].desc.bEndpointAddress));
1070                 }
1071                 else if ((iface_desc->endpoint[i].desc.bmAttributes ==
1072                                         USB_ENDPOINT_XFER_BULK) &&
1073                                 ((iface_desc->endpoint[i].desc.bEndpointAddress &
1074                                         USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT))
1075                 {
1076                         // there are 6 bulk out EP. EP6 highest priority.
1077                         // EP1-4 is EDCA.  EP5 is HCCA.
1078                         pAd->BulkOutEpAddr[BulkOutIdx++] = iface_desc->endpoint[i].desc.bEndpointAddress;
1079                         pAd->BulkOutMaxPacketSize = iface_desc->endpoint[i].desc.wMaxPacketSize;
1080
1081                         DBGPRINT_RAW(RT_DEBUG_TRACE,
1082                                 ("BULK OUT MaximumPacketSize = %d\n", pAd->BulkOutMaxPacketSize));
1083                         DBGPRINT_RAW(RT_DEBUG_TRACE,
1084                                 ("EP address = 0x%2x  \n", iface_desc->endpoint[i].desc.bEndpointAddress));
1085                 }
1086         }
1087
1088         if (!(pAd->BulkInEpAddr && pAd->BulkOutEpAddr[0]))
1089         {
1090                 printk("%s: Could not find both bulk-in and bulk-out endpoints\n", __func__);
1091                 return FALSE;
1092         }
1093
1094         return TRUE;
1095 }
1096
1097
1098 /*
1099 ========================================================================
1100 Routine Description:
1101     Disable DMA.
1102
1103 Arguments:
1104         *pAd                            the raxx interface data pointer
1105
1106 Return Value:
1107         None
1108
1109 Note:
1110 ========================================================================
1111 */
1112 VOID RT28XXDMADisable(
1113         IN RTMP_ADAPTER                 *pAd)
1114 {
1115         // no use
1116 }
1117
1118
1119
1120 /*
1121 ========================================================================
1122 Routine Description:
1123     Enable DMA.
1124
1125 Arguments:
1126         *pAd                            the raxx interface data pointer
1127
1128 Return Value:
1129         None
1130
1131 Note:
1132 ========================================================================
1133 */
1134 VOID RT28XXDMAEnable(
1135         IN RTMP_ADAPTER                 *pAd)
1136 {
1137         WPDMA_GLO_CFG_STRUC     GloCfg;
1138         USB_DMA_CFG_STRUC       UsbCfg;
1139         int                                     i = 0;
1140
1141
1142         RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
1143         do
1144         {
1145                 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
1146                 if ((GloCfg.field.TxDMABusy == 0)  && (GloCfg.field.RxDMABusy == 0))
1147                         break;
1148
1149                 DBGPRINT(RT_DEBUG_TRACE, ("==>  DMABusy\n"));
1150                 RTMPusecDelay(1000);
1151                 i++;
1152         }while ( i <200);
1153
1154
1155         RTMPusecDelay(50);
1156         GloCfg.field.EnTXWriteBackDDONE = 1;
1157         GloCfg.field.EnableRxDMA = 1;
1158         GloCfg.field.EnableTxDMA = 1;
1159         DBGPRINT(RT_DEBUG_TRACE, ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word));
1160         RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
1161
1162         UsbCfg.word = 0;
1163         UsbCfg.field.phyclear = 0;
1164         /* usb version is 1.1,do not use bulk in aggregation */
1165         if (pAd->BulkInMaxPacketSize == 512)
1166                         UsbCfg.field.RxBulkAggEn = 1;
1167         /* for last packet, PBF might use more than limited, so minus 2 to prevent from error */
1168         UsbCfg.field.RxBulkAggLmt = (MAX_RXBULK_SIZE /1024)-3;
1169         UsbCfg.field.RxBulkAggTOut = 0x80; /* 2006-10-18 */
1170         UsbCfg.field.RxBulkEn = 1;
1171         UsbCfg.field.TxBulkEn = 1;
1172
1173         RTUSBWriteMACRegister(pAd, USB_DMA_CFG, UsbCfg.word);
1174
1175 }
1176
1177 /*
1178 ========================================================================
1179 Routine Description:
1180     Write Beacon buffer to Asic.
1181
1182 Arguments:
1183         *pAd                            the raxx interface data pointer
1184
1185 Return Value:
1186         None
1187
1188 Note:
1189 ========================================================================
1190 */
1191 VOID RT28xx_UpdateBeaconToAsic(
1192         IN RTMP_ADAPTER         *pAd,
1193         IN INT                          apidx,
1194         IN ULONG                        FrameLen,
1195         IN ULONG                        UpdatePos)
1196 {
1197         PUCHAR          pBeaconFrame = NULL;
1198         UCHAR                   *ptr;
1199         UINT                    i, padding;
1200         BEACON_SYNC_STRUCT      *pBeaconSync = pAd->CommonCfg.pBeaconSync;
1201         UINT32                  longValue;
1202         BOOLEAN                 bBcnReq = FALSE;
1203         UCHAR                   bcn_idx = 0;
1204
1205
1206         if (pBeaconFrame == NULL)
1207         {
1208                 DBGPRINT(RT_DEBUG_ERROR,("pBeaconFrame is NULL!\n"));
1209                 return;
1210         }
1211
1212         if (pBeaconSync == NULL)
1213         {
1214                 DBGPRINT(RT_DEBUG_ERROR,("pBeaconSync is NULL!\n"));
1215                 return;
1216         }
1217
1218         //if ((pAd->WdsTab.Mode == WDS_BRIDGE_MODE) ||
1219         //      ((pAd->ApCfg.MBSSID[apidx].MSSIDDev == NULL) || !(pAd->ApCfg.MBSSID[apidx].MSSIDDev->flags & IFF_UP))
1220         //      )
1221         if (bBcnReq == FALSE)
1222         {
1223                 /* when the ra interface is down, do not send its beacon frame */
1224                 /* clear all zero */
1225                 for(i=0; i<TXWI_SIZE; i+=4) {
1226                         RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, 0x00);
1227                 }
1228                 pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
1229                 NdisZeroMemory(pBeaconSync->BeaconTxWI[bcn_idx], TXWI_SIZE);
1230         }
1231         else
1232         {
1233                 ptr = (PUCHAR)&pAd->BeaconTxWI;
1234 #ifdef RT_BIG_ENDIAN
1235                 RTMPWIEndianChange(ptr, TYPE_TXWI);
1236 #endif
1237                 if (NdisEqualMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE) == FALSE)
1238                 {       // If BeaconTxWI changed, we need to rewrite the TxWI for the Beacon frames.
1239                         pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
1240                         NdisMoveMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE);
1241                 }
1242
1243                 if ((pBeaconSync->BeaconBitMap & (1 << bcn_idx)) != (1 << bcn_idx))
1244                 {
1245                         for (i=0; i<TXWI_SIZE; i+=4)  // 16-byte TXWI field
1246                         {
1247                                 longValue =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
1248                                 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, longValue);
1249                                 ptr += 4;
1250                         }
1251                 }
1252
1253                 ptr = pBeaconSync->BeaconBuf[bcn_idx];
1254                 padding = (FrameLen & 0x01);
1255                 NdisZeroMemory((PUCHAR)(pBeaconFrame + FrameLen), padding);
1256                 FrameLen += padding;
1257                 for (i = 0 ; i < FrameLen /*HW_BEACON_OFFSET*/; i += 2)
1258                 {
1259                         if (NdisEqualMemory(ptr, pBeaconFrame, 2) == FALSE)
1260                         {
1261                                 NdisMoveMemory(ptr, pBeaconFrame, 2);
1262                                 //shortValue = *ptr + (*(ptr+1)<<8);
1263                                 //RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, shortValue);
1264                                 RTUSBMultiWrite(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, ptr, 2);
1265                         }
1266                         ptr +=2;
1267                         pBeaconFrame += 2;
1268                 }
1269
1270                 pBeaconSync->BeaconBitMap |= (1 << bcn_idx);
1271         }
1272
1273 }
1274
1275
1276 VOID RT2870_BssBeaconStop(
1277         IN RTMP_ADAPTER *pAd)
1278 {
1279         BEACON_SYNC_STRUCT      *pBeaconSync;
1280         int i, offset;
1281         BOOLEAN Cancelled = TRUE;
1282
1283         pBeaconSync = pAd->CommonCfg.pBeaconSync;
1284         if (pBeaconSync && pBeaconSync->EnableBeacon)
1285         {
1286                 INT NumOfBcn;
1287
1288
1289 #ifdef CONFIG_STA_SUPPORT
1290                 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1291                 {
1292                         NumOfBcn = MAX_MESH_NUM;
1293                 }
1294 #endif // CONFIG_STA_SUPPORT //
1295
1296                 RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
1297
1298                 for(i=0; i<NumOfBcn; i++)
1299                 {
1300                         NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
1301                         NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
1302
1303                         for (offset=0; offset<HW_BEACON_OFFSET; offset+=4)
1304                                 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[i] + offset, 0x00);
1305
1306                         pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
1307                         pBeaconSync->TimIELocationInBeacon[i] = 0;
1308                 }
1309                 pBeaconSync->BeaconBitMap = 0;
1310                 pBeaconSync->DtimBitOn = 0;
1311         }
1312 }
1313
1314
1315 VOID RT2870_BssBeaconStart(
1316         IN RTMP_ADAPTER *pAd)
1317 {
1318         int apidx;
1319         BEACON_SYNC_STRUCT      *pBeaconSync;
1320 //      LARGE_INTEGER   tsfTime, deltaTime;
1321
1322         pBeaconSync = pAd->CommonCfg.pBeaconSync;
1323         if (pBeaconSync && pBeaconSync->EnableBeacon)
1324         {
1325                 INT NumOfBcn;
1326
1327
1328 #ifdef CONFIG_STA_SUPPORT
1329                 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1330                 {
1331                         NumOfBcn = MAX_MESH_NUM;
1332                 }
1333 #endif // CONFIG_STA_SUPPORT //
1334
1335                 for(apidx=0; apidx<NumOfBcn; apidx++)
1336                 {
1337                         UCHAR CapabilityInfoLocationInBeacon = 0;
1338                         UCHAR TimIELocationInBeacon = 0;
1339
1340                         NdisZeroMemory(pBeaconSync->BeaconBuf[apidx], HW_BEACON_OFFSET);
1341                         pBeaconSync->CapabilityInfoLocationInBeacon[apidx] = CapabilityInfoLocationInBeacon;
1342                         pBeaconSync->TimIELocationInBeacon[apidx] = TimIELocationInBeacon;
1343                         NdisZeroMemory(pBeaconSync->BeaconTxWI[apidx], TXWI_SIZE);
1344                 }
1345                 pBeaconSync->BeaconBitMap = 0;
1346                 pBeaconSync->DtimBitOn = 0;
1347                 pAd->CommonCfg.BeaconUpdateTimer.Repeat = TRUE;
1348
1349                 pAd->CommonCfg.BeaconAdjust = 0;
1350                 pAd->CommonCfg.BeaconFactor = 0xffffffff / (pAd->CommonCfg.BeaconPeriod << 10);
1351                 pAd->CommonCfg.BeaconRemain = (0xffffffff % (pAd->CommonCfg.BeaconPeriod << 10)) + 1;
1352                 printk("RT2870_BssBeaconStart:BeaconFactor=%d, BeaconRemain=%d!\n", pAd->CommonCfg.BeaconFactor, pAd->CommonCfg.BeaconRemain);
1353                 RTMPSetTimer(&pAd->CommonCfg.BeaconUpdateTimer, pAd->CommonCfg.BeaconPeriod);
1354
1355         }
1356 }
1357
1358
1359 VOID RT2870_BssBeaconInit(
1360         IN RTMP_ADAPTER *pAd)
1361 {
1362         BEACON_SYNC_STRUCT      *pBeaconSync;
1363         int i;
1364
1365         NdisAllocMemory(pAd->CommonCfg.pBeaconSync, sizeof(BEACON_SYNC_STRUCT), MEM_ALLOC_FLAG);
1366         if (pAd->CommonCfg.pBeaconSync)
1367         {
1368                 pBeaconSync = pAd->CommonCfg.pBeaconSync;
1369                 NdisZeroMemory(pBeaconSync, sizeof(BEACON_SYNC_STRUCT));
1370                 for(i=0; i < HW_BEACON_MAX_COUNT; i++)
1371                 {
1372                         NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
1373                         pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
1374                         pBeaconSync->TimIELocationInBeacon[i] = 0;
1375                         NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
1376                 }
1377                 pBeaconSync->BeaconBitMap = 0;
1378
1379                 //RTMPInitTimer(pAd, &pAd->CommonCfg.BeaconUpdateTimer, GET_TIMER_FUNCTION(BeaconUpdateExec), pAd, TRUE);
1380                 pBeaconSync->EnableBeacon = TRUE;
1381         }
1382 }
1383
1384
1385 VOID RT2870_BssBeaconExit(
1386         IN RTMP_ADAPTER *pAd)
1387 {
1388         BEACON_SYNC_STRUCT      *pBeaconSync;
1389         BOOLEAN Cancelled = TRUE;
1390         int i;
1391
1392         if (pAd->CommonCfg.pBeaconSync)
1393         {
1394                 pBeaconSync = pAd->CommonCfg.pBeaconSync;
1395                 pBeaconSync->EnableBeacon = FALSE;
1396                 RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
1397                 pBeaconSync->BeaconBitMap = 0;
1398
1399                 for(i=0; i<HW_BEACON_MAX_COUNT; i++)
1400                 {
1401                         NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
1402                         pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
1403                         pBeaconSync->TimIELocationInBeacon[i] = 0;
1404                         NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
1405                 }
1406
1407                 NdisFreeMemory(pAd->CommonCfg.pBeaconSync, HW_BEACON_OFFSET * HW_BEACON_MAX_COUNT, 0);
1408                 pAd->CommonCfg.pBeaconSync = NULL;
1409         }
1410 }
1411
1412 VOID BeaconUpdateExec(
1413     IN PVOID SystemSpecific1,
1414     IN PVOID FunctionContext,
1415     IN PVOID SystemSpecific2,
1416     IN PVOID SystemSpecific3)
1417 {
1418         PRTMP_ADAPTER   pAd = (PRTMP_ADAPTER)FunctionContext;
1419         LARGE_INTEGER   tsfTime_a;//, tsfTime_b, deltaTime_exp, deltaTime_ab;
1420         UINT32                  delta, remain, remain_low, remain_high;
1421 //      BOOLEAN                 positive;
1422
1423         ReSyncBeaconTime(pAd);
1424
1425
1426
1427         RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &tsfTime_a.u.LowPart);
1428         RTMP_IO_READ32(pAd, TSF_TIMER_DW1, &tsfTime_a.u.HighPart);
1429
1430
1431         //positive=getDeltaTime(tsfTime_a, expectedTime, &deltaTime_exp);
1432         remain_high = pAd->CommonCfg.BeaconRemain * tsfTime_a.u.HighPart;
1433         remain_low = tsfTime_a.u.LowPart % (pAd->CommonCfg.BeaconPeriod << 10);
1434         remain = (remain_high + remain_low)%(pAd->CommonCfg.BeaconPeriod << 10);
1435         delta = (pAd->CommonCfg.BeaconPeriod << 10) - remain;
1436
1437         pAd->CommonCfg.BeaconUpdateTimer.TimerValue = (delta >> 10) + 10;
1438
1439 }
1440