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