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