]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.drivers/staging-add-rt3070-wireless-driver.patch
Fix oinkmaster patch.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.drivers / staging-add-rt3070-wireless-driver.patch
Content-type: text/html ]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.drivers/staging-add-rt3070-wireless-driver.patch


500 - Internal Server Error

Malformed UTF-8 character (fatal) at (eval 6) line 1, <$fd> line 41474.
CommitLineData
2cb7cef9
BS
1From 74165ca9acb4060a4cd2de0095f4ff3f0885da3f Mon Sep 17 00:00:00 2001
2From: Greg Kroah-Hartman <gregkh@suse.de>
3Date: Wed, 25 Feb 2009 16:14:55 -0800
4Subject: Staging: add rt3070 wireless driver
5
6From: Greg Kroah-Hartman <gregkh@suse.de>
7
8This is the Ralink RT3070 driver from the company that does horrible
9things like reading a config file from /etc. However, the driver that
10is currently under development from the wireless development community
11is not working at all yet, so distros and users are using this version
12instead (quite common hardware on a lot of netbook machines).
13
14So here is this driver, for now, until the wireless developers get a
15"clean" version into the main tree, or until this version is cleaned up
16sufficiently to move out of the staging tree.
17
18Ported to the Linux build system, fixed lots of build issues, forward
19ported to the current kernel version, and other minor cleanups were all
20done by me.
21
22Cc: Linux wireless <linux-wireless@vger.kernel.org>
23Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
24
25---
26 drivers/staging/Kconfig | 2
27 drivers/staging/Makefile | 1
28 drivers/staging/rt3070/2870_main_dev.c | 1627 ++++
29 drivers/staging/rt3070/Kconfig | 6
30 drivers/staging/rt3070/Makefile | 47
31 drivers/staging/rt3070/action.h | 68
32 drivers/staging/rt3070/aironet.h | 210
33 drivers/staging/rt3070/ap.h | 557 +
34 drivers/staging/rt3070/chlist.h | 1253 +++
35 drivers/staging/rt3070/common/2870_rtmp_init.c | 1762 ++++
36 drivers/staging/rt3070/common/action.c | 1038 ++
37 drivers/staging/rt3070/common/ba_action.c | 1810 ++++
38 drivers/staging/rt3070/common/cmm_data.c | 2827 +++++++
39 drivers/staging/rt3070/common/cmm_data_2870.c | 980 ++
40 drivers/staging/rt3070/common/cmm_info.c | 3395 +++++++++
41 drivers/staging/rt3070/common/cmm_sanity.c | 1669 ++++
42 drivers/staging/rt3070/common/cmm_sync.c | 711 +
43 drivers/staging/rt3070/common/cmm_wpa.c | 1606 ++++
44 drivers/staging/rt3070/common/dfs.c | 441 +
45 drivers/staging/rt3070/common/eeprom.c | 1498 ++++
46 drivers/staging/rt3070/common/md5.c | 1427 +++
47 drivers/staging/rt3070/common/mlme.c | 9136 +++++++++++++++++++++++++
48 drivers/staging/rt3070/common/netif_block.c | 136
49 drivers/staging/rt3070/common/rtmp_init.c | 4197 +++++++++++
50 drivers/staging/rt3070/common/rtmp_tkip.c | 1613 ++++
51 drivers/staging/rt3070/common/rtmp_wep.c | 508 +
52 drivers/staging/rt3070/common/rtusb_bulk.c | 1382 +++
53 drivers/staging/rt3070/common/rtusb_data.c | 218
54 drivers/staging/rt3070/common/rtusb_io.c | 1908 +++++
55 drivers/staging/rt3070/common/spectrum.c | 1876 +++++
56 drivers/staging/rt3070/dfs.h | 100
57 drivers/staging/rt3070/firmware.h | 558 +
58 drivers/staging/rt3070/leap.h | 215
59 drivers/staging/rt3070/link_list.h | 134
60 drivers/staging/rt3070/md4.h | 42
61 drivers/staging/rt3070/md5.h | 107
62 drivers/staging/rt3070/mlme.h | 1468 ++++
63 drivers/staging/rt3070/netif_block.h | 58
64 drivers/staging/rt3070/oid.h | 1142 +++
65 drivers/staging/rt3070/rt2870.h | 756 ++
66 drivers/staging/rt3070/rt28xx.h | 2725 +++++++
67 drivers/staging/rt3070/rt_ate.c | 6506 +++++++++++++++++
68 drivers/staging/rt3070/rt_ate.h | 294
69 drivers/staging/rt3070/rt_config.h | 121
70 drivers/staging/rt3070/rt_linux.c | 1063 ++
71 drivers/staging/rt3070/rt_linux.h | 887 ++
72 drivers/staging/rt3070/rt_main_dev.c | 1800 ++++
73 drivers/staging/rt3070/rt_profile.c | 2041 +++++
74 drivers/staging/rt3070/rtmp.h | 7728 +++++++++++++++++++++
75 drivers/staging/rt3070/rtmp_ckipmic.h | 113
76 drivers/staging/rt3070/rtmp_def.h | 1559 ++++
77 drivers/staging/rt3070/rtmp_type.h | 95
78 drivers/staging/rt3070/spectrum.h | 322
79 drivers/staging/rt3070/spectrum_def.h | 95
80 drivers/staging/rt3070/sta/aironet.c | 1312 +++
81 drivers/staging/rt3070/sta/assoc.c | 2060 +++++
82 drivers/staging/rt3070/sta/auth.c | 475 +
83 drivers/staging/rt3070/sta/auth_rsp.c | 167
84 drivers/staging/rt3070/sta/connect.c | 2857 +++++++
85 drivers/staging/rt3070/sta/dls.c | 2170 +++++
86 drivers/staging/rt3070/sta/rtmp_data.c | 2637 +++++++
87 drivers/staging/rt3070/sta/sanity.c | 420 +
88 drivers/staging/rt3070/sta/sync.c | 1755 ++++
89 drivers/staging/rt3070/sta/wpa.c | 2099 +++++
90 drivers/staging/rt3070/sta_ioctl.c | 7203 +++++++++++++++++++
91 drivers/staging/rt3070/wpa.h | 356
92 66 files changed, 97349 insertions(+)
93
94--- a/drivers/staging/Kconfig
95+++ b/drivers/staging/Kconfig
96@@ -51,6 +51,8 @@ source "drivers/staging/rt2860/Kconfig"
97
98 source "drivers/staging/rt2870/Kconfig"
99
100+source "drivers/staging/rt3070/Kconfig"
101+
102 source "drivers/staging/benet/Kconfig"
103
104 source "drivers/staging/rtl8187se/Kconfig"
105--- a/drivers/staging/Makefile
106+++ b/drivers/staging/Makefile
107@@ -17,5 +17,6 @@ obj-$(CONFIG_AGNX) += agnx/
108 obj-$(CONFIG_OTUS) += otus/
109 obj-$(CONFIG_RT2860) += rt2860/
110 obj-$(CONFIG_RT2870) += rt2870/
111+obj-$(CONFIG_RT3070) += rt3070/
112 obj-$(CONFIG_BENET) += benet/
113 obj-$(CONFIG_RTL8187SE) += rtl8187se/
114--- /dev/null
115+++ b/drivers/staging/rt3070/2870_main_dev.c
116@@ -0,0 +1,1627 @@
117+/*
118+ *************************************************************************
119+ * Ralink Tech Inc.
120+ * 5F., No.36, Taiyuan St., Jhubei City,
121+ * Hsinchu County 302,
122+ * Taiwan, R.O.C.
123+ *
124+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
125+ *
126+ * This program is free software; you can redistribute it and/or modify *
127+ * it under the terms of the GNU General Public License as published by *
128+ * the Free Software Foundation; either version 2 of the License, or *
129+ * (at your option) any later version. *
130+ * *
131+ * This program is distributed in the hope that it will be useful, *
132+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
133+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
134+ * GNU General Public License for more details. *
135+ * *
136+ * You should have received a copy of the GNU General Public License *
137+ * along with this program; if not, write to the *
138+ * Free Software Foundation, Inc., *
139+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
140+ * *
141+ *************************************************************************
142+
143+ Module Name:
144+ rtmp_main.c
145+
146+ Abstract:
147+ main initialization routines
148+
149+ Revision History:
150+ Who When What
151+ -------- ---------- ----------------------------------------------
152+ Name Date Modification logs
153+ Jan Lee 01-10-2005 modified
154+ Sample Jun/01/07 Merge RT2870 and RT2860 drivers.
155+*/
156+
157+#include "rt_config.h"
158+
159+
160+// Following information will be show when you run 'modinfo'
161+// *** If you have a solution for the bug in current version of driver, please mail to me.
162+// Otherwise post to forum in ralinktech's web site(www.ralinktech.com) and let all users help you. ***
163+MODULE_AUTHOR("Paul Lin <paul_lin@ralinktech.com>");
164+MODULE_DESCRIPTION("RT2870 Wireless Lan Linux Driver");
165+#ifdef CONFIG_STA_SUPPORT
166+MODULE_LICENSE("GPL");
167+#ifdef MODULE_VERSION
168+MODULE_VERSION(STA_DRIVER_VERSION);
169+#endif
170+#endif // CONFIG_STA_SUPPORT //
171+
172+#ifdef MULTIPLE_CARD_SUPPORT
173+// record whether the card in the card list is used in the card file
174+extern UINT8 MC_CardUsed[];
175+#endif // MULTIPLE_CARD_SUPPORT //
176+
177+/* Kernel thread and vars, which handles packets that are completed. Only
178+ * packets that have a "complete" function are sent here. This way, the
179+ * completion is run out of kernel context, and doesn't block the rest of
180+ * the stack. */
181+//static int mlme_kill = 0; // Mlme kernel thread
182+//static int RTUSBCmd_kill = 0; // Command kernel thread
183+//static int TimerFunc_kill = 0; // TimerQ kernel thread
184+
185+//static wait_queue_head_t timerWaitQ;
186+//static wait_queue_t waitQ;
187+
188+extern INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p,
189+ IN UINT argc, OUT PRTMP_ADAPTER *ppAd);
190+
191+
192+/* module table */
193+struct usb_device_id rtusb_usb_id[] = RT2870_USB_DEVICES;
194+INT const rtusb_usb_id_len = sizeof(rtusb_usb_id) / sizeof(struct usb_device_id);
195+MODULE_DEVICE_TABLE(usb, rtusb_usb_id);
196+
197+#ifndef PF_NOFREEZE
198+#define PF_NOFREEZE 0
199+#endif
200+
201+
202+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
203+
204+/**************************************************************************/
205+/**************************************************************************/
206+//tested for kernel 2.4 series
207+/**************************************************************************/
208+/**************************************************************************/
209+static void *rtusb_probe(struct usb_device *dev, UINT interface,
210+ const struct usb_device_id *id_table);
211+static void rtusb_disconnect(struct usb_device *dev, void *ptr);
212+
213+struct usb_driver rtusb_driver = {
214+ name:"rt2870",
215+ probe:rtusb_probe,
216+ disconnect:rtusb_disconnect,
217+ id_table:rtusb_usb_id,
218+ };
219+
220+#else
221+
222+#ifdef CONFIG_PM
223+static int rt2870_suspend(struct usb_interface *intf, pm_message_t state);
224+static int rt2870_resume(struct usb_interface *intf);
225+#endif // CONFIG_PM //
226+
227+/**************************************************************************/
228+/**************************************************************************/
229+//tested for kernel 2.6series
230+/**************************************************************************/
231+/**************************************************************************/
232+static int rtusb_probe (struct usb_interface *intf,
233+ const struct usb_device_id *id);
234+static void rtusb_disconnect(struct usb_interface *intf);
235+
236+struct usb_driver rtusb_driver = {
237+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
238+ .owner = THIS_MODULE,
239+#endif
240+ .name="rt2870",
241+ .probe=rtusb_probe,
242+ .disconnect=rtusb_disconnect,
243+ .id_table=rtusb_usb_id,
244+
245+#ifdef CONFIG_PM
246+ suspend: rt2870_suspend,
247+ resume: rt2870_resume,
248+#endif
249+ };
250+
251+#ifdef CONFIG_PM
252+
253+VOID RT2860RejectPendingPackets(
254+ IN PRTMP_ADAPTER pAd)
255+{
256+ // clear PS packets
257+ // clear TxSw packets
258+}
259+
260+static int rt2870_suspend(
261+ struct usb_interface *intf,
262+ pm_message_t state)
263+{
264+ struct net_device *net_dev;
265+ PRTMP_ADAPTER pAd = usb_get_intfdata(intf);
266+
267+
268+ DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_suspend()\n"));
269+ net_dev = pAd->net_dev;
270+ netif_device_detach(net_dev);
271+
272+ pAd->PM_FlgSuspend = 1;
273+ if (netif_running(net_dev)) {
274+ RTUSBCancelPendingBulkInIRP(pAd);
275+ RTUSBCancelPendingBulkOutIRP(pAd);
276+ }
277+ DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_suspend()\n"));
278+ return 0;
279+}
280+
281+static int rt2870_resume(
282+ struct usb_interface *intf)
283+{
284+ struct net_device *net_dev;
285+ PRTMP_ADAPTER pAd = usb_get_intfdata(intf);
286+
287+
288+ DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_resume()\n"));
289+
290+ pAd->PM_FlgSuspend = 0;
291+ net_dev = pAd->net_dev;
292+ netif_device_attach(net_dev);
293+ netif_start_queue(net_dev);
294+ netif_carrier_on(net_dev);
295+ netif_wake_queue(net_dev);
296+
297+ DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_resume()\n"));
298+ return 0;
299+}
300+#endif // CONFIG_PM //
301+#endif // LINUX_VERSION_CODE //
302+
303+
304+// Init driver module
305+INT __init rtusb_init(void)
306+{
307+ printk("rtusb init --->\n");
308+ return usb_register(&rtusb_driver);
309+}
310+
311+// Deinit driver module
312+VOID __exit rtusb_exit(void)
313+{
314+ usb_deregister(&rtusb_driver);
315+ printk("<--- rtusb exit\n");
316+}
317+
318+module_init(rtusb_init);
319+module_exit(rtusb_exit);
320+
321+
322+
323+
324+/*--------------------------------------------------------------------- */
325+/* function declarations */
326+/*--------------------------------------------------------------------- */
327+
328+/*
329+========================================================================
330+Routine Description:
331+ MLME kernel thread.
332+
333+Arguments:
334+ *Context the pAd, driver control block pointer
335+
336+Return Value:
337+ 0 close the thread
338+
339+Note:
340+========================================================================
341+*/
342+INT MlmeThread(
343+ IN void *Context)
344+{
345+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)Context;
346+ POS_COOKIE pObj;
347+ int status;
348+
349+ pObj = (POS_COOKIE)pAd->OS_Cookie;
350+
351+ rtmp_os_thread_init("rt2870MlmeThread", (PVOID)&(pAd->mlmeComplete));
352+
353+ while (pAd->mlme_kill == 0)
354+ {
355+ /* lock the device pointers */
356+ //down(&(pAd->mlme_semaphore));
357+ status = down_interruptible(&(pAd->mlme_semaphore));
358+
359+ /* lock the device pointers , need to check if required*/
360+ //down(&(pAd->usbdev_semaphore));
361+
362+ if (!pAd->PM_FlgSuspend)
363+ MlmeHandler(pAd);
364+
365+ /* unlock the device pointers */
366+ //up(&(pAd->usbdev_semaphore));
367+ if (status != 0)
368+ {
369+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
370+ break;
371+ }
372+ }
373+
374+ /* notify the exit routine that we're actually exiting now
375+ *
376+ * complete()/wait_for_completion() is similar to up()/down(),
377+ * except that complete() is safe in the case where the structure
378+ * is getting deleted in a parallel mode of execution (i.e. just
379+ * after the down() -- that's necessary for the thread-shutdown
380+ * case.
381+ *
382+ * complete_and_exit() goes even further than this -- it is safe in
383+ * the case that the thread of the caller is going away (not just
384+ * the structure) -- this is necessary for the module-remove case.
385+ * This is important in preemption kernels, which transfer the flow
386+ * of execution immediately upon a complete().
387+ */
388+ DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__FUNCTION__));
389+
390+ pObj->MLMEThr_pid = NULL;
391+
392+ complete_and_exit (&pAd->mlmeComplete, 0);
393+ return 0;
394+
395+}
396+
397+
398+/*
399+========================================================================
400+Routine Description:
401+ USB command kernel thread.
402+
403+Arguments:
404+ *Context the pAd, driver control block pointer
405+
406+Return Value:
407+ 0 close the thread
408+
409+Note:
410+========================================================================
411+*/
412+INT RTUSBCmdThread(
413+ IN void * Context)
414+{
415+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)Context;
416+ POS_COOKIE pObj;
417+ int status;
418+
419+ pObj = (POS_COOKIE)pAd->OS_Cookie;
420+
421+ rtmp_os_thread_init("rt2870CmdThread", (PVOID)&(pAd->CmdQComplete));
422+
423+ NdisAcquireSpinLock(&pAd->CmdQLock);
424+ pAd->CmdQ.CmdQState = RT2870_THREAD_RUNNING;
425+ NdisReleaseSpinLock(&pAd->CmdQLock);
426+
427+ while (pAd->CmdQ.CmdQState == RT2870_THREAD_RUNNING)
428+ {
429+ /* lock the device pointers */
430+ //down(&(pAd->RTUSBCmd_semaphore));
431+ status = down_interruptible(&(pAd->RTUSBCmd_semaphore));
432+
433+ if (pAd->CmdQ.CmdQState == RT2870_THREAD_STOPED)
434+ break;
435+
436+ if (status != 0)
437+ {
438+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
439+ break;
440+ }
441+ /* lock the device pointers , need to check if required*/
442+ //down(&(pAd->usbdev_semaphore));
443+
444+ if (!pAd->PM_FlgSuspend)
445+ CMDHandler(pAd);
446+
447+ /* unlock the device pointers */
448+ //up(&(pAd->usbdev_semaphore));
449+ }
450+
451+ if (!pAd->PM_FlgSuspend)
452+ { // Clear the CmdQElements.
453+ CmdQElmt *pCmdQElmt = NULL;
454+
455+ NdisAcquireSpinLock(&pAd->CmdQLock);
456+ pAd->CmdQ.CmdQState = RT2870_THREAD_STOPED;
457+ while(pAd->CmdQ.size)
458+ {
459+ RTUSBDequeueCmd(&pAd->CmdQ, &pCmdQElmt);
460+ if (pCmdQElmt)
461+ {
462+ if (pCmdQElmt->CmdFromNdis == TRUE)
463+ {
464+ if (pCmdQElmt->buffer != NULL)
465+ NdisFreeMemory(pCmdQElmt->buffer, pCmdQElmt->bufferlength, 0);
466+
467+ NdisFreeMemory(pCmdQElmt, sizeof(CmdQElmt), 0);
468+ }
469+ else
470+ {
471+ if ((pCmdQElmt->buffer != NULL) && (pCmdQElmt->bufferlength != 0))
472+ NdisFreeMemory(pCmdQElmt->buffer, pCmdQElmt->bufferlength, 0);
473+ {
474+ NdisFreeMemory(pCmdQElmt, sizeof(CmdQElmt), 0);
475+ }
476+ }
477+ }
478+ }
479+
480+ NdisReleaseSpinLock(&pAd->CmdQLock);
481+ }
482+ /* notify the exit routine that we're actually exiting now
483+ *
484+ * complete()/wait_for_completion() is similar to up()/down(),
485+ * except that complete() is safe in the case where the structure
486+ * is getting deleted in a parallel mode of execution (i.e. just
487+ * after the down() -- that's necessary for the thread-shutdown
488+ * case.
489+ *
490+ * complete_and_exit() goes even further than this -- it is safe in
491+ * the case that the thread of the caller is going away (not just
492+ * the structure) -- this is necessary for the module-remove case.
493+ * This is important in preemption kernels, which transfer the flow
494+ * of execution immediately upon a complete().
495+ */
496+ DBGPRINT(RT_DEBUG_TRACE,( "<---RTUSBCmdThread\n"));
497+
498+ pObj->RTUSBCmdThr_pid = NULL;
499+
500+ complete_and_exit (&pAd->CmdQComplete, 0);
501+ return 0;
502+
503+}
504+
505+
506+static void RT2870_TimerQ_Handle(RTMP_ADAPTER *pAd)
507+{
508+ int status;
509+ RALINK_TIMER_STRUCT *pTimer;
510+ RT2870_TIMER_ENTRY *pEntry;
511+ unsigned long irqFlag;
512+
513+ while(!pAd->TimerFunc_kill)
514+ {
515+// printk("waiting for event!\n");
516+ pTimer = NULL;
517+
518+ status = down_interruptible(&(pAd->RTUSBTimer_semaphore));
519+
520+ if (pAd->TimerQ.status == RT2870_THREAD_STOPED)
521+ break;
522+
523+ // event happened.
524+ while(pAd->TimerQ.pQHead)
525+ {
526+ RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlag);
527+ pEntry = pAd->TimerQ.pQHead;
528+ if (pEntry)
529+ {
530+ pTimer = pEntry->pRaTimer;
531+
532+ // update pQHead
533+ pAd->TimerQ.pQHead = pEntry->pNext;
534+ if (pEntry == pAd->TimerQ.pQTail)
535+ pAd->TimerQ.pQTail = NULL;
536+
537+ // return this queue entry to timerQFreeList.
538+ pEntry->pNext = pAd->TimerQ.pQPollFreeList;
539+ pAd->TimerQ.pQPollFreeList = pEntry;
540+ }
541+ RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlag);
542+
543+ if (pTimer)
544+ {
545+ if (pTimer->handle != NULL)
546+ if (!pAd->PM_FlgSuspend)
547+ pTimer->handle(NULL, (PVOID) pTimer->cookie, NULL, pTimer);
548+ if ((pTimer->Repeat) && (pTimer->State == FALSE))
549+ RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue);
550+ }
551+ }
552+
553+ if (status != 0)
554+ {
555+ pAd->TimerQ.status = RT2870_THREAD_STOPED;
556+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
557+ break;
558+ }
559+ }
560+}
561+
562+
563+INT TimerQThread(
564+ IN OUT PVOID Context)
565+{
566+ PRTMP_ADAPTER pAd;
567+ POS_COOKIE pObj;
568+
569+ pAd = (PRTMP_ADAPTER)Context;
570+ pObj = (POS_COOKIE) pAd->OS_Cookie;
571+
572+ rtmp_os_thread_init("rt2870TimerQHandle", (PVOID)&(pAd->TimerQComplete));
573+
574+ RT2870_TimerQ_Handle(pAd);
575+
576+ /* notify the exit routine that we're actually exiting now
577+ *
578+ * complete()/wait_for_completion() is similar to up()/down(),
579+ * except that complete() is safe in the case where the structure
580+ * is getting deleted in a parallel mode of execution (i.e. just
581+ * after the down() -- that's necessary for the thread-shutdown
582+ * case.
583+ *
584+ * complete_and_exit() goes even further than this -- it is safe in
585+ * the case that the thread of the caller is going away (not just
586+ * the structure) -- this is necessary for the module-remove case.
587+ * This is important in preemption kernels, which transfer the flow
588+ * of execution immediately upon a complete().
589+ */
590+ DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__FUNCTION__));
591+
592+ pObj->TimerQThr_pid = NULL;
593+
594+ complete_and_exit(&pAd->TimerQComplete, 0);
595+ return 0;
596+
597+}
598+
599+
600+RT2870_TIMER_ENTRY *RT2870_TimerQ_Insert(
601+ IN RTMP_ADAPTER *pAd,
602+ IN RALINK_TIMER_STRUCT *pTimer)
603+{
604+ RT2870_TIMER_ENTRY *pQNode = NULL, *pQTail;
605+ unsigned long irqFlags;
606+
607+
608+ RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
609+ if (pAd->TimerQ.status & RT2870_THREAD_CAN_DO_INSERT)
610+ {
611+ if(pAd->TimerQ.pQPollFreeList)
612+ {
613+ pQNode = pAd->TimerQ.pQPollFreeList;
614+ pAd->TimerQ.pQPollFreeList = pQNode->pNext;
615+
616+ pQNode->pRaTimer = pTimer;
617+ pQNode->pNext = NULL;
618+
619+ pQTail = pAd->TimerQ.pQTail;
620+ if (pAd->TimerQ.pQTail != NULL)
621+ pQTail->pNext = pQNode;
622+ pAd->TimerQ.pQTail = pQNode;
623+ if (pAd->TimerQ.pQHead == NULL)
624+ pAd->TimerQ.pQHead = pQNode;
625+ }
626+ RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
627+
628+ if (pQNode)
629+ up(&pAd->RTUSBTimer_semaphore);
630+ //wake_up(&timerWaitQ);
631+ }
632+ else
633+ {
634+ RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
635+ }
636+ return pQNode;
637+}
638+
639+
640+BOOLEAN RT2870_TimerQ_Remove(
641+ IN RTMP_ADAPTER *pAd,
642+ IN RALINK_TIMER_STRUCT *pTimer)
643+{
644+ RT2870_TIMER_ENTRY *pNode, *pPrev = NULL;
645+ unsigned long irqFlags;
646+
647+ RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
648+ if (pAd->TimerQ.status >= RT2870_THREAD_INITED)
649+ {
650+ pNode = pAd->TimerQ.pQHead;
651+ while (pNode)
652+ {
653+ if (pNode->pRaTimer == pTimer)
654+ break;
655+ pPrev = pNode;
656+ pNode = pNode->pNext;
657+ }
658+
659+ // Now move it to freeList queue.
660+ if (pNode)
661+ {
662+ if (pNode == pAd->TimerQ.pQHead)
663+ pAd->TimerQ.pQHead = pNode->pNext;
664+ if (pNode == pAd->TimerQ.pQTail)
665+ pAd->TimerQ.pQTail = pPrev;
666+ if (pPrev != NULL)
667+ pPrev->pNext = pNode->pNext;
668+
669+ // return this queue entry to timerQFreeList.
670+ pNode->pNext = pAd->TimerQ.pQPollFreeList;
671+ pAd->TimerQ.pQPollFreeList = pNode;
672+ }
673+ }
674+ RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
675+
676+ return TRUE;
677+}
678+
679+
680+void RT2870_TimerQ_Exit(RTMP_ADAPTER *pAd)
681+{
682+ RT2870_TIMER_ENTRY *pTimerQ;
683+ unsigned long irqFlags;
684+
685+ RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
686+ while (pAd->TimerQ.pQHead)
687+ {
688+ pTimerQ = pAd->TimerQ.pQHead;
689+ pAd->TimerQ.pQHead = pTimerQ->pNext;
690+ // remove the timeQ
691+ }
692+ pAd->TimerQ.pQPollFreeList = NULL;
693+ os_free_mem(pAd, pAd->TimerQ.pTimerQPoll);
694+ pAd->TimerQ.pQTail = NULL;
695+ pAd->TimerQ.pQHead = NULL;
696+ pAd->TimerQ.status = RT2870_THREAD_STOPED;
697+ RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
698+
699+}
700+
701+
702+void RT2870_TimerQ_Init(RTMP_ADAPTER *pAd)
703+{
704+ int i;
705+ RT2870_TIMER_ENTRY *pQNode, *pEntry;
706+ unsigned long irqFlags;
707+
708+ NdisAllocateSpinLock(&pAd->TimerQLock);
709+
710+ RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
711+ NdisZeroMemory(&pAd->TimerQ, sizeof(pAd->TimerQ));
712+ //InterlockedExchange(&pAd->TimerQ.count, 0);
713+
714+ /* Initialise the wait q head */
715+ //init_waitqueue_head(&timerWaitQ);
716+
717+ os_alloc_mem(pAd, &pAd->TimerQ.pTimerQPoll, sizeof(RT2870_TIMER_ENTRY) * TIMER_QUEUE_SIZE_MAX);
718+ if (pAd->TimerQ.pTimerQPoll)
719+ {
720+ pEntry = NULL;
721+ pQNode = (RT2870_TIMER_ENTRY *)pAd->TimerQ.pTimerQPoll;
722+ for (i = 0 ;i <TIMER_QUEUE_SIZE_MAX; i++)
723+ {
724+ pQNode->pNext = pEntry;
725+ pEntry = pQNode;
726+ pQNode++;
727+ }
728+ pAd->TimerQ.pQPollFreeList = pEntry;
729+ pAd->TimerQ.pQHead = NULL;
730+ pAd->TimerQ.pQTail = NULL;
731+ pAd->TimerQ.status = RT2870_THREAD_INITED;
732+ }
733+ RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
734+}
735+
736+
737+VOID RT2870_WatchDog(IN RTMP_ADAPTER *pAd)
738+{
739+ PHT_TX_CONTEXT pHTTXContext;
740+ int idx;
741+ ULONG irqFlags;
742+ PURB pUrb;
743+ BOOLEAN needDumpSeq = FALSE;
744+ UINT32 MACValue;
745+
746+
747+ idx = 0;
748+ RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
749+ if ((MACValue & 0xff) !=0 )
750+ {
751+ DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 0 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue));
752+ RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40012);
753+ while((MACValue &0xff) != 0 && (idx++ < 10))
754+ {
755+ RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
756+ NdisMSleep(1);
757+ }
758+ RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006);
759+ }
760+
761+//PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
762+#ifdef CONFIG_STA_SUPPORT
763+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
764+ {
765+ idx = 0;
766+ if ((MACValue & 0xff00) !=0 )
767+ {
768+ DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 1 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue));
769+ RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf4000a);
770+ while((MACValue &0xff00) != 0 && (idx++ < 10))
771+ {
772+ RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
773+ NdisMSleep(1);
774+ }
775+ RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006);
776+ }
777+ }
778+#endif // CONFIG_STA_SUPPORT //
779+
780+ if (pAd->watchDogRxOverFlowCnt >= 2)
781+ {
782+ DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Rx Bulk-In hanged! Cancel the pending Rx bulks request!\n"));
783+ if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
784+ fRTMP_ADAPTER_BULKIN_RESET |
785+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
786+ fRTMP_ADAPTER_NIC_NOT_EXIST))))
787+ {
788+ DBGPRINT(RT_DEBUG_TRACE, ("Call CMDTHREAD_RESET_BULK_IN to cancel the pending Rx Bulk!\n"));
789+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
790+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0);
791+ needDumpSeq = TRUE;
792+ }
793+ pAd->watchDogRxOverFlowCnt = 0;
794+ }
795+
796+
797+ for (idx = 0; idx < NUM_OF_TX_RING; idx++)
798+ {
799+ pUrb = NULL;
800+
801+ RTMP_IRQ_LOCK(&pAd->BulkOutLock[idx], irqFlags);
802+ if ((pAd->BulkOutPending[idx] == TRUE) && pAd->watchDogTxPendingCnt)
803+ {
804+ pAd->watchDogTxPendingCnt[idx]++;
805+
806+ if ((pAd->watchDogTxPendingCnt[idx] > 2) &&
807+ (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_BULKOUT_RESET)))
808+ )
809+ {
810+ // FIXME: Following code just support single bulk out. If you wanna support multiple bulk out. Modify it!
811+ pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[idx]);
812+ if (pHTTXContext->IRPPending)
813+ { // Check TxContext.
814+ pUrb = pHTTXContext->pUrb;
815+ }
816+ else if (idx == MGMTPIPEIDX)
817+ {
818+ PTX_CONTEXT pMLMEContext, pNULLContext, pPsPollContext;
819+
820+ //Check MgmtContext.
821+ pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa);
822+ pPsPollContext = (PTX_CONTEXT)(&pAd->PsPollContext);
823+ pNULLContext = (PTX_CONTEXT)(&pAd->NullContext);
824+
825+ if (pMLMEContext->IRPPending)
826+ {
827+ ASSERT(pMLMEContext->IRPPending);
828+ pUrb = pMLMEContext->pUrb;
829+ }
830+ else if (pNULLContext->IRPPending)
831+ {
832+ ASSERT(pNULLContext->IRPPending);
833+ pUrb = pNULLContext->pUrb;
834+ }
835+ else if (pPsPollContext->IRPPending)
836+ {
837+ ASSERT(pPsPollContext->IRPPending);
838+ pUrb = pPsPollContext->pUrb;
839+ }
840+ }
841+
842+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
843+
844+ DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Tx Bulk-Out hanged! Cancel the pending Tx bulks request of idx(%d)!\n", idx));
845+ if (pUrb)
846+ {
847+ DBGPRINT(RT_DEBUG_TRACE, ("Unlink the pending URB!\n"));
848+ // unlink it now
849+ RTUSB_UNLINK_URB(pUrb);
850+ // Sleep 200 microseconds to give cancellation time to work
851+ RTMPusecDelay(200);
852+ needDumpSeq = TRUE;
853+ }
854+ else
855+ {
856+ DBGPRINT(RT_DEBUG_ERROR, ("Unkonw bulkOut URB maybe hanged!!!!!!!!!!!!\n"));
857+ }
858+ }
859+ else
860+ {
861+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
862+ }
863+ }
864+ else
865+ {
866+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
867+ }
868+ }
869+
870+#ifdef DOT11_N_SUPPORT
871+ // For Sigma debug, dump the ba_reordering sequence.
872+ if((needDumpSeq == TRUE) && (pAd->CommonCfg.bDisableReordering == 0))
873+ {
874+ USHORT Idx;
875+ PBA_REC_ENTRY pBAEntry = NULL;
876+ UCHAR count = 0;
877+ struct reordering_mpdu *mpdu_blk;
878+
879+ Idx = pAd->MacTab.Content[BSSID_WCID].BARecWcidArray[0];
880+
881+ pBAEntry = &pAd->BATable.BARecEntry[Idx];
882+ if((pBAEntry->list.qlen > 0) && (pBAEntry->list.next != NULL))
883+ {
884+ DBGPRINT(RT_DEBUG_TRACE, ("NICUpdateRawCounters():The Queueing pkt in reordering buffer:\n"));
885+ NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
886+ mpdu_blk = pBAEntry->list.next;
887+ while (mpdu_blk)
888+ {
889+ DBGPRINT(RT_DEBUG_TRACE, ("\t%d:Seq-%d, bAMSDU-%d!\n", count, mpdu_blk->Sequence, mpdu_blk->bAMSDU));
890+ mpdu_blk = mpdu_blk->next;
891+ count++;
892+ }
893+
894+ DBGPRINT(RT_DEBUG_TRACE, ("\npBAEntry->LastIndSeq=%d!\n", pBAEntry->LastIndSeq));
895+ NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
896+ }
897+ }
898+#endif // DOT11_N_SUPPORT //
899+}
900+
901+/*
902+========================================================================
903+Routine Description:
904+ Release allocated resources.
905+
906+Arguments:
907+ *dev Point to the PCI or USB device
908+ pAd driver control block pointer
909+
910+Return Value:
911+ None
912+
913+Note:
914+========================================================================
915+*/
916+static void _rtusb_disconnect(struct usb_device *dev, PRTMP_ADAPTER pAd)
917+{
918+ struct net_device *net_dev = NULL;
919+
920+
921+ DBGPRINT(RT_DEBUG_ERROR, ("rtusb_disconnect: unregister usbnet usb-%s-%s\n",
922+ dev->bus->bus_name, dev->devpath));
923+ if (!pAd)
924+ {
925+#ifdef MULTIPLE_CARD_SUPPORT
926+ if ((pAd->MC_RowID >= 0) && (pAd->MC_RowID <= MAX_NUM_OF_MULTIPLE_CARD))
927+ MC_CardUsed[pAd->MC_RowID] = 0; // not clear MAC address
928+#endif // MULTIPLE_CARD_SUPPORT //
929+
930+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
931+ while(MOD_IN_USE > 0)
932+ {
933+ MOD_DEC_USE_COUNT;
934+ }
935+#else
936+ usb_put_dev(dev);
937+#endif // LINUX_VERSION_CODE //
938+
939+ printk("rtusb_disconnect: pAd == NULL!\n");
940+ return;
941+ }
942+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
943+
944+
945+
946+ // for debug, wait to show some messages to /proc system
947+ udelay(1);
948+
949+
950+
951+
952+ net_dev = pAd->net_dev;
953+ if (pAd->net_dev != NULL)
954+ {
955+ printk("rtusb_disconnect: unregister_netdev(), dev->name=%s!\n", net_dev->name);
956+ unregister_netdev (pAd->net_dev);
957+ }
958+ udelay(1);
959+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
960+#else
961+ flush_scheduled_work();
962+#endif // LINUX_VERSION_CODE //
963+ udelay(1);
964+
965+ // free net_device memory
966+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
967+ kfree(net_dev);
968+#else
969+ free_netdev(net_dev);
970+#endif // LINUX_VERSION_CODE //
971+
972+ // free adapter memory
973+ RTMPFreeAdapter(pAd);
974+
975+ // release a use of the usb device structure
976+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
977+ while(MOD_IN_USE > 0)
978+ {
979+ MOD_DEC_USE_COUNT;
980+ }
981+#else
982+ usb_put_dev(dev);
983+#endif // LINUX_VERSION_CODE //
984+ udelay(1);
985+
986+ DBGPRINT(RT_DEBUG_ERROR, (" RTUSB disconnect successfully\n"));
987+}
988+
989+
990+/*
991+========================================================================
992+Routine Description:
993+ Probe RT28XX chipset.
994+
995+Arguments:
996+ *dev Point to the PCI or USB device
997+ interface
998+ *id_table Point to the PCI or USB device ID
999+
1000+Return Value:
1001+ None
1002+
1003+Note:
1004+========================================================================
1005+*/
1006+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
1007+static void *rtusb_probe(struct usb_device *dev, UINT interface,
1008+ const struct usb_device_id *id)
1009+{
1010+ PRTMP_ADAPTER pAd;
1011+ rt28xx_probe((void *)dev, (void *)id, interface, &pAd);
1012+ return (void *)pAd;
1013+}
1014+
1015+//Disconnect function is called within exit routine
1016+static void rtusb_disconnect(struct usb_device *dev, void *ptr)
1017+{
1018+ _rtusb_disconnect(dev, ((PRTMP_ADAPTER)ptr));
1019+}
1020+
1021+#else /* kernel 2.6 series */
1022+static int rtusb_probe (struct usb_interface *intf,
1023+ const struct usb_device_id *id)
1024+{
1025+ PRTMP_ADAPTER pAd;
1026+ return (int)rt28xx_probe((void *)intf, (void *)id, 0, &pAd);
1027+}
1028+
1029+
1030+static void rtusb_disconnect(struct usb_interface *intf)
1031+{
1032+ struct usb_device *dev = interface_to_usbdev(intf);
1033+ PRTMP_ADAPTER pAd;
1034+
1035+
1036+ pAd = usb_get_intfdata(intf);
1037+ usb_set_intfdata(intf, NULL);
1038+
1039+ _rtusb_disconnect(dev, pAd);
1040+}
1041+#endif // LINUX_VERSION_CODE //
1042+
1043+
1044+/*
1045+========================================================================
1046+Routine Description:
1047+ Close kernel threads.
1048+
1049+Arguments:
1050+ *pAd the raxx interface data pointer
1051+
1052+Return Value:
1053+ NONE
1054+
1055+Note:
1056+========================================================================
1057+*/
1058+VOID RT28xxThreadTerminate(
1059+ IN RTMP_ADAPTER *pAd)
1060+{
1061+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
1062+ INT ret;
1063+
1064+
1065+ // Sleep 50 milliseconds so pending io might finish normally
1066+ RTMPusecDelay(50000);
1067+
1068+ // We want to wait until all pending receives and sends to the
1069+ // device object. We cancel any
1070+ // irps. Wait until sends and receives have stopped.
1071+ RTUSBCancelPendingIRPs(pAd);
1072+
1073+ // Terminate Threads
1074+ if (pObj->MLMEThr_pid)
1075+ {
1076+ printk("Terminate the MLMEThr_pid=%d!\n", pid_nr(pObj->MLMEThr_pid));
1077+ mb();
1078+ pAd->mlme_kill = 1;
1079+ //RT28XX_MLME_HANDLER(pAd);
1080+ mb();
1081+ ret = kill_pid(pObj->MLMEThr_pid, SIGTERM, 1);
1082+ if (ret)
1083+ {
1084+ printk (KERN_WARNING "%s: unable to Mlme thread, pid=%d, ret=%d!\n",
1085+ pAd->net_dev->name, pid_nr(pObj->MLMEThr_pid), ret);
1086+ }
1087+ else
1088+ {
1089+ //wait_for_completion (&pAd->notify);
1090+ wait_for_completion (&pAd->mlmeComplete);
1091+ pObj->MLMEThr_pid = NULL;
1092+ }
1093+ }
1094+
1095+ if (pObj->RTUSBCmdThr_pid >= 0)
1096+ {
1097+ printk("Terminate the RTUSBCmdThr_pid=%d!\n", pid_nr(pObj->RTUSBCmdThr_pid));
1098+ mb();
1099+ NdisAcquireSpinLock(&pAd->CmdQLock);
1100+ pAd->CmdQ.CmdQState = RT2870_THREAD_STOPED;
1101+ NdisReleaseSpinLock(&pAd->CmdQLock);
1102+ mb();
1103+ //RTUSBCMDUp(pAd);
1104+ ret = kill_pid(pObj->RTUSBCmdThr_pid, SIGTERM, 1);
1105+ if (ret)
1106+ {
1107+ printk(KERN_WARNING "%s: unable to RTUSBCmd thread, pid=%d, ret=%d!\n",
1108+ pAd->net_dev->name, pid_nr(pObj->RTUSBCmdThr_pid), ret);
1109+ }
1110+ else
1111+ {
1112+ //wait_for_completion (&pAd->notify);
1113+ wait_for_completion (&pAd->CmdQComplete);
1114+ pObj->RTUSBCmdThr_pid = NULL;
1115+ }
1116+ }
1117+ if (pObj->TimerQThr_pid >= 0)
1118+ {
1119+ POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
1120+
1121+ printk("Terminate the TimerQThr_pid=%d!\n", pid_nr(pObj->TimerQThr_pid));
1122+ mb();
1123+ pAd->TimerFunc_kill = 1;
1124+ mb();
1125+ ret = kill_pid(pObj->TimerQThr_pid, SIGTERM, 1);
1126+ if (ret)
1127+ {
1128+ printk(KERN_WARNING "%s: unable to stop TimerQThread, pid=%d, ret=%d!\n",
1129+ pAd->net_dev->name, pid_nr(pObj->TimerQThr_pid), ret);
1130+ }
1131+ else
1132+ {
1133+ printk("wait_for_completion TimerQThr\n");
1134+ wait_for_completion(&pAd->TimerQComplete);
1135+ pObj->TimerQThr_pid = NULL;
1136+ }
1137+ }
1138+ // Kill tasklets
1139+ pAd->mlme_kill = 0;
1140+ pAd->CmdQ.CmdQState = RT2870_THREAD_UNKNOWN;
1141+ pAd->TimerFunc_kill = 0;
1142+}
1143+
1144+
1145+void kill_thread_task(IN PRTMP_ADAPTER pAd)
1146+{
1147+ POS_COOKIE pObj;
1148+
1149+ pObj = (POS_COOKIE) pAd->OS_Cookie;
1150+
1151+ tasklet_kill(&pObj->rx_done_task);
1152+ tasklet_kill(&pObj->mgmt_dma_done_task);
1153+ tasklet_kill(&pObj->ac0_dma_done_task);
1154+ tasklet_kill(&pObj->ac1_dma_done_task);
1155+ tasklet_kill(&pObj->ac2_dma_done_task);
1156+ tasklet_kill(&pObj->ac3_dma_done_task);
1157+ tasklet_kill(&pObj->hcca_dma_done_task);
1158+ tasklet_kill(&pObj->tbtt_task);
1159+
1160+}
1161+
1162+
1163+/*
1164+========================================================================
1165+Routine Description:
1166+ Check the chipset vendor/product ID.
1167+
1168+Arguments:
1169+ _dev_p Point to the PCI or USB device
1170+
1171+Return Value:
1172+ TRUE Check ok
1173+ FALSE Check fail
1174+
1175+Note:
1176+========================================================================
1177+*/
1178+BOOLEAN RT28XXChipsetCheck(
1179+ IN void *_dev_p)
1180+{
1181+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
1182+ struct usb_device *dev_p = (struct usb_device *)_dev_p;
1183+#else
1184+ struct usb_interface *intf = (struct usb_interface *)_dev_p;
1185+ struct usb_device *dev_p = interface_to_usbdev(intf);
1186+#endif // LINUX_VERSION_CODE //
1187+ UINT32 i;
1188+
1189+
1190+ for(i=0; i<rtusb_usb_id_len; i++)
1191+ {
1192+ if (dev_p->descriptor.idVendor == rtusb_usb_id[i].idVendor &&
1193+ dev_p->descriptor.idProduct == rtusb_usb_id[i].idProduct)
1194+ {
1195+ printk("rt2870: idVendor = 0x%x, idProduct = 0x%x\n",
1196+ dev_p->descriptor.idVendor, dev_p->descriptor.idProduct);
1197+ break;
1198+ }
1199+ }
1200+
1201+ if (i == rtusb_usb_id_len)
1202+ {
1203+ printk("rt2870: Error! Device Descriptor not matching!\n");
1204+ return FALSE;
1205+ }
1206+
1207+ return TRUE;
1208+}
1209+
1210+
1211+/*
1212+========================================================================
1213+Routine Description:
1214+ Init net device structure.
1215+
1216+Arguments:
1217+ _dev_p Point to the PCI or USB device
1218+ *net_dev Point to the net device
1219+ *pAd the raxx interface data pointer
1220+
1221+Return Value:
1222+ TRUE Init ok
1223+ FALSE Init fail
1224+
1225+Note:
1226+========================================================================
1227+*/
1228+BOOLEAN RT28XXNetDevInit(
1229+ IN void *_dev_p,
1230+ IN struct net_device *net_dev,
1231+ IN RTMP_ADAPTER *pAd)
1232+{
1233+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
1234+ struct usb_device *dev_p = (struct usb_device *)_dev_p;
1235+#else
1236+ struct usb_interface *intf = (struct usb_interface *)_dev_p;
1237+ struct usb_device *dev_p = interface_to_usbdev(intf);
1238+#endif // LINUX_VERSION_CODE //
1239+
1240+
1241+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
1242+ pAd->config = dev_p->config;
1243+#else
1244+ pAd->config = &dev_p->config->desc;
1245+#endif // LINUX_VERSION_CODE //
1246+ return TRUE;
1247+}
1248+
1249+
1250+/*
1251+========================================================================
1252+Routine Description:
1253+ Init net device structure.
1254+
1255+Arguments:
1256+ _dev_p Point to the PCI or USB device
1257+ *pAd the raxx interface data pointer
1258+
1259+Return Value:
1260+ TRUE Config ok
1261+ FALSE Config fail
1262+
1263+Note:
1264+========================================================================
1265+*/
1266+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
1267+BOOLEAN RT28XXProbePostConfig(
1268+ IN void *_dev_p,
1269+ IN RTMP_ADAPTER *pAd,
1270+ IN INT32 interface)
1271+{
1272+ struct usb_device *dev_p = (struct usb_device *)_dev_p;
1273+ struct usb_interface *intf;
1274+ struct usb_interface_descriptor *iface_desc;
1275+ struct usb_endpoint_descriptor *endpoint;
1276+ ULONG BulkOutIdx;
1277+ UINT32 i;
1278+
1279+
1280+ /* get the active interface descriptor */
1281+ intf = &dev_p->actconfig->interface[interface];
1282+ iface_desc = &intf->altsetting[0];
1283+
1284+ /* get # of enpoints */
1285+ pAd->NumberOfPipes = iface_desc->bNumEndpoints;
1286+ DBGPRINT(RT_DEBUG_TRACE, ("NumEndpoints=%d\n", iface_desc->bNumEndpoints));
1287+
1288+ /* Configure Pipes */
1289+ endpoint = &iface_desc->endpoint[0];
1290+ BulkOutIdx = 0;
1291+
1292+ for(i=0; i<pAd->NumberOfPipes; i++)
1293+ {
1294+ if ((endpoint[i].bmAttributes == USB_ENDPOINT_XFER_BULK) &&
1295+ ((endpoint[i].bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN))
1296+ {
1297+ pAd->BulkInEpAddr = endpoint[i].bEndpointAddress;
1298+ pAd->BulkInMaxPacketSize = endpoint[i].wMaxPacketSize;
1299+
1300+ DBGPRINT_RAW(RT_DEBUG_TRACE,
1301+ ("BULK IN MaximumPacketSize = %d\n", pAd->BulkInMaxPacketSize));
1302+ DBGPRINT_RAW(RT_DEBUG_TRACE,
1303+ ("EP address = 0x%2x \n", endpoint[i].bEndpointAddress));
1304+ }
1305+ else if ((endpoint[i].bmAttributes == USB_ENDPOINT_XFER_BULK) &&
1306+ ((endpoint[i].bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT))
1307+ {
1308+ // There are 6 bulk out EP. EP6 highest priority.
1309+ // EP1-4 is EDCA. EP5 is HCCA.
1310+ pAd->BulkOutEpAddr[BulkOutIdx++] = endpoint[i].bEndpointAddress;
1311+ pAd->BulkOutMaxPacketSize = endpoint[i].wMaxPacketSize;
1312+
1313+ DBGPRINT_RAW(RT_DEBUG_TRACE,
1314+ ("BULK OUT MaximumPacketSize = %d\n", pAd->BulkOutMaxPacketSize));
1315+ DBGPRINT_RAW(RT_DEBUG_TRACE,
1316+ ("EP address = 0x%2x \n", endpoint[i].bEndpointAddress));
1317+ }
1318+ }
1319+
1320+ if (!(pAd->BulkInEpAddr && pAd->BulkOutEpAddr[0]))
1321+ {
1322+ printk("Could not find both bulk-in and bulk-out endpoints\n");
1323+ return FALSE;
1324+ }
1325+
1326+ return TRUE;
1327+}
1328+
1329+#else
1330+BOOLEAN RT28XXProbePostConfig(
1331+ IN void *_dev_p,
1332+ IN RTMP_ADAPTER *pAd,
1333+ IN INT32 interface)
1334+{
1335+ struct usb_interface *intf = (struct usb_interface *)_dev_p;
1336+ struct usb_host_interface *iface_desc;
1337+ ULONG BulkOutIdx;
1338+ UINT32 i;
1339+
1340+
1341+ /* get the active interface descriptor */
1342+ iface_desc = intf->cur_altsetting;
1343+
1344+ /* get # of enpoints */
1345+ pAd->NumberOfPipes = iface_desc->desc.bNumEndpoints;
1346+ DBGPRINT(RT_DEBUG_TRACE,
1347+ ("NumEndpoints=%d\n", iface_desc->desc.bNumEndpoints));
1348+
1349+ /* Configure Pipes */
1350+ BulkOutIdx = 0;
1351+
1352+ for(i=0; i<pAd->NumberOfPipes; i++)
1353+ {
1354+ if ((iface_desc->endpoint[i].desc.bmAttributes ==
1355+ USB_ENDPOINT_XFER_BULK) &&
1356+ ((iface_desc->endpoint[i].desc.bEndpointAddress &
1357+ USB_ENDPOINT_DIR_MASK) == USB_DIR_IN))
1358+ {
1359+ pAd->BulkInEpAddr = iface_desc->endpoint[i].desc.bEndpointAddress;
1360+ pAd->BulkInMaxPacketSize = iface_desc->endpoint[i].desc.wMaxPacketSize;
1361+
1362+ DBGPRINT_RAW(RT_DEBUG_TRACE,
1363+ ("BULK IN MaximumPacketSize = %d\n", pAd->BulkInMaxPacketSize));
1364+ DBGPRINT_RAW(RT_DEBUG_TRACE,
1365+ ("EP address = 0x%2x\n", iface_desc->endpoint[i].desc.bEndpointAddress));
1366+ }
1367+ else if ((iface_desc->endpoint[i].desc.bmAttributes ==
1368+ USB_ENDPOINT_XFER_BULK) &&
1369+ ((iface_desc->endpoint[i].desc.bEndpointAddress &
1370+ USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT))
1371+ {
1372+ // there are 6 bulk out EP. EP6 highest priority.
1373+ // EP1-4 is EDCA. EP5 is HCCA.
1374+ pAd->BulkOutEpAddr[BulkOutIdx++] = iface_desc->endpoint[i].desc.bEndpointAddress;
1375+ pAd->BulkOutMaxPacketSize = iface_desc->endpoint[i].desc.wMaxPacketSize;
1376+
1377+ DBGPRINT_RAW(RT_DEBUG_TRACE,
1378+ ("BULK OUT MaximumPacketSize = %d\n", pAd->BulkOutMaxPacketSize));
1379+ DBGPRINT_RAW(RT_DEBUG_TRACE,
1380+ ("EP address = 0x%2x \n", iface_desc->endpoint[i].desc.bEndpointAddress));
1381+ }
1382+ }
1383+
1384+ if (!(pAd->BulkInEpAddr && pAd->BulkOutEpAddr[0]))
1385+ {
1386+ printk("%s: Could not find both bulk-in and bulk-out endpoints\n", __FUNCTION__);
1387+ return FALSE;
1388+ }
1389+
1390+ return TRUE;
1391+}
1392+#endif // LINUX_VERSION_CODE //
1393+
1394+
1395+/*
1396+========================================================================
1397+Routine Description:
1398+ Disable DMA.
1399+
1400+Arguments:
1401+ *pAd the raxx interface data pointer
1402+
1403+Return Value:
1404+ None
1405+
1406+Note:
1407+========================================================================
1408+*/
1409+VOID RT28XXDMADisable(
1410+ IN RTMP_ADAPTER *pAd)
1411+{
1412+ // no use
1413+}
1414+
1415+
1416+
1417+/*
1418+========================================================================
1419+Routine Description:
1420+ Enable DMA.
1421+
1422+Arguments:
1423+ *pAd the raxx interface data pointer
1424+
1425+Return Value:
1426+ None
1427+
1428+Note:
1429+========================================================================
1430+*/
1431+VOID RT28XXDMAEnable(
1432+ IN RTMP_ADAPTER *pAd)
1433+{
1434+ WPDMA_GLO_CFG_STRUC GloCfg;
1435+ USB_DMA_CFG_STRUC UsbCfg;
1436+ int i = 0;
1437+
1438+
1439+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
1440+ do
1441+ {
1442+ RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
1443+ if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
1444+ break;
1445+
1446+ DBGPRINT(RT_DEBUG_TRACE, ("==> DMABusy\n"));
1447+ RTMPusecDelay(1000);
1448+ i++;
1449+ }while ( i <200);
1450+
1451+
1452+ RTMPusecDelay(50);
1453+ GloCfg.field.EnTXWriteBackDDONE = 1;
1454+ GloCfg.field.EnableRxDMA = 1;
1455+ GloCfg.field.EnableTxDMA = 1;
1456+ DBGPRINT(RT_DEBUG_TRACE, ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word));
1457+ RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
1458+
1459+ UsbCfg.word = 0;
1460+ UsbCfg.field.phyclear = 0;
1461+ /* usb version is 1.1,do not use bulk in aggregation */
1462+ if (pAd->BulkInMaxPacketSize == 512)
1463+ UsbCfg.field.RxBulkAggEn = 1;
1464+ /* for last packet, PBF might use more than limited, so minus 2 to prevent from error */
1465+ UsbCfg.field.RxBulkAggLmt = (MAX_RXBULK_SIZE /1024)-3;
1466+ UsbCfg.field.RxBulkAggTOut = 0x80; /* 2006-10-18 */
1467+ UsbCfg.field.RxBulkEn = 1;
1468+ UsbCfg.field.TxBulkEn = 1;
1469+
1470+ RTUSBWriteMACRegister(pAd, USB_DMA_CFG, UsbCfg.word);
1471+
1472+}
1473+
1474+/*
1475+========================================================================
1476+Routine Description:
1477+ Write Beacon buffer to Asic.
1478+
1479+Arguments:
1480+ *pAd the raxx interface data pointer
1481+
1482+Return Value:
1483+ None
1484+
1485+Note:
1486+========================================================================
1487+*/
1488+VOID RT28xx_UpdateBeaconToAsic(
1489+ IN RTMP_ADAPTER *pAd,
1490+ IN INT apidx,
1491+ IN ULONG FrameLen,
1492+ IN ULONG UpdatePos)
1493+{
1494+ PUCHAR pBeaconFrame = NULL;
1495+ UCHAR *ptr;
1496+ UINT i, padding;
1497+ BEACON_SYNC_STRUCT *pBeaconSync = pAd->CommonCfg.pBeaconSync;
1498+ UINT32 longValue;
1499+// USHORT shortValue;
1500+ BOOLEAN bBcnReq = FALSE;
1501+ UCHAR bcn_idx = 0;
1502+
1503+
1504+ if (pBeaconFrame == NULL)
1505+ {
1506+ DBGPRINT(RT_DEBUG_ERROR,("pBeaconFrame is NULL!\n"));
1507+ return;
1508+ }
1509+
1510+ if (pBeaconSync == NULL)
1511+ {
1512+ DBGPRINT(RT_DEBUG_ERROR,("pBeaconSync is NULL!\n"));
1513+ return;
1514+ }
1515+
1516+ //if ((pAd->WdsTab.Mode == WDS_BRIDGE_MODE) ||
1517+ // ((pAd->ApCfg.MBSSID[apidx].MSSIDDev == NULL) || !(pAd->ApCfg.MBSSID[apidx].MSSIDDev->flags & IFF_UP))
1518+ // )
1519+ if (bBcnReq == FALSE)
1520+ {
1521+ /* when the ra interface is down, do not send its beacon frame */
1522+ /* clear all zero */
1523+ for(i=0; i<TXWI_SIZE; i+=4) {
1524+ RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, 0x00);
1525+ }
1526+ pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
1527+ NdisZeroMemory(pBeaconSync->BeaconTxWI[bcn_idx], TXWI_SIZE);
1528+ }
1529+ else
1530+ {
1531+ ptr = (PUCHAR)&pAd->BeaconTxWI;
1532+#ifdef RT_BIG_ENDIAN
1533+ RTMPWIEndianChange(ptr, TYPE_TXWI);
1534+#endif
1535+ if (NdisEqualMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE) == FALSE)
1536+ { // If BeaconTxWI changed, we need to rewrite the TxWI for the Beacon frames.
1537+ pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
1538+ NdisMoveMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE);
1539+ }
1540+
1541+ if ((pBeaconSync->BeaconBitMap & (1 << bcn_idx)) != (1 << bcn_idx))
1542+ {
1543+ for (i=0; i<TXWI_SIZE; i+=4) // 16-byte TXWI field
1544+ {
1545+ longValue = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
1546+ RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, longValue);
1547+ ptr += 4;
1548+ }
1549+ }
1550+
1551+ ptr = pBeaconSync->BeaconBuf[bcn_idx];
1552+ padding = (FrameLen & 0x01);
1553+ NdisZeroMemory((PUCHAR)(pBeaconFrame + FrameLen), padding);
1554+ FrameLen += padding;
1555+ for (i = 0 ; i < FrameLen /*HW_BEACON_OFFSET*/; i += 2)
1556+ {
1557+ if (NdisEqualMemory(ptr, pBeaconFrame, 2) == FALSE)
1558+ {
1559+ NdisMoveMemory(ptr, pBeaconFrame, 2);
1560+ //shortValue = *ptr + (*(ptr+1)<<8);
1561+ //RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, shortValue);
1562+ RTUSBMultiWrite(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, ptr, 2);
1563+ }
1564+ ptr +=2;
1565+ pBeaconFrame += 2;
1566+ }
1567+
1568+ pBeaconSync->BeaconBitMap |= (1 << bcn_idx);
1569+
1570+ // For AP interface, set the DtimBitOn so that we can send Bcast/Mcast frame out after this beacon frame.
1571+ }
1572+
1573+}
1574+
1575+
1576+VOID RT2870_BssBeaconStop(
1577+ IN RTMP_ADAPTER *pAd)
1578+{
1579+ BEACON_SYNC_STRUCT *pBeaconSync;
1580+ int i, offset;
1581+ BOOLEAN Cancelled = TRUE;
1582+
1583+ pBeaconSync = pAd->CommonCfg.pBeaconSync;
1584+ if (pBeaconSync && pBeaconSync->EnableBeacon)
1585+ {
1586+ INT NumOfBcn;
1587+
1588+
1589+#ifdef CONFIG_STA_SUPPORT
1590+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1591+ {
1592+ NumOfBcn = MAX_MESH_NUM;
1593+ }
1594+#endif // CONFIG_STA_SUPPORT //
1595+
1596+ RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
1597+
1598+ for(i=0; i<NumOfBcn; i++)
1599+ {
1600+ NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
1601+ NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
1602+
1603+ for (offset=0; offset<HW_BEACON_OFFSET; offset+=4)
1604+ RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[i] + offset, 0x00);
1605+
1606+ pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
1607+ pBeaconSync->TimIELocationInBeacon[i] = 0;
1608+ }
1609+ pBeaconSync->BeaconBitMap = 0;
1610+ pBeaconSync->DtimBitOn = 0;
1611+ }
1612+}
1613+
1614+
1615+VOID RT2870_BssBeaconStart(
1616+ IN RTMP_ADAPTER *pAd)
1617+{
1618+ int apidx;
1619+ BEACON_SYNC_STRUCT *pBeaconSync;
1620+// LARGE_INTEGER tsfTime, deltaTime;
1621+
1622+ pBeaconSync = pAd->CommonCfg.pBeaconSync;
1623+ if (pBeaconSync && pBeaconSync->EnableBeacon)
1624+ {
1625+ INT NumOfBcn;
1626+
1627+
1628+#ifdef CONFIG_STA_SUPPORT
1629+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1630+ {
1631+ NumOfBcn = MAX_MESH_NUM;
1632+ }
1633+#endif // CONFIG_STA_SUPPORT //
1634+
1635+ for(apidx=0; apidx<NumOfBcn; apidx++)
1636+ {
1637+ UCHAR CapabilityInfoLocationInBeacon = 0;
1638+ UCHAR TimIELocationInBeacon = 0;
1639+
1640+#ifdef CONFIG_STA_SUPPORT
1641+#endif // CONFIG_STA_SUPPORT //
1642+
1643+ NdisZeroMemory(pBeaconSync->BeaconBuf[apidx], HW_BEACON_OFFSET);
1644+ pBeaconSync->CapabilityInfoLocationInBeacon[apidx] = CapabilityInfoLocationInBeacon;
1645+ pBeaconSync->TimIELocationInBeacon[apidx] = TimIELocationInBeacon;
1646+ NdisZeroMemory(pBeaconSync->BeaconTxWI[apidx], TXWI_SIZE);
1647+ }
1648+ pBeaconSync->BeaconBitMap = 0;
1649+ pBeaconSync->DtimBitOn = 0;
1650+ pAd->CommonCfg.BeaconUpdateTimer.Repeat = TRUE;
1651+
1652+ pAd->CommonCfg.BeaconAdjust = 0;
1653+ pAd->CommonCfg.BeaconFactor = 0xffffffff / (pAd->CommonCfg.BeaconPeriod << 10);
1654+ pAd->CommonCfg.BeaconRemain = (0xffffffff % (pAd->CommonCfg.BeaconPeriod << 10)) + 1;
1655+ printk("RT2870_BssBeaconStart:BeaconFactor=%d, BeaconRemain=%d!\n", pAd->CommonCfg.BeaconFactor, pAd->CommonCfg.BeaconRemain);
1656+ RTMPSetTimer(&pAd->CommonCfg.BeaconUpdateTimer, pAd->CommonCfg.BeaconPeriod);
1657+
1658+ }
1659+}
1660+
1661+
1662+VOID RT2870_BssBeaconInit(
1663+ IN RTMP_ADAPTER *pAd)
1664+{
1665+ BEACON_SYNC_STRUCT *pBeaconSync;
1666+ int i;
1667+
1668+ NdisAllocMemory(pAd->CommonCfg.pBeaconSync, sizeof(BEACON_SYNC_STRUCT), MEM_ALLOC_FLAG);
1669+ if (pAd->CommonCfg.pBeaconSync)
1670+ {
1671+ pBeaconSync = pAd->CommonCfg.pBeaconSync;
1672+ NdisZeroMemory(pBeaconSync, sizeof(BEACON_SYNC_STRUCT));
1673+ for(i=0; i < HW_BEACON_MAX_COUNT; i++)
1674+ {
1675+ NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
1676+ pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
1677+ pBeaconSync->TimIELocationInBeacon[i] = 0;
1678+ NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
1679+ }
1680+ pBeaconSync->BeaconBitMap = 0;
1681+
1682+ //RTMPInitTimer(pAd, &pAd->CommonCfg.BeaconUpdateTimer, GET_TIMER_FUNCTION(BeaconUpdateExec), pAd, TRUE);
1683+ pBeaconSync->EnableBeacon = TRUE;
1684+ }
1685+}
1686+
1687+
1688+VOID RT2870_BssBeaconExit(
1689+ IN RTMP_ADAPTER *pAd)
1690+{
1691+ BEACON_SYNC_STRUCT *pBeaconSync;
1692+ BOOLEAN Cancelled = TRUE;
1693+ int i;
1694+
1695+ if (pAd->CommonCfg.pBeaconSync)
1696+ {
1697+ pBeaconSync = pAd->CommonCfg.pBeaconSync;
1698+ pBeaconSync->EnableBeacon = FALSE;
1699+ RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
1700+ pBeaconSync->BeaconBitMap = 0;
1701+
1702+ for(i=0; i<HW_BEACON_MAX_COUNT; i++)
1703+ {
1704+ NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
1705+ pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
1706+ pBeaconSync->TimIELocationInBeacon[i] = 0;
1707+ NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
1708+ }
1709+
1710+ NdisFreeMemory(pAd->CommonCfg.pBeaconSync, HW_BEACON_OFFSET * HW_BEACON_MAX_COUNT, 0);
1711+ pAd->CommonCfg.pBeaconSync = NULL;
1712+ }
1713+}
1714+
1715+VOID BeaconUpdateExec(
1716+ IN PVOID SystemSpecific1,
1717+ IN PVOID FunctionContext,
1718+ IN PVOID SystemSpecific2,
1719+ IN PVOID SystemSpecific3)
1720+{
1721+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)FunctionContext;
1722+ LARGE_INTEGER tsfTime_a;//, tsfTime_b, deltaTime_exp, deltaTime_ab;
1723+ UINT32 delta, remain, remain_low, remain_high;
1724+// BOOLEAN positive;
1725+
1726+ ReSyncBeaconTime(pAd);
1727+
1728+
1729+
1730+ RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &tsfTime_a.u.LowPart);
1731+ RTMP_IO_READ32(pAd, TSF_TIMER_DW1, &tsfTime_a.u.HighPart);
1732+
1733+
1734+ //positive=getDeltaTime(tsfTime_a, expectedTime, &deltaTime_exp);
1735+ remain_high = pAd->CommonCfg.BeaconRemain * tsfTime_a.u.HighPart;
1736+ remain_low = tsfTime_a.u.LowPart % (pAd->CommonCfg.BeaconPeriod << 10);
1737+ remain = (remain_high + remain_low)%(pAd->CommonCfg.BeaconPeriod << 10);
1738+ delta = (pAd->CommonCfg.BeaconPeriod << 10) - remain;
1739+
1740+ pAd->CommonCfg.BeaconUpdateTimer.TimerValue = (delta >> 10) + 10;
1741+
1742+}
1743+
1744--- /dev/null
1745+++ b/drivers/staging/rt3070/action.h
1746@@ -0,0 +1,68 @@
1747+/*
1748+ *************************************************************************
1749+ * Ralink Tech Inc.
1750+ * 5F., No.36, Taiyuan St., Jhubei City,
1751+ * Hsinchu County 302,
1752+ * Taiwan, R.O.C.
1753+ *
1754+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
1755+ *
1756+ * This program is free software; you can redistribute it and/or modify *
1757+ * it under the terms of the GNU General Public License as published by *
1758+ * the Free Software Foundation; either version 2 of the License, or *
1759+ * (at your option) any later version. *
1760+ * *
1761+ * This program is distributed in the hope that it will be useful, *
1762+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
1763+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
1764+ * GNU General Public License for more details. *
1765+ * *
1766+ * You should have received a copy of the GNU General Public License *
1767+ * along with this program; if not, write to the *
1768+ * Free Software Foundation, Inc., *
1769+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
1770+ * *
1771+ *************************************************************************
1772+
1773+ Module Name:
1774+ aironet.h
1775+
1776+ Abstract:
1777+
1778+ Revision History:
1779+ Who When What
1780+ -------- ---------- ----------------------------------------------
1781+ Name Date Modification logs
1782+ Paul Lin 04-06-15 Initial
1783+*/
1784+
1785+#ifndef __ACTION_H__
1786+#define __ACTION_H__
1787+
1788+typedef struct PACKED __HT_INFO_OCTET
1789+{
1790+#ifdef RT_BIG_ENDIAN
1791+ UCHAR Reserved:5;
1792+ UCHAR STA_Channel_Width:1;
1793+ UCHAR Forty_MHz_Intolerant:1;
1794+ UCHAR Request:1;
1795+#else
1796+ UCHAR Request:1;
1797+ UCHAR Forty_MHz_Intolerant:1;
1798+ UCHAR STA_Channel_Width:1;
1799+ UCHAR Reserved:5;
1800+#endif
1801+} HT_INFORMATION_OCTET;
1802+
1803+
1804+typedef struct PACKED __FRAME_HT_INFO
1805+{
1806+ HEADER_802_11 Hdr;
1807+ UCHAR Category;
1808+ UCHAR Action;
1809+ HT_INFORMATION_OCTET HT_Info;
1810+} FRAME_HT_INFO, *PFRAME_HT_INFO;
1811+
1812+#endif /* __ACTION_H__ */
1813+
1814+
1815--- /dev/null
1816+++ b/drivers/staging/rt3070/aironet.h
1817@@ -0,0 +1,210 @@
1818+/*
1819+ *************************************************************************
1820+ * Ralink Tech Inc.
1821+ * 5F., No.36, Taiyuan St., Jhubei City,
1822+ * Hsinchu County 302,
1823+ * Taiwan, R.O.C.
1824+ *
1825+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
1826+ *
1827+ * This program is free software; you can redistribute it and/or modify *
1828+ * it under the terms of the GNU General Public License as published by *
1829+ * the Free Software Foundation; either version 2 of the License, or *
1830+ * (at your option) any later version. *
1831+ * *
1832+ * This program is distributed in the hope that it will be useful, *
1833+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
1834+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
1835+ * GNU General Public License for more details. *
1836+ * *
1837+ * You should have received a copy of the GNU General Public License *
1838+ * along with this program; if not, write to the *
1839+ * Free Software Foundation, Inc., *
1840+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
1841+ * *
1842+ *************************************************************************
1843+
1844+ Module Name:
1845+ aironet.h
1846+
1847+ Abstract:
1848+
1849+ Revision History:
1850+ Who When What
1851+ -------- ---------- ----------------------------------------------
1852+ Name Date Modification logs
1853+ Paul Lin 04-06-15 Initial
1854+*/
1855+
1856+#ifndef __AIRONET_H__
1857+#define __AIRONET_H__
1858+
1859+// Measurement Type definition
1860+#define MSRN_TYPE_UNUSED 0
1861+#define MSRN_TYPE_CHANNEL_LOAD_REQ 1
1862+#define MSRN_TYPE_NOISE_HIST_REQ 2
1863+#define MSRN_TYPE_BEACON_REQ 3
1864+#define MSRN_TYPE_FRAME_REQ 4
1865+
1866+// Scan Mode in Beacon Request
1867+#define MSRN_SCAN_MODE_PASSIVE 0
1868+#define MSRN_SCAN_MODE_ACTIVE 1
1869+#define MSRN_SCAN_MODE_BEACON_TABLE 2
1870+
1871+// PHY type definition for Aironet beacon report, CCX 2 table 36-9
1872+#define PHY_FH 1
1873+#define PHY_DSS 2
1874+#define PHY_UNUSED 3
1875+#define PHY_OFDM 4
1876+#define PHY_HR_DSS 5
1877+#define PHY_ERP 6
1878+
1879+// RPI table in dBm
1880+#define RPI_0 0 // Power <= -87
1881+#define RPI_1 1 // -87 < Power <= -82
1882+#define RPI_2 2 // -82 < Power <= -77
1883+#define RPI_3 3 // -77 < Power <= -72
1884+#define RPI_4 4 // -72 < Power <= -67
1885+#define RPI_5 5 // -67 < Power <= -62
1886+#define RPI_6 6 // -62 < Power <= -57
1887+#define RPI_7 7 // -57 < Power
1888+
1889+// Cisco Aironet IAPP definetions
1890+#define AIRONET_IAPP_TYPE 0x32
1891+#define AIRONET_IAPP_SUBTYPE_REQUEST 0x01
1892+#define AIRONET_IAPP_SUBTYPE_REPORT 0x81
1893+
1894+// Measurement Request detail format
1895+typedef struct _MEASUREMENT_REQUEST {
1896+ UCHAR Channel;
1897+ UCHAR ScanMode; // Use only in beacon request, other requests did not use this field
1898+ USHORT Duration;
1899+} MEASUREMENT_REQUEST, *PMEASUREMENT_REQUEST;
1900+
1901+// Beacon Measurement Report
1902+// All these field might change to UCHAR, because we didn't do anything to these report.
1903+// We copy all these beacons and report to CCX 2 AP.
1904+typedef struct _BEACON_REPORT {
1905+ UCHAR Channel;
1906+ UCHAR Spare;
1907+ USHORT Duration;
1908+ UCHAR PhyType; // Definiation is listed above table 36-9
1909+ UCHAR RxPower;
1910+ UCHAR BSSID[6];
1911+ UCHAR ParentTSF[4];
1912+ UCHAR TargetTSF[8];
1913+ USHORT BeaconInterval;
1914+ USHORT CapabilityInfo;
1915+} BEACON_REPORT, *PBEACON_REPORT;
1916+
1917+// Frame Measurement Report (Optional)
1918+typedef struct _FRAME_REPORT {
1919+ UCHAR Channel;
1920+ UCHAR Spare;
1921+ USHORT Duration;
1922+ UCHAR TA;
1923+ UCHAR BSSID[6];
1924+ UCHAR RSSI;
1925+ UCHAR Count;
1926+} FRAME_REPORT, *PFRAME_REPORT;
1927+
1928+#pragma pack(1)
1929+// Channel Load Report
1930+typedef struct _CHANNEL_LOAD_REPORT {
1931+ UCHAR Channel;
1932+ UCHAR Spare;
1933+ USHORT Duration;
1934+ UCHAR CCABusy;
1935+} CHANNEL_LOAD_REPORT, *PCHANNEL_LOAD_REPORT;
1936+#pragma pack()
1937+
1938+// Nosie Histogram Report
1939+typedef struct _NOISE_HIST_REPORT {
1940+ UCHAR Channel;
1941+ UCHAR Spare;
1942+ USHORT Duration;
1943+ UCHAR Density[8];
1944+} NOISE_HIST_REPORT, *PNOISE_HIST_REPORT;
1945+
1946+// Radio Management Capability element
1947+typedef struct _RADIO_MANAGEMENT_CAPABILITY {
1948+ UCHAR Eid; // TODO: Why the Eid is 1 byte, not normal 2 bytes???
1949+ UCHAR Length;
1950+ UCHAR AironetOui[3]; // AIronet OUI (00 40 96)
1951+ UCHAR Type; // Type / Version
1952+ USHORT Status; // swap16 required
1953+} RADIO_MANAGEMENT_CAPABILITY, *PRADIO_MANAGEMENT_CAPABILITY;
1954+
1955+// Measurement Mode Bit definition
1956+typedef struct _MEASUREMENT_MODE {
1957+ UCHAR Rsvd:4;
1958+ UCHAR Report:1;
1959+ UCHAR NotUsed:1;
1960+ UCHAR Enable:1;
1961+ UCHAR Parallel:1;
1962+} MEASUREMENT_MODE, *PMEASUREMENT_MODE;
1963+
1964+// Measurement Request element, This is little endian mode
1965+typedef struct _MEASUREMENT_REQUEST_ELEMENT {
1966+ USHORT Eid;
1967+ USHORT Length; // swap16 required
1968+ USHORT Token; // non-zero unique token
1969+ UCHAR Mode; // Measurement Mode
1970+ UCHAR Type; // Measurement type
1971+} MEASUREMENT_REQUEST_ELEMENT, *PMEASUREMENT_REQUEST_ELEMENT;
1972+
1973+// Measurement Report element, This is little endian mode
1974+typedef struct _MEASUREMENT_REPORT_ELEMENT {
1975+ USHORT Eid;
1976+ USHORT Length; // swap16 required
1977+ USHORT Token; // non-zero unique token
1978+ UCHAR Mode; // Measurement Mode
1979+ UCHAR Type; // Measurement type
1980+} MEASUREMENT_REPORT_ELEMENT, *PMEASUREMENT_REPORT_ELEMENT;
1981+
1982+// Cisco Aironet IAPP Frame Header, Network byte order used
1983+typedef struct _AIRONET_IAPP_HEADER {
1984+ UCHAR CiscoSnapHeader[8]; // 8 bytes Cisco snap header
1985+ USHORT Length; // IAPP ID & length, remember to swap16 in LE system
1986+ UCHAR Type; // IAPP type
1987+ UCHAR SubType; // IAPP subtype
1988+ UCHAR DA[6]; // Destination MAC address
1989+ UCHAR SA[6]; // Source MAC address
1990+ USHORT Token; // Dialog token, no need to swap16 since it is for yoken usage only
1991+} AIRONET_IAPP_HEADER, *PAIRONET_IAPP_HEADER;
1992+
1993+// Radio Measurement Request frame
1994+typedef struct _AIRONET_RM_REQUEST_FRAME {
1995+ AIRONET_IAPP_HEADER IAPP; // Common header
1996+ UCHAR Delay; // Activation Delay
1997+ UCHAR Offset; // Measurement offset
1998+} AIRONET_RM_REQUEST_FRAME, *PAIRONET_RM_REQUEST_FRAME;
1999+
2000+// Radio Measurement Report frame
2001+typedef struct _AIRONET_RM_REPORT_FRAME {
2002+ AIRONET_IAPP_HEADER IAPP; // Common header
2003+} AIRONET_RM_REPORT_FRAME, *PAIRONET_RM_REPORT_FRAME;
2004+
2005+// Saved element request actions which will saved in StaCfg.
2006+typedef struct _RM_REQUEST_ACTION {
2007+ MEASUREMENT_REQUEST_ELEMENT ReqElem; // Saved request element
2008+ MEASUREMENT_REQUEST Measurement; // Saved measurement within the request element
2009+} RM_REQUEST_ACTION, *PRM_REQUEST_ACTION;
2010+
2011+// CCX administration control
2012+typedef union _CCX_CONTROL {
2013+ struct {
2014+ UINT32 Enable:1; // Enable CCX2
2015+ UINT32 LeapEnable:1; // Enable LEAP at CCX2
2016+ UINT32 RMEnable:1; // Radio Measurement Enable
2017+ UINT32 DCRMEnable:1; // Non serving channel Radio Measurement enable
2018+ UINT32 QOSEnable:1; // Enable QOS for CCX 2.0 support
2019+ UINT32 FastRoamEnable:1; // Enable fast roaming
2020+ UINT32 Rsvd:2; // Not used
2021+ UINT32 dBmToRoam:8; // the condition to roam when receiving Rssi less than this value. It's negative value.
2022+ UINT32 TuLimit:16; // Limit for different channel scan
2023+ } field;
2024+ UINT32 word;
2025+} CCX_CONTROL, *PCCX_CONTROL;
2026+
2027+#endif // __AIRONET_H__
2028--- /dev/null
2029+++ b/drivers/staging/rt3070/ap.h
2030@@ -0,0 +1,557 @@
2031+/*
2032+ *************************************************************************
2033+ * Ralink Tech Inc.
2034+ * 5F., No.36, Taiyuan St., Jhubei City,
2035+ * Hsinchu County 302,
2036+ * Taiwan, R.O.C.
2037+ *
2038+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
2039+ *
2040+ * This program is free software; you can redistribute it and/or modify *
2041+ * it under the terms of the GNU General Public License as published by *
2042+ * the Free Software Foundation; either version 2 of the License, or *
2043+ * (at your option) any later version. *
2044+ * *
2045+ * This program is distributed in the hope that it will be useful, *
2046+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
2047+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
2048+ * GNU General Public License for more details. *
2049+ * *
2050+ * You should have received a copy of the GNU General Public License *
2051+ * along with this program; if not, write to the *
2052+ * Free Software Foundation, Inc., *
2053+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
2054+ * *
2055+ *************************************************************************
2056+
2057+ Module Name:
2058+ ap.h
2059+
2060+ Abstract:
2061+ Miniport generic portion header file
2062+
2063+ Revision History:
2064+ Who When What
2065+ -------- ---------- ----------------------------------------------
2066+ Paul Lin 08-01-2002 created
2067+ James Tan 09-06-2002 modified (Revise NTCRegTable)
2068+ John Chang 12-22-2004 modified for RT2561/2661. merge with STA driver
2069+*/
2070+#ifndef __AP_H__
2071+#define __AP_H__
2072+
2073+
2074+
2075+// ========================= AP RTMP.h ================================
2076+
2077+
2078+
2079+// =============================================================
2080+// Function Prototypes
2081+// =============================================================
2082+
2083+// ap_data.c
2084+
2085+BOOLEAN APBridgeToWirelessSta(
2086+ IN PRTMP_ADAPTER pAd,
2087+ IN PUCHAR pHeader,
2088+ IN UINT HdrLen,
2089+ IN PUCHAR pData,
2090+ IN UINT DataLen,
2091+ IN ULONG fromwdsidx);
2092+
2093+BOOLEAN APHandleRxDoneInterrupt(
2094+ IN PRTMP_ADAPTER pAd);
2095+
2096+VOID APSendPackets(
2097+ IN NDIS_HANDLE MiniportAdapterContext,
2098+ IN PPNDIS_PACKET ppPacketArray,
2099+ IN UINT NumberOfPackets);
2100+
2101+NDIS_STATUS APSendPacket(
2102+ IN PRTMP_ADAPTER pAd,
2103+ IN PNDIS_PACKET pPacket);
2104+
2105+
2106+NDIS_STATUS APHardTransmit(
2107+ IN PRTMP_ADAPTER pAd,
2108+ IN TX_BLK *pTxBlk,
2109+ IN UCHAR QueIdx);
2110+
2111+VOID APRxEAPOLFrameIndicate(
2112+ IN PRTMP_ADAPTER pAd,
2113+ IN MAC_TABLE_ENTRY *pEntry,
2114+ IN RX_BLK *pRxBlk,
2115+ IN UCHAR FromWhichBSSID);
2116+
2117+NDIS_STATUS APCheckRxError(
2118+ IN PRTMP_ADAPTER pAd,
2119+ IN PRT28XX_RXD_STRUC pRxD,
2120+ IN UCHAR Wcid);
2121+
2122+BOOLEAN APCheckClass2Class3Error(
2123+ IN PRTMP_ADAPTER pAd,
2124+ IN ULONG Wcid,
2125+ IN PHEADER_802_11 pHeader);
2126+
2127+VOID APHandleRxPsPoll(
2128+ IN PRTMP_ADAPTER pAd,
2129+ IN PUCHAR pAddr,
2130+ IN USHORT Aid,
2131+ IN BOOLEAN isActive);
2132+
2133+VOID RTMPDescriptorEndianChange(
2134+ IN PUCHAR pData,
2135+ IN ULONG DescriptorType);
2136+
2137+VOID RTMPFrameEndianChange(
2138+ IN PRTMP_ADAPTER pAd,
2139+ IN PUCHAR pData,
2140+ IN ULONG Dir,
2141+ IN BOOLEAN FromRxDoneInt);
2142+
2143+// ap_assoc.c
2144+
2145+VOID APAssocStateMachineInit(
2146+ IN PRTMP_ADAPTER pAd,
2147+ IN STATE_MACHINE *S,
2148+ OUT STATE_MACHINE_FUNC Trans[]);
2149+
2150+VOID APPeerAssocReqAction(
2151+ IN PRTMP_ADAPTER pAd,
2152+ IN MLME_QUEUE_ELEM *Elem);
2153+
2154+VOID APPeerReassocReqAction(
2155+ IN PRTMP_ADAPTER pAd,
2156+ IN MLME_QUEUE_ELEM *Elem);
2157+
2158+VOID APPeerDisassocReqAction(
2159+ IN PRTMP_ADAPTER pAd,
2160+ IN MLME_QUEUE_ELEM *Elem);
2161+
2162+VOID MbssKickOutStas(
2163+ IN PRTMP_ADAPTER pAd,
2164+ IN INT apidx,
2165+ IN USHORT Reason);
2166+
2167+VOID APMlmeKickOutSta(
2168+ IN PRTMP_ADAPTER pAd,
2169+ IN PUCHAR pStaAddr,
2170+ IN UCHAR Wcid,
2171+ IN USHORT Reason);
2172+
2173+VOID APMlmeDisassocReqAction(
2174+ IN PRTMP_ADAPTER pAd,
2175+ IN MLME_QUEUE_ELEM *Elem);
2176+
2177+VOID APCls3errAction(
2178+ IN PRTMP_ADAPTER pAd,
2179+ IN ULONG Wcid,
2180+ IN PHEADER_802_11 pHeader);
2181+
2182+
2183+USHORT APBuildAssociation(
2184+ IN PRTMP_ADAPTER pAd,
2185+ IN MAC_TABLE_ENTRY *pEntry,
2186+ IN USHORT CapabilityInfo,
2187+ IN UCHAR MaxSupportedRateIn500Kbps,
2188+ IN UCHAR *RSN,
2189+ IN UCHAR *pRSNLen,
2190+ IN BOOLEAN bWmmCapable,
2191+ IN ULONG RalinkIe,
2192+#ifdef DOT11N_DRAFT3
2193+ IN EXT_CAP_INFO_ELEMENT ExtCapInfo,
2194+#endif // DOT11N_DRAFT3 //
2195+ IN HT_CAPABILITY_IE *pHtCapability,
2196+ IN UCHAR HtCapabilityLen,
2197+ OUT USHORT *pAid);
2198+
2199+/*
2200+VOID RTMPAddClientSec(
2201+ IN PRTMP_ADAPTER pAd,
2202+ IN UCHAR BssIdx,
2203+ IN UCHAR KeyIdx,
2204+ IN UCHAR CipherAlg,
2205+ IN PUCHAR pKey,
2206+ IN PUCHAR pTxMic,
2207+ IN PUCHAR pRxMic,
2208+ IN MAC_TABLE_ENTRY *pEntry);
2209+*/
2210+
2211+// ap_auth.c
2212+
2213+void APAuthStateMachineInit(
2214+ IN PRTMP_ADAPTER pAd,
2215+ IN STATE_MACHINE *Sm,
2216+ OUT STATE_MACHINE_FUNC Trans[]);
2217+
2218+VOID APMlmeDeauthReqAction(
2219+ IN PRTMP_ADAPTER pAd,
2220+ IN MLME_QUEUE_ELEM *Elem);
2221+
2222+VOID APCls2errAction(
2223+ IN PRTMP_ADAPTER pAd,
2224+ IN ULONG Wcid,
2225+ IN PHEADER_802_11 pHeader);
2226+
2227+// ap_authrsp.c
2228+
2229+VOID APAuthRspStateMachineInit(
2230+ IN PRTMP_ADAPTER pAd,
2231+ IN PSTATE_MACHINE Sm,
2232+ IN STATE_MACHINE_FUNC Trans[]);
2233+
2234+VOID APPeerAuthAtAuthRspIdleAction(
2235+ IN PRTMP_ADAPTER pAd,
2236+ IN MLME_QUEUE_ELEM *Elem);
2237+
2238+VOID APPeerDeauthReqAction(
2239+ IN PRTMP_ADAPTER pAd,
2240+ IN MLME_QUEUE_ELEM *Elem);
2241+
2242+VOID APPeerAuthSimpleRspGenAndSend(
2243+ IN PRTMP_ADAPTER pAd,
2244+ IN PHEADER_802_11 pHdr80211,
2245+ IN USHORT Alg,
2246+ IN USHORT Seq,
2247+ IN USHORT StatusCode);
2248+
2249+// ap_connect.c
2250+
2251+BOOLEAN BeaconTransmitRequired(
2252+ IN PRTMP_ADAPTER pAd,
2253+ IN INT apidx);
2254+
2255+VOID APMakeBssBeacon(
2256+ IN PRTMP_ADAPTER pAd,
2257+ IN INT apidx);
2258+
2259+VOID APUpdateBeaconFrame(
2260+ IN PRTMP_ADAPTER pAd,
2261+ IN INT apidx);
2262+
2263+VOID APMakeAllBssBeacon(
2264+ IN PRTMP_ADAPTER pAd);
2265+
2266+VOID APUpdateAllBeaconFrame(
2267+ IN PRTMP_ADAPTER pAd);
2268+
2269+
2270+// ap_sync.c
2271+
2272+VOID APSyncStateMachineInit(
2273+ IN PRTMP_ADAPTER pAd,
2274+ IN STATE_MACHINE *Sm,
2275+ OUT STATE_MACHINE_FUNC Trans[]);
2276+
2277+VOID APScanTimeout(
2278+ IN PVOID SystemSpecific1,
2279+ IN PVOID FunctionContext,
2280+ IN PVOID SystemSpecific2,
2281+ IN PVOID SystemSpecific3);
2282+
2283+VOID APInvalidStateWhenScan(
2284+ IN PRTMP_ADAPTER pAd,
2285+ IN MLME_QUEUE_ELEM *Elem);
2286+
2287+VOID APScanTimeoutAction(
2288+ IN PRTMP_ADAPTER pAd,
2289+ IN MLME_QUEUE_ELEM *Elem);
2290+
2291+VOID APPeerProbeReqAction(
2292+ IN PRTMP_ADAPTER pAd,
2293+ IN MLME_QUEUE_ELEM *Elem);
2294+
2295+VOID APPeerBeaconAction(
2296+ IN PRTMP_ADAPTER pAd,
2297+ IN MLME_QUEUE_ELEM *Elem);
2298+
2299+VOID APMlmeScanReqAction(
2300+ IN PRTMP_ADAPTER pAd,
2301+ IN MLME_QUEUE_ELEM *Elem);
2302+
2303+VOID APPeerBeaconAtScanAction(
2304+ IN PRTMP_ADAPTER pAd,
2305+ IN MLME_QUEUE_ELEM *Elem);
2306+
2307+VOID APScanCnclAction(
2308+ IN PRTMP_ADAPTER pAd,
2309+ IN MLME_QUEUE_ELEM *Elem);
2310+
2311+VOID ApSiteSurvey(
2312+ IN PRTMP_ADAPTER pAd);
2313+
2314+VOID SupportRate(
2315+ IN PUCHAR SupRate,
2316+ IN UCHAR SupRateLen,
2317+ IN PUCHAR ExtRate,
2318+ IN UCHAR ExtRateLen,
2319+ OUT PUCHAR *Rates,
2320+ OUT PUCHAR RatesLen,
2321+ OUT PUCHAR pMaxSupportRate);
2322+
2323+
2324+BOOLEAN ApScanRunning(
2325+ IN PRTMP_ADAPTER pAd);
2326+
2327+#ifdef DOT11N_DRAFT3
2328+VOID APOverlappingBSSScan(
2329+ IN RTMP_ADAPTER *pAd);
2330+#endif // DOT11N_DRAFT3 //
2331+
2332+// ap_wpa.c
2333+
2334+VOID APWpaStateMachineInit(
2335+ IN PRTMP_ADAPTER pAd,
2336+ IN STATE_MACHINE *Sm,
2337+ OUT STATE_MACHINE_FUNC Trans[]);
2338+
2339+// ap_mlme.c
2340+
2341+VOID APMlmePeriodicExec(
2342+ IN PRTMP_ADAPTER pAd);
2343+
2344+VOID APMlmeSelectTxRateTable(
2345+ IN PRTMP_ADAPTER pAd,
2346+ IN PMAC_TABLE_ENTRY pEntry,
2347+ IN PUCHAR *ppTable,
2348+ IN PUCHAR pTableSize,
2349+ IN PUCHAR pInitTxRateIdx);
2350+
2351+VOID APMlmeSetTxRate(
2352+ IN PRTMP_ADAPTER pAd,
2353+ IN PMAC_TABLE_ENTRY pEntry,
2354+ IN PRTMP_TX_RATE_SWITCH pTxRate);
2355+
2356+VOID APMlmeDynamicTxRateSwitching(
2357+ IN PRTMP_ADAPTER pAd);
2358+
2359+VOID APQuickResponeForRateUpExec(
2360+ IN PVOID SystemSpecific1,
2361+ IN PVOID FunctionContext,
2362+ IN PVOID SystemSpecific2,
2363+ IN PVOID SystemSpecific3);
2364+
2365+BOOLEAN APMsgTypeSubst(
2366+ IN PRTMP_ADAPTER pAd,
2367+ IN PFRAME_802_11 pFrame,
2368+ OUT INT *Machine,
2369+ OUT INT *MsgType);
2370+
2371+VOID APQuickResponeForRateUpExec(
2372+ IN PVOID SystemSpecific1,
2373+ IN PVOID FunctionContext,
2374+ IN PVOID SystemSpecific2,
2375+ IN PVOID SystemSpecific3);
2376+
2377+#ifdef RT2870
2378+VOID BeaconUpdateExec(
2379+ IN PVOID SystemSpecific1,
2380+ IN PVOID FunctionContext,
2381+ IN PVOID SystemSpecific2,
2382+ IN PVOID SystemSpecific3);
2383+#endif // RT2870 //
2384+
2385+VOID RTMPSetPiggyBack(
2386+ IN PRTMP_ADAPTER pAd,
2387+ IN BOOLEAN bPiggyBack);
2388+
2389+VOID APAsicEvaluateRxAnt(
2390+ IN PRTMP_ADAPTER pAd);
2391+
2392+VOID APAsicRxAntEvalTimeout(
2393+ IN PRTMP_ADAPTER pAd);
2394+
2395+// ap.c
2396+
2397+VOID APSwitchChannel(
2398+ IN PRTMP_ADAPTER pAd,
2399+ IN INT Channel);
2400+
2401+NDIS_STATUS APInitialize(
2402+ IN PRTMP_ADAPTER pAd);
2403+
2404+VOID APShutdown(
2405+ IN PRTMP_ADAPTER pAd);
2406+
2407+VOID APStartUp(
2408+ IN PRTMP_ADAPTER pAd);
2409+
2410+VOID APStop(
2411+ IN PRTMP_ADAPTER pAd);
2412+
2413+VOID APCleanupPsQueue(
2414+ IN PRTMP_ADAPTER pAd,
2415+ IN PQUEUE_HEADER pQueue);
2416+
2417+VOID MacTableReset(
2418+ IN PRTMP_ADAPTER pAd);
2419+
2420+MAC_TABLE_ENTRY *MacTableInsertEntry(
2421+ IN PRTMP_ADAPTER pAd,
2422+ IN PUCHAR pAddr,
2423+ IN UCHAR apidx,
2424+ IN BOOLEAN CleanAll);
2425+
2426+BOOLEAN MacTableDeleteEntry(
2427+ IN PRTMP_ADAPTER pAd,
2428+ IN USHORT wcid,
2429+ IN PUCHAR pAddr);
2430+
2431+MAC_TABLE_ENTRY *MacTableLookup(
2432+ IN PRTMP_ADAPTER pAd,
2433+ IN PUCHAR pAddr);
2434+
2435+VOID MacTableMaintenance(
2436+ IN PRTMP_ADAPTER pAd);
2437+
2438+UINT32 MacTableAssocStaNumGet(
2439+ IN PRTMP_ADAPTER pAd);
2440+
2441+MAC_TABLE_ENTRY *APSsPsInquiry(
2442+ IN PRTMP_ADAPTER pAd,
2443+ IN PUCHAR pAddr,
2444+ OUT SST *Sst,
2445+ OUT USHORT *Aid,
2446+ OUT UCHAR *PsMode,
2447+ OUT UCHAR *Rate);
2448+
2449+BOOLEAN APPsIndicate(
2450+ IN PRTMP_ADAPTER pAd,
2451+ IN PUCHAR pAddr,
2452+ IN ULONG Wcid,
2453+ IN UCHAR Psm);
2454+
2455+VOID ApLogEvent(
2456+ IN PRTMP_ADAPTER pAd,
2457+ IN PUCHAR pAddr,
2458+ IN USHORT Event);
2459+
2460+#ifdef DOT11_N_SUPPORT
2461+VOID APUpdateOperationMode(
2462+ IN PRTMP_ADAPTER pAd);
2463+#endif // DOT11_N_SUPPORT //
2464+
2465+VOID APUpdateCapabilityAndErpIe(
2466+ IN PRTMP_ADAPTER pAd);
2467+
2468+BOOLEAN ApCheckAccessControlList(
2469+ IN PRTMP_ADAPTER pAd,
2470+ IN PUCHAR pAddr,
2471+ IN UCHAR Apidx);
2472+
2473+VOID ApUpdateAccessControlList(
2474+ IN PRTMP_ADAPTER pAd,
2475+ IN UCHAR Apidx);
2476+
2477+VOID ApEnqueueNullFrame(
2478+ IN PRTMP_ADAPTER pAd,
2479+ IN PUCHAR pAddr,
2480+ IN UCHAR TxRate,
2481+ IN UCHAR PID,
2482+ IN UCHAR apidx,
2483+ IN BOOLEAN bQosNull,
2484+ IN BOOLEAN bEOSP,
2485+ IN UCHAR OldUP);
2486+
2487+VOID ApSendFrame(
2488+ IN PRTMP_ADAPTER pAd,
2489+ IN PVOID pBuffer,
2490+ IN ULONG Length,
2491+ IN UCHAR TxRate,
2492+ IN UCHAR PID);
2493+
2494+VOID ApEnqueueAckFrame(
2495+ IN PRTMP_ADAPTER pAd,
2496+ IN PUCHAR pAddr,
2497+ IN UCHAR TxRate,
2498+ IN UCHAR apidx);
2499+
2500+UCHAR APAutoSelectChannel(
2501+ IN PRTMP_ADAPTER pAd,
2502+ IN BOOLEAN Optimal);
2503+
2504+// ap_sanity.c
2505+
2506+
2507+BOOLEAN PeerAssocReqCmmSanity(
2508+ IN PRTMP_ADAPTER pAd,
2509+ IN BOOLEAN isRessoc,
2510+ IN VOID *Msg,
2511+ IN ULONG MsgLen,
2512+ OUT PUCHAR pAddr2,
2513+ OUT USHORT *pCapabilityInfo,
2514+ OUT USHORT *pListenInterval,
2515+ OUT PUCHAR pApAddr,
2516+ OUT UCHAR *pSsidLen,
2517+ OUT char *Ssid,
2518+ OUT UCHAR *pRatesLen,
2519+ OUT UCHAR Rates[],
2520+ OUT UCHAR *RSN,
2521+ OUT UCHAR *pRSNLen,
2522+ OUT BOOLEAN *pbWmmCapable,
2523+ OUT ULONG *pRalinkIe,
2524+#ifdef DOT11N_DRAFT3
2525+ OUT EXT_CAP_INFO_ELEMENT *pExtCapInfo,
2526+#endif // DOT11N_DRAFT3 //
2527+ OUT UCHAR *pHtCapabilityLen,
2528+ OUT HT_CAPABILITY_IE *pHtCapability);
2529+
2530+
2531+BOOLEAN PeerDisassocReqSanity(
2532+ IN PRTMP_ADAPTER pAd,
2533+ IN VOID *Msg,
2534+ IN ULONG MsgLen,
2535+ OUT PUCHAR pAddr2,
2536+ OUT USHORT *Reason);
2537+
2538+BOOLEAN PeerDeauthReqSanity(
2539+ IN PRTMP_ADAPTER pAd,
2540+ IN VOID *Msg,
2541+ IN ULONG MsgLen,
2542+ OUT PUCHAR pAddr2,
2543+ OUT USHORT *Reason);
2544+
2545+BOOLEAN APPeerAuthSanity(
2546+ IN PRTMP_ADAPTER pAd,
2547+ IN VOID *Msg,
2548+ IN ULONG MsgLen,
2549+ OUT PUCHAR pAddr1,
2550+ OUT PUCHAR pAddr2,
2551+ OUT USHORT *Alg,
2552+ OUT USHORT *Seq,
2553+ OUT USHORT *Status,
2554+ CHAR *ChlgText);
2555+
2556+BOOLEAN APPeerProbeReqSanity(
2557+ IN PRTMP_ADAPTER pAd,
2558+ IN VOID *Msg,
2559+ IN ULONG MsgLen,
2560+ OUT PUCHAR pAddr2,
2561+ OUT CHAR Ssid[],
2562+ OUT UCHAR *SsidLen);
2563+
2564+BOOLEAN APPeerBeaconAndProbeRspSanity(
2565+ IN PRTMP_ADAPTER pAd,
2566+ IN VOID *Msg,
2567+ IN ULONG MsgLen,
2568+ OUT PUCHAR pAddr2,
2569+ OUT PUCHAR pBssid,
2570+ OUT CHAR Ssid[],
2571+ OUT UCHAR *SsidLen,
2572+ OUT UCHAR *BssType,
2573+ OUT USHORT *BeaconPeriod,
2574+ OUT UCHAR *Channel,
2575+ OUT LARGE_INTEGER *Timestamp,
2576+ OUT USHORT *CapabilityInfo,
2577+ OUT UCHAR Rate[],
2578+ OUT UCHAR *RateLen,
2579+ OUT BOOLEAN *ExtendedRateIeExist,
2580+ OUT UCHAR *Erp);
2581+
2582+
2583+// ================== end of AP RTMP.h ========================
2584+
2585+
2586+#endif // __AP_H__
2587+
2588--- /dev/null
2589+++ b/drivers/staging/rt3070/chlist.h
2590@@ -0,0 +1,1253 @@
2591+/*
2592+ *************************************************************************
2593+ * Ralink Tech Inc.
2594+ * 5F., No.36, Taiyuan St., Jhubei City,
2595+ * Hsinchu County 302,
2596+ * Taiwan, R.O.C.
2597+ *
2598+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
2599+ *
2600+ * This program is free software; you can redistribute it and/or modify *
2601+ * it under the terms of the GNU General Public License as published by *
2602+ * the Free Software Foundation; either version 2 of the License, or *
2603+ * (at your option) any later version. *
2604+ * *
2605+ * This program is distributed in the hope that it will be useful, *
2606+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
2607+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
2608+ * GNU General Public License for more details. *
2609+ * *
2610+ * You should have received a copy of the GNU General Public License *
2611+ * along with this program; if not, write to the *
2612+ * Free Software Foundation, Inc., *
2613+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
2614+ * *
2615+ *************************************************************************
2616+
2617+ Module Name:
2618+ chlist.c
2619+
2620+ Abstract:
2621+
2622+ Revision History:
2623+ Who When What
2624+ -------- ---------- ----------------------------------------------
2625+ Fonchi Wu 2007-12-19 created
2626+*/
2627+
2628+#ifndef __CHLIST_H__
2629+#define __CHLIST_H__
2630+
2631+#include "rtmp_type.h"
2632+#include "rtmp_def.h"
2633+
2634+
2635+#define ODOR 0
2636+#define IDOR 1
2637+#define BOTH 2
2638+
2639+#define BAND_5G 0
2640+#define BAND_24G 1
2641+#define BAND_BOTH 2
2642+
2643+typedef struct _CH_DESP {
2644+ UCHAR FirstChannel;
2645+ UCHAR NumOfCh;
2646+ CHAR MaxTxPwr; // dBm
2647+ UCHAR Geography; // 0:out door, 1:in door, 2:both
2648+ BOOLEAN DfsReq; // Dfs require, 0: No, 1: yes.
2649+} CH_DESP, *PCH_DESP;
2650+
2651+typedef struct _CH_REGION {
2652+ UCHAR CountReg[3];
2653+ UCHAR DfsType; // 0: CE, 1: FCC, 2: JAP, 3:JAP_W53, JAP_W56
2654+ CH_DESP ChDesp[10];
2655+} CH_REGION, *PCH_REGION;
2656+
2657+static CH_REGION ChRegion[] =
2658+{
2659+ { // Antigua and Berbuda
2660+ "AG",
2661+ CE,
2662+ {
2663+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
2664+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
2665+ { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
2666+ { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
2667+ { 0}, // end
2668+ }
2669+ },
2670+
2671+ { // Argentina
2672+ "AR",
2673+ CE,
2674+ {
2675+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
2676+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
2677+ { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
2678+ { 0}, // end
2679+ }
2680+ },
2681+
2682+ { // Aruba
2683+ "AW",
2684+ CE,
2685+ {
2686+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
2687+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
2688+ { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
2689+ { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
2690+ { 0}, // end
2691+ }
2692+ },
2693+
2694+ { // Australia
2695+ "AU",
2696+ CE,
2697+ {
2698+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
2699+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
2700+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
2701+ { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165
2702+ { 0}, // end
2703+ }
2704+ },
2705+
2706+ { // Austria
2707+ "AT",
2708+ CE,
2709+ {
2710+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
2711+ { 36, 4, 23, IDOR, TRUE}, // 5G, ch 36~48
2712+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
2713+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
2714+ { 0}, // end
2715+ }
2716+ },
2717+
2718+ { // Bahamas
2719+ "BS",
2720+ CE,
2721+ {
2722+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
2723+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
2724+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
2725+ { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165
2726+ { 0}, // end
2727+ }
2728+ },
2729+
2730+ { // Barbados
2731+ "BB",
2732+ CE,
2733+ {
2734+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
2735+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
2736+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
2737+ { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
2738+ { 0}, // end
2739+ }
2740+ },
2741+
2742+ { // Bermuda
2743+ "BM",
2744+ CE,
2745+ {
2746+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
2747+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
2748+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
2749+ { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
2750+ { 0}, // end
2751+ }
2752+ },
2753+
2754+ { // Brazil
2755+ "BR",
2756+ CE,
2757+ {
2758+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
2759+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
2760+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
2761+ { 100, 11, 24, BOTH, FALSE}, // 5G, ch 100~140
2762+ { 149, 5, 30, BOTH, FALSE}, // 5G, ch 100~140
2763+ { 0}, // end
2764+ }
2765+ },
2766+
2767+ { // Belgium
2768+ "BE",
2769+ CE,
2770+ {
2771+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
2772+ { 36, 4, 18, IDOR, FALSE}, // 5G, ch 36~48
2773+ { 52, 4, 18, IDOR, FALSE}, // 5G, ch 52~64
2774+ { 0}, // end
2775+ }
2776+ },
2777+
2778+ { // Bulgaria
2779+ "BG",
2780+ CE,
2781+ {
2782+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
2783+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
2784+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
2785+ { 100, 11, 30, ODOR, TRUE}, // 5G, ch 100~140
2786+ { 0}, // end
2787+ }
2788+ },
2789+
2790+ { // Canada
2791+ "CA",
2792+ CE,
2793+ {
2794+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
2795+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
2796+ { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
2797+ { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165
2798+ { 0}, // end
2799+ }
2800+ },
2801+
2802+ { // Cayman IsLands
2803+ "KY",
2804+ CE,
2805+ {
2806+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
2807+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
2808+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
2809+ { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
2810+ { 0}, // end
2811+ }
2812+ },
2813+
2814+ { // Chile
2815+ "CL",
2816+ CE,
2817+ {
2818+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
2819+ { 36, 4, 20, BOTH, FALSE}, // 5G, ch 36~48
2820+ { 52, 4, 20, BOTH, FALSE}, // 5G, ch 52~64
2821+ { 149, 5, 20, BOTH, FALSE}, // 5G, ch 149~165
2822+ { 0}, // end
2823+ }
2824+ },
2825+
2826+ { // China
2827+ "CN",
2828+ CE,
2829+ {
2830+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
2831+ { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161
2832+ { 0}, // end
2833+ }
2834+ },
2835+
2836+ { // Colombia
2837+ "CO",
2838+ CE,
2839+ {
2840+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
2841+ { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48
2842+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
2843+ { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
2844+ { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165
2845+ { 0}, // end
2846+ }
2847+ },
2848+
2849+ { // Costa Rica
2850+ "CR",
2851+ CE,
2852+ {
2853+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
2854+ { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48
2855+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
2856+ { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
2857+ { 0}, // end
2858+ }
2859+ },
2860+
2861+ { // Cyprus
2862+ "CY",
2863+ CE,
2864+ {
2865+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
2866+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
2867+ { 52, 4, 24, IDOR, TRUE}, // 5G, ch 52~64
2868+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
2869+ { 0}, // end
2870+ }
2871+ },
2872+
2873+ { // Czech_Republic
2874+ "CZ",
2875+ CE,
2876+ {
2877+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
2878+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
2879+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
2880+ { 0}, // end
2881+ }
2882+ },
2883+
2884+ { // Denmark
2885+ "DK",
2886+ CE,
2887+ {
2888+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
2889+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
2890+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
2891+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
2892+ { 0}, // end
2893+ }
2894+ },
2895+
2896+ { // Dominican Republic
2897+ "DO",
2898+ CE,
2899+ {
2900+ { 1, 0, 20, BOTH, FALSE}, // 2.4 G, ch 0
2901+ { 149, 4, 20, BOTH, FALSE}, // 5G, ch 149~161
2902+ { 0}, // end
2903+ }
2904+ },
2905+
2906+ { // Equador
2907+ "EC",
2908+ CE,
2909+ {
2910+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
2911+ { 100, 11, 27, BOTH, FALSE}, // 5G, ch 100~140
2912+ { 0}, // end
2913+ }
2914+ },
2915+
2916+ { // El Salvador
2917+ "SV",
2918+ CE,
2919+ {
2920+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
2921+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
2922+ { 52, 4, 30, BOTH, TRUE}, // 5G, ch 52~64
2923+ { 149, 4, 36, BOTH, TRUE}, // 5G, ch 149~165
2924+ { 0}, // end
2925+ }
2926+ },
2927+
2928+ { // Finland
2929+ "FI",
2930+ CE,
2931+ {
2932+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
2933+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
2934+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
2935+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
2936+ { 0}, // end
2937+ }
2938+ },
2939+
2940+ { // France
2941+ "FR",
2942+ CE,
2943+ {
2944+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
2945+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
2946+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
2947+ { 0}, // end
2948+ }
2949+ },
2950+
2951+ { // Germany
2952+ "DE",
2953+ CE,
2954+ {
2955+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
2956+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
2957+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
2958+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
2959+ { 0}, // end
2960+ }
2961+ },
2962+
2963+ { // Greece
2964+ "GR",
2965+ CE,
2966+ {
2967+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
2968+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
2969+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
2970+ { 100, 11, 30, ODOR, TRUE}, // 5G, ch 100~140
2971+ { 0}, // end
2972+ }
2973+ },
2974+
2975+ { // Guam
2976+ "GU",
2977+ CE,
2978+ {
2979+ { 1, 11, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
2980+ { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48
2981+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
2982+ { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
2983+ { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165
2984+ { 0}, // end
2985+ }
2986+ },
2987+
2988+ { // Guatemala
2989+ "GT",
2990+ CE,
2991+ {
2992+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
2993+ { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48
2994+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
2995+ { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
2996+ { 0}, // end
2997+ }
2998+ },
2999+
3000+ { // Haiti
3001+ "HT",
3002+ CE,
3003+ {
3004+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
3005+ { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48
3006+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
3007+ { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
3008+ { 0}, // end
3009+ }
3010+ },
3011+
3012+ { // Honduras
3013+ "HN",
3014+ CE,
3015+ {
3016+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
3017+ { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161
3018+ { 0}, // end
3019+ }
3020+ },
3021+
3022+ { // Hong Kong
3023+ "HK",
3024+ CE,
3025+ {
3026+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
3027+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
3028+ { 52, 4, 23, IDOR, FALSE}, // 5G, ch 52~64
3029+ { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
3030+ { 0}, // end
3031+ }
3032+ },
3033+
3034+ { // Hungary
3035+ "HU",
3036+ CE,
3037+ {
3038+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
3039+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
3040+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
3041+ { 0}, // end
3042+ }
3043+ },
3044+
3045+ { // Iceland
3046+ "IS",
3047+ CE,
3048+ {
3049+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
3050+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
3051+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
3052+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
3053+ { 0}, // end
3054+ }
3055+ },
3056+
3057+ { // India
3058+ "IN",
3059+ CE,
3060+ {
3061+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
3062+ { 149, 4, 24, IDOR, FALSE}, // 5G, ch 149~161
3063+ { 0}, // end
3064+ }
3065+ },
3066+
3067+ { // Indonesia
3068+ "ID",
3069+ CE,
3070+ {
3071+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
3072+ { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161
3073+ { 0}, // end
3074+ }
3075+ },
3076+
3077+ { // Ireland
3078+ "IE",
3079+ CE,
3080+ {
3081+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
3082+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
3083+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
3084+ { 100, 11, 30, ODOR, TRUE}, // 5G, ch 100~140
3085+ { 0}, // end
3086+ }
3087+ },
3088+
3089+ { // Israel
3090+ "IL",
3091+ CE,
3092+ {
3093+ { 1, 3, 20, IDOR, FALSE}, // 2.4 G, ch 1~3
3094+ { 4, 6, 20, BOTH, FALSE}, // 2.4 G, ch 4~9
3095+ { 10, 4, 20, IDOR, FALSE}, // 2.4 G, ch 10~13
3096+ { 0}, // end
3097+ }
3098+ },
3099+
3100+ { // Italy
3101+ "IT",
3102+ CE,
3103+ {
3104+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
3105+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
3106+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
3107+ { 100, 11, 30, ODOR, TRUE}, // 5G, ch 100~140
3108+ { 0}, // end
3109+ }
3110+ },
3111+
3112+ { // Japan
3113+ "JP",
3114+ JAP,
3115+ {
3116+ { 1, 14, 20, BOTH, FALSE}, // 2.4 G, ch 1~14
3117+ { 34, 4, 23, IDOR, FALSE}, // 5G, ch 34~46
3118+ { 0}, // end
3119+ }
3120+ },
3121+
3122+ { // Jordan
3123+ "JO",
3124+ CE,
3125+ {
3126+ { 1, 13, 20, IDOR, FALSE}, // 2.4 G, ch 1~13
3127+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
3128+ { 149, 4, 23, IDOR, FALSE}, // 5G, ch 149~161
3129+ { 0}, // end
3130+ }
3131+ },
3132+
3133+ { // Latvia
3134+ "LV",
3135+ CE,
3136+ {
3137+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
3138+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
3139+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
3140+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
3141+ { 0}, // end
3142+ }
3143+ },
3144+
3145+ { // Liechtenstein
3146+ "LI",
3147+ CE,
3148+ {
3149+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
3150+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
3151+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
3152+ { 0}, // end
3153+ }
3154+ },
3155+
3156+ { // Lithuania
3157+ "LT",
3158+ CE,
3159+ {
3160+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
3161+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
3162+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
3163+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
3164+ { 0}, // end
3165+ }
3166+ },
3167+
3168+ { // Luxemburg
3169+ "LU",
3170+ CE,
3171+ {
3172+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
3173+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
3174+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
3175+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
3176+ { 0}, // end
3177+ }
3178+ },
3179+
3180+ { // Malaysia
3181+ "MY",
3182+ CE,
3183+ {
3184+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
3185+ { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
3186+ { 149, 5, 20, BOTH, FALSE}, // 5G, ch 149~165
3187+ { 0}, // end
3188+ }
3189+ },
3190+
3191+ { // Malta
3192+ "MT",
3193+ CE,
3194+ {
3195+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
3196+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
3197+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
3198+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
3199+ { 0}, // end
3200+ }
3201+ },
3202+
3203+ { // Marocco
3204+ "MA",
3205+ CE,
3206+ {
3207+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
3208+ { 36, 4, 24, IDOR, FALSE}, // 5G, ch 36~48
3209+ { 0}, // end
3210+ }
3211+ },
3212+
3213+ { // Mexico
3214+ "MX",
3215+ CE,
3216+ {
3217+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
3218+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
3219+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
3220+ { 149, 5, 30, IDOR, FALSE}, // 5G, ch 149~165
3221+ { 0}, // end
3222+ }
3223+ },
3224+
3225+ { // Netherlands
3226+ "NL",
3227+ CE,
3228+ {
3229+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
3230+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
3231+ { 52, 4, 24, IDOR, TRUE}, // 5G, ch 52~64
3232+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
3233+ { 0}, // end
3234+ }
3235+ },
3236+
3237+ { // New Zealand
3238+ "NZ",
3239+ CE,
3240+ {
3241+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
3242+ { 36, 4, 24, BOTH, FALSE}, // 5G, ch 36~48
3243+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
3244+ { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
3245+ { 0}, // end
3246+ }
3247+ },
3248+
3249+ { // Norway
3250+ "NO",
3251+ CE,
3252+ {
3253+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
3254+ { 36, 4, 24, IDOR, FALSE}, // 5G, ch 36~48
3255+ { 52, 4, 24, IDOR, TRUE}, // 5G, ch 52~64
3256+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 149~161
3257+ { 0}, // end
3258+ }
3259+ },
3260+
3261+ { // Peru
3262+ "PE",
3263+ CE,
3264+ {
3265+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
3266+ { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161
3267+ { 0}, // end
3268+ }
3269+ },
3270+
3271+ { // Portugal
3272+ "PT",
3273+ CE,
3274+ {
3275+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
3276+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
3277+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
3278+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
3279+ { 0}, // end
3280+ }
3281+ },
3282+
3283+ { // Poland
3284+ "PL",
3285+ CE,
3286+ {
3287+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
3288+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
3289+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
3290+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
3291+ { 0}, // end
3292+ }
3293+ },
3294+
3295+ { // Romania
3296+ "RO",
3297+ CE,
3298+ {
3299+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
3300+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
3301+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
3302+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
3303+ { 0}, // end
3304+ }
3305+ },
3306+
3307+ { // Russia
3308+ "RU",
3309+ CE,
3310+ {
3311+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
3312+ { 149, 4, 20, IDOR, FALSE}, // 5G, ch 149~161
3313+ { 0}, // end
3314+ }
3315+ },
3316+
3317+ { // Saudi Arabia
3318+ "SA",
3319+ CE,
3320+ {
3321+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
3322+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
3323+ { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
3324+ { 149, 4, 23, BOTH, FALSE}, // 5G, ch 149~161
3325+ { 0}, // end
3326+ }
3327+ },
3328+
3329+ { // Serbia_and_Montenegro
3330+ "CS",
3331+ CE,
3332+ {
3333+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
3334+ { 0}, // end
3335+ }
3336+ },
3337+
3338+ { // Singapore
3339+ "SG",
3340+ CE,
3341+ {
3342+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
3343+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
3344+ { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
3345+ { 149, 4, 20, BOTH, FALSE}, // 5G, ch 149~161
3346+ { 0}, // end
3347+ }
3348+ },
3349+
3350+ { // Slovakia
3351+ "SK",
3352+ CE,
3353+ {
3354+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
3355+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
3356+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
3357+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
3358+ { 0}, // end
3359+ }
3360+ },
3361+
3362+ { // Slovenia
3363+ "SI",
3364+ CE,
3365+ {
3366+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
3367+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
3368+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
3369+ { 0}, // end
3370+ }
3371+ },
3372+
3373+ { // South Africa
3374+ "ZA",
3375+ CE,
3376+ {
3377+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
3378+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
3379+ { 52, 4, 23, IDOR, FALSE}, // 5G, ch 52~64
3380+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
3381+ { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
3382+ { 0}, // end
3383+ }
3384+ },
3385+
3386+ { // South Korea
3387+ "KR",
3388+ CE,
3389+ {
3390+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
3391+ { 36, 4, 20, BOTH, FALSE}, // 5G, ch 36~48
3392+ { 52, 4, 20, BOTH, FALSE}, // 5G, ch 52~64
3393+ { 100, 8, 20, BOTH, FALSE}, // 5G, ch 100~128
3394+ { 149, 4, 20, BOTH, FALSE}, // 5G, ch 149~161
3395+ { 0}, // end
3396+ }
3397+ },
3398+
3399+ { // Spain
3400+ "ES",
3401+ CE,
3402+ {
3403+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
3404+ { 36, 4, 17, IDOR, FALSE}, // 5G, ch 36~48
3405+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
3406+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
3407+ { 0}, // end
3408+ }
3409+ },
3410+
3411+ { // Sweden
3412+ "SE",
3413+ CE,
3414+ {
3415+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
3416+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
3417+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
3418+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
3419+ { 0}, // end
3420+ }
3421+ },
3422+
3423+ { // Switzerland
3424+ "CH",
3425+ CE,
3426+ {
3427+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
3428+ { 36, 4, 23, IDOR, TRUE}, // 5G, ch 36~48
3429+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
3430+ { 0}, // end
3431+ }
3432+ },
3433+
3434+ { // Taiwan
3435+ "TW",
3436+ CE,
3437+ {
3438+ { 1, 11, 30, BOTH, FALSE}, // 2.4 G, ch 1~11
3439+ { 52, 4, 23, IDOR, FALSE}, // 5G, ch 52~64
3440+ { 0}, // end
3441+ }
3442+ },
3443+
3444+ { // Turkey
3445+ "TR",
3446+ CE,
3447+ {
3448+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
3449+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
3450+ { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
3451+ { 0}, // end
3452+ }
3453+ },
3454+
3455+ { // UK
3456+ "GB",
3457+ CE,
3458+ {
3459+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
3460+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 52~64
3461+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
3462+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
3463+ { 0}, // end
3464+ }
3465+ },
3466+
3467+ { // Ukraine
3468+ "UA",
3469+ CE,
3470+ {
3471+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
3472+ { 0}, // end
3473+ }
3474+ },
3475+
3476+ { // United_Arab_Emirates
3477+ "AE",
3478+ CE,
3479+ {
3480+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
3481+ { 0}, // end
3482+ }
3483+ },
3484+
3485+ { // United_States
3486+ "US",
3487+ CE,
3488+ {
3489+ { 1, 11, 30, BOTH, FALSE}, // 2.4 G, ch 1~11
3490+ { 36, 4, 17, IDOR, FALSE}, // 5G, ch 52~64
3491+ { 52, 4, 24, BOTH, TRUE}, // 5G, ch 52~64
3492+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
3493+ { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165
3494+ { 0}, // end
3495+ }
3496+ },
3497+
3498+ { // Venezuela
3499+ "VE",
3500+ CE,
3501+ {
3502+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
3503+ { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161
3504+ { 0}, // end
3505+ }
3506+ },
3507+
3508+ { // Default
3509+ "",
3510+ CE,
3511+ {
3512+ { 1, 11, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
3513+ { 36, 4, 20, BOTH, FALSE}, // 5G, ch 52~64
3514+ { 52, 4, 20, BOTH, FALSE}, // 5G, ch 52~64
3515+ { 100, 11, 20, BOTH, FALSE}, // 5G, ch 100~140
3516+ { 149, 5, 20, BOTH, FALSE}, // 5G, ch 149~165
3517+ { 0}, // end
3518+ }
3519+ },
3520+};
3521+
3522+static inline PCH_REGION GetChRegion(
3523+ IN PUCHAR CntryCode)
3524+{
3525+ INT loop = 0;
3526+ PCH_REGION pChRegion = NULL;
3527+
3528+ while (strcmp(ChRegion[loop].CountReg, "") != 0)
3529+ {
3530+ if (strncmp(ChRegion[loop].CountReg, CntryCode, 2) == 0)
3531+ {
3532+ pChRegion = &ChRegion[loop];
3533+ break;
3534+ }
3535+ loop++;
3536+ }
3537+
3538+ if (pChRegion == NULL)
3539+ pChRegion = &ChRegion[loop];
3540+ return pChRegion;
3541+}
3542+
3543+static inline VOID ChBandCheck(
3544+ IN UCHAR PhyMode,
3545+ OUT PUCHAR pChType)
3546+{
3547+ switch(PhyMode)
3548+ {
3549+ case PHY_11A:
3550+#ifdef DOT11_N_SUPPORT
3551+ case PHY_11AN_MIXED:
3552+#endif // DOT11_N_SUPPORT //
3553+ *pChType = BAND_5G;
3554+ break;
3555+ case PHY_11ABG_MIXED:
3556+#ifdef DOT11_N_SUPPORT
3557+ case PHY_11AGN_MIXED:
3558+ case PHY_11ABGN_MIXED:
3559+#endif // DOT11_N_SUPPORT //
3560+ *pChType = BAND_BOTH;
3561+ break;
3562+
3563+ default:
3564+ *pChType = BAND_24G;
3565+ break;
3566+ }
3567+}
3568+
3569+static inline UCHAR FillChList(
3570+ IN PRTMP_ADAPTER pAd,
3571+ IN PCH_DESP pChDesp,
3572+ IN UCHAR Offset,
3573+ IN UCHAR increment)
3574+{
3575+ INT i, j, l;
3576+ UCHAR channel;
3577+
3578+ j = Offset;
3579+ for (i = 0; i < pChDesp->NumOfCh; i++)
3580+ {
3581+ channel = pChDesp->FirstChannel + i * increment;
3582+ for (l=0; l<MAX_NUM_OF_CHANNELS; l++)
3583+ {
3584+ if (channel == pAd->TxPower[l].Channel)
3585+ {
3586+ pAd->ChannelList[j].Power = pAd->TxPower[l].Power;
3587+ pAd->ChannelList[j].Power2 = pAd->TxPower[l].Power2;
3588+ break;
3589+ }
3590+ }
3591+ if (l == MAX_NUM_OF_CHANNELS)
3592+ continue;
3593+
3594+ pAd->ChannelList[j].Channel = pChDesp->FirstChannel + i * increment;
3595+ pAd->ChannelList[j].MaxTxPwr = pChDesp->MaxTxPwr;
3596+ pAd->ChannelList[j].DfsReq = pChDesp->DfsReq;
3597+ j++;
3598+ }
3599+ pAd->ChannelListNum = j;
3600+
3601+ return j;
3602+}
3603+
3604+static inline VOID CreateChList(
3605+ IN PRTMP_ADAPTER pAd,
3606+ IN PCH_REGION pChRegion,
3607+ IN UCHAR Geography)
3608+{
3609+ INT i;
3610+ UCHAR offset = 0;
3611+ PCH_DESP pChDesp;
3612+ UCHAR ChType;
3613+ UCHAR increment;
3614+
3615+ if (pChRegion == NULL)
3616+ return;
3617+
3618+ ChBandCheck(pAd->CommonCfg.PhyMode, &ChType);
3619+
3620+ for (i=0; i<10; i++)
3621+ {
3622+ pChDesp = &pChRegion->ChDesp[i];
3623+ if (pChDesp->FirstChannel == 0)
3624+ break;
3625+
3626+ if (ChType == BAND_5G)
3627+ {
3628+ if (pChDesp->FirstChannel <= 14)
3629+ continue;
3630+ }
3631+ else if (ChType == BAND_24G)
3632+ {
3633+ if (pChDesp->FirstChannel > 14)
3634+ continue;
3635+ }
3636+
3637+ if ((pChDesp->Geography == BOTH)
3638+ || (pChDesp->Geography == Geography))
3639+ {
3640+ if (pChDesp->FirstChannel > 14)
3641+ increment = 4;
3642+ else
3643+ increment = 1;
3644+ offset = FillChList(pAd, pChDesp, offset, increment);
3645+ }
3646+ }
3647+}
3648+
3649+static inline VOID BuildChannelListEx(
3650+ IN PRTMP_ADAPTER pAd)
3651+{
3652+ PCH_REGION pChReg;
3653+
3654+ pChReg = GetChRegion(pAd->CommonCfg.CountryCode);
3655+ CreateChList(pAd, pChReg, pAd->CommonCfg.Geography);
3656+}
3657+
3658+static inline VOID BuildBeaconChList(
3659+ IN PRTMP_ADAPTER pAd,
3660+ OUT PUCHAR pBuf,
3661+ OUT PULONG pBufLen)
3662+{
3663+ INT i;
3664+ ULONG TmpLen;
3665+ PCH_REGION pChRegion;
3666+ PCH_DESP pChDesp;
3667+ UCHAR ChType;
3668+
3669+ pChRegion = GetChRegion(pAd->CommonCfg.CountryCode);
3670+
3671+ if (pChRegion == NULL)
3672+ return;
3673+
3674+ ChBandCheck(pAd->CommonCfg.PhyMode, &ChType);
3675+ *pBufLen = 0;
3676+
3677+ for (i=0; i<10; i++)
3678+ {
3679+ pChDesp = &pChRegion->ChDesp[i];
3680+ if (pChDesp->FirstChannel == 0)
3681+ break;
3682+
3683+ if (ChType == BAND_5G)
3684+ {
3685+ if (pChDesp->FirstChannel <= 14)
3686+ continue;
3687+ }
3688+ else if (ChType == BAND_24G)
3689+ {
3690+ if (pChDesp->FirstChannel > 14)
3691+ continue;
3692+ }
3693+
3694+ if ((pChDesp->Geography == BOTH)
3695+ || (pChDesp->Geography == pAd->CommonCfg.Geography))
3696+ {
3697+ MakeOutgoingFrame(pBuf + *pBufLen, &TmpLen,
3698+ 1, &pChDesp->FirstChannel,
3699+ 1, &pChDesp->NumOfCh,
3700+ 1, &pChDesp->MaxTxPwr,
3701+ END_OF_ARGS);
3702+ *pBufLen += TmpLen;
3703+ }
3704+ }
3705+}
3706+
3707+
3708+#ifdef DOT11_N_SUPPORT
3709+static inline BOOLEAN IsValidChannel(
3710+ IN PRTMP_ADAPTER pAd,
3711+ IN UCHAR channel)
3712+
3713+{
3714+ INT i;
3715+
3716+ for (i = 0; i < pAd->ChannelListNum; i++)
3717+ {
3718+ if (pAd->ChannelList[i].Channel == channel)
3719+ break;
3720+ }
3721+
3722+ if (i == pAd->ChannelListNum)
3723+ return FALSE;
3724+ else
3725+ return TRUE;
3726+}
3727+
3728+
3729+static inline UCHAR GetExtCh(
3730+ IN UCHAR Channel,
3731+ IN UCHAR Direction)
3732+{
3733+ CHAR ExtCh;
3734+
3735+ if (Direction == EXTCHA_ABOVE)
3736+ ExtCh = Channel + 4;
3737+ else
3738+ ExtCh = (Channel - 4) > 0 ? (Channel - 4) : 0;
3739+
3740+ return ExtCh;
3741+}
3742+
3743+
3744+static inline VOID N_ChannelCheck(
3745+ IN PRTMP_ADAPTER pAd)
3746+{
3747+ //UCHAR ChannelNum = pAd->ChannelListNum;
3748+ UCHAR Channel = pAd->CommonCfg.Channel;
3749+
3750+ if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40))
3751+ {
3752+ if (Channel > 14)
3753+ {
3754+ if ((Channel == 36) || (Channel == 44) || (Channel == 52) || (Channel == 60) || (Channel == 100) || (Channel == 108) ||
3755+ (Channel == 116) || (Channel == 124) || (Channel == 132) || (Channel == 149) || (Channel == 157))
3756+ {
3757+ pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE;
3758+ }
3759+ else if ((Channel == 40) || (Channel == 48) || (Channel == 56) || (Channel == 64) || (Channel == 104) || (Channel == 112) ||
3760+ (Channel == 120) || (Channel == 128) || (Channel == 136) || (Channel == 153) || (Channel == 161))
3761+ {
3762+ pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_BELOW;
3763+ }
3764+ else
3765+ {
3766+ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
3767+ }
3768+ }
3769+ else
3770+ {
3771+ do
3772+ {
3773+ UCHAR ExtCh;
3774+ UCHAR Dir = pAd->CommonCfg.RegTransmitSetting.field.EXTCHA;
3775+ ExtCh = GetExtCh(Channel, Dir);
3776+ if (IsValidChannel(pAd, ExtCh))
3777+ break;
3778+
3779+ Dir = (Dir == EXTCHA_ABOVE) ? EXTCHA_BELOW : EXTCHA_ABOVE;
3780+ ExtCh = GetExtCh(Channel, Dir);
3781+ if (IsValidChannel(pAd, ExtCh))
3782+ {
3783+ pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = Dir;
3784+ break;
3785+ }
3786+ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
3787+ } while(FALSE);
3788+
3789+ if (Channel == 14)
3790+ {
3791+ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
3792+ //pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_NONE; // We didn't set the ExtCh as NONE due to it'll set in RTMPSetHT()
3793+ }
3794+ }
3795+ }
3796+
3797+
3798+}
3799+
3800+
3801+static inline VOID N_SetCenCh(
3802+ IN PRTMP_ADAPTER pAd)
3803+{
3804+ if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
3805+ {
3806+ if (pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)
3807+ {
3808+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2;
3809+ }
3810+ else
3811+ {
3812+ if (pAd->CommonCfg.Channel == 14)
3813+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 1;
3814+ else
3815+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2;
3816+ }
3817+ }
3818+ else
3819+ {
3820+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
3821+ }
3822+}
3823+#endif // DOT11_N_SUPPORT //
3824+
3825+
3826+static inline UINT8 GetCuntryMaxTxPwr(
3827+ IN PRTMP_ADAPTER pAd,
3828+ IN UINT8 channel)
3829+{
3830+ int i;
3831+ for (i = 0; i < pAd->ChannelListNum; i++)
3832+ {
3833+ if (pAd->ChannelList[i].Channel == channel)
3834+ break;
3835+ }
3836+
3837+ if (i == pAd->ChannelListNum)
3838+ return 0xff;
3839+ else
3840+ return pAd->ChannelList[i].MaxTxPwr;
3841+}
3842+#endif // __CHLIST_H__
3843+
3844--- /dev/null
3845+++ b/drivers/staging/rt3070/common/2870_rtmp_init.c
3846@@ -0,0 +1,1762 @@
3847+/*
3848+ *************************************************************************
3849+ * Ralink Tech Inc.
3850+ * 5F., No.36, Taiyuan St., Jhubei City,
3851+ * Hsinchu County 302,
3852+ * Taiwan, R.O.C.
3853+ *
3854+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
3855+ *
3856+ * This program is free software; you can redistribute it and/or modify *
3857+ * it under the terms of the GNU General Public License as published by *
3858+ * the Free Software Foundation; either version 2 of the License, or *
3859+ * (at your option) any later version. *
3860+ * *
3861+ * This program is distributed in the hope that it will be useful, *
3862+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
3863+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
3864+ * GNU General Public License for more details. *
3865+ * *
3866+ * You should have received a copy of the GNU General Public License *
3867+ * along with this program; if not, write to the *
3868+ * Free Software Foundation, Inc., *
3869+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
3870+ * *
3871+ *************************************************************************
3872+
3873+ Module Name:
3874+ 2870_rtmp_init.c
3875+
3876+ Abstract:
3877+ Miniport generic portion header file
3878+
3879+ Revision History:
3880+ Who When What
3881+ -------- ---------- ----------------------------------------------
3882+ Paul Lin 2002-08-01 created
3883+ John Chang 2004-08-20 RT2561/2661 use scatter-gather scheme
3884+ Jan Lee 2006-09-15 RT2860. Change for 802.11n , EEPROM, Led, BA, HT.
3885+ Sample Lin 2007-05-31 Merge RT2860 and RT2870 drivers.
3886+*/
3887+
3888+#include "../rt_config.h"
3889+
3890+
3891+static void rx_done_tasklet(unsigned long data);
3892+static void rt2870_hcca_dma_done_tasklet(unsigned long data);
3893+static void rt2870_ac3_dma_done_tasklet(unsigned long data);
3894+static void rt2870_ac2_dma_done_tasklet(unsigned long data);
3895+static void rt2870_ac1_dma_done_tasklet(unsigned long data);
3896+static void rt2870_ac0_dma_done_tasklet(unsigned long data);
3897+static void rt2870_mgmt_dma_done_tasklet(unsigned long data);
3898+static void rt2870_null_frame_complete_tasklet(unsigned long data);
3899+static void rt2870_rts_frame_complete_tasklet(unsigned long data);
3900+static void rt2870_pspoll_frame_complete_tasklet(unsigned long data);
3901+static void rt2870_dataout_complete_tasklet(unsigned long data);
3902+
3903+
3904+/*
3905+========================================================================
3906+Routine Description:
3907+ Initialize receive data structures.
3908+
3909+Arguments:
3910+ pAd Pointer to our adapter
3911+
3912+Return Value:
3913+ NDIS_STATUS_SUCCESS
3914+ NDIS_STATUS_RESOURCES
3915+
3916+Note:
3917+ Initialize all receive releated private buffer, include those define
3918+ in RTMP_ADAPTER structure and all private data structures. The mahor
3919+ work is to allocate buffer for each packet and chain buffer to
3920+ NDIS packet descriptor.
3921+========================================================================
3922+*/
3923+NDIS_STATUS NICInitRecv(
3924+ IN PRTMP_ADAPTER pAd)
3925+{
3926+ UCHAR i;
3927+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
3928+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
3929+
3930+
3931+ DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitRecv\n"));
3932+ pObj = pObj;
3933+
3934+ //InterlockedExchange(&pAd->PendingRx, 0);
3935+ pAd->PendingRx = 0;
3936+ pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index
3937+ pAd->NextRxBulkInIndex = 0 ; //RX_RING_SIZE -1; // Rx Bulk pointer
3938+ pAd->NextRxBulkInPosition = 0;
3939+
3940+ for (i = 0; i < (RX_RING_SIZE); i++)
3941+ {
3942+ PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
3943+
3944+ //Allocate URB
3945+ pRxContext->pUrb = RTUSB_ALLOC_URB(0);
3946+ if (pRxContext->pUrb == NULL)
3947+ {
3948+ Status = NDIS_STATUS_RESOURCES;
3949+ goto out1;
3950+ }
3951+
3952+ // Allocate transfer buffer
3953+ pRxContext->TransferBuffer = RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE, &pRxContext->data_dma);
3954+ if (pRxContext->TransferBuffer == NULL)
3955+ {
3956+ Status = NDIS_STATUS_RESOURCES;
3957+ goto out1;
3958+ }
3959+
3960+ NdisZeroMemory(pRxContext->TransferBuffer, MAX_RXBULK_SIZE);
3961+
3962+ pRxContext->pAd = pAd;
3963+ pRxContext->pIrp = NULL;
3964+ pRxContext->InUse = FALSE;
3965+ pRxContext->IRPPending = FALSE;
3966+ pRxContext->Readable = FALSE;
3967+ //pRxContext->ReorderInUse = FALSE;
3968+ pRxContext->bRxHandling = FALSE;
3969+ pRxContext->BulkInOffset = 0;
3970+ }
3971+
3972+ DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitRecv\n"));
3973+ return Status;
3974+
3975+out1:
3976+ for (i = 0; i < (RX_RING_SIZE); i++)
3977+ {
3978+ PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
3979+
3980+ if (NULL != pRxContext->TransferBuffer)
3981+ {
3982+ RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE,
3983+ pRxContext->TransferBuffer, pRxContext->data_dma);
3984+ pRxContext->TransferBuffer = NULL;
3985+ }
3986+
3987+ if (NULL != pRxContext->pUrb)
3988+ {
3989+ RTUSB_UNLINK_URB(pRxContext->pUrb);
3990+ RTUSB_FREE_URB(pRxContext->pUrb);
3991+ pRxContext->pUrb = NULL;
3992+ }
3993+ }
3994+
3995+ return Status;
3996+}
3997+
3998+
3999+/*
4000+========================================================================
4001+Routine Description:
4002+ Initialize transmit data structures.
4003+
4004+Arguments:
4005+ pAd Pointer to our adapter
4006+
4007+Return Value:
4008+ NDIS_STATUS_SUCCESS
4009+ NDIS_STATUS_RESOURCES
4010+
4011+Note:
4012+========================================================================
4013+*/
4014+NDIS_STATUS NICInitTransmit(
4015+ IN PRTMP_ADAPTER pAd)
4016+{
4017+#define LM_USB_ALLOC(pObj, Context, TB_Type, BufferSize, Status, msg1, err1, msg2, err2) \
4018+ Context->pUrb = RTUSB_ALLOC_URB(0); \
4019+ if (Context->pUrb == NULL) { \
4020+ DBGPRINT(RT_DEBUG_ERROR, msg1); \
4021+ Status = NDIS_STATUS_RESOURCES; \
4022+ goto err1; } \
4023+ \
4024+ Context->TransferBuffer = \
4025+ (TB_Type)RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, BufferSize, &Context->data_dma); \
4026+ if (Context->TransferBuffer == NULL) { \
4027+ DBGPRINT(RT_DEBUG_ERROR, msg2); \
4028+ Status = NDIS_STATUS_RESOURCES; \
4029+ goto err2; }
4030+
4031+#define LM_URB_FREE(pObj, Context, BufferSize) \
4032+ if (NULL != Context->pUrb) { \
4033+ RTUSB_UNLINK_URB(Context->pUrb); \
4034+ RTUSB_FREE_URB(Context->pUrb); \
4035+ Context->pUrb = NULL; } \
4036+ if (NULL != Context->TransferBuffer) { \
4037+ RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize, \
4038+ Context->TransferBuffer, \
4039+ Context->data_dma); \
4040+ Context->TransferBuffer = NULL; }
4041+
4042+ UCHAR i, acidx;
4043+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
4044+ PTX_CONTEXT pNullContext = &(pAd->NullContext);
4045+ PTX_CONTEXT pPsPollContext = &(pAd->PsPollContext);
4046+ PTX_CONTEXT pRTSContext = &(pAd->RTSContext);
4047+ PTX_CONTEXT pMLMEContext = NULL;
4048+// PHT_TX_CONTEXT pHTTXContext = NULL;
4049+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
4050+ PVOID RingBaseVa;
4051+// RTMP_TX_RING *pTxRing;
4052+ RTMP_MGMT_RING *pMgmtRing;
4053+
4054+ DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitTransmit\n"));
4055+ pObj = pObj;
4056+
4057+ // Init 4 set of Tx parameters
4058+ for(acidx = 0; acidx < NUM_OF_TX_RING; acidx++)
4059+ {
4060+ // Initialize all Transmit releated queues
4061+ InitializeQueueHeader(&pAd->TxSwQueue[acidx]);
4062+
4063+ // Next Local tx ring pointer waiting for buck out
4064+ pAd->NextBulkOutIndex[acidx] = acidx;
4065+ pAd->BulkOutPending[acidx] = FALSE; // Buck Out control flag
4066+ //pAd->DataBulkDoneIdx[acidx] = 0;
4067+ }
4068+
4069+ //pAd->NextMLMEIndex = 0;
4070+ //pAd->PushMgmtIndex = 0;
4071+ //pAd->PopMgmtIndex = 0;
4072+ //InterlockedExchange(&pAd->MgmtQueueSize, 0);
4073+ //InterlockedExchange(&pAd->TxCount, 0);
4074+
4075+ //pAd->PrioRingFirstIndex = 0;
4076+ //pAd->PrioRingTxCnt = 0;
4077+
4078+ do
4079+ {
4080+ //
4081+ // TX_RING_SIZE, 4 ACs
4082+ //
4083+#ifdef CONFIG_STA_SUPPORT
4084+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
4085+ for(acidx=0; acidx<4; acidx++)
4086+#endif // CONFIG_STA_SUPPORT //
4087+ {
4088+#if 1 //def DOT11_N_SUPPORT
4089+ PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]);
4090+
4091+ NdisZeroMemory(pHTTXContext, sizeof(HT_TX_CONTEXT));
4092+ //Allocate URB
4093+ LM_USB_ALLOC(pObj, pHTTXContext, PHTTX_BUFFER, sizeof(HTTX_BUFFER), Status,
4094+ ("<-- ERROR in Alloc TX TxContext[%d] urb!! \n", acidx),
4095+ done,
4096+ ("<-- ERROR in Alloc TX TxContext[%d] HTTX_BUFFER !! \n", acidx),
4097+ out1);
4098+
4099+ NdisZeroMemory(pHTTXContext->TransferBuffer->Aggregation, 4);
4100+ pHTTXContext->pAd = pAd;
4101+ pHTTXContext->pIrp = NULL;
4102+ pHTTXContext->IRPPending = FALSE;
4103+ pHTTXContext->NextBulkOutPosition = 0;
4104+ pHTTXContext->ENextBulkOutPosition = 0;
4105+ pHTTXContext->CurWritePosition = 0;
4106+ pHTTXContext->CurWriteRealPos = 0;
4107+ pHTTXContext->BulkOutSize = 0;
4108+ pHTTXContext->BulkOutPipeId = acidx;
4109+ pHTTXContext->bRingEmpty = TRUE;
4110+ pHTTXContext->bCopySavePad = FALSE;
4111+#endif // DOT11_N_SUPPORT //
4112+ pAd->BulkOutPending[acidx] = FALSE;
4113+ }
4114+
4115+
4116+ //
4117+ // MGMT_RING_SIZE
4118+ //
4119+ // Allocate MGMT ring descriptor's memory
4120+ pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * sizeof(TX_CONTEXT);
4121+ RTMPAllocateMemory(&pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);
4122+ if (pAd->MgmtDescRing.AllocVa == NULL)
4123+ {
4124+ DBGPRINT_ERR(("Failed to allocate a big buffer for MgmtDescRing!\n"));
4125+ Status = NDIS_STATUS_RESOURCES;
4126+ goto out1;
4127+ }
4128+ NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);
4129+ RingBaseVa = pAd->MgmtDescRing.AllocVa;
4130+
4131+ // Initialize MGMT Ring and associated buffer memory
4132+ pMgmtRing = &pAd->MgmtRing;
4133+ for (i = 0; i < MGMT_RING_SIZE; i++)
4134+ {
4135+ // link the pre-allocated Mgmt buffer to MgmtRing.Cell
4136+ pMgmtRing->Cell[i].AllocSize = sizeof(TX_CONTEXT);
4137+ pMgmtRing->Cell[i].AllocVa = RingBaseVa;
4138+ pMgmtRing->Cell[i].pNdisPacket = NULL;
4139+ pMgmtRing->Cell[i].pNextNdisPacket = NULL;
4140+
4141+ //Allocate URB for MLMEContext
4142+ pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
4143+ pMLMEContext->pUrb = RTUSB_ALLOC_URB(0);
4144+ if (pMLMEContext->pUrb == NULL)
4145+ {
4146+ DBGPRINT(RT_DEBUG_ERROR, ("<-- ERROR in Alloc TX MLMEContext[%d] urb!! \n", i));
4147+ Status = NDIS_STATUS_RESOURCES;
4148+ goto out2;
4149+ }
4150+ pMLMEContext->pAd = pAd;
4151+ pMLMEContext->pIrp = NULL;
4152+ pMLMEContext->TransferBuffer = NULL;
4153+ pMLMEContext->InUse = FALSE;
4154+ pMLMEContext->IRPPending = FALSE;
4155+ pMLMEContext->bWaitingBulkOut = FALSE;
4156+ pMLMEContext->BulkOutSize = 0;
4157+ pMLMEContext->SelfIdx = i;
4158+
4159+ // Offset to next ring descriptor address
4160+ RingBaseVa = (PUCHAR) RingBaseVa + sizeof(TX_CONTEXT);
4161+ }
4162+ DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", i));
4163+
4164+ //pAd->MgmtRing.TxSwFreeIdx = (MGMT_RING_SIZE - 1);
4165+ pAd->MgmtRing.TxSwFreeIdx = MGMT_RING_SIZE;
4166+ pAd->MgmtRing.TxCpuIdx = 0;
4167+ pAd->MgmtRing.TxDmaIdx = 0;
4168+
4169+ //
4170+ // BEACON_RING_SIZE
4171+ //
4172+ for(i=0; i<BEACON_RING_SIZE; i++) // 2
4173+ {
4174+ PTX_CONTEXT pBeaconContext = &(pAd->BeaconContext[i]);
4175+
4176+
4177+ NdisZeroMemory(pBeaconContext, sizeof(TX_CONTEXT));
4178+
4179+ //Allocate URB
4180+ LM_USB_ALLOC(pObj, pBeaconContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
4181+ ("<-- ERROR in Alloc TX BeaconContext[%d] urb!! \n", i),
4182+ out2,
4183+ ("<-- ERROR in Alloc TX BeaconContext[%d] TX_BUFFER !! \n", i),
4184+ out3);
4185+
4186+ pBeaconContext->pAd = pAd;
4187+ pBeaconContext->pIrp = NULL;
4188+ pBeaconContext->InUse = FALSE;
4189+ pBeaconContext->IRPPending = FALSE;
4190+ }
4191+
4192+ //
4193+ // NullContext
4194+ //
4195+ NdisZeroMemory(pNullContext, sizeof(TX_CONTEXT));
4196+
4197+ //Allocate URB
4198+ LM_USB_ALLOC(pObj, pNullContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
4199+ ("<-- ERROR in Alloc TX NullContext urb!! \n"),
4200+ out3,
4201+ ("<-- ERROR in Alloc TX NullContext TX_BUFFER !! \n"),
4202+ out4);
4203+
4204+ pNullContext->pAd = pAd;
4205+ pNullContext->pIrp = NULL;
4206+ pNullContext->InUse = FALSE;
4207+ pNullContext->IRPPending = FALSE;
4208+
4209+ //
4210+ // RTSContext
4211+ //
4212+ NdisZeroMemory(pRTSContext, sizeof(TX_CONTEXT));
4213+
4214+ //Allocate URB
4215+ LM_USB_ALLOC(pObj, pRTSContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
4216+ ("<-- ERROR in Alloc TX RTSContext urb!! \n"),
4217+ out4,
4218+ ("<-- ERROR in Alloc TX RTSContext TX_BUFFER !! \n"),
4219+ out5);
4220+
4221+ pRTSContext->pAd = pAd;
4222+ pRTSContext->pIrp = NULL;
4223+ pRTSContext->InUse = FALSE;
4224+ pRTSContext->IRPPending = FALSE;
4225+
4226+ //
4227+ // PsPollContext
4228+ //
4229+ //NdisZeroMemory(pPsPollContext, sizeof(TX_CONTEXT));
4230+ //Allocate URB
4231+ LM_USB_ALLOC(pObj, pPsPollContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
4232+ ("<-- ERROR in Alloc TX PsPollContext urb!! \n"),
4233+ out5,
4234+ ("<-- ERROR in Alloc TX PsPollContext TX_BUFFER !! \n"),
4235+ out6);
4236+
4237+ pPsPollContext->pAd = pAd;
4238+ pPsPollContext->pIrp = NULL;
4239+ pPsPollContext->InUse = FALSE;
4240+ pPsPollContext->IRPPending = FALSE;
4241+ pPsPollContext->bAggregatible = FALSE;
4242+ pPsPollContext->LastOne = TRUE;
4243+
4244+ } while (FALSE);
4245+
4246+
4247+done:
4248+ DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitTransmit\n"));
4249+
4250+ return Status;
4251+
4252+ /* --------------------------- ERROR HANDLE --------------------------- */
4253+out6:
4254+ LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER));
4255+
4256+out5:
4257+ LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER));
4258+
4259+out4:
4260+ LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER));
4261+
4262+out3:
4263+ for(i=0; i<BEACON_RING_SIZE; i++)
4264+ {
4265+ PTX_CONTEXT pBeaconContext = &(pAd->BeaconContext[i]);
4266+ if (pBeaconContext)
4267+ LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER));
4268+ }
4269+
4270+out2:
4271+ if (pAd->MgmtDescRing.AllocVa)
4272+ {
4273+ pMgmtRing = &pAd->MgmtRing;
4274+ for(i=0; i<MGMT_RING_SIZE; i++)
4275+ {
4276+ pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
4277+ if (pMLMEContext)
4278+ LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER));
4279+ }
4280+ NdisFreeMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize, 0);
4281+ pAd->MgmtDescRing.AllocVa = NULL;
4282+ }
4283+
4284+out1:
4285+#ifdef CONFIG_STA_SUPPORT
4286+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
4287+ for(acidx=0; acidx<4; acidx++)
4288+#endif // CONFIG_STA_SUPPORT //
4289+ {
4290+ PHT_TX_CONTEXT pTxContext = &(pAd->TxContext[acidx]);
4291+ if (pTxContext)
4292+ LM_URB_FREE(pObj, pTxContext, sizeof(HTTX_BUFFER));
4293+ }
4294+
4295+ // Here we didn't have any pre-allocated memory need to free.
4296+
4297+ return Status;
4298+}
4299+
4300+
4301+/*
4302+========================================================================
4303+Routine Description:
4304+ Allocate DMA memory blocks for send, receive.
4305+
4306+Arguments:
4307+ pAd Pointer to our adapter
4308+
4309+Return Value:
4310+ NDIS_STATUS_SUCCESS
4311+ NDIS_STATUS_FAILURE
4312+ NDIS_STATUS_RESOURCES
4313+
4314+Note:
4315+========================================================================
4316+*/
4317+NDIS_STATUS RTMPAllocTxRxRingMemory(
4318+ IN PRTMP_ADAPTER pAd)
4319+{
4320+// COUNTER_802_11 pCounter = &pAd->WlanCounters;
4321+ NDIS_STATUS Status;
4322+ INT num;
4323+
4324+
4325+ DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
4326+
4327+
4328+ do
4329+ {
4330+ // Init the CmdQ and CmdQLock
4331+ NdisAllocateSpinLock(&pAd->CmdQLock);
4332+ NdisAcquireSpinLock(&pAd->CmdQLock);
4333+ RTUSBInitializeCmdQ(&pAd->CmdQ);
4334+ NdisReleaseSpinLock(&pAd->CmdQLock);
4335+
4336+
4337+ NdisAllocateSpinLock(&pAd->MLMEBulkOutLock);
4338+ //NdisAllocateSpinLock(&pAd->MLMEWaitQueueLock);
4339+ NdisAllocateSpinLock(&pAd->BulkOutLock[0]);
4340+ NdisAllocateSpinLock(&pAd->BulkOutLock[1]);
4341+ NdisAllocateSpinLock(&pAd->BulkOutLock[2]);
4342+ NdisAllocateSpinLock(&pAd->BulkOutLock[3]);
4343+ NdisAllocateSpinLock(&pAd->BulkOutLock[4]);
4344+ NdisAllocateSpinLock(&pAd->BulkOutLock[5]);
4345+ NdisAllocateSpinLock(&pAd->BulkInLock);
4346+
4347+ for (num = 0; num < NUM_OF_TX_RING; num++)
4348+ {
4349+ NdisAllocateSpinLock(&pAd->TxContextQueueLock[num]);
4350+ }
4351+
4352+#ifdef RALINK_ATE
4353+ NdisAllocateSpinLock(&pAd->GenericLock);
4354+#endif // RALINK_ATE //
4355+
4356+// NdisAllocateSpinLock(&pAd->MemLock); // Not used in RT28XX
4357+
4358+// NdisAllocateSpinLock(&pAd->MacTabLock); // init it in UserCfgInit()
4359+// NdisAllocateSpinLock(&pAd->BATabLock); // init it in BATableInit()
4360+
4361+// for(num=0; num<MAX_LEN_OF_BA_REC_TABLE; num++)
4362+// {
4363+// NdisAllocateSpinLock(&pAd->BATable.BARecEntry[num].RxReRingLock);
4364+// }
4365+
4366+ //
4367+ // Init Mac Table
4368+ //
4369+// MacTableInitialize(pAd);
4370+
4371+ //
4372+ // Init send data structures and related parameters
4373+ //
4374+ Status = NICInitTransmit(pAd);
4375+ if (Status != NDIS_STATUS_SUCCESS)
4376+ break;
4377+
4378+ //
4379+ // Init receive data structures and related parameters
4380+ //
4381+ Status = NICInitRecv(pAd);
4382+ if (Status != NDIS_STATUS_SUCCESS)
4383+ break;
4384+
4385+ pAd->PendingIoCount = 1;
4386+
4387+ } while (FALSE);
4388+
4389+ NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME));
4390+ pAd->FragFrame.pFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
4391+
4392+ if (pAd->FragFrame.pFragPacket == NULL)
4393+ {
4394+ Status = NDIS_STATUS_RESOURCES;
4395+ }
4396+
4397+ DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status));
4398+ return Status;
4399+}
4400+
4401+
4402+/*
4403+========================================================================
4404+Routine Description:
4405+ Calls USB_InterfaceStop and frees memory allocated for the URBs
4406+ calls NdisMDeregisterDevice and frees the memory
4407+ allocated in VNetInitialize for the Adapter Object
4408+
4409+Arguments:
4410+ *pAd the raxx interface data pointer
4411+
4412+Return Value:
4413+ None
4414+
4415+Note:
4416+========================================================================
4417+*/
4418+VOID RTMPFreeTxRxRingMemory(
4419+ IN PRTMP_ADAPTER pAd)
4420+{
4421+#define LM_URB_FREE(pObj, Context, BufferSize) \
4422+ if (NULL != Context->pUrb) { \
4423+ RTUSB_UNLINK_URB(Context->pUrb); \
4424+ RTUSB_FREE_URB(Context->pUrb); \
4425+ Context->pUrb = NULL; } \
4426+ if (NULL != Context->TransferBuffer) { \
4427+ RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize, \
4428+ Context->TransferBuffer, \
4429+ Context->data_dma); \
4430+ Context->TransferBuffer = NULL; }
4431+
4432+
4433+ UINT i, acidx;
4434+ PTX_CONTEXT pNullContext = &pAd->NullContext;
4435+ PTX_CONTEXT pPsPollContext = &pAd->PsPollContext;
4436+ PTX_CONTEXT pRTSContext = &pAd->RTSContext;
4437+// PHT_TX_CONTEXT pHTTXContext;
4438+ //PRTMP_REORDERBUF pReorderBuf;
4439+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
4440+// RTMP_TX_RING *pTxRing;
4441+
4442+ DBGPRINT(RT_DEBUG_ERROR, ("---> RTMPFreeTxRxRingMemory\n"));
4443+ pObj = pObj;
4444+
4445+ // Free all resources for the RECEIVE buffer queue.
4446+ for(i=0; i<(RX_RING_SIZE); i++)
4447+ {
4448+ PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
4449+ if (pRxContext)
4450+ LM_URB_FREE(pObj, pRxContext, MAX_RXBULK_SIZE);
4451+ }
4452+
4453+ // Free PsPoll frame resource
4454+ LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER));
4455+
4456+ // Free NULL frame resource
4457+ LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER));
4458+
4459+ // Free RTS frame resource
4460+ LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER));
4461+
4462+
4463+ // Free beacon frame resource
4464+ for(i=0; i<BEACON_RING_SIZE; i++)
4465+ {
4466+ PTX_CONTEXT pBeaconContext = &(pAd->BeaconContext[i]);
4467+ if (pBeaconContext)
4468+ LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER));
4469+ }
4470+
4471+
4472+ // Free mgmt frame resource
4473+ for(i = 0; i < MGMT_RING_SIZE; i++)
4474+ {
4475+ PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa;
4476+ //LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER));
4477+ if (NULL != pAd->MgmtRing.Cell[i].pNdisPacket)
4478+ {
4479+ RTMPFreeNdisPacket(pAd, pAd->MgmtRing.Cell[i].pNdisPacket);
4480+ pAd->MgmtRing.Cell[i].pNdisPacket = NULL;
4481+ pMLMEContext->TransferBuffer = NULL;
4482+ }
4483+
4484+ if (pMLMEContext)
4485+ {
4486+ if (NULL != pMLMEContext->pUrb)
4487+ {
4488+ RTUSB_UNLINK_URB(pMLMEContext->pUrb);
4489+ RTUSB_FREE_URB(pMLMEContext->pUrb);
4490+ pMLMEContext->pUrb = NULL;
4491+ }
4492+ }
4493+ }
4494+ if (pAd->MgmtDescRing.AllocVa)
4495+ NdisFreeMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize, 0);
4496+
4497+
4498+ // Free Tx frame resource
4499+#ifdef CONFIG_STA_SUPPORT
4500+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
4501+ for(acidx=0; acidx<4; acidx++)
4502+#endif // CONFIG_STA_SUPPORT //
4503+ {
4504+ PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]);
4505+ if (pHTTXContext)
4506+ LM_URB_FREE(pObj, pHTTXContext, sizeof(HTTX_BUFFER));
4507+ }
4508+
4509+ if (pAd->FragFrame.pFragPacket)
4510+ RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, NDIS_STATUS_SUCCESS);
4511+
4512+ for(i=0; i<6; i++)
4513+ {
4514+ NdisFreeSpinLock(&pAd->BulkOutLock[i]);
4515+ }
4516+
4517+ NdisFreeSpinLock(&pAd->BulkInLock);
4518+ NdisFreeSpinLock(&pAd->MLMEBulkOutLock);
4519+
4520+ NdisFreeSpinLock(&pAd->CmdQLock);
4521+#ifdef RALINK_ATE
4522+ NdisFreeSpinLock(&pAd->GenericLock);
4523+#endif // RALINK_ATE //
4524+ // Clear all pending bulk-out request flags.
4525+ RTUSB_CLEAR_BULK_FLAG(pAd, 0xffffffff);
4526+
4527+// NdisFreeSpinLock(&pAd->MacTabLock);
4528+
4529+// for(i=0; i<MAX_LEN_OF_BA_REC_TABLE; i++)
4530+// {
4531+// NdisFreeSpinLock(&pAd->BATable.BARecEntry[i].RxReRingLock);
4532+// }
4533+
4534+ DBGPRINT(RT_DEBUG_ERROR, ("<--- ReleaseAdapter\n"));
4535+}
4536+
4537+
4538+/*
4539+========================================================================
4540+Routine Description:
4541+ Allocate memory for adapter control block.
4542+
4543+Arguments:
4544+ pAd Pointer to our adapter
4545+
4546+Return Value:
4547+ NDIS_STATUS_SUCCESS
4548+ NDIS_STATUS_FAILURE
4549+ NDIS_STATUS_RESOURCES
4550+
4551+Note:
4552+========================================================================
4553+*/
4554+NDIS_STATUS AdapterBlockAllocateMemory(
4555+ IN PVOID handle,
4556+ OUT PVOID *ppAd)
4557+{
4558+ PUSB_DEV usb_dev;
4559+ POS_COOKIE pObj = (POS_COOKIE) handle;
4560+
4561+
4562+ usb_dev = pObj->pUsb_Dev;
4563+
4564+ pObj->MLMEThr_pid = NULL;
4565+ pObj->RTUSBCmdThr_pid = NULL;
4566+
4567+ *ppAd = (PVOID)vmalloc(sizeof(RTMP_ADAPTER));
4568+
4569+ if (*ppAd)
4570+ {
4571+ NdisZeroMemory(*ppAd, sizeof(RTMP_ADAPTER));
4572+ ((PRTMP_ADAPTER)*ppAd)->OS_Cookie = handle;
4573+ return (NDIS_STATUS_SUCCESS);
4574+ }
4575+ else
4576+ {
4577+ return (NDIS_STATUS_FAILURE);
4578+ }
4579+}
4580+
4581+
4582+/*
4583+========================================================================
4584+Routine Description:
4585+ Create kernel threads & tasklets.
4586+
4587+Arguments:
4588+ *net_dev Pointer to wireless net device interface
4589+
4590+Return Value:
4591+ NDIS_STATUS_SUCCESS
4592+ NDIS_STATUS_FAILURE
4593+
4594+Note:
4595+========================================================================
4596+*/
4597+NDIS_STATUS CreateThreads(
4598+ IN struct net_device *net_dev)
4599+{
4600+ PRTMP_ADAPTER pAd = net_dev->ml_priv;
4601+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
4602+ pid_t pid_number;
4603+
4604+ //init_MUTEX(&(pAd->usbdev_semaphore));
4605+
4606+ init_MUTEX_LOCKED(&(pAd->mlme_semaphore));
4607+ init_completion (&pAd->mlmeComplete);
4608+
4609+ init_MUTEX_LOCKED(&(pAd->RTUSBCmd_semaphore));
4610+ init_completion (&pAd->CmdQComplete);
4611+
4612+ init_MUTEX_LOCKED(&(pAd->RTUSBTimer_semaphore));
4613+ init_completion (&pAd->TimerQComplete);
4614+
4615+ // Creat MLME Thread
4616+ pObj->MLMEThr_pid = NULL;
4617+ pid_number = kernel_thread(MlmeThread, pAd, CLONE_VM);
4618+ if (pid_number < 0)
4619+ {
4620+ printk (KERN_WARNING "%s: unable to start Mlme thread\n",pAd->net_dev->name);
4621+ return NDIS_STATUS_FAILURE;
4622+ }
4623+ pObj->MLMEThr_pid = find_get_pid(pid_number);
4624+ // Wait for the thread to start
4625+ wait_for_completion(&(pAd->mlmeComplete));
4626+
4627+ // Creat Command Thread
4628+ pObj->RTUSBCmdThr_pid = NULL;
4629+ pid_number = kernel_thread(RTUSBCmdThread, pAd, CLONE_VM);
4630+ if (pid_number < 0)
4631+ {
4632+ printk (KERN_WARNING "%s: unable to start RTUSBCmd thread\n",pAd->net_dev->name);
4633+ return NDIS_STATUS_FAILURE;
4634+ }
4635+ pObj->RTUSBCmdThr_pid = find_get_pid(pid_number);
4636+ wait_for_completion(&(pAd->CmdQComplete));
4637+
4638+ pObj->TimerQThr_pid = NULL;
4639+ pid_number = kernel_thread(TimerQThread, pAd, CLONE_VM);
4640+ if (pid_number < 0)
4641+ {
4642+ printk (KERN_WARNING "%s: unable to start TimerQThread\n",pAd->net_dev->name);
4643+ return NDIS_STATUS_FAILURE;
4644+ }
4645+ pObj->TimerQThr_pid = find_get_pid(pid_number);
4646+ // Wait for the thread to start
4647+ wait_for_completion(&(pAd->TimerQComplete));
4648+
4649+ // Create receive tasklet
4650+ tasklet_init(&pObj->rx_done_task, rx_done_tasklet, (ULONG)pAd);
4651+ tasklet_init(&pObj->mgmt_dma_done_task, rt2870_mgmt_dma_done_tasklet, (unsigned long)pAd);
4652+ tasklet_init(&pObj->ac0_dma_done_task, rt2870_ac0_dma_done_tasklet, (unsigned long)pAd);
4653+ tasklet_init(&pObj->ac1_dma_done_task, rt2870_ac1_dma_done_tasklet, (unsigned long)pAd);
4654+ tasklet_init(&pObj->ac2_dma_done_task, rt2870_ac2_dma_done_tasklet, (unsigned long)pAd);
4655+ tasklet_init(&pObj->ac3_dma_done_task, rt2870_ac3_dma_done_tasklet, (unsigned long)pAd);
4656+ tasklet_init(&pObj->hcca_dma_done_task, rt2870_hcca_dma_done_tasklet, (unsigned long)pAd);
4657+ tasklet_init(&pObj->tbtt_task, tbtt_tasklet, (unsigned long)pAd);
4658+ tasklet_init(&pObj->null_frame_complete_task, rt2870_null_frame_complete_tasklet, (unsigned long)pAd);
4659+ tasklet_init(&pObj->rts_frame_complete_task, rt2870_rts_frame_complete_tasklet, (unsigned long)pAd);
4660+ tasklet_init(&pObj->pspoll_frame_complete_task, rt2870_pspoll_frame_complete_tasklet, (unsigned long)pAd);
4661+
4662+ return NDIS_STATUS_SUCCESS;
4663+}
4664+
4665+
4666+#ifdef CONFIG_STA_SUPPORT
4667+/*
4668+========================================================================
4669+Routine Description:
4670+ As STA's BSSID is a WC too, it uses shared key table.
4671+ This function write correct unicast TX key to ASIC WCID.
4672+ And we still make a copy in our MacTab.Content[BSSID_WCID].PairwiseKey.
4673+ Caller guarantee TKIP/AES always has keyidx = 0. (pairwise key)
4674+ Caller guarantee WEP calls this function when set Txkey, default key index=0~3.
4675+
4676+Arguments:
4677+ pAd Pointer to our adapter
4678+ pKey Pointer to the where the key stored
4679+
4680+Return Value:
4681+ NDIS_SUCCESS Add key successfully
4682+
4683+Note:
4684+========================================================================
4685+*/
4686+VOID RTMPAddBSSIDCipher(
4687+ IN PRTMP_ADAPTER pAd,
4688+ IN UCHAR Aid,
4689+ IN PNDIS_802_11_KEY pKey,
4690+ IN UCHAR CipherAlg)
4691+{
4692+ PUCHAR pTxMic, pRxMic;
4693+ BOOLEAN bKeyRSC, bAuthenticator; // indicate the receive SC set by KeyRSC value
4694+// UCHAR CipherAlg;
4695+ UCHAR i;
4696+ ULONG WCIDAttri;
4697+ USHORT offset;
4698+ UCHAR KeyIdx, IVEIV[8];
4699+ UINT32 Value;
4700+
4701+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddBSSIDCipher==> Aid = %d\n",Aid));
4702+
4703+ // Bit 29 of Add-key KeyRSC
4704+ bKeyRSC = (pKey->KeyIndex & 0x20000000) ? TRUE : FALSE;
4705+
4706+ // Bit 28 of Add-key Authenticator
4707+ bAuthenticator = (pKey->KeyIndex & 0x10000000) ? TRUE : FALSE;
4708+ KeyIdx = (UCHAR)pKey->KeyIndex&0xff;
4709+
4710+ if (KeyIdx > 4)
4711+ return;
4712+
4713+
4714+ if (pAd->MacTab.Content[Aid].PairwiseKey.CipherAlg == CIPHER_TKIP)
4715+ { if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
4716+ {
4717+ // for WPA-None Tx, Rx MIC is the same
4718+ pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 16;
4719+ pRxMic = pTxMic;
4720+ }
4721+ else if (bAuthenticator == TRUE)
4722+ {
4723+ pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 16;
4724+ pRxMic = (PUCHAR) (&pKey->KeyMaterial) + 24;
4725+ }
4726+ else
4727+ {
4728+ pRxMic = (PUCHAR) (&pKey->KeyMaterial) + 16;
4729+ pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 24;
4730+ }
4731+
4732+ offset = PAIRWISE_KEY_TABLE_BASE + (Aid * HW_KEY_ENTRY_SIZE) + 0x10;
4733+ for (i=0; i<8; )
4734+ {
4735+ Value = *(pTxMic+i);
4736+ Value += (*(pTxMic+i+1)<<8);
4737+ Value += (*(pTxMic+i+2)<<16);
4738+ Value += (*(pTxMic+i+3)<<24);
4739+ RTUSBWriteMACRegister(pAd, offset+i, Value);
4740+ i+=4;
4741+ }
4742+
4743+ offset = PAIRWISE_KEY_TABLE_BASE + (Aid * HW_KEY_ENTRY_SIZE) + 0x18;
4744+ for (i=0; i<8; )
4745+ {
4746+ Value = *(pRxMic+i);
4747+ Value += (*(pRxMic+i+1)<<8);
4748+ Value += (*(pRxMic+i+2)<<16);
4749+ Value += (*(pRxMic+i+3)<<24);
4750+ RTUSBWriteMACRegister(pAd, offset+i, Value);
4751+ i+=4;
4752+ }
4753+
4754+ // Only Key lenth equal to TKIP key have these
4755+ NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.RxMic, pRxMic, 8);
4756+ NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.TxMic, pTxMic, 8);
4757+
4758+ DBGPRINT(RT_DEBUG_TRACE,
4759+ (" TxMIC = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x \n",
4760+ pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],
4761+ pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
4762+ DBGPRINT(RT_DEBUG_TRACE,
4763+ (" RxMIC = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x \n",
4764+ pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],
4765+ pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
4766+ }
4767+
4768+ // 2. Record Security Key.
4769+ pAd->MacTab.Content[BSSID_WCID].PairwiseKey.KeyLen= (UCHAR)pKey->KeyLength;
4770+ NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.Key, &pKey->KeyMaterial, pKey->KeyLength);
4771+
4772+ // 3. Check RxTsc. And used to init to ASIC IV.
4773+ if (bKeyRSC == TRUE)
4774+ NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.RxTsc, &pKey->KeyRSC, 6);
4775+ else
4776+ NdisZeroMemory(pAd->MacTab.Content[Aid].PairwiseKey.RxTsc, 6);
4777+
4778+ // 4. Init TxTsc to one based on WiFi WPA specs
4779+ pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[0] = 1;
4780+ pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[1] = 0;
4781+ pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[2] = 0;
4782+ pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[3] = 0;
4783+ pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[4] = 0;
4784+ pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[5] = 0;
4785+
4786+ CipherAlg = pAd->MacTab.Content[Aid].PairwiseKey.CipherAlg;
4787+
4788+ offset = PAIRWISE_KEY_TABLE_BASE + (Aid * HW_KEY_ENTRY_SIZE);
4789+ RTUSBMultiWrite(pAd, (USHORT) offset, pKey->KeyMaterial,
4790+ ((pKey->KeyLength == LEN_TKIP_KEY) ? 16 : (USHORT)pKey->KeyLength));
4791+
4792+ offset = SHARED_KEY_TABLE_BASE + (KeyIdx * HW_KEY_ENTRY_SIZE);
4793+ RTUSBMultiWrite(pAd, (USHORT) offset, pKey->KeyMaterial, (USHORT)pKey->KeyLength);
4794+
4795+ offset = PAIRWISE_IVEIV_TABLE_BASE + (Aid * HW_IVEIV_ENTRY_SIZE);
4796+ NdisZeroMemory(IVEIV, 8);
4797+
4798+ // IV/EIV
4799+ if ((CipherAlg == CIPHER_TKIP) ||
4800+ (CipherAlg == CIPHER_TKIP_NO_MIC) ||
4801+ (CipherAlg == CIPHER_AES))
4802+ {
4803+ IVEIV[3] = 0x20; // Eiv bit on. keyid always 0 for pairwise key
4804+ }
4805+ // default key idx needs to set.
4806+ // in TKIP/AES KeyIdx = 0 , WEP KeyIdx is default tx key.
4807+ else
4808+ {
4809+ IVEIV[3] |= (KeyIdx<< 6);
4810+ }
4811+ RTUSBMultiWrite(pAd, (USHORT) offset, IVEIV, 8);
4812+
4813+ // WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:1=PAIRWISE KEY, BSSIdx is 0
4814+ if ((CipherAlg == CIPHER_TKIP) ||
4815+ (CipherAlg == CIPHER_TKIP_NO_MIC) ||
4816+ (CipherAlg == CIPHER_AES))
4817+ {
4818+ WCIDAttri = (CipherAlg<<1)|SHAREDKEYTABLE;
4819+ }
4820+ else
4821+ WCIDAttri = (CipherAlg<<1)|SHAREDKEYTABLE;
4822+
4823+ offset = MAC_WCID_ATTRIBUTE_BASE + (Aid* HW_WCID_ATTRI_SIZE);
4824+ RTUSBWriteMACRegister(pAd, offset, WCIDAttri);
4825+ RTUSBReadMACRegister(pAd, offset, &Value);
4826+
4827+ DBGPRINT(RT_DEBUG_TRACE, ("BSSID_WCID : offset = %x, WCIDAttri = %lx\n",
4828+ offset, WCIDAttri));
4829+
4830+ // pAddr
4831+ // Add Bssid mac address at linkup. not here. check!
4832+ /*offset = MAC_WCID_BASE + (BSSID_WCID * HW_WCID_ENTRY_SIZE);
4833+ *for (i=0; i<MAC_ADDR_LEN; i++)
4834+ {
4835+ RTMP_IO_WRITE8(pAd, offset+i, pKey->BSSID[i]);
4836+ }
4837+ */
4838+
4839+ DBGPRINT(RT_DEBUG_ERROR, ("AddBSSIDasWCIDEntry: Alg=%s, KeyLength = %d\n",
4840+ CipherName[CipherAlg], pKey->KeyLength));
4841+ DBGPRINT(RT_DEBUG_TRACE, ("Key [idx=%x] [KeyLen = %d]\n",
4842+ pKey->KeyIndex, pKey->KeyLength));
4843+ for(i=0; i<pKey->KeyLength; i++)
4844+ DBGPRINT_RAW(RT_DEBUG_TRACE,(" %x:", pKey->KeyMaterial[i]));
4845+ DBGPRINT(RT_DEBUG_TRACE,(" \n"));
4846+}
4847+#endif // CONFIG_STA_SUPPORT //
4848+
4849+/*
4850+========================================================================
4851+Routine Description:
4852+ Get a received packet.
4853+
4854+Arguments:
4855+ pAd device control block
4856+ pSaveRxD receive descriptor information
4857+ *pbReschedule need reschedule flag
4858+ *pRxPending pending received packet flag
4859+
4860+Return Value:
4861+ the recieved packet
4862+
4863+Note:
4864+========================================================================
4865+*/
4866+#define RT2870_RXDMALEN_FIELD_SIZE 4
4867+PNDIS_PACKET GetPacketFromRxRing(
4868+ IN PRTMP_ADAPTER pAd,
4869+ OUT PRT28XX_RXD_STRUC pSaveRxD,
4870+ OUT BOOLEAN *pbReschedule,
4871+ IN OUT UINT32 *pRxPending)
4872+{
4873+ PRX_CONTEXT pRxContext;
4874+ PNDIS_PACKET pSkb;
4875+ PUCHAR pData;
4876+ ULONG ThisFrameLen;
4877+ ULONG RxBufferLength;
4878+ PRXWI_STRUC pRxWI;
4879+
4880+ pRxContext = &pAd->RxContext[pAd->NextRxBulkInReadIndex];
4881+ if ((pRxContext->Readable == FALSE) || (pRxContext->InUse == TRUE))
4882+ return NULL;
4883+
4884+ RxBufferLength = pRxContext->BulkInOffset - pAd->ReadPosition;
4885+ if (RxBufferLength < (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXWI_STRUC) + sizeof(RXINFO_STRUC)))
4886+ {
4887+ goto label_null;
4888+ }
4889+
4890+ pData = &pRxContext->TransferBuffer[pAd->ReadPosition]; /* 4KB */
4891+ // The RXDMA field is 4 bytes, now just use the first 2 bytes. The Length including the (RXWI + MSDU + Padding)
4892+ ThisFrameLen = *pData + (*(pData+1)<<8);
4893+ if (ThisFrameLen == 0)
4894+ {
4895+ DBGPRINT(RT_DEBUG_TRACE, ("BIRIdx(%d): RXDMALen is zero.[%ld], BulkInBufLen = %ld)\n",
4896+ pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset));
4897+ goto label_null;
4898+ }
4899+ if ((ThisFrameLen&0x3) != 0)
4900+ {
4901+ DBGPRINT(RT_DEBUG_ERROR, ("BIRIdx(%d): RXDMALen not multiple of 4.[%ld], BulkInBufLen = %ld)\n",
4902+ pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset));
4903+ goto label_null;
4904+ }
4905+
4906+ if ((ThisFrameLen + 8)> RxBufferLength) // 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXINFO_STRUC))
4907+ {
4908+ DBGPRINT(RT_DEBUG_TRACE,("BIRIdx(%d):FrameLen(0x%lx) outranges. BulkInLen=0x%lx, remaining RxBufLen=0x%lx, ReadPos=0x%lx\n",
4909+ pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset, RxBufferLength, pAd->ReadPosition));
4910+
4911+ // error frame. finish this loop
4912+ goto label_null;
4913+ }
4914+
4915+ // skip USB frame length field
4916+ pData += RT2870_RXDMALEN_FIELD_SIZE;
4917+ pRxWI = (PRXWI_STRUC)pData;
4918+#ifdef RT_BIG_ENDIAN
4919+ RTMPWIEndianChange(pData, TYPE_RXWI);
4920+#endif // RT_BIG_ENDIAN //
4921+ if (pRxWI->MPDUtotalByteCount > ThisFrameLen)
4922+ {
4923+ DBGPRINT(RT_DEBUG_ERROR, ("%s():pRxWIMPDUtotalByteCount(%d) large than RxDMALen(%ld)\n",
4924+ __FUNCTION__, pRxWI->MPDUtotalByteCount, ThisFrameLen));
4925+ goto label_null;
4926+ }
4927+#ifdef RT_BIG_ENDIAN
4928+ RTMPWIEndianChange(pData, TYPE_RXWI);
4929+#endif // RT_BIG_ENDIAN //
4930+
4931+ // allocate a rx packet
4932+ pSkb = dev_alloc_skb(ThisFrameLen);
4933+ if (pSkb == NULL)
4934+ {
4935+ DBGPRINT(RT_DEBUG_ERROR,("%s():Cannot Allocate sk buffer for this Bulk-In buffer!\n", __FUNCTION__));
4936+ goto label_null;
4937+ }
4938+
4939+ // copy the rx packet
4940+ memcpy(skb_put(pSkb, ThisFrameLen), pData, ThisFrameLen);
4941+ RTPKT_TO_OSPKT(pSkb)->dev = get_netdev_from_bssid(pAd, BSS0);
4942+ RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pSkb), PKTSRC_NDIS);
4943+
4944+ // copy RxD
4945+ *pSaveRxD = *(PRXINFO_STRUC)(pData + ThisFrameLen);
4946+#ifdef RT_BIG_ENDIAN
4947+ RTMPDescriptorEndianChange((PUCHAR)pSaveRxD, TYPE_RXINFO);
4948+#endif // RT_BIG_ENDIAN //
4949+
4950+ // update next packet read position.
4951+ pAd->ReadPosition += (ThisFrameLen + RT2870_RXDMALEN_FIELD_SIZE + RXINFO_SIZE); // 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXINFO_STRUC))
4952+
4953+ return pSkb;
4954+
4955+label_null:
4956+
4957+ return NULL;
4958+}
4959+
4960+
4961+/*
4962+========================================================================
4963+Routine Description:
4964+ Handle received packets.
4965+
4966+Arguments:
4967+ data - URB information pointer
4968+
4969+Return Value:
4970+ None
4971+
4972+Note:
4973+========================================================================
4974+*/
4975+static void rx_done_tasklet(unsigned long data)
4976+{
4977+ purbb_t pUrb;
4978+ PRX_CONTEXT pRxContext;
4979+ PRTMP_ADAPTER pAd;
4980+ NTSTATUS Status;
4981+ unsigned int IrqFlags;
4982+
4983+ pUrb = (purbb_t)data;
4984+ pRxContext = (PRX_CONTEXT)pUrb->context;
4985+ pAd = pRxContext->pAd;
4986+ Status = pUrb->status;
4987+
4988+
4989+ RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
4990+ pRxContext->InUse = FALSE;
4991+ pRxContext->IRPPending = FALSE;
4992+ pRxContext->BulkInOffset += pUrb->actual_length;
4993+ //NdisInterlockedDecrement(&pAd->PendingRx);
4994+ pAd->PendingRx--;
4995+
4996+ if (Status == USB_ST_NOERROR)
4997+ {
4998+ pAd->BulkInComplete++;
4999+ pAd->NextRxBulkInPosition = 0;
5000+ if (pRxContext->BulkInOffset) // As jan's comment, it may bulk-in success but size is zero.
5001+ {
5002+ pRxContext->Readable = TRUE;
5003+ INC_RING_INDEX(pAd->NextRxBulkInIndex, RX_RING_SIZE);
5004+ }
5005+ RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
5006+ }
5007+ else // STATUS_OTHER
5008+ {
5009+ pAd->BulkInCompleteFail++;
5010+ // Still read this packet although it may comtain wrong bytes.
5011+ pRxContext->Readable = FALSE;
5012+ RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
5013+
5014+ // Parsing all packets. because after reset, the index will reset to all zero.
5015+ if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
5016+ fRTMP_ADAPTER_BULKIN_RESET |
5017+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
5018+ fRTMP_ADAPTER_NIC_NOT_EXIST))))
5019+ {
5020+
5021+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk In Failed. Status=%d, BIIdx=0x%x, BIRIdx=0x%x, actual_length= 0x%x\n",
5022+ Status, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex, pRxContext->pUrb->actual_length));
5023+
5024+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
5025+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0);
5026+ }
5027+ }
5028+
5029+ ASSERT((pRxContext->InUse == pRxContext->IRPPending));
5030+
5031+#ifdef RALINK_ATE
5032+ if (ATE_ON(pAd))
5033+ {
5034+ // If the driver is in ATE mode and Rx frame is set into here.
5035+ if (pAd->ContinBulkIn == TRUE)
5036+ {
5037+ RTUSBBulkReceive(pAd);
5038+ }
5039+ }
5040+ else
5041+#endif // RALINK_ATE //
5042+ RTUSBBulkReceive(pAd);
5043+
5044+ return;
5045+
5046+}
5047+
5048+
5049+static void rt2870_mgmt_dma_done_tasklet(unsigned long data)
5050+{
5051+ PRTMP_ADAPTER pAd;
5052+ PTX_CONTEXT pMLMEContext;
5053+ int index;
5054+ PNDIS_PACKET pPacket;
5055+ purbb_t pUrb;
5056+ NTSTATUS Status;
5057+ unsigned long IrqFlags;
5058+
5059+
5060+ pUrb = (purbb_t)data;
5061+ pMLMEContext = (PTX_CONTEXT)pUrb->context;
5062+ pAd = pMLMEContext->pAd;
5063+ Status = pUrb->status;
5064+ index = pMLMEContext->SelfIdx;
5065+
5066+ ASSERT((pAd->MgmtRing.TxDmaIdx == index));
5067+
5068+ RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
5069+
5070+
5071+ if (Status != USB_ST_NOERROR)
5072+ {
5073+ //Bulk-Out fail status handle
5074+ if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
5075+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
5076+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
5077+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
5078+ {
5079+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out MLME Failed, Status=%d!\n", Status));
5080+ // TODO: How to handle about the MLMEBulkOut failed issue. Need to resend the mgmt pkt?
5081+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
5082+ pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
5083+ }
5084+ }
5085+
5086+ pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
5087+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
5088+
5089+ RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
5090+ // Reset MLME context flags
5091+ pMLMEContext->IRPPending = FALSE;
5092+ pMLMEContext->InUse = FALSE;
5093+ pMLMEContext->bWaitingBulkOut = FALSE;
5094+ pMLMEContext->BulkOutSize = 0;
5095+
5096+ pPacket = pAd->MgmtRing.Cell[index].pNdisPacket;
5097+ pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
5098+
5099+ // Increase MgmtRing Index
5100+ INC_RING_INDEX(pAd->MgmtRing.TxDmaIdx, MGMT_RING_SIZE);
5101+ pAd->MgmtRing.TxSwFreeIdx++;
5102+ RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);
5103+
5104+ // No-matter success or fail, we free the mgmt packet.
5105+ if (pPacket)
5106+ RTMPFreeNdisPacket(pAd, pPacket);
5107+
5108+ if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
5109+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
5110+ fRTMP_ADAPTER_NIC_NOT_EXIST))))
5111+ {
5112+ // do nothing and return directly.
5113+ }
5114+ else
5115+ {
5116+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET) &&
5117+ ((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG))
5118+ { // For Mgmt Bulk-Out failed, ignore it now.
5119+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
5120+ }
5121+ else
5122+ {
5123+
5124+ // Always call Bulk routine, even reset bulk.
5125+ // The protectioon of rest bulk should be in BulkOut routine
5126+ if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE /* pMLMEContext->bWaitingBulkOut == TRUE */)
5127+ {
5128+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
5129+ }
5130+ RTUSBKickBulkOut(pAd);
5131+ }
5132+ }
5133+
5134+}
5135+
5136+
5137+static void rt2870_hcca_dma_done_tasklet(unsigned long data)
5138+{
5139+ PRTMP_ADAPTER pAd;
5140+ PHT_TX_CONTEXT pHTTXContext;
5141+ UCHAR BulkOutPipeId = 4;
5142+ purbb_t pUrb;
5143+
5144+
5145+ pUrb = (purbb_t)data;
5146+ pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
5147+ pAd = pHTTXContext->pAd;
5148+
5149+ rt2870_dataout_complete_tasklet((unsigned long)pUrb);
5150+
5151+ if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
5152+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
5153+ fRTMP_ADAPTER_NIC_NOT_EXIST))))
5154+ {
5155+ // do nothing and return directly.
5156+ }
5157+ else
5158+ {
5159+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
5160+ {
5161+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
5162+ }
5163+ else
5164+ { pHTTXContext = &pAd->TxContext[BulkOutPipeId];
5165+ if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
5166+ /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
5167+ (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
5168+ (pHTTXContext->bCurWriting == FALSE))
5169+ {
5170+ RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
5171+ }
5172+
5173+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<4);
5174+ RTUSBKickBulkOut(pAd);
5175+ }
5176+ }
5177+
5178+
5179+ return;
5180+}
5181+
5182+
5183+static void rt2870_ac3_dma_done_tasklet(unsigned long data)
5184+{
5185+ PRTMP_ADAPTER pAd;
5186+ PHT_TX_CONTEXT pHTTXContext;
5187+ UCHAR BulkOutPipeId = 3;
5188+ purbb_t pUrb;
5189+
5190+
5191+ pUrb = (purbb_t)data;
5192+ pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
5193+ pAd = pHTTXContext->pAd;
5194+
5195+ rt2870_dataout_complete_tasklet((unsigned long)pUrb);
5196+
5197+ if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
5198+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
5199+ fRTMP_ADAPTER_NIC_NOT_EXIST))))
5200+ {
5201+ // do nothing and return directly.
5202+ }
5203+ else
5204+ {
5205+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
5206+ {
5207+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
5208+ }
5209+ else
5210+ { pHTTXContext = &pAd->TxContext[BulkOutPipeId];
5211+ if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
5212+ /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
5213+ (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
5214+ (pHTTXContext->bCurWriting == FALSE))
5215+ {
5216+ RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
5217+ }
5218+
5219+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<3);
5220+ RTUSBKickBulkOut(pAd);
5221+ }
5222+ }
5223+
5224+
5225+ return;
5226+}
5227+
5228+
5229+static void rt2870_ac2_dma_done_tasklet(unsigned long data)
5230+{
5231+ PRTMP_ADAPTER pAd;
5232+ PHT_TX_CONTEXT pHTTXContext;
5233+ UCHAR BulkOutPipeId = 2;
5234+ purbb_t pUrb;
5235+
5236+
5237+ pUrb = (purbb_t)data;
5238+ pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
5239+ pAd = pHTTXContext->pAd;
5240+
5241+ rt2870_dataout_complete_tasklet((unsigned long)pUrb);
5242+
5243+ if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
5244+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
5245+ fRTMP_ADAPTER_NIC_NOT_EXIST))))
5246+ {
5247+ // do nothing and return directly.
5248+ }
5249+ else
5250+ {
5251+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
5252+ {
5253+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
5254+ }
5255+ else
5256+ { pHTTXContext = &pAd->TxContext[BulkOutPipeId];
5257+ if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
5258+ /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
5259+ (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
5260+ (pHTTXContext->bCurWriting == FALSE))
5261+ {
5262+ RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
5263+ }
5264+
5265+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<2);
5266+ RTUSBKickBulkOut(pAd);
5267+ }
5268+ }
5269+
5270+ return;
5271+}
5272+
5273+
5274+static void rt2870_ac1_dma_done_tasklet(unsigned long data)
5275+{
5276+ PRTMP_ADAPTER pAd;
5277+ PHT_TX_CONTEXT pHTTXContext;
5278+ UCHAR BulkOutPipeId = 1;
5279+ purbb_t pUrb;
5280+
5281+
5282+ pUrb = (purbb_t)data;
5283+ pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
5284+ pAd = pHTTXContext->pAd;
5285+
5286+ rt2870_dataout_complete_tasklet((unsigned long)pUrb);
5287+
5288+ if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
5289+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
5290+ fRTMP_ADAPTER_NIC_NOT_EXIST))))
5291+ {
5292+ // do nothing and return directly.
5293+ }
5294+ else
5295+ {
5296+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
5297+ {
5298+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
5299+ }
5300+ else
5301+ { pHTTXContext = &pAd->TxContext[BulkOutPipeId];
5302+ if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
5303+ /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
5304+ (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
5305+ (pHTTXContext->bCurWriting == FALSE))
5306+ {
5307+ RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
5308+ }
5309+
5310+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<1);
5311+ RTUSBKickBulkOut(pAd);
5312+ }
5313+ }
5314+
5315+
5316+ return;
5317+}
5318+
5319+
5320+static void rt2870_ac0_dma_done_tasklet(unsigned long data)
5321+{
5322+ PRTMP_ADAPTER pAd;
5323+ PHT_TX_CONTEXT pHTTXContext;
5324+ UCHAR BulkOutPipeId = 0;
5325+ purbb_t pUrb;
5326+
5327+
5328+ pUrb = (purbb_t)data;
5329+ pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
5330+ pAd = pHTTXContext->pAd;
5331+
5332+ rt2870_dataout_complete_tasklet((unsigned long)pUrb);
5333+
5334+ if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
5335+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
5336+ fRTMP_ADAPTER_NIC_NOT_EXIST))))
5337+ {
5338+ // do nothing and return directly.
5339+ }
5340+ else
5341+ {
5342+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
5343+ {
5344+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
5345+ }
5346+ else
5347+ { pHTTXContext = &pAd->TxContext[BulkOutPipeId];
5348+ if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
5349+ /* ((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
5350+ (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
5351+ (pHTTXContext->bCurWriting == FALSE))
5352+ {
5353+ RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
5354+ }
5355+
5356+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL);
5357+ RTUSBKickBulkOut(pAd);
5358+ }
5359+ }
5360+
5361+
5362+ return;
5363+
5364+}
5365+
5366+
5367+static void rt2870_null_frame_complete_tasklet(unsigned long data)
5368+{
5369+ PRTMP_ADAPTER pAd;
5370+ PTX_CONTEXT pNullContext;
5371+ purbb_t pUrb;
5372+ NTSTATUS Status;
5373+ unsigned long irqFlag;
5374+
5375+
5376+ pUrb = (purbb_t)data;
5377+ pNullContext = (PTX_CONTEXT)pUrb->context;
5378+ pAd = pNullContext->pAd;
5379+ Status = pUrb->status;
5380+
5381+ // Reset Null frame context flags
5382+ RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag);
5383+ pNullContext->IRPPending = FALSE;
5384+ pNullContext->InUse = FALSE;
5385+ pAd->BulkOutPending[0] = FALSE;
5386+ pAd->watchDogTxPendingCnt[0] = 0;
5387+
5388+ if (Status == USB_ST_NOERROR)
5389+ {
5390+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
5391+
5392+ RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
5393+ }
5394+ else // STATUS_OTHER
5395+ {
5396+ if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
5397+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
5398+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
5399+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
5400+ {
5401+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out Null Frame Failed, ReasonCode=%d!\n", Status));
5402+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
5403+ pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
5404+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
5405+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
5406+ }
5407+ else
5408+ {
5409+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
5410+ }
5411+ }
5412+
5413+ // Always call Bulk routine, even reset bulk.
5414+ // The protectioon of rest bulk should be in BulkOut routine
5415+ RTUSBKickBulkOut(pAd);
5416+
5417+}
5418+
5419+
5420+static void rt2870_rts_frame_complete_tasklet(unsigned long data)
5421+{
5422+ PRTMP_ADAPTER pAd;
5423+ PTX_CONTEXT pRTSContext;
5424+ purbb_t pUrb;
5425+ NTSTATUS Status;
5426+ unsigned long irqFlag;
5427+
5428+
5429+ pUrb = (purbb_t)data;
5430+ pRTSContext = (PTX_CONTEXT)pUrb->context;
5431+ pAd = pRTSContext->pAd;
5432+ Status = pUrb->status;
5433+
5434+ // Reset RTS frame context flags
5435+ RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag);
5436+ pRTSContext->IRPPending = FALSE;
5437+ pRTSContext->InUse = FALSE;
5438+
5439+ if (Status == USB_ST_NOERROR)
5440+ {
5441+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
5442+ RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
5443+ }
5444+ else // STATUS_OTHER
5445+ {
5446+ if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
5447+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
5448+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
5449+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
5450+ {
5451+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out RTS Frame Failed\n"));
5452+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
5453+ pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
5454+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
5455+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
5456+ }
5457+ else
5458+ {
5459+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
5460+ }
5461+ }
5462+
5463+ RTMP_SEM_LOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
5464+ pAd->BulkOutPending[pRTSContext->BulkOutPipeId] = FALSE;
5465+ RTMP_SEM_UNLOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
5466+
5467+ // Always call Bulk routine, even reset bulk.
5468+ // The protectioon of rest bulk should be in BulkOut routine
5469+ RTUSBKickBulkOut(pAd);
5470+
5471+}
5472+
5473+
5474+static void rt2870_pspoll_frame_complete_tasklet(unsigned long data)
5475+{
5476+ PRTMP_ADAPTER pAd;
5477+ PTX_CONTEXT pPsPollContext;
5478+ purbb_t pUrb;
5479+ NTSTATUS Status;
5480+
5481+
5482+ pUrb = (purbb_t)data;
5483+ pPsPollContext = (PTX_CONTEXT)pUrb->context;
5484+ pAd = pPsPollContext->pAd;
5485+ Status = pUrb->status;
5486+
5487+ // Reset PsPoll context flags
5488+ pPsPollContext->IRPPending = FALSE;
5489+ pPsPollContext->InUse = FALSE;
5490+ pAd->watchDogTxPendingCnt[0] = 0;
5491+
5492+ if (Status == USB_ST_NOERROR)
5493+ {
5494+ RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
5495+ }
5496+ else // STATUS_OTHER
5497+ {
5498+ if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
5499+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
5500+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
5501+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
5502+ {
5503+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out PSPoll Failed\n"));
5504+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
5505+ pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
5506+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
5507+ }
5508+ }
5509+
5510+ RTMP_SEM_LOCK(&pAd->BulkOutLock[0]);
5511+ pAd->BulkOutPending[0] = FALSE;
5512+ RTMP_SEM_UNLOCK(&pAd->BulkOutLock[0]);
5513+
5514+ // Always call Bulk routine, even reset bulk.
5515+ // The protectioon of rest bulk should be in BulkOut routine
5516+ RTUSBKickBulkOut(pAd);
5517+
5518+}
5519+
5520+
5521+static void rt2870_dataout_complete_tasklet(unsigned long data)
5522+{
5523+ PRTMP_ADAPTER pAd;
5524+ purbb_t pUrb;
5525+ POS_COOKIE pObj;
5526+ PHT_TX_CONTEXT pHTTXContext;
5527+ UCHAR BulkOutPipeId;
5528+ NTSTATUS Status;
5529+ unsigned long IrqFlags;
5530+
5531+
5532+ pUrb = (purbb_t)data;
5533+ pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
5534+ pAd = pHTTXContext->pAd;
5535+ pObj = (POS_COOKIE) pAd->OS_Cookie;
5536+ Status = pUrb->status;
5537+
5538+ // Store BulkOut PipeId
5539+ BulkOutPipeId = pHTTXContext->BulkOutPipeId;
5540+ pAd->BulkOutDataOneSecCount++;
5541+
5542+ //DBGPRINT(RT_DEBUG_LOUD, ("Done-B(%d):I=0x%lx, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", BulkOutPipeId, in_interrupt(), pHTTXContext->CurWritePosition,
5543+ // pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
5544+
5545+ RTMP_IRQ_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
5546+ pAd->BulkOutPending[BulkOutPipeId] = FALSE;
5547+ pHTTXContext->IRPPending = FALSE;
5548+ pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;
5549+
5550+ if (Status == USB_ST_NOERROR)
5551+ {
5552+ pAd->BulkOutComplete++;
5553+
5554+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
5555+
5556+ pAd->Counters8023.GoodTransmits++;
5557+ //RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
5558+ FREE_HTTX_RING(pAd, BulkOutPipeId, pHTTXContext);
5559+ //RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
5560+
5561+
5562+ }
5563+ else // STATUS_OTHER
5564+ {
5565+ PUCHAR pBuf;
5566+
5567+ pAd->BulkOutCompleteOther++;
5568+
5569+ pBuf = &pHTTXContext->TransferBuffer->field.WirelessPacket[pHTTXContext->NextBulkOutPosition];
5570+
5571+ if (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
5572+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
5573+ fRTMP_ADAPTER_NIC_NOT_EXIST |
5574+ fRTMP_ADAPTER_BULKOUT_RESET)))
5575+ {
5576+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
5577+ pAd->bulkResetPipeid = BulkOutPipeId;
5578+ pAd->bulkResetReq[BulkOutPipeId] = pAd->BulkOutReq;
5579+ }
5580+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
5581+
5582+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkOutDataPacket failed: ReasonCode=%d!\n", Status));
5583+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("\t>>BulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n", pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther));
5584+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("\t>>BulkOut Header:%x %x %x %x %x %x %x %x\n", pBuf[0], pBuf[1], pBuf[2], pBuf[3], pBuf[4], pBuf[5], pBuf[6], pBuf[7]));
5585+ //DBGPRINT_RAW(RT_DEBUG_ERROR, (">>BulkOutCompleteCancel=0x%x, BulkOutCompleteOther=0x%x\n", pAd->BulkOutCompleteCancel, pAd->BulkOutCompleteOther));
5586+
5587+ }
5588+
5589+ //
5590+ // bInUse = TRUE, means some process are filling TX data, after that must turn on bWaitingBulkOut
5591+ // bWaitingBulkOut = TRUE, means the TX data are waiting for bulk out.
5592+ //
5593+ //RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
5594+ if ((pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition) &&
5595+ (pHTTXContext->ENextBulkOutPosition != (pHTTXContext->CurWritePosition+8)) &&
5596+ !RTUSB_TEST_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId)))
5597+ {
5598+ // Indicate There is data avaliable
5599+ RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
5600+ }
5601+ //RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
5602+
5603+ // Always call Bulk routine, even reset bulk.
5604+ // The protection of rest bulk should be in BulkOut routine
5605+ RTUSBKickBulkOut(pAd);
5606+}
5607+
5608+/* End of 2870_rtmp_init.c */
5609--- /dev/null
5610+++ b/drivers/staging/rt3070/common/action.c
5611@@ -0,0 +1,1038 @@
5612+/*
5613+ *************************************************************************
5614+ * Ralink Tech Inc.
5615+ * 5F., No.36, Taiyuan St., Jhubei City,
5616+ * Hsinchu County 302,
5617+ * Taiwan, R.O.C.
5618+ *
5619+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
5620+ *
5621+ * This program is free software; you can redistribute it and/or modify *
5622+ * it under the terms of the GNU General Public License as published by *
5623+ * the Free Software Foundation; either version 2 of the License, or *
5624+ * (at your option) any later version. *
5625+ * *
5626+ * This program is distributed in the hope that it will be useful, *
5627+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
5628+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
5629+ * GNU General Public License for more details. *
5630+ * *
5631+ * You should have received a copy of the GNU General Public License *
5632+ * along with this program; if not, write to the *
5633+ * Free Software Foundation, Inc., *
5634+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
5635+ * *
5636+ *************************************************************************
5637+
5638+ Module Name:
5639+ action.c
5640+
5641+ Abstract:
5642+ Handle association related requests either from WSTA or from local MLME
5643+
5644+ Revision History:
5645+ Who When What
5646+ -------- ---------- ----------------------------------------------
5647+ Jan Lee 2006 created for rt2860
5648+ */
5649+
5650+#include "../rt_config.h"
5651+#include "../action.h"
5652+
5653+
5654+static VOID ReservedAction(
5655+ IN PRTMP_ADAPTER pAd,
5656+ IN MLME_QUEUE_ELEM *Elem);
5657+
5658+/*
5659+ ==========================================================================
5660+ Description:
5661+ association state machine init, including state transition and timer init
5662+ Parameters:
5663+ S - pointer to the association state machine
5664+ Note:
5665+ The state machine looks like the following
5666+
5667+ ASSOC_IDLE
5668+ MT2_MLME_DISASSOC_REQ mlme_disassoc_req_action
5669+ MT2_PEER_DISASSOC_REQ peer_disassoc_action
5670+ MT2_PEER_ASSOC_REQ drop
5671+ MT2_PEER_REASSOC_REQ drop
5672+ MT2_CLS3ERR cls3err_action
5673+ ==========================================================================
5674+ */
5675+VOID ActionStateMachineInit(
5676+ IN PRTMP_ADAPTER pAd,
5677+ IN STATE_MACHINE *S,
5678+ OUT STATE_MACHINE_FUNC Trans[])
5679+{
5680+ StateMachineInit(S, (STATE_MACHINE_FUNC *)Trans, MAX_ACT_STATE, MAX_ACT_MSG, (STATE_MACHINE_FUNC)Drop, ACT_IDLE, ACT_MACHINE_BASE);
5681+
5682+ StateMachineSetAction(S, ACT_IDLE, MT2_PEER_SPECTRUM_CATE, (STATE_MACHINE_FUNC)PeerSpectrumAction);
5683+ StateMachineSetAction(S, ACT_IDLE, MT2_PEER_QOS_CATE, (STATE_MACHINE_FUNC)PeerQOSAction);
5684+
5685+ StateMachineSetAction(S, ACT_IDLE, MT2_PEER_DLS_CATE, (STATE_MACHINE_FUNC)ReservedAction);
5686+#ifdef QOS_DLS_SUPPORT
5687+ StateMachineSetAction(S, ACT_IDLE, MT2_PEER_DLS_CATE, (STATE_MACHINE_FUNC)PeerDLSAction);
5688+#endif // QOS_DLS_SUPPORT //
5689+
5690+#ifdef DOT11_N_SUPPORT
5691+ StateMachineSetAction(S, ACT_IDLE, MT2_PEER_BA_CATE, (STATE_MACHINE_FUNC)PeerBAAction);
5692+ StateMachineSetAction(S, ACT_IDLE, MT2_PEER_HT_CATE, (STATE_MACHINE_FUNC)PeerHTAction);
5693+ StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ADD_BA_CATE, (STATE_MACHINE_FUNC)MlmeADDBAAction);
5694+ StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ORI_DELBA_CATE, (STATE_MACHINE_FUNC)MlmeDELBAAction);
5695+ StateMachineSetAction(S, ACT_IDLE, MT2_MLME_REC_DELBA_CATE, (STATE_MACHINE_FUNC)MlmeDELBAAction);
5696+#endif // DOT11_N_SUPPORT //
5697+
5698+ StateMachineSetAction(S, ACT_IDLE, MT2_PEER_PUBLIC_CATE, (STATE_MACHINE_FUNC)PeerPublicAction);
5699+ StateMachineSetAction(S, ACT_IDLE, MT2_PEER_RM_CATE, (STATE_MACHINE_FUNC)PeerRMAction);
5700+
5701+ StateMachineSetAction(S, ACT_IDLE, MT2_MLME_QOS_CATE, (STATE_MACHINE_FUNC)MlmeQOSAction);
5702+ StateMachineSetAction(S, ACT_IDLE, MT2_MLME_DLS_CATE, (STATE_MACHINE_FUNC)MlmeDLSAction);
5703+ StateMachineSetAction(S, ACT_IDLE, MT2_ACT_INVALID, (STATE_MACHINE_FUNC)MlmeInvalidAction);
5704+}
5705+
5706+#ifdef DOT11_N_SUPPORT
5707+VOID MlmeADDBAAction(
5708+ IN PRTMP_ADAPTER pAd,
5709+ IN MLME_QUEUE_ELEM *Elem)
5710+
5711+{
5712+ MLME_ADDBA_REQ_STRUCT *pInfo;
5713+ UCHAR Addr[6];
5714+ PUCHAR pOutBuffer = NULL;
5715+ NDIS_STATUS NStatus;
5716+ ULONG Idx;
5717+ FRAME_ADDBA_REQ Frame;
5718+ ULONG FrameLen;
5719+ BA_ORI_ENTRY *pBAEntry = NULL;
5720+
5721+ pInfo = (MLME_ADDBA_REQ_STRUCT *)Elem->Msg;
5722+ NdisZeroMemory(&Frame, sizeof(FRAME_ADDBA_REQ));
5723+
5724+ if(MlmeAddBAReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr))
5725+ {
5726+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
5727+ if(NStatus != NDIS_STATUS_SUCCESS)
5728+ {
5729+ DBGPRINT(RT_DEBUG_TRACE,("BA - MlmeADDBAAction() allocate memory failed \n"));
5730+ return;
5731+ }
5732+ // 1. find entry
5733+ Idx = pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID];
5734+ if (Idx == 0)
5735+ {
5736+ MlmeFreeMemory(pAd, pOutBuffer);
5737+ DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() can't find BAOriEntry \n"));
5738+ return;
5739+ }
5740+ else
5741+ {
5742+ pBAEntry =&pAd->BATable.BAOriEntry[Idx];
5743+ }
5744+
5745+#ifdef CONFIG_STA_SUPPORT
5746+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
5747+ {
5748+ if (ADHOC_ON(pAd))
5749+ ActHeaderInit(pAd, &Frame.Hdr, pInfo->pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
5750+ else
5751+ ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pInfo->pAddr);
5752+
5753+ }
5754+#endif // CONFIG_STA_SUPPORT //
5755+
5756+ Frame.Category = CATEGORY_BA;
5757+ Frame.Action = ADDBA_REQ;
5758+ Frame.BaParm.AMSDUSupported = 0;
5759+ Frame.BaParm.BAPolicy = IMMED_BA;
5760+ Frame.BaParm.TID = pInfo->TID;
5761+ Frame.BaParm.BufSize = pInfo->BaBufSize;
5762+ Frame.Token = pInfo->Token;
5763+ Frame.TimeOutValue = pInfo->TimeOutValue;
5764+ Frame.BaStartSeq.field.FragNum = 0;
5765+ Frame.BaStartSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID];
5766+
5767+ *(USHORT *)(&Frame.BaParm) = cpu2le16(*(USHORT *)(&Frame.BaParm));
5768+ Frame.TimeOutValue = cpu2le16(Frame.TimeOutValue);
5769+ Frame.BaStartSeq.word = cpu2le16(Frame.BaStartSeq.word);
5770+
5771+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
5772+ sizeof(FRAME_ADDBA_REQ), &Frame,
5773+ END_OF_ARGS);
5774+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
5775+ //MiniportDataMMRequest(pAd, MapUserPriorityToAccessCategory[pInfo->TID], pOutBuffer, FrameLen);
5776+ MlmeFreeMemory(pAd, pOutBuffer);
5777+
5778+ DBGPRINT(RT_DEBUG_TRACE, ("BA - Send ADDBA request. StartSeq = %x, FrameLen = %ld. BufSize = %d\n", Frame.BaStartSeq.field.StartSeq, FrameLen, Frame.BaParm.BufSize));
5779+ }
5780+}
5781+
5782+/*
5783+ ==========================================================================
5784+ Description:
5785+ send DELBA and delete BaEntry if any
5786+ Parametrs:
5787+ Elem - MLME message MLME_DELBA_REQ_STRUCT
5788+
5789+ IRQL = DISPATCH_LEVEL
5790+
5791+ ==========================================================================
5792+ */
5793+VOID MlmeDELBAAction(
5794+ IN PRTMP_ADAPTER pAd,
5795+ IN MLME_QUEUE_ELEM *Elem)
5796+{
5797+ MLME_DELBA_REQ_STRUCT *pInfo;
5798+ PUCHAR pOutBuffer = NULL;
5799+ PUCHAR pOutBuffer2 = NULL;
5800+ NDIS_STATUS NStatus;
5801+ ULONG Idx;
5802+ FRAME_DELBA_REQ Frame;
5803+ ULONG FrameLen;
5804+ FRAME_BAR FrameBar;
5805+
5806+ pInfo = (MLME_DELBA_REQ_STRUCT *)Elem->Msg;
5807+ // must send back DELBA
5808+ NdisZeroMemory(&Frame, sizeof(FRAME_DELBA_REQ));
5809+ DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeDELBAAction(), Initiator(%d) \n", pInfo->Initiator));
5810+
5811+ if(MlmeDelBAReqSanity(pAd, Elem->Msg, Elem->MsgLen))
5812+ {
5813+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
5814+ if(NStatus != NDIS_STATUS_SUCCESS)
5815+ {
5816+ DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeDELBAAction() allocate memory failed 1. \n"));
5817+ return;
5818+ }
5819+
5820+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2); //Get an unused nonpaged memory
5821+ if(NStatus != NDIS_STATUS_SUCCESS)
5822+ {
5823+ MlmeFreeMemory(pAd, pOutBuffer);
5824+ DBGPRINT(RT_DEBUG_ERROR, ("BA - MlmeDELBAAction() allocate memory failed 2. \n"));
5825+ return;
5826+ }
5827+
5828+ // SEND BAR (Send BAR to refresh peer reordering buffer.)
5829+ Idx = pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID];
5830+
5831+#ifdef CONFIG_STA_SUPPORT
5832+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
5833+ BarHeaderInit(pAd, &FrameBar, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress);
5834+#endif // CONFIG_STA_SUPPORT //
5835+
5836+ FrameBar.StartingSeq.field.FragNum = 0; // make sure sequence not clear in DEL funciton.
5837+ FrameBar.StartingSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID]; // make sure sequence not clear in DEL funciton.
5838+ FrameBar.BarControl.TID = pInfo->TID; // make sure sequence not clear in DEL funciton.
5839+ FrameBar.BarControl.ACKPolicy = IMMED_BA; // make sure sequence not clear in DEL funciton.
5840+ FrameBar.BarControl.Compressed = 1; // make sure sequence not clear in DEL funciton.
5841+ FrameBar.BarControl.MTID = 0; // make sure sequence not clear in DEL funciton.
5842+
5843+ MakeOutgoingFrame(pOutBuffer2, &FrameLen,
5844+ sizeof(FRAME_BAR), &FrameBar,
5845+ END_OF_ARGS);
5846+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer2, FrameLen);
5847+ MlmeFreeMemory(pAd, pOutBuffer2);
5848+ DBGPRINT(RT_DEBUG_TRACE,("BA - MlmeDELBAAction() . Send BAR to refresh peer reordering buffer \n"));
5849+
5850+ // SEND DELBA FRAME
5851+ FrameLen = 0;
5852+#ifdef CONFIG_STA_SUPPORT
5853+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
5854+ {
5855+ if (ADHOC_ON(pAd))
5856+ ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
5857+ else
5858+ ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->MacTab.Content[pInfo->Wcid].Addr);
5859+ }
5860+#endif // CONFIG_STA_SUPPORT //
5861+ Frame.Category = CATEGORY_BA;
5862+ Frame.Action = DELBA;
5863+ Frame.DelbaParm.Initiator = pInfo->Initiator;
5864+ Frame.DelbaParm.TID = pInfo->TID;
5865+ Frame.ReasonCode = 39; // Time Out
5866+ *(USHORT *)(&Frame.DelbaParm) = cpu2le16(*(USHORT *)(&Frame.DelbaParm));
5867+ Frame.ReasonCode = cpu2le16(Frame.ReasonCode);
5868+
5869+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
5870+ sizeof(FRAME_DELBA_REQ), &Frame,
5871+ END_OF_ARGS);
5872+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
5873+ MlmeFreeMemory(pAd, pOutBuffer);
5874+ DBGPRINT(RT_DEBUG_TRACE, ("BA - MlmeDELBAAction() . 3 DELBA sent. Initiator(%d)\n", pInfo->Initiator));
5875+ }
5876+}
5877+#endif // DOT11_N_SUPPORT //
5878+
5879+VOID MlmeQOSAction(
5880+ IN PRTMP_ADAPTER pAd,
5881+ IN MLME_QUEUE_ELEM *Elem)
5882+{
5883+}
5884+
5885+VOID MlmeDLSAction(
5886+ IN PRTMP_ADAPTER pAd,
5887+ IN MLME_QUEUE_ELEM *Elem)
5888+{
5889+}
5890+
5891+VOID MlmeInvalidAction(
5892+ IN PRTMP_ADAPTER pAd,
5893+ IN MLME_QUEUE_ELEM *Elem)
5894+{
5895+ //PUCHAR pOutBuffer = NULL;
5896+ //Return the receiving frame except the MSB of category filed set to 1. 7.3.1.11
5897+}
5898+
5899+VOID PeerQOSAction(
5900+ IN PRTMP_ADAPTER pAd,
5901+ IN MLME_QUEUE_ELEM *Elem)
5902+{
5903+}
5904+
5905+#ifdef QOS_DLS_SUPPORT
5906+VOID PeerDLSAction(
5907+ IN PRTMP_ADAPTER pAd,
5908+ IN MLME_QUEUE_ELEM *Elem)
5909+{
5910+ UCHAR Action = Elem->Msg[LENGTH_802_11+1];
5911+
5912+ switch(Action)
5913+ {
5914+ case ACTION_DLS_REQUEST:
5915+#ifdef CONFIG_STA_SUPPORT
5916+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
5917+ PeerDlsReqAction(pAd, Elem);
5918+#endif // CONFIG_STA_SUPPORT //
5919+ break;
5920+
5921+ case ACTION_DLS_RESPONSE:
5922+#ifdef CONFIG_STA_SUPPORT
5923+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
5924+ PeerDlsRspAction(pAd, Elem);
5925+#endif // CONFIG_STA_SUPPORT //
5926+ break;
5927+
5928+ case ACTION_DLS_TEARDOWN:
5929+#ifdef CONFIG_STA_SUPPORT
5930+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
5931+ PeerDlsTearDownAction(pAd, Elem);
5932+#endif // CONFIG_STA_SUPPORT //
5933+ break;
5934+ }
5935+}
5936+#endif // QOS_DLS_SUPPORT //
5937+
5938+#ifdef DOT11_N_SUPPORT
5939+VOID PeerBAAction(
5940+ IN PRTMP_ADAPTER pAd,
5941+ IN MLME_QUEUE_ELEM *Elem)
5942+{
5943+ UCHAR Action = Elem->Msg[LENGTH_802_11+1];
5944+
5945+ switch(Action)
5946+ {
5947+ case ADDBA_REQ:
5948+ PeerAddBAReqAction(pAd,Elem);
5949+ break;
5950+ case ADDBA_RESP:
5951+ PeerAddBARspAction(pAd,Elem);
5952+ break;
5953+ case DELBA:
5954+ PeerDelBAAction(pAd,Elem);
5955+ break;
5956+ }
5957+}
5958+
5959+
5960+#ifdef DOT11N_DRAFT3
5961+
5962+#ifdef CONFIG_STA_SUPPORT
5963+VOID StaPublicAction(
5964+ IN PRTMP_ADAPTER pAd,
5965+ IN UCHAR Bss2040Coexist)
5966+{
5967+ BSS_2040_COEXIST_IE BssCoexist;
5968+ MLME_SCAN_REQ_STRUCT ScanReq;
5969+
5970+ BssCoexist.word = Bss2040Coexist;
5971+ // AP asks Station to return a 20/40 BSS Coexistence mgmt frame. So we first starts a scan, then send back 20/40 BSS Coexistence mgmt frame
5972+ if ((BssCoexist.field.InfoReq == 1) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SCAN_2040)))
5973+ {
5974+ // Clear record first. After scan , will update those bit and send back to transmiter.
5975+ pAd->CommonCfg.BSSCoexist2040.field.InfoReq = 1;
5976+ pAd->CommonCfg.BSSCoexist2040.field.Intolerant40 = 0;
5977+ pAd->CommonCfg.BSSCoexist2040.field.BSS20WidthReq = 0;
5978+ // Fill out stuff for scan request
5979+ ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_2040_BSS_COEXIST);
5980+ MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
5981+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
5982+ }
5983+}
5984+
5985+
5986+/*
5987+Description : Build Intolerant Channel Rerpot from Trigger event table.
5988+return : how many bytes copied.
5989+*/
5990+ULONG BuildIntolerantChannelRep(
5991+ IN PRTMP_ADAPTER pAd,
5992+ IN PUCHAR pDest)
5993+{
5994+ ULONG FrameLen = 0;
5995+ ULONG ReadOffset = 0;
5996+ UCHAR i;
5997+ UCHAR LastRegClass = 0xff;
5998+ PUCHAR pLen;
5999+
6000+ for ( i = 0;i < MAX_TRIGGER_EVENT;i++)
6001+ {
6002+ if (pAd->CommonCfg.TriggerEventTab.EventA[i].bValid == TRUE)
6003+ {
6004+ if (pAd->CommonCfg.TriggerEventTab.EventA[i].RegClass == LastRegClass)
6005+ {
6006+ *(pDest + ReadOffset) = (UCHAR)pAd->CommonCfg.TriggerEventTab.EventA[i].Channel;
6007+ *pLen++;
6008+ ReadOffset++;
6009+ FrameLen++;
6010+ }
6011+ else
6012+ {
6013+ *(pDest + ReadOffset) = IE_2040_BSS_INTOLERANT_REPORT; // IE
6014+ *(pDest + ReadOffset + 1) = 2; // Len = RegClass byte + channel byte.
6015+ pLen = pDest + ReadOffset + 1;
6016+ LastRegClass = pAd->CommonCfg.TriggerEventTab.EventA[i].RegClass;
6017+ *(pDest + ReadOffset + 2) = LastRegClass; // Len = RegClass byte + channel byte.
6018+ *(pDest + ReadOffset + 3) = (UCHAR)pAd->CommonCfg.TriggerEventTab.EventA[i].Channel;
6019+ FrameLen += 4;
6020+ ReadOffset += 4;
6021+ }
6022+
6023+ }
6024+ }
6025+ return FrameLen;
6026+}
6027+
6028+
6029+/*
6030+Description : Send 20/40 BSS Coexistence Action frame If one trigger event is triggered.
6031+*/
6032+VOID Send2040CoexistAction(
6033+ IN PRTMP_ADAPTER pAd,
6034+ IN UCHAR Wcid,
6035+ IN BOOLEAN bAddIntolerantCha)
6036+{
6037+ PUCHAR pOutBuffer = NULL;
6038+ NDIS_STATUS NStatus;
6039+ FRAME_ACTION_HDR Frame;
6040+ ULONG FrameLen;
6041+ ULONG IntolerantChaRepLen;
6042+
6043+ IntolerantChaRepLen = 0;
6044+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
6045+ if(NStatus != NDIS_STATUS_SUCCESS)
6046+ {
6047+ DBGPRINT(RT_DEBUG_ERROR,("ACT - Send2040CoexistAction() allocate memory failed \n"));
6048+ return;
6049+ }
6050+ ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[Wcid].Addr, pAd->CommonCfg.Bssid);
6051+ Frame.Category = CATEGORY_PUBLIC;
6052+ Frame.Action = ACTION_BSS_2040_COEXIST;
6053+
6054+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
6055+ sizeof(FRAME_ACTION_HDR), &Frame,
6056+ END_OF_ARGS);
6057+
6058+ *(pOutBuffer + FrameLen) = pAd->CommonCfg.BSSCoexist2040.word;
6059+ FrameLen++;
6060+
6061+ if (bAddIntolerantCha == TRUE)
6062+ IntolerantChaRepLen = BuildIntolerantChannelRep(pAd, pOutBuffer + FrameLen);
6063+
6064+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen + IntolerantChaRepLen);
6065+ DBGPRINT(RT_DEBUG_ERROR,("ACT - Send2040CoexistAction( BSSCoexist2040 = 0x%x ) \n", pAd->CommonCfg.BSSCoexist2040.word));
6066+
6067+}
6068+
6069+
6070+/*
6071+ ==========================================================================
6072+ Description:
6073+ After scan, Update 20/40 BSS Coexistence IE and send out.
6074+ According to 802.11n D3.03 11.14.10
6075+
6076+ Parameters:
6077+ ==========================================================================
6078+ */
6079+VOID Update2040CoexistFrameAndNotify(
6080+ IN PRTMP_ADAPTER pAd,
6081+ IN UCHAR Wcid,
6082+ IN BOOLEAN bAddIntolerantCha)
6083+{
6084+ BSS_2040_COEXIST_IE OldValue;
6085+
6086+ OldValue.word = pAd->CommonCfg.BSSCoexist2040.word;
6087+ if ((pAd->CommonCfg.TriggerEventTab.EventANo > 0) || (pAd->CommonCfg.TriggerEventTab.EventBCountDown > 0))
6088+ pAd->CommonCfg.BSSCoexist2040.field.BSS20WidthReq = 1;
6089+
6090+ // Need to check !!!!
6091+ // How STA will set Intolerant40 if implementation dependent. Now we don't set this bit first.!!!!!
6092+ // So Only check BSS20WidthReq change.
6093+ if (OldValue.field.BSS20WidthReq != pAd->CommonCfg.BSSCoexist2040.field.BSS20WidthReq)
6094+ {
6095+ Send2040CoexistAction(pAd, Wcid, bAddIntolerantCha);
6096+ }
6097+}
6098+#endif // CONFIG_STA_SUPPORT //
6099+
6100+
6101+BOOLEAN ChannelSwitchSanityCheck(
6102+ IN PRTMP_ADAPTER pAd,
6103+ IN UCHAR Wcid,
6104+ IN UCHAR NewChannel,
6105+ IN UCHAR Secondary)
6106+{
6107+ UCHAR i;
6108+
6109+ if (Wcid >= MAX_LEN_OF_MAC_TABLE)
6110+ return FALSE;
6111+
6112+ if ((NewChannel > 7) && (Secondary == 1))
6113+ return FALSE;
6114+
6115+ if ((NewChannel < 5) && (Secondary == 3))
6116+ return FALSE;
6117+
6118+ // 0. Check if new channel is in the channellist.
6119+ for (i = 0;i < pAd->ChannelListNum;i++)
6120+ {
6121+ if (pAd->ChannelList[i].Channel == NewChannel)
6122+ {
6123+ break;
6124+ }
6125+ }
6126+
6127+ if (i == pAd->ChannelListNum)
6128+ return FALSE;
6129+
6130+ return TRUE;
6131+}
6132+
6133+
6134+VOID ChannelSwitchAction(
6135+ IN PRTMP_ADAPTER pAd,
6136+ IN UCHAR Wcid,
6137+ IN UCHAR NewChannel,
6138+ IN UCHAR Secondary)
6139+{
6140+ UCHAR BBPValue = 0;
6141+ ULONG MACValue;
6142+
6143+ DBGPRINT(RT_DEBUG_TRACE,("SPECTRUM - ChannelSwitchAction(NewChannel = %d , Secondary = %d) \n", NewChannel, Secondary));
6144+
6145+ if (ChannelSwitchSanityCheck(pAd, Wcid, NewChannel, Secondary) == FALSE)
6146+ return;
6147+
6148+ // 1. Switches to BW = 20.
6149+ if (Secondary == 0)
6150+ {
6151+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
6152+ BBPValue&= (~0x18);
6153+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
6154+ if (pAd->MACVersion == 0x28600100)
6155+ {
6156+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
6157+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
6158+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
6159+ DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
6160+ }
6161+ pAd->CommonCfg.BBPCurrentBW = BW_20;
6162+ pAd->CommonCfg.Channel = NewChannel;
6163+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
6164+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel,FALSE);
6165+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
6166+ pAd->MacTab.Content[Wcid].HTPhyMode.field.BW = 0;
6167+ DBGPRINT(RT_DEBUG_TRACE, ("!!!20MHz !!! \n" ));
6168+ }
6169+ // 1. Switches to BW = 40 And Station supports BW = 40.
6170+ else if (((Secondary == 1) || (Secondary == 3)) && (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == 1))
6171+ {
6172+ pAd->CommonCfg.Channel = NewChannel;
6173+
6174+ if (Secondary == 1)
6175+ {
6176+ // Secondary above.
6177+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2;
6178+ RTMP_IO_READ32(pAd, TX_BAND_CFG, &MACValue);
6179+ MACValue &= 0xfe;
6180+ RTMP_IO_WRITE32(pAd, TX_BAND_CFG, MACValue);
6181+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
6182+ BBPValue&= (~0x18);
6183+ BBPValue|= (0x10);
6184+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
6185+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPValue);
6186+ BBPValue&= (~0x20);
6187+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPValue);
6188+ DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
6189+ }
6190+ else
6191+ {
6192+ // Secondary below.
6193+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2;
6194+ RTMP_IO_READ32(pAd, TX_BAND_CFG, &MACValue);
6195+ MACValue &= 0xfe;
6196+ MACValue |= 0x1;
6197+ RTMP_IO_WRITE32(pAd, TX_BAND_CFG, MACValue);
6198+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
6199+ BBPValue&= (~0x18);
6200+ BBPValue|= (0x10);
6201+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
6202+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPValue);
6203+ BBPValue&= (~0x20);
6204+ BBPValue|= (0x20);
6205+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPValue);
6206+ DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
6207+ }
6208+ pAd->CommonCfg.BBPCurrentBW = BW_40;
6209+ AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
6210+ AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
6211+ pAd->MacTab.Content[Wcid].HTPhyMode.field.BW = 1;
6212+ }
6213+}
6214+#endif // DOT11N_DRAFT3 //
6215+#endif // DOT11_N_SUPPORT //
6216+
6217+VOID PeerPublicAction(
6218+ IN PRTMP_ADAPTER pAd,
6219+ IN MLME_QUEUE_ELEM *Elem)
6220+{
6221+#ifdef DOT11N_DRAFT3
6222+ UCHAR Action = Elem->Msg[LENGTH_802_11+1];
6223+#endif // DOT11N_DRAFT3 //
6224+
6225+ if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
6226+ return;
6227+
6228+#ifdef DOT11N_DRAFT3
6229+ switch(Action)
6230+ {
6231+ case ACTION_BSS_2040_COEXIST: // Format defined in IEEE 7.4.7a.1 in 11n Draf3.03
6232+ {
6233+ //UCHAR BssCoexist;
6234+ BSS_2040_COEXIST_ELEMENT *pCoexistInfo;
6235+ BSS_2040_COEXIST_IE *pBssCoexistIe;
6236+ BSS_2040_INTOLERANT_CH_REPORT *pIntolerantReport = NULL;
6237+
6238+ if (Elem->MsgLen <= (LENGTH_802_11 + sizeof(BSS_2040_COEXIST_ELEMENT)) )
6239+ {
6240+ DBGPRINT(RT_DEBUG_ERROR, ("ACTION - 20/40 BSS Coexistence Management Frame length too short! len = %ld!\n", Elem->MsgLen));
6241+ break;
6242+ }
6243+ DBGPRINT(RT_DEBUG_TRACE, ("ACTION - 20/40 BSS Coexistence Management action----> \n"));
6244+ hex_dump("CoexistenceMgmtFrame", Elem->Msg, Elem->MsgLen);
6245+
6246+
6247+ pCoexistInfo = (BSS_2040_COEXIST_ELEMENT *) &Elem->Msg[LENGTH_802_11+2];
6248+ //hex_dump("CoexistInfo", (PUCHAR)pCoexistInfo, sizeof(BSS_2040_COEXIST_ELEMENT));
6249+ if (Elem->MsgLen >= (LENGTH_802_11 + sizeof(BSS_2040_COEXIST_ELEMENT) + sizeof(BSS_2040_INTOLERANT_CH_REPORT)))
6250+ {
6251+ pIntolerantReport = (BSS_2040_INTOLERANT_CH_REPORT *)((PUCHAR)pCoexistInfo + sizeof(BSS_2040_COEXIST_ELEMENT));
6252+ }
6253+ //hex_dump("IntolerantReport ", (PUCHAR)pIntolerantReport, sizeof(BSS_2040_INTOLERANT_CH_REPORT));
6254+
6255+ pBssCoexistIe = (BSS_2040_COEXIST_IE *)(&pCoexistInfo->BssCoexistIe);
6256+
6257+#ifdef CONFIG_STA_SUPPORT
6258+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
6259+ {
6260+ if (INFRA_ON(pAd))
6261+ {
6262+ StaPublicAction(pAd, pCoexistInfo);
6263+ }
6264+ }
6265+#endif // CONFIG_STA_SUPPORT //
6266+
6267+ }
6268+ break;
6269+ }
6270+
6271+#endif // DOT11N_DRAFT3 //
6272+
6273+}
6274+
6275+
6276+static VOID ReservedAction(
6277+ IN PRTMP_ADAPTER pAd,
6278+ IN MLME_QUEUE_ELEM *Elem)
6279+{
6280+ UCHAR Category;
6281+
6282+ if (Elem->MsgLen <= LENGTH_802_11)
6283+ {
6284+ return;
6285+ }
6286+
6287+ Category = Elem->Msg[LENGTH_802_11];
6288+ DBGPRINT(RT_DEBUG_TRACE,("Rcv reserved category(%d) Action Frame\n", Category));
6289+ hex_dump("Reserved Action Frame", &Elem->Msg[0], Elem->MsgLen);
6290+}
6291+
6292+VOID PeerRMAction(
6293+ IN PRTMP_ADAPTER pAd,
6294+ IN MLME_QUEUE_ELEM *Elem)
6295+
6296+{
6297+ return;
6298+}
6299+
6300+#ifdef DOT11_N_SUPPORT
6301+static VOID respond_ht_information_exchange_action(
6302+ IN PRTMP_ADAPTER pAd,
6303+ IN MLME_QUEUE_ELEM *Elem)
6304+{
6305+ PUCHAR pOutBuffer = NULL;
6306+ NDIS_STATUS NStatus;
6307+ ULONG FrameLen;
6308+ FRAME_HT_INFO HTINFOframe, *pFrame;
6309+ UCHAR *pAddr;
6310+
6311+
6312+ // 2. Always send back ADDBA Response
6313+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
6314+
6315+ if (NStatus != NDIS_STATUS_SUCCESS)
6316+ {
6317+ DBGPRINT(RT_DEBUG_TRACE,("ACTION - respond_ht_information_exchange_action() allocate memory failed \n"));
6318+ return;
6319+ }
6320+
6321+ // get RA
6322+ pFrame = (FRAME_HT_INFO *) &Elem->Msg[0];
6323+ pAddr = pFrame->Hdr.Addr2;
6324+
6325+ NdisZeroMemory(&HTINFOframe, sizeof(FRAME_HT_INFO));
6326+ // 2-1. Prepare ADDBA Response frame.
6327+#ifdef CONFIG_STA_SUPPORT
6328+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
6329+ {
6330+ if (ADHOC_ON(pAd))
6331+ ActHeaderInit(pAd, &HTINFOframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
6332+ else
6333+ ActHeaderInit(pAd, &HTINFOframe.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAddr);
6334+ }
6335+#endif // CONFIG_STA_SUPPORT //
6336+
6337+ HTINFOframe.Category = CATEGORY_HT;
6338+ HTINFOframe.Action = HT_INFO_EXCHANGE;
6339+ HTINFOframe.HT_Info.Request = 0;
6340+ HTINFOframe.HT_Info.Forty_MHz_Intolerant = pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant;
6341+ HTINFOframe.HT_Info.STA_Channel_Width = pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth;
6342+
6343+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
6344+ sizeof(FRAME_HT_INFO), &HTINFOframe,
6345+ END_OF_ARGS);
6346+
6347+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
6348+ MlmeFreeMemory(pAd, pOutBuffer);
6349+}
6350+
6351+
6352+#ifdef DOT11N_DRAFT3
6353+VOID SendNotifyBWActionFrame(
6354+ IN PRTMP_ADAPTER pAd,
6355+ IN UCHAR Wcid,
6356+ IN UCHAR apidx)
6357+{
6358+ PUCHAR pOutBuffer = NULL;
6359+ NDIS_STATUS NStatus;
6360+ FRAME_ACTION_HDR Frame;
6361+ ULONG FrameLen;
6362+ PUCHAR pAddr1;
6363+
6364+
6365+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
6366+ if(NStatus != NDIS_STATUS_SUCCESS)
6367+ {
6368+ DBGPRINT(RT_DEBUG_ERROR,("ACT - SendNotifyBWAction() allocate memory failed \n"));
6369+ return;
6370+ }
6371+
6372+ if (Wcid == MCAST_WCID)
6373+ pAddr1 = &BROADCAST_ADDR[0];
6374+ else
6375+ pAddr1 = pAd->MacTab.Content[Wcid].Addr;
6376+ ActHeaderInit(pAd, &Frame.Hdr, pAddr1, pAd->ApCfg.MBSSID[apidx].Bssid, pAd->ApCfg.MBSSID[apidx].Bssid);
6377+
6378+ Frame.Category = CATEGORY_HT;
6379+ Frame.Action = NOTIFY_BW_ACTION;
6380+
6381+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
6382+ sizeof(FRAME_ACTION_HDR), &Frame,
6383+ END_OF_ARGS);
6384+
6385+ *(pOutBuffer + FrameLen) = pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth;
6386+ FrameLen++;
6387+
6388+
6389+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
6390+ DBGPRINT(RT_DEBUG_TRACE,("ACT - SendNotifyBWAction(NotifyBW= %d)!\n", pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth));
6391+
6392+}
6393+#endif // DOT11N_DRAFT3 //
6394+
6395+
6396+VOID PeerHTAction(
6397+ IN PRTMP_ADAPTER pAd,
6398+ IN MLME_QUEUE_ELEM *Elem)
6399+{
6400+ UCHAR Action = Elem->Msg[LENGTH_802_11+1];
6401+
6402+ if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
6403+ return;
6404+
6405+ switch(Action)
6406+ {
6407+ case NOTIFY_BW_ACTION:
6408+ DBGPRINT(RT_DEBUG_TRACE,("ACTION - HT Notify Channel bandwidth action----> \n"));
6409+#ifdef CONFIG_STA_SUPPORT
6410+ if(pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
6411+ {
6412+ // Note, this is to patch DIR-1353 AP. When the AP set to Wep, it will use legacy mode. But AP still keeps
6413+ // sending BW_Notify Action frame, and cause us to linkup and linkdown.
6414+ // In legacy mode, don't need to parse HT action frame.
6415+ DBGPRINT(RT_DEBUG_TRACE,("ACTION -Ignore HT Notify Channel BW when link as legacy mode. BW = %d---> \n",
6416+ Elem->Msg[LENGTH_802_11+2] ));
6417+ break;
6418+ }
6419+#endif // CONFIG_STA_SUPPORT //
6420+
6421+ if (Elem->Msg[LENGTH_802_11+2] == 0) // 7.4.8.2. if value is 1, keep the same as supported channel bandwidth.
6422+ pAd->MacTab.Content[Elem->Wcid].HTPhyMode.field.BW = 0;
6423+
6424+ break;
6425+
6426+ case SMPS_ACTION:
6427+ // 7.3.1.25
6428+ DBGPRINT(RT_DEBUG_TRACE,("ACTION - SMPS action----> \n"));
6429+ if (((Elem->Msg[LENGTH_802_11+2]&0x1) == 0))
6430+ {
6431+ pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_ENABLE;
6432+ }
6433+ else if (((Elem->Msg[LENGTH_802_11+2]&0x2) == 0))
6434+ {
6435+ pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_STATIC;
6436+ }
6437+ else
6438+ {
6439+ pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_DYNAMIC;
6440+ }
6441+
6442+ DBGPRINT(RT_DEBUG_TRACE,("Aid(%d) MIMO PS = %d\n", Elem->Wcid, pAd->MacTab.Content[Elem->Wcid].MmpsMode));
6443+ // rt2860c : add something for smps change.
6444+ break;
6445+
6446+ case SETPCO_ACTION:
6447+ break;
6448+
6449+ case MIMO_CHA_MEASURE_ACTION:
6450+ break;
6451+
6452+ case HT_INFO_EXCHANGE:
6453+ {
6454+ HT_INFORMATION_OCTET *pHT_info;
6455+
6456+ pHT_info = (HT_INFORMATION_OCTET *) &Elem->Msg[LENGTH_802_11+2];
6457+ // 7.4.8.10
6458+ DBGPRINT(RT_DEBUG_TRACE,("ACTION - HT Information Exchange action----> \n"));
6459+ if (pHT_info->Request)
6460+ {
6461+ respond_ht_information_exchange_action(pAd, Elem);
6462+ }
6463+ }
6464+ break;
6465+ }
6466+}
6467+
6468+
6469+/*
6470+ ==========================================================================
6471+ Description:
6472+ Retry sending ADDBA Reqest.
6473+
6474+ IRQL = DISPATCH_LEVEL
6475+
6476+ Parametrs:
6477+ p8023Header: if this is already 802.3 format, p8023Header is NULL
6478+
6479+ Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
6480+ FALSE , then continue indicaterx at this moment.
6481+ ==========================================================================
6482+ */
6483+VOID ORIBATimerTimeout(
6484+ IN PRTMP_ADAPTER pAd)
6485+{
6486+ MAC_TABLE_ENTRY *pEntry;
6487+ INT i, total;
6488+// FRAME_BAR FrameBar;
6489+// ULONG FrameLen;
6490+// NDIS_STATUS NStatus;
6491+// PUCHAR pOutBuffer = NULL;
6492+// USHORT Sequence;
6493+ UCHAR TID;
6494+
6495+#ifdef RALINK_ATE
6496+ if (ATE_ON(pAd))
6497+ return;
6498+#endif // RALINK_ATE //
6499+
6500+ total = pAd->MacTab.Size * NUM_OF_TID;
6501+
6502+ for (i = 1; ((i <MAX_LEN_OF_BA_ORI_TABLE) && (total > 0)) ; i++)
6503+ {
6504+ if (pAd->BATable.BAOriEntry[i].ORI_BA_Status == Originator_Done)
6505+ {
6506+ pEntry = &pAd->MacTab.Content[pAd->BATable.BAOriEntry[i].Wcid];
6507+ TID = pAd->BATable.BAOriEntry[i].TID;
6508+
6509+ ASSERT(pAd->BATable.BAOriEntry[i].Wcid < MAX_LEN_OF_MAC_TABLE);
6510+ }
6511+ total --;
6512+ }
6513+}
6514+
6515+
6516+VOID SendRefreshBAR(
6517+ IN PRTMP_ADAPTER pAd,
6518+ IN MAC_TABLE_ENTRY *pEntry)
6519+{
6520+ FRAME_BAR FrameBar;
6521+ ULONG FrameLen;
6522+ NDIS_STATUS NStatus;
6523+ PUCHAR pOutBuffer = NULL;
6524+ USHORT Sequence;
6525+ UCHAR i, TID;
6526+ USHORT idx;
6527+ BA_ORI_ENTRY *pBAEntry;
6528+
6529+ for (i = 0; i <NUM_OF_TID; i++)
6530+ {
6531+ idx = pEntry->BAOriWcidArray[i];
6532+ if (idx == 0)
6533+ {
6534+ continue;
6535+ }
6536+ pBAEntry = &pAd->BATable.BAOriEntry[idx];
6537+
6538+ if (pBAEntry->ORI_BA_Status == Originator_Done)
6539+ {
6540+ TID = pBAEntry->TID;
6541+
6542+ ASSERT(pBAEntry->Wcid < MAX_LEN_OF_MAC_TABLE);
6543+
6544+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
6545+ if(NStatus != NDIS_STATUS_SUCCESS)
6546+ {
6547+ DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() allocate memory failed \n"));
6548+ return;
6549+ }
6550+
6551+ Sequence = pEntry->TxSeq[TID];
6552+
6553+
6554+#ifdef CONFIG_STA_SUPPORT
6555+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
6556+ BarHeaderInit(pAd, &FrameBar, pEntry->Addr, pAd->CurrentAddress);
6557+#endif // CONFIG_STA_SUPPORT //
6558+
6559+ FrameBar.StartingSeq.field.FragNum = 0; // make sure sequence not clear in DEL function.
6560+ FrameBar.StartingSeq.field.StartSeq = Sequence; // make sure sequence not clear in DEL funciton.
6561+ FrameBar.BarControl.TID = TID; // make sure sequence not clear in DEL funciton.
6562+
6563+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
6564+ sizeof(FRAME_BAR), &FrameBar,
6565+ END_OF_ARGS);
6566+ //if (!(CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET)))
6567+ if (1) // Now we always send BAR.
6568+ {
6569+ //MiniportMMRequestUnlock(pAd, 0, pOutBuffer, FrameLen);
6570+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
6571+ //MiniportDataMMRequest(pAd, MapUserPriorityToAccessCategory[TID], pOutBuffer, FrameLen);
6572+ }
6573+ MlmeFreeMemory(pAd, pOutBuffer);
6574+ }
6575+ }
6576+}
6577+#endif // DOT11_N_SUPPORT //
6578+
6579+VOID ActHeaderInit(
6580+ IN PRTMP_ADAPTER pAd,
6581+ IN OUT PHEADER_802_11 pHdr80211,
6582+ IN PUCHAR Addr1,
6583+ IN PUCHAR Addr2,
6584+ IN PUCHAR Addr3)
6585+{
6586+ NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
6587+ pHdr80211->FC.Type = BTYPE_MGMT;
6588+ pHdr80211->FC.SubType = SUBTYPE_ACTION;
6589+
6590+ COPY_MAC_ADDR(pHdr80211->Addr1, Addr1);
6591+ COPY_MAC_ADDR(pHdr80211->Addr2, Addr2);
6592+ COPY_MAC_ADDR(pHdr80211->Addr3, Addr3);
6593+}
6594+
6595+VOID BarHeaderInit(
6596+ IN PRTMP_ADAPTER pAd,
6597+ IN OUT PFRAME_BAR pCntlBar,
6598+ IN PUCHAR pDA,
6599+ IN PUCHAR pSA)
6600+{
6601+// USHORT Duration;
6602+
6603+ NdisZeroMemory(pCntlBar, sizeof(FRAME_BAR));
6604+ pCntlBar->FC.Type = BTYPE_CNTL;
6605+ pCntlBar->FC.SubType = SUBTYPE_BLOCK_ACK_REQ;
6606+ pCntlBar->BarControl.MTID = 0;
6607+ pCntlBar->BarControl.Compressed = 1;
6608+ pCntlBar->BarControl.ACKPolicy = 0;
6609+
6610+
6611+ pCntlBar->Duration = 16 + RTMPCalcDuration(pAd, RATE_1, sizeof(FRAME_BA));
6612+
6613+ COPY_MAC_ADDR(pCntlBar->Addr1, pDA);
6614+ COPY_MAC_ADDR(pCntlBar->Addr2, pSA);
6615+}
6616+
6617+
6618+/*
6619+ ==========================================================================
6620+ Description:
6621+ Insert Category and action code into the action frame.
6622+
6623+ Parametrs:
6624+ 1. frame buffer pointer.
6625+ 2. frame length.
6626+ 3. category code of the frame.
6627+ 4. action code of the frame.
6628+
6629+ Return : None.
6630+ ==========================================================================
6631+ */
6632+VOID InsertActField(
6633+ IN PRTMP_ADAPTER pAd,
6634+ OUT PUCHAR pFrameBuf,
6635+ OUT PULONG pFrameLen,
6636+ IN UINT8 Category,
6637+ IN UINT8 ActCode)
6638+{
6639+ ULONG TempLen;
6640+
6641+ MakeOutgoingFrame( pFrameBuf, &TempLen,
6642+ 1, &Category,
6643+ 1, &ActCode,
6644+ END_OF_ARGS);
6645+
6646+ *pFrameLen = *pFrameLen + TempLen;
6647+
6648+ return;
6649+}
6650--- /dev/null
6651+++ b/drivers/staging/rt3070/common/ba_action.c
6652@@ -0,0 +1,1810 @@
6653+/*
6654+ *************************************************************************
6655+ * Ralink Tech Inc.
6656+ * 5F., No.36, Taiyuan St., Jhubei City,
6657+ * Hsinchu County 302,
6658+ * Taiwan, R.O.C.
6659+ *
6660+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
6661+ *
6662+ * This program is free software; you can redistribute it and/or modify *
6663+ * it under the terms of the GNU General Public License as published by *
6664+ * the Free Software Foundation; either version 2 of the License, or *
6665+ * (at your option) any later version. *
6666+ * *
6667+ * This program is distributed in the hope that it will be useful, *
6668+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
6669+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
6670+ * GNU General Public License for more details. *
6671+ * *
6672+ * You should have received a copy of the GNU General Public License *
6673+ * along with this program; if not, write to the *
6674+ * Free Software Foundation, Inc., *
6675+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
6676+ * *
6677+ *************************************************************************
6678+ */
6679+
6680+
6681+#ifdef DOT11_N_SUPPORT
6682+
6683+#include "../rt_config.h"
6684+
6685+
6686+
6687+#define BA_ORI_INIT_SEQ (pEntry->TxSeq[TID]) //1 // inital sequence number of BA session
6688+
6689+#define ORI_SESSION_MAX_RETRY 8
6690+#define ORI_BA_SESSION_TIMEOUT (2000) // ms
6691+#define REC_BA_SESSION_IDLE_TIMEOUT (1000) // ms
6692+
6693+#define REORDERING_PACKET_TIMEOUT ((100 * HZ)/1000) // system ticks -- 100 ms
6694+#define MAX_REORDERING_PACKET_TIMEOUT ((3000 * HZ)/1000) // system ticks -- 100 ms
6695+
6696+#define RESET_RCV_SEQ (0xFFFF)
6697+
6698+static void ba_mpdu_blk_free(PRTMP_ADAPTER pAd, struct reordering_mpdu *mpdu_blk);
6699+
6700+
6701+BA_ORI_ENTRY *BATableAllocOriEntry(
6702+ IN PRTMP_ADAPTER pAd,
6703+ OUT USHORT *Idx);
6704+
6705+BA_REC_ENTRY *BATableAllocRecEntry(
6706+ IN PRTMP_ADAPTER pAd,
6707+ OUT USHORT *Idx);
6708+
6709+VOID BAOriSessionSetupTimeout(
6710+ IN PVOID SystemSpecific1,
6711+ IN PVOID FunctionContext,
6712+ IN PVOID SystemSpecific2,
6713+ IN PVOID SystemSpecific3);
6714+
6715+VOID BARecSessionIdleTimeout(
6716+ IN PVOID SystemSpecific1,
6717+ IN PVOID FunctionContext,
6718+ IN PVOID SystemSpecific2,
6719+ IN PVOID SystemSpecific3);
6720+
6721+
6722+BUILD_TIMER_FUNCTION(BAOriSessionSetupTimeout);
6723+BUILD_TIMER_FUNCTION(BARecSessionIdleTimeout);
6724+
6725+#define ANNOUNCE_REORDERING_PACKET(_pAd, _mpdu_blk) \
6726+ Announce_Reordering_Packet(_pAd, _mpdu_blk);
6727+
6728+VOID BA_MaxWinSizeReasign(
6729+ IN PRTMP_ADAPTER pAd,
6730+ IN MAC_TABLE_ENTRY *pEntryPeer,
6731+ OUT UCHAR *pWinSize)
6732+{
6733+ UCHAR MaxSize;
6734+
6735+
6736+ if (pAd->MACVersion >= RALINK_2883_VERSION) // 3*3
6737+ {
6738+ if (pAd->MACVersion >= RALINK_3070_VERSION)
6739+ {
6740+ if (pEntryPeer->WepStatus != Ndis802_11EncryptionDisabled)
6741+ MaxSize = 7; // for non-open mode
6742+ else
6743+ MaxSize = 13;
6744+ }
6745+ else
6746+ MaxSize = 31;
6747+ }
6748+ else if (pAd->MACVersion >= RALINK_2880E_VERSION) // 2880 e
6749+ {
6750+ if (pEntryPeer->WepStatus != Ndis802_11EncryptionDisabled)
6751+ MaxSize = 7; // for non-open mode
6752+ else
6753+ MaxSize = 13;
6754+ }
6755+ else
6756+ MaxSize = 7;
6757+
6758+ DBGPRINT(RT_DEBUG_TRACE, ("ba> Win Size = %d, Max Size = %d\n",
6759+ *pWinSize, MaxSize));
6760+
6761+ if ((*pWinSize) > MaxSize)
6762+ {
6763+ DBGPRINT(RT_DEBUG_TRACE, ("ba> reassign max win size from %d to %d\n",
6764+ *pWinSize, MaxSize));
6765+
6766+ *pWinSize = MaxSize;
6767+ }
6768+}
6769+
6770+void Announce_Reordering_Packet(IN PRTMP_ADAPTER pAd,
6771+ IN struct reordering_mpdu *mpdu)
6772+{
6773+ PNDIS_PACKET pPacket;
6774+
6775+ pPacket = mpdu->pPacket;
6776+
6777+ if (mpdu->bAMSDU)
6778+ {
6779+ ASSERT(0);
6780+ BA_Reorder_AMSDU_Annnounce(pAd, pPacket);
6781+ }
6782+ else
6783+ {
6784+ //
6785+ // pass this 802.3 packet to upper layer or forward this packet to WM directly
6786+ //
6787+
6788+#ifdef CONFIG_STA_SUPPORT
6789+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
6790+ ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket, RTMP_GET_PACKET_IF(pPacket));
6791+#endif // CONFIG_STA_SUPPORT //
6792+ }
6793+}
6794+
6795+/*
6796+ * Insert a reordering mpdu into sorted linked list by sequence no.
6797+ */
6798+BOOLEAN ba_reordering_mpdu_insertsorted(struct reordering_list *list, struct reordering_mpdu *mpdu)
6799+{
6800+
6801+ struct reordering_mpdu **ppScan = &list->next;
6802+
6803+ while (*ppScan != NULL)
6804+ {
6805+ if (SEQ_SMALLER((*ppScan)->Sequence, mpdu->Sequence, MAXSEQ))
6806+ {
6807+ ppScan = &(*ppScan)->next;
6808+ }
6809+ else if ((*ppScan)->Sequence == mpdu->Sequence)
6810+ {
6811+ /* give up this duplicated frame */
6812+ return(FALSE);
6813+ }
6814+ else
6815+ {
6816+ /* find position */
6817+ break;
6818+ }
6819+ }
6820+
6821+ mpdu->next = *ppScan;
6822+ *ppScan = mpdu;
6823+ list->qlen++;
6824+ return TRUE;
6825+}
6826+
6827+
6828+/*
6829+ * caller lock critical section if necessary
6830+ */
6831+static inline void ba_enqueue(struct reordering_list *list, struct reordering_mpdu *mpdu_blk)
6832+{
6833+ list->qlen++;
6834+ mpdu_blk->next = list->next;
6835+ list->next = mpdu_blk;
6836+}
6837+
6838+/*
6839+ * caller lock critical section if necessary
6840+ */
6841+static inline struct reordering_mpdu * ba_dequeue(struct reordering_list *list)
6842+{
6843+ struct reordering_mpdu *mpdu_blk = NULL;
6844+
6845+ ASSERT(list);
6846+
6847+ if (list->qlen)
6848+ {
6849+ list->qlen--;
6850+ mpdu_blk = list->next;
6851+ if (mpdu_blk)
6852+ {
6853+ list->next = mpdu_blk->next;
6854+ mpdu_blk->next = NULL;
6855+ }
6856+ }
6857+ return mpdu_blk;
6858+}
6859+
6860+
6861+static inline struct reordering_mpdu *ba_reordering_mpdu_dequeue(struct reordering_list *list)
6862+{
6863+ return(ba_dequeue(list));
6864+}
6865+
6866+
6867+static inline struct reordering_mpdu *ba_reordering_mpdu_probe(struct reordering_list *list)
6868+ {
6869+ ASSERT(list);
6870+
6871+ return(list->next);
6872+ }
6873+
6874+
6875+/*
6876+ * free all resource for reordering mechanism
6877+ */
6878+void ba_reordering_resource_release(PRTMP_ADAPTER pAd)
6879+{
6880+ BA_TABLE *Tab;
6881+ PBA_REC_ENTRY pBAEntry;
6882+ struct reordering_mpdu *mpdu_blk;
6883+ int i;
6884+
6885+ Tab = &pAd->BATable;
6886+
6887+ /* I. release all pending reordering packet */
6888+ NdisAcquireSpinLock(&pAd->BATabLock);
6889+ for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++)
6890+ {
6891+ pBAEntry = &Tab->BARecEntry[i];
6892+ if (pBAEntry->REC_BA_Status != Recipient_NONE)
6893+ {
6894+ while ((mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list)))
6895+ {
6896+ ASSERT(mpdu_blk->pPacket);
6897+ RELEASE_NDIS_PACKET(pAd, mpdu_blk->pPacket, NDIS_STATUS_FAILURE);
6898+ ba_mpdu_blk_free(pAd, mpdu_blk);
6899+ }
6900+ }
6901+ }
6902+ NdisReleaseSpinLock(&pAd->BATabLock);
6903+
6904+ ASSERT(pBAEntry->list.qlen == 0);
6905+ /* II. free memory of reordering mpdu table */
6906+ NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock);
6907+ os_free_mem(pAd, pAd->mpdu_blk_pool.mem);
6908+ NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock);
6909+}
6910+
6911+
6912+
6913+/*
6914+ * Allocate all resource for reordering mechanism
6915+ */
6916+BOOLEAN ba_reordering_resource_init(PRTMP_ADAPTER pAd, int num)
6917+{
6918+ int i;
6919+ PUCHAR mem;
6920+ struct reordering_mpdu *mpdu_blk;
6921+ struct reordering_list *freelist;
6922+
6923+ /* allocate spinlock */
6924+ NdisAllocateSpinLock(&pAd->mpdu_blk_pool.lock);
6925+
6926+ /* initialize freelist */
6927+ freelist = &pAd->mpdu_blk_pool.freelist;
6928+ freelist->next = NULL;
6929+ freelist->qlen = 0;
6930+
6931+ DBGPRINT(RT_DEBUG_TRACE, ("Allocate %d memory for BA reordering\n", (UINT32)(num*sizeof(struct reordering_mpdu))));
6932+
6933+ /* allocate number of mpdu_blk memory */
6934+ os_alloc_mem(pAd, (PUCHAR *)&mem, (num*sizeof(struct reordering_mpdu)));
6935+
6936+ pAd->mpdu_blk_pool.mem = mem;
6937+
6938+ if (mem == NULL)
6939+ {
6940+ DBGPRINT(RT_DEBUG_ERROR, ("Can't Allocate Memory for BA Reordering\n"));
6941+ return(FALSE);
6942+ }
6943+
6944+ /* build mpdu_blk free list */
6945+ for (i=0; i<num; i++)
6946+ {
6947+ /* get mpdu_blk */
6948+ mpdu_blk = (struct reordering_mpdu *) mem;
6949+ /* initial mpdu_blk */
6950+ NdisZeroMemory(mpdu_blk, sizeof(struct reordering_mpdu));
6951+ /* next mpdu_blk */
6952+ mem += sizeof(struct reordering_mpdu);
6953+ /* insert mpdu_blk into freelist */
6954+ ba_enqueue(freelist, mpdu_blk);
6955+ }
6956+
6957+ return(TRUE);
6958+}
6959+
6960+//static int blk_count=0; // sample take off, no use
6961+
6962+static struct reordering_mpdu *ba_mpdu_blk_alloc(PRTMP_ADAPTER pAd)
6963+{
6964+ struct reordering_mpdu *mpdu_blk;
6965+
6966+ NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock);
6967+ mpdu_blk = ba_dequeue(&pAd->mpdu_blk_pool.freelist);
6968+ if (mpdu_blk)
6969+ {
6970+// blk_count++;
6971+ /* reset mpdu_blk */
6972+ NdisZeroMemory(mpdu_blk, sizeof(struct reordering_mpdu));
6973+ }
6974+ NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock);
6975+ return mpdu_blk;
6976+}
6977+
6978+static void ba_mpdu_blk_free(PRTMP_ADAPTER pAd, struct reordering_mpdu *mpdu_blk)
6979+{
6980+ ASSERT(mpdu_blk);
6981+
6982+ NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock);
6983+// blk_count--;
6984+ ba_enqueue(&pAd->mpdu_blk_pool.freelist, mpdu_blk);
6985+ NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock);
6986+}
6987+
6988+
6989+static USHORT ba_indicate_reordering_mpdus_in_order(
6990+ IN PRTMP_ADAPTER pAd,
6991+ IN PBA_REC_ENTRY pBAEntry,
6992+ IN USHORT StartSeq)
6993+{
6994+ struct reordering_mpdu *mpdu_blk;
6995+ USHORT LastIndSeq = RESET_RCV_SEQ;
6996+
6997+ NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
6998+
6999+ while ((mpdu_blk = ba_reordering_mpdu_probe(&pBAEntry->list)))
7000+ {
7001+ /* find in-order frame */
7002+ if (!SEQ_STEPONE(mpdu_blk->Sequence, StartSeq, MAXSEQ))
7003+ {
7004+ break;
7005+ }
7006+ /* dequeue in-order frame from reodering list */
7007+ mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list);
7008+ /* pass this frame up */
7009+ ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
7010+ /* move to next sequence */
7011+ StartSeq = mpdu_blk->Sequence;
7012+ LastIndSeq = StartSeq;
7013+ /* free mpdu_blk */
7014+ ba_mpdu_blk_free(pAd, mpdu_blk);
7015+ }
7016+
7017+ NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
7018+
7019+ /* update last indicated sequence */
7020+ return LastIndSeq;
7021+}
7022+
7023+static void ba_indicate_reordering_mpdus_le_seq(
7024+ IN PRTMP_ADAPTER pAd,
7025+ IN PBA_REC_ENTRY pBAEntry,
7026+ IN USHORT Sequence)
7027+{
7028+ struct reordering_mpdu *mpdu_blk;
7029+
7030+ NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
7031+ while ((mpdu_blk = ba_reordering_mpdu_probe(&pBAEntry->list)))
7032+ {
7033+ /* find in-order frame */
7034+ if ((mpdu_blk->Sequence == Sequence) || SEQ_SMALLER(mpdu_blk->Sequence, Sequence, MAXSEQ))
7035+ {
7036+ /* dequeue in-order frame from reodering list */
7037+ mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list);
7038+ /* pass this frame up */
7039+ ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
7040+ /* free mpdu_blk */
7041+ ba_mpdu_blk_free(pAd, mpdu_blk);
7042+ }
7043+ else
7044+ {
7045+ break;
7046+ }
7047+ }
7048+ NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
7049+}
7050+
7051+
7052+static void ba_refresh_reordering_mpdus(
7053+ IN PRTMP_ADAPTER pAd,
7054+ PBA_REC_ENTRY pBAEntry)
7055+{
7056+ struct reordering_mpdu *mpdu_blk;
7057+
7058+ NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
7059+
7060+ /* dequeue in-order frame from reodering list */
7061+ while ((mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list)))
7062+ {
7063+ /* pass this frame up */
7064+ ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
7065+
7066+ pBAEntry->LastIndSeq = mpdu_blk->Sequence;
7067+ ba_mpdu_blk_free(pAd, mpdu_blk);
7068+
7069+ /* update last indicated sequence */
7070+ }
7071+ ASSERT(pBAEntry->list.qlen == 0);
7072+ pBAEntry->LastIndSeq = RESET_RCV_SEQ;
7073+ NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
7074+}
7075+
7076+
7077+//static
7078+void ba_flush_reordering_timeout_mpdus(
7079+ IN PRTMP_ADAPTER pAd,
7080+ IN PBA_REC_ENTRY pBAEntry,
7081+ IN ULONG Now32)
7082+
7083+{
7084+ USHORT Sequence;
7085+
7086+// if ((RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+REORDERING_PACKET_TIMEOUT)) &&
7087+// (pBAEntry->list.qlen > ((pBAEntry->BAWinSize*7)/8))) //||
7088+// (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(10*REORDERING_PACKET_TIMEOUT))) &&
7089+// (pBAEntry->list.qlen > (pBAEntry->BAWinSize/8)))
7090+ if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(MAX_REORDERING_PACKET_TIMEOUT/6)))
7091+ &&(pBAEntry->list.qlen > 1)
7092+ )
7093+ {
7094+ DBGPRINT(RT_DEBUG_TRACE,("timeout[%d] (%08lx-%08lx = %d > %d): %x, flush all!\n ", pBAEntry->list.qlen, Now32, (pBAEntry->LastIndSeqAtTimer),
7095+ (int)((long) Now32 - (long)(pBAEntry->LastIndSeqAtTimer)), MAX_REORDERING_PACKET_TIMEOUT,
7096+ pBAEntry->LastIndSeq));
7097+ ba_refresh_reordering_mpdus(pAd, pBAEntry);
7098+ pBAEntry->LastIndSeqAtTimer = Now32;
7099+ }
7100+ else
7101+ if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(REORDERING_PACKET_TIMEOUT)))
7102+ && (pBAEntry->list.qlen > 0)
7103+ )
7104+ {
7105+// printk("timeout[%d] (%lx-%lx = %d > %d): %x, ", pBAEntry->list.qlen, Now32, (pBAEntry->LastIndSeqAtTimer),
7106+// (int)((long) Now32 - (long)(pBAEntry->LastIndSeqAtTimer)), REORDERING_PACKET_TIMEOUT,
7107+// pBAEntry->LastIndSeq);
7108+ //
7109+ // force LastIndSeq to shift to LastIndSeq+1
7110+ //
7111+ Sequence = (pBAEntry->LastIndSeq+1) & MAXSEQ;
7112+ ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, Sequence);
7113+ pBAEntry->LastIndSeqAtTimer = Now32;
7114+ pBAEntry->LastIndSeq = Sequence;
7115+ //
7116+ // indicate in-order mpdus
7117+ //
7118+ Sequence = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, Sequence);
7119+ if (Sequence != RESET_RCV_SEQ)
7120+ {
7121+ pBAEntry->LastIndSeq = Sequence;
7122+ }
7123+
7124+ //printk("%x, flush one!\n", pBAEntry->LastIndSeq);
7125+
7126+ }
7127+}
7128+
7129+
7130+/*
7131+ * generate ADDBA request to
7132+ * set up BA agreement
7133+ */
7134+VOID BAOriSessionSetUp(
7135+ IN PRTMP_ADAPTER pAd,
7136+ IN MAC_TABLE_ENTRY *pEntry,
7137+ IN UCHAR TID,
7138+ IN USHORT TimeOut,
7139+ IN ULONG DelayTime,
7140+ IN BOOLEAN isForced)
7141+
7142+{
7143+ //MLME_ADDBA_REQ_STRUCT AddbaReq;
7144+ BA_ORI_ENTRY *pBAEntry = NULL;
7145+ USHORT Idx;
7146+ BOOLEAN Cancelled;
7147+
7148+ if ((pAd->CommonCfg.BACapability.field.AutoBA != TRUE) && (isForced == FALSE))
7149+ return;
7150+
7151+ // if this entry is limited to use legacy tx mode, it doesn't generate BA.
7152+ if (RTMPStaFixedTxMode(pAd, pEntry) != FIXED_TXMODE_HT)
7153+ return;
7154+
7155+ if ((pEntry->BADeclineBitmap & (1<<TID)) && (isForced == FALSE))
7156+ {
7157+ // try again after 3 secs
7158+ DelayTime = 3000;
7159+// printk("DeCline BA from Peer\n");
7160+// return;
7161+ }
7162+
7163+
7164+ Idx = pEntry->BAOriWcidArray[TID];
7165+ if (Idx == 0)
7166+ {
7167+ // allocate a BA session
7168+ pBAEntry = BATableAllocOriEntry(pAd, &Idx);
7169+ if (pBAEntry == NULL)
7170+ {
7171+ DBGPRINT(RT_DEBUG_TRACE,("ADDBA - MlmeADDBAAction() allocate BA session failed \n"));
7172+ return;
7173+ }
7174+ }
7175+ else
7176+ {
7177+ pBAEntry =&pAd->BATable.BAOriEntry[Idx];
7178+ }
7179+
7180+ if (pBAEntry->ORI_BA_Status >= Originator_WaitRes)
7181+ {
7182+ return;
7183+ }
7184+
7185+ pEntry->BAOriWcidArray[TID] = Idx;
7186+
7187+ // Initialize BA session
7188+ pBAEntry->ORI_BA_Status = Originator_WaitRes;
7189+ pBAEntry->Wcid = pEntry->Aid;
7190+ pBAEntry->BAWinSize = pAd->CommonCfg.BACapability.field.RxBAWinLimit;
7191+ pBAEntry->Sequence = BA_ORI_INIT_SEQ;
7192+ pBAEntry->Token = 1; // (2008-01-21) Jan Lee recommends it - this token can't be 0
7193+ pBAEntry->TID = TID;
7194+ pBAEntry->TimeOutValue = TimeOut;
7195+ pBAEntry->pAdapter = pAd;
7196+
7197+ DBGPRINT(RT_DEBUG_TRACE,("Send AddBA to %02x:%02x:%02x:%02x:%02x:%02x Tid:%d isForced:%d Wcid:%d\n"
7198+ ,pEntry->Addr[0],pEntry->Addr[1],pEntry->Addr[2]
7199+ ,pEntry->Addr[3],pEntry->Addr[4],pEntry->Addr[5]
7200+ ,TID,isForced,pEntry->Aid));
7201+
7202+ if (!(pEntry->TXBAbitmap & (1<<TID)))
7203+ {
7204+ RTMPInitTimer(pAd, &pBAEntry->ORIBATimer, GET_TIMER_FUNCTION(BAOriSessionSetupTimeout), pBAEntry, FALSE);
7205+ }
7206+ else
7207+ RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
7208+
7209+ // set timer to send ADDBA request
7210+ RTMPSetTimer(&pBAEntry->ORIBATimer, DelayTime);
7211+}
7212+
7213+VOID BAOriSessionAdd(
7214+ IN PRTMP_ADAPTER pAd,
7215+ IN MAC_TABLE_ENTRY *pEntry,
7216+ IN PFRAME_ADDBA_RSP pFrame)
7217+{
7218+ BA_ORI_ENTRY *pBAEntry = NULL;
7219+ BOOLEAN Cancelled;
7220+ UCHAR TID;
7221+ USHORT Idx;
7222+ PUCHAR pOutBuffer2 = NULL;
7223+ NDIS_STATUS NStatus;
7224+ ULONG FrameLen;
7225+ FRAME_BAR FrameBar;
7226+
7227+ TID = pFrame->BaParm.TID;
7228+ Idx = pEntry->BAOriWcidArray[TID];
7229+ pBAEntry =&pAd->BATable.BAOriEntry[Idx];
7230+
7231+ // Start fill in parameters.
7232+ if ((Idx !=0) && (pBAEntry->TID == TID) && (pBAEntry->ORI_BA_Status == Originator_WaitRes))
7233+ {
7234+ pBAEntry->BAWinSize = min(pBAEntry->BAWinSize, ((UCHAR)pFrame->BaParm.BufSize));
7235+ BA_MaxWinSizeReasign(pAd, pEntry, &pBAEntry->BAWinSize);
7236+
7237+ pBAEntry->TimeOutValue = pFrame->TimeOutValue;
7238+ pBAEntry->ORI_BA_Status = Originator_Done;
7239+ // reset sequence number
7240+ pBAEntry->Sequence = BA_ORI_INIT_SEQ;
7241+ // Set Bitmap flag.
7242+ pEntry->TXBAbitmap |= (1<<TID);
7243+ RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
7244+
7245+ pBAEntry->ORIBATimer.TimerValue = 0; //pFrame->TimeOutValue;
7246+
7247+ DBGPRINT(RT_DEBUG_TRACE,("%s : TXBAbitmap = %x, BAWinSize = %d, TimeOut = %ld\n", __FUNCTION__, pEntry->TXBAbitmap,
7248+ pBAEntry->BAWinSize, pBAEntry->ORIBATimer.TimerValue));
7249+
7250+ // SEND BAR ;
7251+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2); //Get an unused nonpaged memory
7252+ if (NStatus != NDIS_STATUS_SUCCESS)
7253+ {
7254+ DBGPRINT(RT_DEBUG_TRACE,("BA - BAOriSessionAdd() allocate memory failed \n"));
7255+ return;
7256+ }
7257+
7258+
7259+#ifdef CONFIG_STA_SUPPORT
7260+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
7261+ BarHeaderInit(pAd, &FrameBar, pAd->MacTab.Content[pBAEntry->Wcid].Addr, pAd->CurrentAddress);
7262+#endif // CONFIG_STA_SUPPORT //
7263+
7264+ FrameBar.StartingSeq.field.FragNum = 0; // make sure sequence not clear in DEL function.
7265+ FrameBar.StartingSeq.field.StartSeq = pBAEntry->Sequence; // make sure sequence not clear in DEL funciton.
7266+ FrameBar.BarControl.TID = pBAEntry->TID; // make sure sequence not clear in DEL funciton.
7267+ MakeOutgoingFrame(pOutBuffer2, &FrameLen,
7268+ sizeof(FRAME_BAR), &FrameBar,
7269+ END_OF_ARGS);
7270+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer2, FrameLen);
7271+ MlmeFreeMemory(pAd, pOutBuffer2);
7272+
7273+
7274+ if (pBAEntry->ORIBATimer.TimerValue)
7275+ RTMPSetTimer(&pBAEntry->ORIBATimer, pBAEntry->ORIBATimer.TimerValue); // in mSec
7276+ }
7277+}
7278+
7279+BOOLEAN BARecSessionAdd(
7280+ IN PRTMP_ADAPTER pAd,
7281+ IN MAC_TABLE_ENTRY *pEntry,
7282+ IN PFRAME_ADDBA_REQ pFrame)
7283+{
7284+ BA_REC_ENTRY *pBAEntry = NULL;
7285+ BOOLEAN Status = TRUE;
7286+ BOOLEAN Cancelled;
7287+ USHORT Idx;
7288+ UCHAR TID;
7289+ UCHAR BAWinSize;
7290+ //UINT32 Value;
7291+ //UINT offset;
7292+
7293+
7294+ ASSERT(pEntry);
7295+
7296+ // find TID
7297+ TID = pFrame->BaParm.TID;
7298+
7299+ BAWinSize = min(((UCHAR)pFrame->BaParm.BufSize), (UCHAR)pAd->CommonCfg.BACapability.field.RxBAWinLimit);
7300+
7301+ // Intel patch
7302+ if (BAWinSize == 0)
7303+ {
7304+ BAWinSize = 64;
7305+ }
7306+
7307+ Idx = pEntry->BARecWcidArray[TID];
7308+
7309+
7310+ if (Idx == 0)
7311+ {
7312+ pBAEntry = BATableAllocRecEntry(pAd, &Idx);
7313+ }
7314+ else
7315+ {
7316+ pBAEntry = &pAd->BATable.BARecEntry[Idx];
7317+ // flush all pending reordering mpdus
7318+ ba_refresh_reordering_mpdus(pAd, pBAEntry);
7319+ }
7320+
7321+ DBGPRINT(RT_DEBUG_TRACE,("%s(%ld): Idx = %d, BAWinSize(req %d) = %d\n", __FUNCTION__, pAd->BATable.numAsRecipient, Idx,
7322+ pFrame->BaParm.BufSize, BAWinSize));
7323+
7324+ // Start fill in parameters.
7325+ if (pBAEntry != NULL)
7326+ {
7327+ ASSERT(pBAEntry->list.qlen == 0);
7328+
7329+ pBAEntry->REC_BA_Status = Recipient_HandleRes;
7330+ pBAEntry->BAWinSize = BAWinSize;
7331+ pBAEntry->Wcid = pEntry->Aid;
7332+ pBAEntry->TID = TID;
7333+ pBAEntry->TimeOutValue = pFrame->TimeOutValue;
7334+ pBAEntry->REC_BA_Status = Recipient_Accept;
7335+ // initial sequence number
7336+ pBAEntry->LastIndSeq = RESET_RCV_SEQ; //pFrame->BaStartSeq.field.StartSeq;
7337+
7338+ printk("Start Seq = %08x\n", pFrame->BaStartSeq.field.StartSeq);
7339+
7340+ if (pEntry->RXBAbitmap & (1<<TID))
7341+ {
7342+ RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled);
7343+ }
7344+ else
7345+ {
7346+ RTMPInitTimer(pAd, &pBAEntry->RECBATimer, GET_TIMER_FUNCTION(BARecSessionIdleTimeout), pBAEntry, TRUE);
7347+ }
7348+
7349+ // Set Bitmap flag.
7350+ pEntry->RXBAbitmap |= (1<<TID);
7351+ pEntry->BARecWcidArray[TID] = Idx;
7352+
7353+ pEntry->BADeclineBitmap &= ~(1<<TID);
7354+
7355+ // Set BA session mask in WCID table.
7356+ RT28XX_ADD_BA_SESSION_TO_ASIC(pAd, pEntry->Aid, TID);
7357+
7358+ DBGPRINT(RT_DEBUG_TRACE,("MACEntry[%d]RXBAbitmap = 0x%x. BARecWcidArray=%d\n",
7359+ pEntry->Aid, pEntry->RXBAbitmap, pEntry->BARecWcidArray[TID]));
7360+ }
7361+ else
7362+ {
7363+ Status = FALSE;
7364+ DBGPRINT(RT_DEBUG_TRACE,("Can't Accept ADDBA for %02x:%02x:%02x:%02x:%02x:%02x TID = %d\n",
7365+ PRINT_MAC(pEntry->Addr), TID));
7366+ }
7367+ return(Status);
7368+}
7369+
7370+
7371+BA_REC_ENTRY *BATableAllocRecEntry(
7372+ IN PRTMP_ADAPTER pAd,
7373+ OUT USHORT *Idx)
7374+{
7375+ int i;
7376+ BA_REC_ENTRY *pBAEntry = NULL;
7377+
7378+
7379+ NdisAcquireSpinLock(&pAd->BATabLock);
7380+
7381+ if (pAd->BATable.numAsRecipient >= MAX_BARECI_SESSION)
7382+ {
7383+ printk("BA Recipeint Session (%ld) > %d\n", pAd->BATable.numAsRecipient,
7384+ MAX_BARECI_SESSION);
7385+ goto done;
7386+ }
7387+
7388+ // reserve idx 0 to identify BAWcidArray[TID] as empty
7389+ for (i=1; i < MAX_LEN_OF_BA_REC_TABLE; i++)
7390+ {
7391+ pBAEntry =&pAd->BATable.BARecEntry[i];
7392+ if ((pBAEntry->REC_BA_Status == Recipient_NONE))
7393+ {
7394+ // get one
7395+ pAd->BATable.numAsRecipient++;
7396+ pBAEntry->REC_BA_Status = Recipient_USED;
7397+ *Idx = i;
7398+ break;
7399+ }
7400+ }
7401+
7402+done:
7403+ NdisReleaseSpinLock(&pAd->BATabLock);
7404+ return pBAEntry;
7405+}
7406+
7407+BA_ORI_ENTRY *BATableAllocOriEntry(
7408+ IN PRTMP_ADAPTER pAd,
7409+ OUT USHORT *Idx)
7410+{
7411+ int i;
7412+ BA_ORI_ENTRY *pBAEntry = NULL;
7413+
7414+ NdisAcquireSpinLock(&pAd->BATabLock);
7415+
7416+ if (pAd->BATable.numAsOriginator >= (MAX_LEN_OF_BA_ORI_TABLE))
7417+ {
7418+ goto done;
7419+ }
7420+
7421+ // reserve idx 0 to identify BAWcidArray[TID] as empty
7422+ for (i=1; i<MAX_LEN_OF_BA_ORI_TABLE; i++)
7423+ {
7424+ pBAEntry =&pAd->BATable.BAOriEntry[i];
7425+ if ((pBAEntry->ORI_BA_Status == Originator_NONE))
7426+ {
7427+ // get one
7428+ pAd->BATable.numAsOriginator++;
7429+ pBAEntry->ORI_BA_Status = Originator_USED;
7430+ pBAEntry->pAdapter = pAd;
7431+ *Idx = i;
7432+ break;
7433+ }
7434+ }
7435+
7436+done:
7437+ NdisReleaseSpinLock(&pAd->BATabLock);
7438+ return pBAEntry;
7439+}
7440+
7441+
7442+VOID BATableFreeOriEntry(
7443+ IN PRTMP_ADAPTER pAd,
7444+ IN ULONG Idx)
7445+{
7446+ BA_ORI_ENTRY *pBAEntry = NULL;
7447+ MAC_TABLE_ENTRY *pEntry;
7448+
7449+
7450+ if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_ORI_TABLE))
7451+ return;
7452+
7453+ pBAEntry =&pAd->BATable.BAOriEntry[Idx];
7454+
7455+ if (pBAEntry->ORI_BA_Status != Originator_NONE)
7456+ {
7457+ pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
7458+ pEntry->BAOriWcidArray[pBAEntry->TID] = 0;
7459+
7460+
7461+ NdisAcquireSpinLock(&pAd->BATabLock);
7462+ if (pBAEntry->ORI_BA_Status == Originator_Done)
7463+ {
7464+ pEntry->TXBAbitmap &= (~(1<<(pBAEntry->TID) ));
7465+ DBGPRINT(RT_DEBUG_TRACE, ("BATableFreeOriEntry numAsOriginator= %ld\n", pAd->BATable.numAsRecipient));
7466+ // Erase Bitmap flag.
7467+ }
7468+
7469+ ASSERT(pAd->BATable.numAsOriginator != 0);
7470+
7471+ pAd->BATable.numAsOriginator -= 1;
7472+
7473+ pBAEntry->ORI_BA_Status = Originator_NONE;
7474+ pBAEntry->Token = 0;
7475+ NdisReleaseSpinLock(&pAd->BATabLock);
7476+ }
7477+}
7478+
7479+
7480+VOID BATableFreeRecEntry(
7481+ IN PRTMP_ADAPTER pAd,
7482+ IN ULONG Idx)
7483+{
7484+ BA_REC_ENTRY *pBAEntry = NULL;
7485+ MAC_TABLE_ENTRY *pEntry;
7486+
7487+
7488+ if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_REC_TABLE))
7489+ return;
7490+
7491+ pBAEntry =&pAd->BATable.BARecEntry[Idx];
7492+
7493+ if (pBAEntry->REC_BA_Status != Recipient_NONE)
7494+ {
7495+ pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
7496+ pEntry->BARecWcidArray[pBAEntry->TID] = 0;
7497+
7498+ NdisAcquireSpinLock(&pAd->BATabLock);
7499+
7500+ ASSERT(pAd->BATable.numAsRecipient != 0);
7501+
7502+ pAd->BATable.numAsRecipient -= 1;
7503+
7504+ pBAEntry->REC_BA_Status = Recipient_NONE;
7505+ NdisReleaseSpinLock(&pAd->BATabLock);
7506+ }
7507+}
7508+
7509+
7510+VOID BAOriSessionTearDown(
7511+ IN OUT PRTMP_ADAPTER pAd,
7512+ IN UCHAR Wcid,
7513+ IN UCHAR TID,
7514+ IN BOOLEAN bPassive,
7515+ IN BOOLEAN bForceSend)
7516+{
7517+ ULONG Idx = 0;
7518+ BA_ORI_ENTRY *pBAEntry;
7519+ BOOLEAN Cancelled;
7520+
7521+ if (Wcid >= MAX_LEN_OF_MAC_TABLE)
7522+ {
7523+ return;
7524+ }
7525+
7526+ //
7527+ // Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID).
7528+ //
7529+ Idx = pAd->MacTab.Content[Wcid].BAOriWcidArray[TID];
7530+ if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_ORI_TABLE))
7531+ {
7532+ if (bForceSend == TRUE)
7533+ {
7534+ // force send specified TID DelBA
7535+ MLME_DELBA_REQ_STRUCT DelbaReq;
7536+ MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
7537+
7538+ NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
7539+ NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
7540+
7541+ COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr);
7542+ DelbaReq.Wcid = Wcid;
7543+ DelbaReq.TID = TID;
7544+ DelbaReq.Initiator = ORIGINATOR;
7545+#if 1
7546+ Elem->MsgLen = sizeof(DelbaReq);
7547+ NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
7548+ MlmeDELBAAction(pAd, Elem);
7549+ kfree(Elem);
7550+#else
7551+ MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq);
7552+ RT28XX_MLME_HANDLER(pAd);
7553+#endif
7554+ }
7555+
7556+ return;
7557+ }
7558+
7559+ DBGPRINT(RT_DEBUG_TRACE,("%s===>Wcid=%d.TID=%d \n", __FUNCTION__, Wcid, TID));
7560+
7561+ pBAEntry = &pAd->BATable.BAOriEntry[Idx];
7562+ DBGPRINT(RT_DEBUG_TRACE,("\t===>Idx = %ld, Wcid=%d.TID=%d, ORI_BA_Status = %d \n", Idx, Wcid, TID, pBAEntry->ORI_BA_Status));
7563+ //
7564+ // Prepare DelBA action frame and send to the peer.
7565+ //
7566+ if ((bPassive == FALSE) && (TID == pBAEntry->TID) && (pBAEntry->ORI_BA_Status == Originator_Done))
7567+ {
7568+ MLME_DELBA_REQ_STRUCT DelbaReq;
7569+ MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
7570+
7571+ NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
7572+ NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
7573+
7574+ COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr);
7575+ DelbaReq.Wcid = Wcid;
7576+ DelbaReq.TID = pBAEntry->TID;
7577+ DelbaReq.Initiator = ORIGINATOR;
7578+#if 1
7579+ Elem->MsgLen = sizeof(DelbaReq);
7580+ NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
7581+ MlmeDELBAAction(pAd, Elem);
7582+ kfree(Elem);
7583+#else
7584+ MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq);
7585+ RT28XX_MLME_HANDLER(pAd);
7586+#endif
7587+ }
7588+ RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
7589+ BATableFreeOriEntry(pAd, Idx);
7590+
7591+ if (bPassive)
7592+ {
7593+ //BAOriSessionSetUp(pAd, &pAd->MacTab.Content[Wcid], TID, 0, 10000, TRUE);
7594+ }
7595+}
7596+
7597+VOID BARecSessionTearDown(
7598+ IN OUT PRTMP_ADAPTER pAd,
7599+ IN UCHAR Wcid,
7600+ IN UCHAR TID,
7601+ IN BOOLEAN bPassive)
7602+{
7603+ ULONG Idx = 0;
7604+ BA_REC_ENTRY *pBAEntry;
7605+
7606+ if (Wcid >= MAX_LEN_OF_MAC_TABLE)
7607+ {
7608+ return;
7609+ }
7610+
7611+ //
7612+ // Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID).
7613+ //
7614+ Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
7615+ if (Idx == 0)
7616+ return;
7617+
7618+ DBGPRINT(RT_DEBUG_TRACE,("%s===>Wcid=%d.TID=%d \n", __FUNCTION__, Wcid, TID));
7619+
7620+
7621+ pBAEntry = &pAd->BATable.BARecEntry[Idx];
7622+ DBGPRINT(RT_DEBUG_TRACE,("\t===>Idx = %ld, Wcid=%d.TID=%d, REC_BA_Status = %d \n", Idx, Wcid, TID, pBAEntry->REC_BA_Status));
7623+ //
7624+ // Prepare DelBA action frame and send to the peer.
7625+ //
7626+ if ((TID == pBAEntry->TID) && (pBAEntry->REC_BA_Status == Recipient_Accept))
7627+ {
7628+ MLME_DELBA_REQ_STRUCT DelbaReq;
7629+ BOOLEAN Cancelled;
7630+ MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
7631+ //ULONG offset;
7632+ //UINT32 VALUE;
7633+
7634+ RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled);
7635+
7636+ //
7637+ // 1. Send DELBA Action Frame
7638+ //
7639+ if (bPassive == FALSE)
7640+ {
7641+ NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
7642+ NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
7643+
7644+ COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr);
7645+ DelbaReq.Wcid = Wcid;
7646+ DelbaReq.TID = TID;
7647+ DelbaReq.Initiator = RECIPIENT;
7648+#if 1
7649+ Elem->MsgLen = sizeof(DelbaReq);
7650+ NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
7651+ MlmeDELBAAction(pAd, Elem);
7652+ kfree(Elem);
7653+#else
7654+ MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq);
7655+ RT28XX_MLME_HANDLER(pAd);
7656+#endif
7657+ }
7658+
7659+
7660+ //
7661+ // 2. Free resource of BA session
7662+ //
7663+ // flush all pending reordering mpdus
7664+ ba_refresh_reordering_mpdus(pAd, pBAEntry);
7665+
7666+ NdisAcquireSpinLock(&pAd->BATabLock);
7667+
7668+ // Erase Bitmap flag.
7669+ pBAEntry->LastIndSeq = RESET_RCV_SEQ;
7670+ pBAEntry->BAWinSize = 0;
7671+ // Erase Bitmap flag at software mactable
7672+ pAd->MacTab.Content[Wcid].RXBAbitmap &= (~(1<<(pBAEntry->TID)));
7673+ pAd->MacTab.Content[Wcid].BARecWcidArray[TID] = 0;
7674+
7675+ RT28XX_DEL_BA_SESSION_FROM_ASIC(pAd, Wcid, TID);
7676+
7677+ NdisReleaseSpinLock(&pAd->BATabLock);
7678+
7679+ }
7680+
7681+ BATableFreeRecEntry(pAd, Idx);
7682+}
7683+
7684+VOID BASessionTearDownALL(
7685+ IN OUT PRTMP_ADAPTER pAd,
7686+ IN UCHAR Wcid)
7687+{
7688+ int i;
7689+
7690+ for (i=0; i<NUM_OF_TID; i++)
7691+ {
7692+ BAOriSessionTearDown(pAd, Wcid, i, FALSE, FALSE);
7693+ BARecSessionTearDown(pAd, Wcid, i, FALSE);
7694+ }
7695+}
7696+
7697+
7698+/*
7699+ ==========================================================================
7700+ Description:
7701+ Retry sending ADDBA Reqest.
7702+
7703+ IRQL = DISPATCH_LEVEL
7704+
7705+ Parametrs:
7706+ p8023Header: if this is already 802.3 format, p8023Header is NULL
7707+
7708+ Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
7709+ FALSE , then continue indicaterx at this moment.
7710+ ==========================================================================
7711+ */
7712+VOID BAOriSessionSetupTimeout(
7713+ IN PVOID SystemSpecific1,
7714+ IN PVOID FunctionContext,
7715+ IN PVOID SystemSpecific2,
7716+ IN PVOID SystemSpecific3)
7717+{
7718+ BA_ORI_ENTRY *pBAEntry = (BA_ORI_ENTRY *)FunctionContext;
7719+ MAC_TABLE_ENTRY *pEntry;
7720+ PRTMP_ADAPTER pAd;
7721+
7722+ if (pBAEntry == NULL)
7723+ return;
7724+
7725+ pAd = pBAEntry->pAdapter;
7726+
7727+#ifdef CONFIG_STA_SUPPORT
7728+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
7729+ {
7730+ // Do nothing if monitor mode is on
7731+ if (MONITOR_ON(pAd))
7732+ return;
7733+ }
7734+#endif // CONFIG_STA_SUPPORT //
7735+
7736+#ifdef RALINK_ATE
7737+ // Nothing to do in ATE mode.
7738+ if (ATE_ON(pAd))
7739+ return;
7740+#endif // RALINK_ATE //
7741+
7742+ pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
7743+
7744+ if ((pBAEntry->ORI_BA_Status == Originator_WaitRes) && (pBAEntry->Token < ORI_SESSION_MAX_RETRY))
7745+ {
7746+ MLME_ADDBA_REQ_STRUCT AddbaReq;
7747+
7748+ NdisZeroMemory(&AddbaReq, sizeof(AddbaReq));
7749+ COPY_MAC_ADDR(AddbaReq.pAddr, pEntry->Addr);
7750+ AddbaReq.Wcid = (UCHAR)(pEntry->Aid);
7751+ AddbaReq.TID = pBAEntry->TID;
7752+ AddbaReq.BaBufSize = pAd->CommonCfg.BACapability.field.RxBAWinLimit;
7753+ AddbaReq.TimeOutValue = 0;
7754+ AddbaReq.Token = pBAEntry->Token;
7755+ MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ADD_BA_CATE, sizeof(MLME_ADDBA_REQ_STRUCT), (PVOID)&AddbaReq);
7756+ RT28XX_MLME_HANDLER(pAd);
7757+ //DBGPRINT(RT_DEBUG_TRACE,("BA Ori Session Timeout(%d) : Send ADD BA again\n", pBAEntry->Token));
7758+
7759+ DBGPRINT(RT_DEBUG_TRACE,("BA Ori Session Timeout(%d) to %02x:%02x:%02x:%02x:%02x:%02x Tid:%d Wcid:%d\n"
7760+ ,pBAEntry->Token
7761+ ,pEntry->Addr[0],pEntry->Addr[1],pEntry->Addr[2]
7762+ ,pEntry->Addr[3],pEntry->Addr[4],pEntry->Addr[5]
7763+ ,pBAEntry->TID,pEntry->Aid));
7764+
7765+ pBAEntry->Token++;
7766+ RTMPSetTimer(&pBAEntry->ORIBATimer, ORI_BA_SESSION_TIMEOUT);
7767+ }
7768+ else
7769+ {
7770+ BATableFreeOriEntry(pAd, pEntry->BAOriWcidArray[pBAEntry->TID]);
7771+ }
7772+}
7773+
7774+/*
7775+ ==========================================================================
7776+ Description:
7777+ Retry sending ADDBA Reqest.
7778+
7779+ IRQL = DISPATCH_LEVEL
7780+
7781+ Parametrs:
7782+ p8023Header: if this is already 802.3 format, p8023Header is NULL
7783+
7784+ Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
7785+ FALSE , then continue indicaterx at this moment.
7786+ ==========================================================================
7787+ */
7788+VOID BARecSessionIdleTimeout(
7789+ IN PVOID SystemSpecific1,
7790+ IN PVOID FunctionContext,
7791+ IN PVOID SystemSpecific2,
7792+ IN PVOID SystemSpecific3)
7793+{
7794+
7795+ BA_REC_ENTRY *pBAEntry = (BA_REC_ENTRY *)FunctionContext;
7796+ PRTMP_ADAPTER pAd;
7797+ ULONG Now32;
7798+
7799+ if (pBAEntry == NULL)
7800+ return;
7801+
7802+ if ((pBAEntry->REC_BA_Status == Recipient_Accept))
7803+ {
7804+ NdisGetSystemUpTime(&Now32);
7805+
7806+ if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer + REC_BA_SESSION_IDLE_TIMEOUT)))
7807+ {
7808+ pAd = pBAEntry->pAdapter;
7809+ // flush all pending reordering mpdus
7810+ ba_refresh_reordering_mpdus(pAd, pBAEntry);
7811+ printk("%ld: REC BA session Timeout\n", Now32);
7812+ }
7813+ }
7814+}
7815+
7816+
7817+VOID PeerAddBAReqAction(
7818+ IN PRTMP_ADAPTER pAd,
7819+ IN MLME_QUEUE_ELEM *Elem)
7820+
7821+{
7822+ // 7.4.4.1
7823+ //ULONG Idx;
7824+ UCHAR Status = 1;
7825+ UCHAR pAddr[6];
7826+ FRAME_ADDBA_RSP ADDframe;
7827+ PUCHAR pOutBuffer = NULL;
7828+ NDIS_STATUS NStatus;
7829+ PFRAME_ADDBA_REQ pAddreqFrame = NULL;
7830+ //UCHAR BufSize;
7831+ ULONG FrameLen;
7832+ PULONG ptemp;
7833+ PMAC_TABLE_ENTRY pMacEntry;
7834+
7835+ DBGPRINT(RT_DEBUG_TRACE, ("%s ==> (Wcid = %d)\n", __FUNCTION__, Elem->Wcid));
7836+
7837+ //hex_dump("AddBAReq", Elem->Msg, Elem->MsgLen);
7838+
7839+ //ADDBA Request from unknown peer, ignore this.
7840+ if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
7841+ return;
7842+
7843+ pMacEntry = &pAd->MacTab.Content[Elem->Wcid];
7844+ DBGPRINT(RT_DEBUG_TRACE,("BA - PeerAddBAReqAction----> \n"));
7845+ ptemp = (PULONG)Elem->Msg;
7846+ //DBGPRINT_RAW(RT_DEBUG_EMU, ("%08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x\n", *(ptemp), *(ptemp+1), *(ptemp+2), *(ptemp+3), *(ptemp+4), *(ptemp+5), *(ptemp+6), *(ptemp+7), *(ptemp+8)));
7847+
7848+ if (PeerAddBAReqActionSanity(pAd, Elem->Msg, Elem->MsgLen, pAddr))
7849+ {
7850+
7851+ if ((pAd->CommonCfg.bBADecline == FALSE) && IS_HT_STA(pMacEntry))
7852+ {
7853+ pAddreqFrame = (PFRAME_ADDBA_REQ)(&Elem->Msg[0]);
7854+ printk("Rcv Wcid(%d) AddBAReq\n", Elem->Wcid);
7855+ if (BARecSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid], pAddreqFrame))
7856+ Status = 0;
7857+ else
7858+ Status = 38; // more parameters have invalid values
7859+ }
7860+ else
7861+ {
7862+ Status = 37; // the request has been declined.
7863+ }
7864+ }
7865+
7866+ if (pAd->MacTab.Content[Elem->Wcid].ValidAsCLI)
7867+ ASSERT(pAd->MacTab.Content[Elem->Wcid].Sst == SST_ASSOC);
7868+
7869+ pAddreqFrame = (PFRAME_ADDBA_REQ)(&Elem->Msg[0]);
7870+ // 2. Always send back ADDBA Response
7871+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
7872+ if (NStatus != NDIS_STATUS_SUCCESS)
7873+ {
7874+ DBGPRINT(RT_DEBUG_TRACE,("ACTION - PeerBAAction() allocate memory failed \n"));
7875+ return;
7876+ }
7877+
7878+ NdisZeroMemory(&ADDframe, sizeof(FRAME_ADDBA_RSP));
7879+ // 2-1. Prepare ADDBA Response frame.
7880+#ifdef CONFIG_STA_SUPPORT
7881+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
7882+ {
7883+ if (ADHOC_ON(pAd))
7884+ ActHeaderInit(pAd, &ADDframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
7885+ else
7886+ ActHeaderInit(pAd, &ADDframe.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAddr);
7887+ }
7888+#endif // CONFIG_STA_SUPPORT //
7889+ ADDframe.Category = CATEGORY_BA;
7890+ ADDframe.Action = ADDBA_RESP;
7891+ ADDframe.Token = pAddreqFrame->Token;
7892+ // What is the Status code?? need to check.
7893+ ADDframe.StatusCode = Status;
7894+ ADDframe.BaParm.BAPolicy = IMMED_BA;
7895+ ADDframe.BaParm.AMSDUSupported = 0;
7896+ ADDframe.BaParm.TID = pAddreqFrame->BaParm.TID;
7897+ ADDframe.BaParm.BufSize = min(((UCHAR)pAddreqFrame->BaParm.BufSize), (UCHAR)pAd->CommonCfg.BACapability.field.RxBAWinLimit);
7898+ if (ADDframe.BaParm.BufSize == 0)
7899+ {
7900+ ADDframe.BaParm.BufSize = 64;
7901+ }
7902+ ADDframe.TimeOutValue = 0; //pAddreqFrame->TimeOutValue;
7903+
7904+ *(USHORT *)(&ADDframe.BaParm) = cpu2le16(*(USHORT *)(&ADDframe.BaParm));
7905+ ADDframe.StatusCode = cpu2le16(ADDframe.StatusCode);
7906+ ADDframe.TimeOutValue = cpu2le16(ADDframe.TimeOutValue);
7907+
7908+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
7909+ sizeof(FRAME_ADDBA_RSP), &ADDframe,
7910+ END_OF_ARGS);
7911+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
7912+ MlmeFreeMemory(pAd, pOutBuffer);
7913+
7914+ DBGPRINT(RT_DEBUG_TRACE, ("%s(%d): TID(%d), BufSize(%d) <== \n", __FUNCTION__, Elem->Wcid, ADDframe.BaParm.TID,
7915+ ADDframe.BaParm.BufSize));
7916+}
7917+
7918+
7919+VOID PeerAddBARspAction(
7920+ IN PRTMP_ADAPTER pAd,
7921+ IN MLME_QUEUE_ELEM *Elem)
7922+
7923+{
7924+ //UCHAR Idx, i;
7925+ //PUCHAR pOutBuffer = NULL;
7926+ PFRAME_ADDBA_RSP pFrame = NULL;
7927+ //PBA_ORI_ENTRY pBAEntry;
7928+
7929+ //ADDBA Response from unknown peer, ignore this.
7930+ if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
7931+ return;
7932+
7933+ DBGPRINT(RT_DEBUG_TRACE, ("%s ==> Wcid(%d)\n", __FUNCTION__, Elem->Wcid));
7934+
7935+ //hex_dump("PeerAddBARspAction()", Elem->Msg, Elem->MsgLen);
7936+
7937+ if (PeerAddBARspActionSanity(pAd, Elem->Msg, Elem->MsgLen))
7938+ {
7939+ pFrame = (PFRAME_ADDBA_RSP)(&Elem->Msg[0]);
7940+
7941+ DBGPRINT(RT_DEBUG_TRACE, ("\t\t StatusCode = %d\n", pFrame->StatusCode));
7942+ switch (pFrame->StatusCode)
7943+ {
7944+ case 0:
7945+ // I want a BAsession with this peer as an originator.
7946+ BAOriSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid], pFrame);
7947+ break;
7948+ default:
7949+ // check status == USED ???
7950+ BAOriSessionTearDown(pAd, Elem->Wcid, pFrame->BaParm.TID, TRUE, FALSE);
7951+ break;
7952+ }
7953+ // Rcv Decline StatusCode
7954+ if ((pFrame->StatusCode == 37)
7955+#ifdef CONFIG_STA_SUPPORT
7956+ || ((pAd->OpMode == OPMODE_STA) && STA_TGN_WIFI_ON(pAd) && (pFrame->StatusCode != 0))
7957+#endif // CONFIG_STA_SUPPORT //
7958+ )
7959+ {
7960+ pAd->MacTab.Content[Elem->Wcid].BADeclineBitmap |= 1<<pFrame->BaParm.TID;
7961+ }
7962+ }
7963+}
7964+
7965+VOID PeerDelBAAction(
7966+ IN PRTMP_ADAPTER pAd,
7967+ IN MLME_QUEUE_ELEM *Elem)
7968+
7969+{
7970+ //UCHAR Idx;
7971+ //PUCHAR pOutBuffer = NULL;
7972+ PFRAME_DELBA_REQ pDelFrame = NULL;
7973+
7974+ DBGPRINT(RT_DEBUG_TRACE,("%s ==>\n", __FUNCTION__));
7975+ //DELBA Request from unknown peer, ignore this.
7976+ if (PeerDelBAActionSanity(pAd, Elem->Wcid, Elem->Msg, Elem->MsgLen))
7977+ {
7978+ pDelFrame = (PFRAME_DELBA_REQ)(&Elem->Msg[0]);
7979+ if (pDelFrame->DelbaParm.Initiator == ORIGINATOR)
7980+ {
7981+ DBGPRINT(RT_DEBUG_TRACE,("BA - PeerDelBAAction----> ORIGINATOR\n"));
7982+ BARecSessionTearDown(pAd, Elem->Wcid, pDelFrame->DelbaParm.TID, TRUE);
7983+ }
7984+ else
7985+ {
7986+ DBGPRINT(RT_DEBUG_TRACE,("BA - PeerDelBAAction----> RECIPIENT, Reason = %d\n", pDelFrame->ReasonCode));
7987+ //hex_dump("DelBA Frame", pDelFrame, Elem->MsgLen);
7988+ BAOriSessionTearDown(pAd, Elem->Wcid, pDelFrame->DelbaParm.TID, TRUE, FALSE);
7989+ }
7990+ }
7991+}
7992+
7993+
7994+BOOLEAN CntlEnqueueForRecv(
7995+ IN PRTMP_ADAPTER pAd,
7996+ IN ULONG Wcid,
7997+ IN ULONG MsgLen,
7998+ IN PFRAME_BA_REQ pMsg)
7999+{
8000+ PFRAME_BA_REQ pFrame = pMsg;
8001+ //PRTMP_REORDERBUF pBuffer;
8002+ //PRTMP_REORDERBUF pDmaBuf;
8003+ PBA_REC_ENTRY pBAEntry;
8004+ //BOOLEAN Result;
8005+ ULONG Idx;
8006+ //UCHAR NumRxPkt;
8007+ UCHAR TID;//, i;
8008+
8009+ TID = (UCHAR)pFrame->BARControl.TID;
8010+
8011+ DBGPRINT(RT_DEBUG_TRACE, ("%s(): BAR-Wcid(%ld), Tid (%d)\n", __FUNCTION__, Wcid, TID));
8012+ //hex_dump("BAR", (PCHAR) pFrame, MsgLen);
8013+ // Do nothing if the driver is starting halt state.
8014+ // This might happen when timer already been fired before cancel timer with mlmehalt
8015+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
8016+ return FALSE;
8017+
8018+ // First check the size, it MUST not exceed the mlme queue size
8019+ if (MsgLen > MGMT_DMA_BUFFER_SIZE)
8020+ {
8021+ DBGPRINT_ERR(("CntlEnqueueForRecv: frame too large, size = %ld \n", MsgLen));
8022+ return FALSE;
8023+ }
8024+ else if (MsgLen != sizeof(FRAME_BA_REQ))
8025+ {
8026+ DBGPRINT_ERR(("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen));
8027+ return FALSE;
8028+ }
8029+ else if (MsgLen != sizeof(FRAME_BA_REQ))
8030+ {
8031+ DBGPRINT_ERR(("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen));
8032+ return FALSE;
8033+ }
8034+
8035+ if ((Wcid < MAX_LEN_OF_MAC_TABLE) && (TID < 8))
8036+ {
8037+ // if this receiving packet is from SA that is in our OriEntry. Since WCID <9 has direct mapping. no need search.
8038+ Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
8039+ pBAEntry = &pAd->BATable.BARecEntry[Idx];
8040+ }
8041+ else
8042+ {
8043+ return FALSE;
8044+ }
8045+
8046+ DBGPRINT(RT_DEBUG_TRACE, ("BAR(%ld) : Tid (%d) - %04x:%04x\n", Wcid, TID, pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq ));
8047+
8048+ if (SEQ_SMALLER(pBAEntry->LastIndSeq, pFrame->BAStartingSeq.field.StartSeq, MAXSEQ))
8049+ {
8050+ //printk("BAR Seq = %x, LastIndSeq = %x\n", pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq);
8051+ ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, pFrame->BAStartingSeq.field.StartSeq);
8052+ pBAEntry->LastIndSeq = (pFrame->BAStartingSeq.field.StartSeq == 0) ? MAXSEQ :(pFrame->BAStartingSeq.field.StartSeq -1);
8053+ }
8054+ //ba_refresh_reordering_mpdus(pAd, pBAEntry);
8055+ return TRUE;
8056+}
8057+
8058+/*
8059+Description : Send PSMP Action frame If PSMP mode switches.
8060+*/
8061+VOID SendPSMPAction(
8062+ IN PRTMP_ADAPTER pAd,
8063+ IN UCHAR Wcid,
8064+ IN UCHAR Psmp)
8065+{
8066+ PUCHAR pOutBuffer = NULL;
8067+ NDIS_STATUS NStatus;
8068+ //ULONG Idx;
8069+ FRAME_PSMP_ACTION Frame;
8070+ ULONG FrameLen;
8071+#ifdef RT30xx
8072+ UCHAR bbpdata=0;
8073+ UINT32 macdata;
8074+#endif // RT30xx //
8075+
8076+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
8077+ if (NStatus != NDIS_STATUS_SUCCESS)
8078+ {
8079+ DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() allocate memory failed \n"));
8080+ return;
8081+ }
8082+#ifdef CONFIG_STA_SUPPORT
8083+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
8084+ ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->MacTab.Content[Wcid].Addr);
8085+#endif // CONFIG_STA_SUPPORT //
8086+
8087+ Frame.Category = CATEGORY_HT;
8088+ Frame.Action = SMPS_ACTION;
8089+ switch (Psmp)
8090+ {
8091+ case MMPS_ENABLE:
8092+#ifdef RT30xx
8093+ if (IS_RT3090(pAd))
8094+ {
8095+ // disable MMPS BBP control register
8096+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpdata);
8097+ bbpdata &= ~(0x04); //bit 2
8098+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpdata);
8099+
8100+ // disable MMPS MAC control register
8101+ RTMP_IO_READ32(pAd, 0x1210, &macdata);
8102+ macdata &= ~(0x09); //bit 0, 3
8103+ RTMP_IO_WRITE32(pAd, 0x1210, macdata);
8104+ }
8105+#endif // RT30xx //
8106+ Frame.Psmp = 0;
8107+ break;
8108+ case MMPS_DYNAMIC:
8109+#ifdef RT30xx
8110+ if (IS_RT3090(pAd))
8111+ {
8112+ // enable MMPS BBP control register
8113+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpdata);
8114+ bbpdata |= 0x04; //bit 2
8115+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpdata);
8116+
8117+ // enable MMPS MAC control register
8118+ RTMP_IO_READ32(pAd, 0x1210, &macdata);
8119+ macdata |= 0x09; //bit 0, 3
8120+ RTMP_IO_WRITE32(pAd, 0x1210, macdata);
8121+ }
8122+#endif // RT30xx //
8123+ Frame.Psmp = 3;
8124+ break;
8125+ case MMPS_STATIC:
8126+#ifdef RT30xx
8127+ if (IS_RT3090(pAd))
8128+ {
8129+ // enable MMPS BBP control register
8130+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpdata);
8131+ bbpdata |= 0x04; //bit 2
8132+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpdata);
8133+
8134+ // enable MMPS MAC control register
8135+ RTMP_IO_READ32(pAd, 0x1210, &macdata);
8136+ macdata |= 0x09; //bit 0, 3
8137+ RTMP_IO_WRITE32(pAd, 0x1210, macdata);
8138+ }
8139+#endif // RT30xx //
8140+ Frame.Psmp = 1;
8141+ break;
8142+ }
8143+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
8144+ sizeof(FRAME_PSMP_ACTION), &Frame,
8145+ END_OF_ARGS);
8146+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
8147+ MlmeFreeMemory(pAd, pOutBuffer);
8148+ DBGPRINT(RT_DEBUG_ERROR,("HT - SendPSMPAction( %d ) \n", Frame.Psmp));
8149+}
8150+
8151+
8152+#define RADIO_MEASUREMENT_REQUEST_ACTION 0
8153+
8154+typedef struct PACKED
8155+{
8156+ UCHAR RegulatoryClass;
8157+ UCHAR ChannelNumber;
8158+ USHORT RandomInterval;
8159+ USHORT MeasurementDuration;
8160+ UCHAR MeasurementMode;
8161+ UCHAR BSSID[MAC_ADDR_LEN];
8162+ UCHAR ReportingCondition;
8163+ UCHAR Threshold;
8164+ UCHAR SSIDIE[2]; // 2 byte
8165+} BEACON_REQUEST;
8166+
8167+typedef struct PACKED
8168+{
8169+ UCHAR ID;
8170+ UCHAR Length;
8171+ UCHAR Token;
8172+ UCHAR RequestMode;
8173+ UCHAR Type;
8174+} MEASUREMENT_REQ;
8175+
8176+
8177+
8178+
8179+void convert_reordering_packet_to_preAMSDU_or_802_3_packet(
8180+ IN PRTMP_ADAPTER pAd,
8181+ IN RX_BLK *pRxBlk,
8182+ IN UCHAR FromWhichBSSID)
8183+{
8184+ PNDIS_PACKET pRxPkt;
8185+ UCHAR Header802_3[LENGTH_802_3];
8186+
8187+ // 1. get 802.3 Header
8188+ // 2. remove LLC
8189+ // a. pointer pRxBlk->pData to payload
8190+ // b. modify pRxBlk->DataSize
8191+
8192+#ifdef CONFIG_STA_SUPPORT
8193+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
8194+ RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
8195+#endif // CONFIG_STA_SUPPORT //
8196+
8197+ ASSERT(pRxBlk->pRxPacket);
8198+ pRxPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
8199+
8200+ RTPKT_TO_OSPKT(pRxPkt)->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
8201+ RTPKT_TO_OSPKT(pRxPkt)->data = pRxBlk->pData;
8202+ RTPKT_TO_OSPKT(pRxPkt)->len = pRxBlk->DataSize;
8203+ RTPKT_TO_OSPKT(pRxPkt)->tail = RTPKT_TO_OSPKT(pRxPkt)->data + RTPKT_TO_OSPKT(pRxPkt)->len;
8204+
8205+ //
8206+ // copy 802.3 header, if necessary
8207+ //
8208+ if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU))
8209+ {
8210+
8211+#ifdef CONFIG_STA_SUPPORT
8212+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
8213+ {
8214+#ifdef LINUX
8215+ NdisMoveMemory(skb_push(pRxPkt, LENGTH_802_3), Header802_3, LENGTH_802_3);
8216+#endif
8217+#ifdef UCOS
8218+ NdisMoveMemory(net_pkt_push(pRxPkt, LENGTH_802_3), Header802_3, LENGTH_802_3);
8219+#endif
8220+ }
8221+#endif // CONFIG_STA_SUPPORT //
8222+ }
8223+}
8224+
8225+
8226+#define INDICATE_LEGACY_OR_AMSDU(_pAd, _pRxBlk, _fromWhichBSSID) \
8227+ do \
8228+ { \
8229+ if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_AMSDU)) \
8230+ { \
8231+ Indicate_AMSDU_Packet(_pAd, _pRxBlk, _fromWhichBSSID); \
8232+ } \
8233+ else if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_EAP)) \
8234+ { \
8235+ Indicate_EAPOL_Packet(_pAd, _pRxBlk, _fromWhichBSSID); \
8236+ } \
8237+ else \
8238+ { \
8239+ Indicate_Legacy_Packet(_pAd, _pRxBlk, _fromWhichBSSID); \
8240+ } \
8241+ } while (0);
8242+
8243+
8244+
8245+static VOID ba_enqueue_reordering_packet(
8246+ IN PRTMP_ADAPTER pAd,
8247+ IN PBA_REC_ENTRY pBAEntry,
8248+ IN RX_BLK *pRxBlk,
8249+ IN UCHAR FromWhichBSSID)
8250+{
8251+ struct reordering_mpdu *mpdu_blk;
8252+ UINT16 Sequence = (UINT16) pRxBlk->pHeader->Sequence;
8253+
8254+ mpdu_blk = ba_mpdu_blk_alloc(pAd);
8255+ if (mpdu_blk != NULL)
8256+ {
8257+ // Write RxD buffer address & allocated buffer length
8258+ NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
8259+
8260+ mpdu_blk->Sequence = Sequence;
8261+
8262+ mpdu_blk->bAMSDU = RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU);
8263+
8264+ convert_reordering_packet_to_preAMSDU_or_802_3_packet(pAd, pRxBlk, FromWhichBSSID);
8265+
8266+ STATS_INC_RX_PACKETS(pAd, FromWhichBSSID);
8267+
8268+ //
8269+ // it is necessary for reordering packet to record
8270+ // which BSS it come from
8271+ //
8272+ RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID);
8273+
8274+ mpdu_blk->pPacket = pRxBlk->pRxPacket;
8275+
8276+ if (ba_reordering_mpdu_insertsorted(&pBAEntry->list, mpdu_blk) == FALSE)
8277+ {
8278+ // had been already within reordering list
8279+ // don't indicate
8280+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_SUCCESS);
8281+ ba_mpdu_blk_free(pAd, mpdu_blk);
8282+ }
8283+
8284+ ASSERT((0<= pBAEntry->list.qlen) && (pBAEntry->list.qlen <= pBAEntry->BAWinSize));
8285+ NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
8286+ }
8287+ else
8288+ {
8289+ DBGPRINT(RT_DEBUG_ERROR, ("!!! (%d) Can't allocate reordering mpdu blk\n",
8290+ pBAEntry->list.qlen));
8291+ /*
8292+ * flush all pending reordering mpdus
8293+ * and receving mpdu to upper layer
8294+ * make tcp/ip to take care reordering mechanism
8295+ */
8296+ //ba_refresh_reordering_mpdus(pAd, pBAEntry);
8297+ ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, Sequence);
8298+
8299+ pBAEntry->LastIndSeq = Sequence;
8300+ INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
8301+ }
8302+}
8303+
8304+
8305+/*
8306+ ==========================================================================
8307+ Description:
8308+ Indicate this packet to upper layer or put it into reordering buffer
8309+
8310+ Parametrs:
8311+ pRxBlk : carry necessary packet info 802.11 format
8312+ FromWhichBSSID : the packet received from which BSS
8313+
8314+ Return :
8315+ none
8316+
8317+ Note :
8318+ the packet queued into reordering buffer need to cover to 802.3 format
8319+ or pre_AMSDU format
8320+ ==========================================================================
8321+ */
8322+
8323+VOID Indicate_AMPDU_Packet(
8324+ IN PRTMP_ADAPTER pAd,
8325+ IN RX_BLK *pRxBlk,
8326+ IN UCHAR FromWhichBSSID)
8327+{
8328+ USHORT Idx;
8329+ PBA_REC_ENTRY pBAEntry = NULL;
8330+ UINT16 Sequence = pRxBlk->pHeader->Sequence;
8331+ ULONG Now32;
8332+ UCHAR Wcid = pRxBlk->pRxWI->WirelessCliID;
8333+ UCHAR TID = pRxBlk->pRxWI->TID;
8334+
8335+
8336+ if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU) && (pRxBlk->DataSize > MAX_RX_PKT_LEN))
8337+ {
8338+ // release packet
8339+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
8340+ return;
8341+ }
8342+
8343+ if (Wcid < MAX_LEN_OF_MAC_TABLE)
8344+ {
8345+ Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
8346+ if (Idx == 0)
8347+ {
8348+ /* Rec BA Session had been torn down */
8349+ INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
8350+ return;
8351+ }
8352+ pBAEntry = &pAd->BATable.BARecEntry[Idx];
8353+ }
8354+ else
8355+ {
8356+ // impossible !!!
8357+ ASSERT(0);
8358+ // release packet
8359+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
8360+ return;
8361+ }
8362+
8363+ ASSERT(pBAEntry);
8364+
8365+ // update last rx time
8366+ NdisGetSystemUpTime(&Now32);
8367+
8368+ pBAEntry->rcvSeq = Sequence;
8369+
8370+
8371+ ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32);
8372+ pBAEntry->LastIndSeqAtTimer = Now32;
8373+
8374+ //
8375+ // Reset Last Indicate Sequence
8376+ //
8377+ if (pBAEntry->LastIndSeq == RESET_RCV_SEQ)
8378+ {
8379+ ASSERT((pBAEntry->list.qlen == 0) && (pBAEntry->list.next == NULL));
8380+
8381+ // reset rcv sequence of BA session
8382+ pBAEntry->LastIndSeq = Sequence;
8383+ pBAEntry->LastIndSeqAtTimer = Now32;
8384+ INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
8385+ return;
8386+ }
8387+
8388+
8389+ //
8390+ // I. Check if in order.
8391+ //
8392+ if (SEQ_STEPONE(Sequence, pBAEntry->LastIndSeq, MAXSEQ))
8393+ {
8394+ USHORT LastIndSeq;
8395+
8396+ pBAEntry->LastIndSeq = Sequence;
8397+ INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
8398+ LastIndSeq = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, pBAEntry->LastIndSeq);
8399+ if (LastIndSeq != RESET_RCV_SEQ)
8400+ {
8401+ pBAEntry->LastIndSeq = LastIndSeq;
8402+ }
8403+ pBAEntry->LastIndSeqAtTimer = Now32;
8404+ }
8405+ //
8406+ // II. Drop Duplicated Packet
8407+ //
8408+ else if (Sequence == pBAEntry->LastIndSeq)
8409+ {
8410+
8411+ // drop and release packet
8412+ pBAEntry->nDropPacket++;
8413+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
8414+ }
8415+ //
8416+ // III. Drop Old Received Packet
8417+ //
8418+ else if (SEQ_SMALLER(Sequence, pBAEntry->LastIndSeq, MAXSEQ))
8419+ {
8420+
8421+ // drop and release packet
8422+ pBAEntry->nDropPacket++;
8423+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
8424+ }
8425+ //
8426+ // IV. Receive Sequence within Window Size
8427+ //
8428+ else if (SEQ_SMALLER(Sequence, (((pBAEntry->LastIndSeq+pBAEntry->BAWinSize+1)) & MAXSEQ), MAXSEQ))
8429+ {
8430+ ba_enqueue_reordering_packet(pAd, pBAEntry, pRxBlk, FromWhichBSSID);
8431+ }
8432+ //
8433+ // V. Receive seq surpasses Win(lastseq + nMSDU). So refresh all reorder buffer
8434+ //
8435+ else
8436+ {
8437+ LONG WinStartSeq, TmpSeq;
8438+
8439+
8440+ TmpSeq = Sequence - (pBAEntry->BAWinSize) -1;
8441+ if (TmpSeq < 0)
8442+ {
8443+ TmpSeq = (MAXSEQ+1) + TmpSeq;
8444+ }
8445+ WinStartSeq = (TmpSeq+1) & MAXSEQ;
8446+ ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, WinStartSeq);
8447+ pBAEntry->LastIndSeq = WinStartSeq; //TmpSeq;
8448+
8449+ pBAEntry->LastIndSeqAtTimer = Now32;
8450+
8451+ ba_enqueue_reordering_packet(pAd, pBAEntry, pRxBlk, FromWhichBSSID);
8452+
8453+ TmpSeq = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, pBAEntry->LastIndSeq);
8454+ if (TmpSeq != RESET_RCV_SEQ)
8455+ {
8456+ pBAEntry->LastIndSeq = TmpSeq;
8457+ }
8458+ }
8459+}
8460+
8461+#endif // DOT11_N_SUPPORT //
8462+
8463--- /dev/null
8464+++ b/drivers/staging/rt3070/common/cmm_data_2870.c
8465@@ -0,0 +1,980 @@
8466+/*
8467+ *************************************************************************
8468+ * Ralink Tech Inc.
8469+ * 5F., No.36, Taiyuan St., Jhubei City,
8470+ * Hsinchu County 302,
8471+ * Taiwan, R.O.C.
8472+ *
8473+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
8474+ *
8475+ * This program is free software; you can redistribute it and/or modify *
8476+ * it under the terms of the GNU General Public License as published by *
8477+ * the Free Software Foundation; either version 2 of the License, or *
8478+ * (at your option) any later version. *
8479+ * *
8480+ * This program is distributed in the hope that it will be useful, *
8481+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
8482+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
8483+ * GNU General Public License for more details. *
8484+ * *
8485+ * You should have received a copy of the GNU General Public License *
8486+ * along with this program; if not, write to the *
8487+ * Free Software Foundation, Inc., *
8488+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
8489+ * *
8490+ *************************************************************************
8491+*/
8492+/*
8493+ All functions in this file must be USB-depended, or you should out your function
8494+ in other files.
8495+
8496+*/
8497+#include "../rt_config.h"
8498+
8499+
8500+/*
8501+ We can do copy the frame into pTxContext when match following conditions.
8502+ =>
8503+ =>
8504+ =>
8505+*/
8506+static inline NDIS_STATUS RtmpUSBCanDoWrite(
8507+ IN RTMP_ADAPTER *pAd,
8508+ IN UCHAR QueIdx,
8509+ IN HT_TX_CONTEXT *pHTTXContext)
8510+{
8511+ NDIS_STATUS canWrite = NDIS_STATUS_RESOURCES;
8512+
8513+ if (((pHTTXContext->CurWritePosition) < pHTTXContext->NextBulkOutPosition) && (pHTTXContext->CurWritePosition + LOCAL_TXBUF_SIZE) > pHTTXContext->NextBulkOutPosition)
8514+ {
8515+ DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c1!\n"));
8516+ RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
8517+ }
8518+ else if ((pHTTXContext->CurWritePosition == 8) && (pHTTXContext->NextBulkOutPosition < LOCAL_TXBUF_SIZE))
8519+ {
8520+ DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c2!\n"));
8521+ RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
8522+ }
8523+ else if (pHTTXContext->bCurWriting == TRUE)
8524+ {
8525+ DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c3!\n"));
8526+ }
8527+ else
8528+ {
8529+ canWrite = NDIS_STATUS_SUCCESS;
8530+ }
8531+
8532+
8533+ return canWrite;
8534+}
8535+
8536+
8537+USHORT RtmpUSB_WriteSubTxResource(
8538+ IN PRTMP_ADAPTER pAd,
8539+ IN TX_BLK *pTxBlk,
8540+ IN BOOLEAN bIsLast,
8541+ OUT USHORT *FreeNumber)
8542+{
8543+
8544+ // Dummy function. Should be removed in the future.
8545+ return 0;
8546+
8547+}
8548+
8549+USHORT RtmpUSB_WriteFragTxResource(
8550+ IN PRTMP_ADAPTER pAd,
8551+ IN TX_BLK *pTxBlk,
8552+ IN UCHAR fragNum,
8553+ OUT USHORT *FreeNumber)
8554+{
8555+ HT_TX_CONTEXT *pHTTXContext;
8556+ USHORT hwHdrLen; // The hwHdrLen consist of 802.11 header length plus the header padding length.
8557+ UINT32 fillOffset;
8558+ TXINFO_STRUC *pTxInfo;
8559+ TXWI_STRUC *pTxWI;
8560+ PUCHAR pWirelessPacket = NULL;
8561+ UCHAR QueIdx;
8562+ NDIS_STATUS Status;
8563+ unsigned long IrqFlags;
8564+ UINT32 USBDMApktLen = 0, DMAHdrLen, padding;
8565+ BOOLEAN TxQLastRound = FALSE;
8566+
8567+ //
8568+ // get Tx Ring Resource & Dma Buffer address
8569+ //
8570+ QueIdx = pTxBlk->QueIdx;
8571+ pHTTXContext = &pAd->TxContext[QueIdx];
8572+
8573+ RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
8574+
8575+ pHTTXContext = &pAd->TxContext[QueIdx];
8576+ fillOffset = pHTTXContext->CurWritePosition;
8577+
8578+ if(fragNum == 0)
8579+ {
8580+ // Check if we have enough space for this bulk-out batch.
8581+ Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
8582+ if (Status == NDIS_STATUS_SUCCESS)
8583+ {
8584+ pHTTXContext->bCurWriting = TRUE;
8585+
8586+ // Reserve space for 8 bytes padding.
8587+ if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition))
8588+ {
8589+ pHTTXContext->ENextBulkOutPosition += 8;
8590+ pHTTXContext->CurWritePosition += 8;
8591+ fillOffset += 8;
8592+ }
8593+ pTxBlk->Priv = 0;
8594+ pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
8595+ }
8596+ else
8597+ {
8598+ RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
8599+
8600+ RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
8601+ return(Status);
8602+ }
8603+ }
8604+ else
8605+ {
8606+ // For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer.
8607+ Status = ((pHTTXContext->bCurWriting == TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE);
8608+ if (Status == NDIS_STATUS_SUCCESS)
8609+ {
8610+ fillOffset += pTxBlk->Priv;
8611+ }
8612+ else
8613+ {
8614+ RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
8615+
8616+ RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
8617+ return(Status);
8618+ }
8619+ }
8620+
8621+ NdisZeroMemory((PUCHAR)(&pTxBlk->HeaderBuf[0]), TXINFO_SIZE);
8622+ pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]);
8623+ pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]);
8624+
8625+ pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
8626+
8627+ // copy TXWI + WLAN Header + LLC into DMA Header Buffer
8628+ //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
8629+ hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
8630+
8631+ // Build our URB for USBD
8632+ DMAHdrLen = TXWI_SIZE + hwHdrLen;
8633+ USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen;
8634+ padding = (4 - (USBDMApktLen % 4)) & 0x03; // round up to 4 byte alignment
8635+ USBDMApktLen += padding;
8636+
8637+ pTxBlk->Priv += (TXINFO_SIZE + USBDMApktLen);
8638+
8639+ // For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload
8640+ RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(USBDMApktLen), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE);
8641+
8642+ if (fragNum == pTxBlk->TotalFragNum)
8643+ {
8644+ pTxInfo->USBDMATxburst = 0;
8645+ if ((pHTTXContext->CurWritePosition + pTxBlk->Priv + 3906)> MAX_TXBULK_LIMIT)
8646+ {
8647+ pTxInfo->SwUseLastRound = 1;
8648+ TxQLastRound = TRUE;
8649+ }
8650+ }
8651+ else
8652+ {
8653+ pTxInfo->USBDMATxburst = 1;
8654+ }
8655+
8656+ NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
8657+#ifdef RT_BIG_ENDIAN
8658+ RTMPFrameEndianChange(pAd, (PUCHAR)(pWirelessPacket + TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE);
8659+#endif // RT_BIG_ENDIAN //
8660+ pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
8661+ pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
8662+
8663+ RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
8664+
8665+ NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
8666+
8667+ // Zero the last padding.
8668+ pWirelessPacket += pTxBlk->SrcBufLen;
8669+ NdisZeroMemory(pWirelessPacket, padding + 8);
8670+
8671+ if (fragNum == pTxBlk->TotalFragNum)
8672+ {
8673+ RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
8674+
8675+ // Update the pHTTXContext->CurWritePosition. 3906 used to prevent the NextBulkOut is a A-RALINK/A-MSDU Frame.
8676+ pHTTXContext->CurWritePosition += pTxBlk->Priv;
8677+ if (TxQLastRound == TRUE)
8678+ pHTTXContext->CurWritePosition = 8;
8679+ pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
8680+
8681+
8682+ // Finally, set bCurWriting as FALSE
8683+ pHTTXContext->bCurWriting = FALSE;
8684+
8685+ RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
8686+
8687+ // succeed and release the skb buffer
8688+ RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
8689+ }
8690+
8691+
8692+ return(Status);
8693+
8694+}
8695+
8696+
8697+USHORT RtmpUSB_WriteSingleTxResource(
8698+ IN PRTMP_ADAPTER pAd,
8699+ IN TX_BLK *pTxBlk,
8700+ IN BOOLEAN bIsLast,
8701+ OUT USHORT *FreeNumber)
8702+{
8703+ HT_TX_CONTEXT *pHTTXContext;
8704+ USHORT hwHdrLen;
8705+ UINT32 fillOffset;
8706+ TXINFO_STRUC *pTxInfo;
8707+ TXWI_STRUC *pTxWI;
8708+ PUCHAR pWirelessPacket;
8709+ UCHAR QueIdx;
8710+ unsigned long IrqFlags;
8711+ NDIS_STATUS Status;
8712+ UINT32 USBDMApktLen = 0, DMAHdrLen, padding;
8713+ BOOLEAN bTxQLastRound = FALSE;
8714+
8715+ // For USB, didn't need PCI_MAP_SINGLE()
8716+ //SrcBufPA = PCI_MAP_SINGLE(pAd, (char *) pTxBlk->pSrcBufData, pTxBlk->SrcBufLen, PCI_DMA_TODEVICE);
8717+
8718+
8719+ //
8720+ // get Tx Ring Resource & Dma Buffer address
8721+ //
8722+ QueIdx = pTxBlk->QueIdx;
8723+
8724+ RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
8725+ pHTTXContext = &pAd->TxContext[QueIdx];
8726+ fillOffset = pHTTXContext->CurWritePosition;
8727+
8728+
8729+
8730+ // Check ring full.
8731+ Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
8732+ if(Status == NDIS_STATUS_SUCCESS)
8733+ {
8734+ pHTTXContext->bCurWriting = TRUE;
8735+
8736+ pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]);
8737+ pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]);
8738+
8739+ // Reserve space for 8 bytes padding.
8740+ if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition))
8741+ {
8742+ pHTTXContext->ENextBulkOutPosition += 8;
8743+ pHTTXContext->CurWritePosition += 8;
8744+ fillOffset += 8;
8745+ }
8746+ pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
8747+
8748+ pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
8749+
8750+ // copy TXWI + WLAN Header + LLC into DMA Header Buffer
8751+ //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
8752+ hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
8753+
8754+ // Build our URB for USBD
8755+ DMAHdrLen = TXWI_SIZE + hwHdrLen;
8756+ USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen;
8757+ padding = (4 - (USBDMApktLen % 4)) & 0x03; // round up to 4 byte alignment
8758+ USBDMApktLen += padding;
8759+
8760+ pTxBlk->Priv = (TXINFO_SIZE + USBDMApktLen);
8761+
8762+ // For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload
8763+ //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
8764+#ifdef CONFIG_STA_SUPPORT
8765+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
8766+ RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(USBDMApktLen), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE);
8767+#endif // CONFIG_STA_SUPPORT //
8768+
8769+ if ((pHTTXContext->CurWritePosition + 3906 + pTxBlk->Priv) > MAX_TXBULK_LIMIT)
8770+ {
8771+ pTxInfo->SwUseLastRound = 1;
8772+ bTxQLastRound = TRUE;
8773+ }
8774+ NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
8775+#ifdef RT_BIG_ENDIAN
8776+ RTMPFrameEndianChange(pAd, (PUCHAR)(pWirelessPacket + TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE);
8777+#endif // RT_BIG_ENDIAN //
8778+ pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
8779+
8780+ // We unlock it here to prevent the first 8 bytes maybe over-writed issue.
8781+ // 1. First we got CurWritePosition but the first 8 bytes still not write to the pTxcontext.
8782+ // 2. An interrupt break our routine and handle bulk-out complete.
8783+ // 3. In the bulk-out compllete, it need to do another bulk-out,
8784+ // if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition,
8785+ // but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE.
8786+ // 4. Interrupt complete.
8787+ // 5. Our interrupted routine go back and fill the first 8 bytes to pTxContext.
8788+ // 6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition.
8789+ // and the packet will wrong.
8790+ pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
8791+ RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
8792+
8793+ NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
8794+ pWirelessPacket += pTxBlk->SrcBufLen;
8795+ NdisZeroMemory(pWirelessPacket, padding + 8);
8796+
8797+ RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
8798+
8799+ pHTTXContext->CurWritePosition += pTxBlk->Priv;
8800+ if (bTxQLastRound)
8801+ pHTTXContext->CurWritePosition = 8;
8802+ pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
8803+
8804+ pHTTXContext->bCurWriting = FALSE;
8805+ }
8806+
8807+
8808+ RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
8809+
8810+
8811+ // succeed and release the skb buffer
8812+ RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
8813+
8814+ return(Status);
8815+
8816+}
8817+
8818+
8819+USHORT RtmpUSB_WriteMultiTxResource(
8820+ IN PRTMP_ADAPTER pAd,
8821+ IN TX_BLK *pTxBlk,
8822+ IN UCHAR frameNum,
8823+ OUT USHORT *FreeNumber)
8824+{
8825+ HT_TX_CONTEXT *pHTTXContext;
8826+ USHORT hwHdrLen; // The hwHdrLen consist of 802.11 header length plus the header padding length.
8827+ UINT32 fillOffset;
8828+ TXINFO_STRUC *pTxInfo;
8829+ TXWI_STRUC *pTxWI;
8830+ PUCHAR pWirelessPacket = NULL;
8831+ UCHAR QueIdx;
8832+ NDIS_STATUS Status;
8833+ unsigned long IrqFlags;
8834+ //UINT32 USBDMApktLen = 0, DMAHdrLen, padding;
8835+
8836+ //
8837+ // get Tx Ring Resource & Dma Buffer address
8838+ //
8839+ QueIdx = pTxBlk->QueIdx;
8840+ pHTTXContext = &pAd->TxContext[QueIdx];
8841+
8842+ RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
8843+
8844+ if(frameNum == 0)
8845+ {
8846+ // Check if we have enough space for this bulk-out batch.
8847+ Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
8848+ if (Status == NDIS_STATUS_SUCCESS)
8849+ {
8850+ pHTTXContext->bCurWriting = TRUE;
8851+
8852+ pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]);
8853+ pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]);
8854+
8855+
8856+ // Reserve space for 8 bytes padding.
8857+ if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition))
8858+ {
8859+
8860+ pHTTXContext->CurWritePosition += 8;
8861+ pHTTXContext->ENextBulkOutPosition += 8;
8862+ }
8863+ fillOffset = pHTTXContext->CurWritePosition;
8864+ pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
8865+
8866+ pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
8867+
8868+ //
8869+ // Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
8870+ //
8871+ if (pTxBlk->TxFrameType == TX_AMSDU_FRAME)
8872+ //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD;
8873+ hwHdrLen = pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD + pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD;
8874+ else if (pTxBlk->TxFrameType == TX_RALINK_FRAME)
8875+ //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD;
8876+ hwHdrLen = pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD + pTxBlk->HdrPadLen + LENGTH_ARALINK_HEADER_FIELD;
8877+ else
8878+ //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
8879+ hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
8880+
8881+ // Update the pTxBlk->Priv.
8882+ pTxBlk->Priv = TXINFO_SIZE + TXWI_SIZE + hwHdrLen;
8883+
8884+ // pTxInfo->USBDMApktLen now just a temp value and will to correct latter.
8885+ RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(pTxBlk->Priv), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE);
8886+
8887+ // Copy it.
8888+ NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, pTxBlk->Priv);
8889+#ifdef RT_BIG_ENDIAN
8890+ RTMPFrameEndianChange(pAd, (PUCHAR)(pWirelessPacket+ TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE);
8891+#endif // RT_BIG_ENDIAN //
8892+ pHTTXContext->CurWriteRealPos += pTxBlk->Priv;
8893+ pWirelessPacket += pTxBlk->Priv;
8894+ }
8895+ }
8896+ else
8897+ { // For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer.
8898+
8899+ Status = ((pHTTXContext->bCurWriting == TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE);
8900+ if (Status == NDIS_STATUS_SUCCESS)
8901+ {
8902+ fillOffset = (pHTTXContext->CurWritePosition + pTxBlk->Priv);
8903+ pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
8904+
8905+ //hwHdrLen = pTxBlk->MpduHeaderLen;
8906+ NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, pTxBlk->MpduHeaderLen);
8907+ pWirelessPacket += (pTxBlk->MpduHeaderLen);
8908+ pTxBlk->Priv += pTxBlk->MpduHeaderLen;
8909+ }
8910+ else
8911+ { // It should not happened now unless we are going to shutdown.
8912+ DBGPRINT(RT_DEBUG_ERROR, ("WriteMultiTxResource():bCurWriting is FALSE when handle sub-sequent frames.\n"));
8913+ Status = NDIS_STATUS_FAILURE;
8914+ }
8915+ }
8916+
8917+
8918+ // We unlock it here to prevent the first 8 bytes maybe over-write issue.
8919+ // 1. First we got CurWritePosition but the first 8 bytes still not write to the pTxContext.
8920+ // 2. An interrupt break our routine and handle bulk-out complete.
8921+ // 3. In the bulk-out compllete, it need to do another bulk-out,
8922+ // if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition,
8923+ // but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE.
8924+ // 4. Interrupt complete.
8925+ // 5. Our interrupted routine go back and fill the first 8 bytes to pTxContext.
8926+ // 6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition.
8927+ // and the packet will wrong.
8928+ RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
8929+
8930+ if (Status != NDIS_STATUS_SUCCESS)
8931+ {
8932+ DBGPRINT(RT_DEBUG_ERROR,("WriteMultiTxResource: CWPos = %ld, NBOutPos = %ld.\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition));
8933+ goto done;
8934+ }
8935+
8936+ // Copy the frame content into DMA buffer and update the pTxBlk->Priv
8937+ NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
8938+ pWirelessPacket += pTxBlk->SrcBufLen;
8939+ pTxBlk->Priv += pTxBlk->SrcBufLen;
8940+
8941+done:
8942+ // Release the skb buffer here
8943+ RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
8944+
8945+ return(Status);
8946+
8947+}
8948+
8949+
8950+VOID RtmpUSB_FinalWriteTxResource(
8951+ IN PRTMP_ADAPTER pAd,
8952+ IN TX_BLK *pTxBlk,
8953+ IN USHORT totalMPDUSize,
8954+ IN USHORT TxIdx)
8955+{
8956+ UCHAR QueIdx;
8957+ HT_TX_CONTEXT *pHTTXContext;
8958+ UINT32 fillOffset;
8959+ TXINFO_STRUC *pTxInfo;
8960+ TXWI_STRUC *pTxWI;
8961+ UINT32 USBDMApktLen, padding;
8962+ unsigned long IrqFlags;
8963+ PUCHAR pWirelessPacket;
8964+
8965+ QueIdx = pTxBlk->QueIdx;
8966+ pHTTXContext = &pAd->TxContext[QueIdx];
8967+
8968+ RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
8969+
8970+ if (pHTTXContext->bCurWriting == TRUE)
8971+ {
8972+ fillOffset = pHTTXContext->CurWritePosition;
8973+ if (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) || ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition))
8974+ && (pHTTXContext->bCopySavePad == TRUE))
8975+ pWirelessPacket = (PUCHAR)(&pHTTXContext->SavedPad[0]);
8976+ else
8977+ pWirelessPacket = (PUCHAR)(&pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset]);
8978+
8979+ //
8980+ // Update TxInfo->USBDMApktLen ,
8981+ // the length = TXWI_SIZE + 802.11_hdr + 802.11_hdr_pad + payload_of_all_batch_frames + Bulk-Out-padding
8982+ //
8983+ pTxInfo = (PTXINFO_STRUC)(pWirelessPacket);
8984+
8985+ // Calculate the bulk-out padding
8986+ USBDMApktLen = pTxBlk->Priv - TXINFO_SIZE;
8987+ padding = (4 - (USBDMApktLen % 4)) & 0x03; // round up to 4 byte alignment
8988+ USBDMApktLen += padding;
8989+
8990+ pTxInfo->USBDMATxPktLen = USBDMApktLen;
8991+
8992+ //
8993+ // Update TXWI->MPDUtotalByteCount ,
8994+ // the length = 802.11 header + payload_of_all_batch_frames
8995+ pTxWI= (PTXWI_STRUC)(pWirelessPacket + TXINFO_SIZE);
8996+ pTxWI->MPDUtotalByteCount = totalMPDUSize;
8997+
8998+ //
8999+ // Update the pHTTXContext->CurWritePosition
9000+ //
9001+ pHTTXContext->CurWritePosition += (TXINFO_SIZE + USBDMApktLen);
9002+ if ((pHTTXContext->CurWritePosition + 3906)> MAX_TXBULK_LIMIT)
9003+ { // Add 3906 for prevent the NextBulkOut packet size is a A-RALINK/A-MSDU Frame.
9004+ pHTTXContext->CurWritePosition = 8;
9005+ pTxInfo->SwUseLastRound = 1;
9006+ }
9007+ pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
9008+
9009+
9010+ //
9011+ // Zero the last padding.
9012+ //
9013+ pWirelessPacket = (&pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset + pTxBlk->Priv]);
9014+ NdisZeroMemory(pWirelessPacket, padding + 8);
9015+
9016+ // Finally, set bCurWriting as FALSE
9017+ pHTTXContext->bCurWriting = FALSE;
9018+
9019+ }
9020+ else
9021+ { // It should not happened now unless we are going to shutdown.
9022+ DBGPRINT(RT_DEBUG_ERROR, ("FinalWriteTxResource():bCurWriting is FALSE when handle last frames.\n"));
9023+ }
9024+
9025+ RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
9026+
9027+}
9028+
9029+
9030+VOID RtmpUSBDataLastTxIdx(
9031+ IN PRTMP_ADAPTER pAd,
9032+ IN UCHAR QueIdx,
9033+ IN USHORT TxIdx)
9034+{
9035+ // DO nothing for USB.
9036+}
9037+
9038+
9039+/*
9040+ When can do bulk-out:
9041+ 1. TxSwFreeIdx < TX_RING_SIZE;
9042+ It means has at least one Ring entity is ready for bulk-out, kick it out.
9043+ 2. If TxSwFreeIdx == TX_RING_SIZE
9044+ Check if the CurWriting flag is FALSE, if it's FALSE, we can do kick out.
9045+
9046+*/
9047+VOID RtmpUSBDataKickOut(
9048+ IN PRTMP_ADAPTER pAd,
9049+ IN TX_BLK *pTxBlk,
9050+ IN UCHAR QueIdx)
9051+{
9052+ RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
9053+ RTUSBKickBulkOut(pAd);
9054+
9055+}
9056+
9057+
9058+/*
9059+ Must be run in Interrupt context
9060+ This function handle RT2870 specific TxDesc and cpu index update and kick the packet out.
9061+ */
9062+int RtmpUSBMgmtKickOut(
9063+ IN RTMP_ADAPTER *pAd,
9064+ IN UCHAR QueIdx,
9065+ IN PNDIS_PACKET pPacket,
9066+ IN PUCHAR pSrcBufVA,
9067+ IN UINT SrcBufLen)
9068+{
9069+ PTXINFO_STRUC pTxInfo;
9070+ ULONG BulkOutSize;
9071+ UCHAR padLen;
9072+ PUCHAR pDest;
9073+ ULONG SwIdx = pAd->MgmtRing.TxCpuIdx;
9074+ PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[SwIdx].AllocVa;
9075+ unsigned long IrqFlags;
9076+
9077+
9078+ pTxInfo = (PTXINFO_STRUC)(pSrcBufVA);
9079+
9080+ // Build our URB for USBD
9081+ BulkOutSize = SrcBufLen;
9082+ BulkOutSize = (BulkOutSize + 3) & (~3);
9083+ RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(BulkOutSize - TXINFO_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
9084+
9085+ BulkOutSize += 4; // Always add 4 extra bytes at every packet.
9086+
9087+ // If BulkOutSize is multiple of BulkOutMaxPacketSize, add extra 4 bytes again.
9088+ if ((BulkOutSize % pAd->BulkOutMaxPacketSize) == 0)
9089+ BulkOutSize += 4;
9090+
9091+ padLen = BulkOutSize - SrcBufLen;
9092+ ASSERT((padLen <= RTMP_PKT_TAIL_PADDING));
9093+
9094+ // Now memzero all extra padding bytes.
9095+ pDest = (PUCHAR)(pSrcBufVA + SrcBufLen);
9096+ skb_put(GET_OS_PKT_TYPE(pPacket), padLen);
9097+ NdisZeroMemory(pDest, padLen);
9098+
9099+ RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
9100+
9101+ pAd->MgmtRing.Cell[pAd->MgmtRing.TxCpuIdx].pNdisPacket = pPacket;
9102+ pMLMEContext->TransferBuffer = (PTX_BUFFER)(GET_OS_PKT_DATAPTR(pPacket));
9103+
9104+ // Length in TxInfo should be 8 less than bulkout size.
9105+ pMLMEContext->BulkOutSize = BulkOutSize;
9106+ pMLMEContext->InUse = TRUE;
9107+ pMLMEContext->bWaitingBulkOut = TRUE;
9108+
9109+
9110+ //for debug
9111+ //hex_dump("RtmpUSBMgmtKickOut", &pMLMEContext->TransferBuffer->field.WirelessPacket[0], (pMLMEContext->BulkOutSize > 16 ? 16 : pMLMEContext->BulkOutSize));
9112+
9113+ //pAd->RalinkCounters.KickTxCount++;
9114+ //pAd->RalinkCounters.OneSecTxDoneCount++;
9115+
9116+ //if (pAd->MgmtRing.TxSwFreeIdx == MGMT_RING_SIZE)
9117+ // needKickOut = TRUE;
9118+
9119+ // Decrease the TxSwFreeIdx and Increase the TX_CTX_IDX
9120+ pAd->MgmtRing.TxSwFreeIdx--;
9121+ INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);
9122+
9123+ RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);
9124+
9125+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
9126+ //if (needKickOut)
9127+ RTUSBKickBulkOut(pAd);
9128+
9129+ return 0;
9130+}
9131+
9132+
9133+VOID RtmpUSBNullFrameKickOut(
9134+ IN RTMP_ADAPTER *pAd,
9135+ IN UCHAR QueIdx,
9136+ IN UCHAR *pNullFrame,
9137+ IN UINT32 frameLen)
9138+{
9139+ if (pAd->NullContext.InUse == FALSE)
9140+ {
9141+ PTX_CONTEXT pNullContext;
9142+ PTXINFO_STRUC pTxInfo;
9143+ PTXWI_STRUC pTxWI;
9144+ PUCHAR pWirelessPkt;
9145+
9146+ pNullContext = &(pAd->NullContext);
9147+
9148+ // Set the in use bit
9149+ pNullContext->InUse = TRUE;
9150+ pWirelessPkt = (PUCHAR)&pNullContext->TransferBuffer->field.WirelessPacket[0];
9151+
9152+ RTMPZeroMemory(&pWirelessPkt[0], 100);
9153+ pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[0];
9154+ RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(HEADER_802_11)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
9155+ pTxInfo->QSEL = FIFO_EDCA;
9156+ pTxWI = (PTXWI_STRUC)&pWirelessPkt[TXINFO_SIZE];
9157+ RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(HEADER_802_11)),
9158+ 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
9159+#ifdef RT_BIG_ENDIAN
9160+ RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
9161+#endif // RT_BIG_ENDIAN //
9162+
9163+ RTMPMoveMemory(&pWirelessPkt[TXWI_SIZE+TXINFO_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11));
9164+#ifdef RT_BIG_ENDIAN
9165+ RTMPFrameEndianChange(pAd, (PUCHAR)&pWirelessPkt[TXINFO_SIZE + TXWI_SIZE], DIR_WRITE, FALSE);
9166+#endif // RT_BIG_ENDIAN //
9167+ pAd->NullContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;
9168+
9169+ // Fill out frame length information for global Bulk out arbitor
9170+ //pNullContext->BulkOutSize = TransferBufferLength;
9171+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - send NULL Frame @%d Mbps...\n", RateIdToMbps[pAd->CommonCfg.TxRate]));
9172+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);
9173+
9174+ // Kick bulk out
9175+ RTUSBKickBulkOut(pAd);
9176+ }
9177+
9178+}
9179+
9180+#ifdef CONFIG_STA_SUPPORT
9181+/*
9182+ ========================================================================
9183+
9184+ Routine Description:
9185+ Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound
9186+
9187+ Arguments:
9188+ pRxD Pointer to the Rx descriptor
9189+
9190+ Return Value:
9191+ NDIS_STATUS_SUCCESS No err
9192+ NDIS_STATUS_FAILURE Error
9193+
9194+ Note:
9195+
9196+ ========================================================================
9197+*/
9198+NDIS_STATUS RTMPCheckRxError(
9199+ IN PRTMP_ADAPTER pAd,
9200+ IN PHEADER_802_11 pHeader,
9201+ IN PRXWI_STRUC pRxWI,
9202+ IN PRT28XX_RXD_STRUC pRxINFO)
9203+{
9204+ PCIPHER_KEY pWpaKey;
9205+ INT dBm;
9206+
9207+ if (pAd->bPromiscuous == TRUE)
9208+ return(NDIS_STATUS_SUCCESS);
9209+ if(pRxINFO == NULL)
9210+ return(NDIS_STATUS_FAILURE);
9211+
9212+ // Phy errors & CRC errors
9213+ if (pRxINFO->Crc)
9214+ {
9215+ // Check RSSI for Noise Hist statistic collection.
9216+ dBm = (INT) (pRxWI->RSSI0) - pAd->BbpRssiToDbmDelta;
9217+ if (dBm <= -87)
9218+ pAd->StaCfg.RPIDensity[0] += 1;
9219+ else if (dBm <= -82)
9220+ pAd->StaCfg.RPIDensity[1] += 1;
9221+ else if (dBm <= -77)
9222+ pAd->StaCfg.RPIDensity[2] += 1;
9223+ else if (dBm <= -72)
9224+ pAd->StaCfg.RPIDensity[3] += 1;
9225+ else if (dBm <= -67)
9226+ pAd->StaCfg.RPIDensity[4] += 1;
9227+ else if (dBm <= -62)
9228+ pAd->StaCfg.RPIDensity[5] += 1;
9229+ else if (dBm <= -57)
9230+ pAd->StaCfg.RPIDensity[6] += 1;
9231+ else if (dBm > -57)
9232+ pAd->StaCfg.RPIDensity[7] += 1;
9233+
9234+ return(NDIS_STATUS_FAILURE);
9235+ }
9236+
9237+ // Add Rx size to channel load counter, we should ignore error counts
9238+ pAd->StaCfg.CLBusyBytes += (pRxWI->MPDUtotalByteCount+ 14);
9239+
9240+ // Drop ToDs promiscous frame, it is opened due to CCX 2 channel load statistics
9241+ if (pHeader->FC.ToDs)
9242+ {
9243+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("Err;FC.ToDs\n"));
9244+ return NDIS_STATUS_FAILURE;
9245+ }
9246+
9247+ // Paul 04-03 for OFDM Rx length issue
9248+ if (pRxWI->MPDUtotalByteCount > MAX_AGGREGATION_SIZE)
9249+ {
9250+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("received packet too long\n"));
9251+ return NDIS_STATUS_FAILURE;
9252+ }
9253+
9254+ // Drop not U2M frames, cant's drop here because we will drop beacon in this case
9255+ // I am kind of doubting the U2M bit operation
9256+ // if (pRxD->U2M == 0)
9257+ // return(NDIS_STATUS_FAILURE);
9258+
9259+ // drop decyption fail frame
9260+ if (pRxINFO->Decrypted && pRxINFO->CipherErr)
9261+ {
9262+
9263+ //
9264+ // MIC Error
9265+ //
9266+ if ((pRxINFO->CipherErr == 2) && pRxINFO->MyBss)
9267+ {
9268+ pWpaKey = &pAd->SharedKey[BSS0][pRxWI->KeyIndex];
9269+ RTMPReportMicError(pAd, pWpaKey);
9270+ DBGPRINT_RAW(RT_DEBUG_ERROR,("Rx MIC Value error\n"));
9271+ }
9272+
9273+ if (pRxINFO->Decrypted &&
9274+ (pAd->SharedKey[BSS0][pRxWI->KeyIndex].CipherAlg == CIPHER_AES) &&
9275+ (pHeader->Sequence == pAd->FragFrame.Sequence))
9276+ {
9277+ //
9278+ // Acceptable since the First FragFrame no CipherErr problem.
9279+ //
9280+ return(NDIS_STATUS_SUCCESS);
9281+ }
9282+
9283+ return(NDIS_STATUS_FAILURE);
9284+ }
9285+
9286+ return(NDIS_STATUS_SUCCESS);
9287+}
9288+
9289+VOID RT28xxUsbStaAsicForceWakeup(
9290+ IN PRTMP_ADAPTER pAd,
9291+ IN BOOLEAN bFromTx)
9292+{
9293+ AUTO_WAKEUP_STRUC AutoWakeupCfg;
9294+
9295+ AutoWakeupCfg.word = 0;
9296+ RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
9297+
9298+ AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
9299+
9300+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
9301+}
9302+
9303+VOID RT28xxUsbStaAsicSleepThenAutoWakeup(
9304+ IN PRTMP_ADAPTER pAd,
9305+ IN USHORT TbttNumToNextWakeUp)
9306+{
9307+ AUTO_WAKEUP_STRUC AutoWakeupCfg;
9308+
9309+ // we have decided to SLEEP, so at least do it for a BEACON period.
9310+ if (TbttNumToNextWakeUp == 0)
9311+ TbttNumToNextWakeUp = 1;
9312+
9313+ AutoWakeupCfg.word = 0;
9314+ RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
9315+
9316+ AutoWakeupCfg.field.NumofSleepingTbtt = TbttNumToNextWakeUp - 1;
9317+ AutoWakeupCfg.field.EnableAutoWakeup = 1;
9318+ AutoWakeupCfg.field.AutoLeadTime = 5;
9319+ RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
9320+
9321+ AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02); // send POWER-SAVE command to MCU. Timeout 40us.
9322+
9323+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE);
9324+
9325+}
9326+#endif // CONFIG_STA_SUPPORT //
9327+
9328+VOID RT28xxUsbMlmeRadioOn(
9329+ IN PRTMP_ADAPTER pAd)
9330+{
9331+ DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOn()\n"));
9332+
9333+ if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
9334+ return;
9335+
9336+#ifdef CONFIG_STA_SUPPORT
9337+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
9338+ {
9339+ AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
9340+ RTMPusecDelay(10000);
9341+ }
9342+#endif // CONFIG_STA_SUPPORT //
9343+ NICResetFromError(pAd);
9344+
9345+ // Enable Tx/Rx
9346+ RTMPEnableRxTx(pAd);
9347+
9348+#ifdef RT3070
9349+ if (IS_RT3071(pAd))
9350+ {
9351+ RT30xxReverseRFSleepModeSetup(pAd);
9352+ }
9353+#endif // RT3070 //
9354+
9355+ // Clear Radio off flag
9356+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
9357+
9358+#ifdef CONFIG_STA_SUPPORT
9359+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
9360+ RTUSBBulkReceive(pAd);
9361+#endif // CONFIG_STA_SUPPORT //
9362+
9363+ // Set LED
9364+ RTMPSetLED(pAd, LED_RADIO_ON);
9365+}
9366+
9367+VOID RT28xxUsbMlmeRadioOFF(
9368+ IN PRTMP_ADAPTER pAd)
9369+{
9370+ WPDMA_GLO_CFG_STRUC GloCfg;
9371+ UINT32 Value, i;
9372+
9373+ DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOFF()\n"));
9374+
9375+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
9376+ return;
9377+
9378+ // Set LED
9379+ RTMPSetLED(pAd, LED_RADIO_OFF);
9380+ // Set Radio off flag
9381+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
9382+
9383+#ifdef CONFIG_STA_SUPPORT
9384+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
9385+ {
9386+ // Link down first if any association exists
9387+ if (INFRA_ON(pAd) || ADHOC_ON(pAd))
9388+ LinkDown(pAd, FALSE);
9389+ RTMPusecDelay(10000);
9390+
9391+ //==========================================
9392+ // Clean up old bss table
9393+ BssTableInit(&pAd->ScanTab);
9394+ }
9395+#endif // CONFIG_STA_SUPPORT //
9396+
9397+
9398+ if (pAd->CommonCfg.BBPCurrentBW == BW_40)
9399+ {
9400+ // Must using 40MHz.
9401+ AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel);
9402+ }
9403+ else
9404+ {
9405+ // Must using 20MHz.
9406+ AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
9407+ }
9408+
9409+ // Disable Tx/Rx DMA
9410+ RTUSBReadMACRegister(pAd, WPDMA_GLO_CFG, &GloCfg.word); // disable DMA
9411+ GloCfg.field.EnableTxDMA = 0;
9412+ GloCfg.field.EnableRxDMA = 0;
9413+ RTUSBWriteMACRegister(pAd, WPDMA_GLO_CFG, GloCfg.word); // abort all TX rings
9414+
9415+ // Waiting for DMA idle
9416+ i = 0;
9417+ do
9418+ {
9419+ RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
9420+ if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
9421+ break;
9422+
9423+ RTMPusecDelay(1000);
9424+ }while (i++ < 100);
9425+
9426+ // Disable MAC Tx/Rx
9427+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
9428+ Value &= (0xfffffff3);
9429+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
9430+
9431+ // MAC_SYS_CTRL => value = 0x0 => 40mA
9432+ //RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0);
9433+
9434+ // PWR_PIN_CFG => value = 0x0 => 40mA
9435+ //RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0);
9436+
9437+ // TX_PIN_CFG => value = 0x0 => 20mA
9438+ //RTMP_IO_WRITE32(pAd, TX_PIN_CFG, 0);
9439+
9440+#ifdef CONFIG_STA_SUPPORT
9441+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
9442+ AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
9443+#endif // CONFIG_STA_SUPPORT //
9444+}
9445+
9446--- /dev/null
9447+++ b/drivers/staging/rt3070/common/cmm_data.c
9448@@ -0,0 +1,2827 @@
9449+/*
9450+ *************************************************************************
9451+ * Ralink Tech Inc.
9452+ * 5F., No.36, Taiyuan St., Jhubei City,
9453+ * Hsinchu County 302,
9454+ * Taiwan, R.O.C.
9455+ *
9456+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
9457+ *
9458+ * This program is free software; you can redistribute it and/or modify *
9459+ * it under the terms of the GNU General Public License as published by *
9460+ * the Free Software Foundation; either version 2 of the License, or *
9461+ * (at your option) any later version. *
9462+ * *
9463+ * This program is distributed in the hope that it will be useful, *
9464+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
9465+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
9466+ * GNU General Public License for more details. *
9467+ * *
9468+ * You should have received a copy of the GNU General Public License *
9469+ * along with this program; if not, write to the *
9470+ * Free Software Foundation, Inc., *
9471+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
9472+ * *
9473+ *************************************************************************
9474+*/
9475+
9476+#include "../rt_config.h"
9477+
9478+#define MAX_TX_IN_TBTT (16)
9479+
9480+
9481+UCHAR SNAP_802_1H[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
9482+UCHAR SNAP_BRIDGE_TUNNEL[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8};
9483+// Add Cisco Aironet SNAP heade for CCX2 support
9484+UCHAR SNAP_AIRONET[] = {0xaa, 0xaa, 0x03, 0x00, 0x40, 0x96, 0x00, 0x00};
9485+UCHAR CKIP_LLC_SNAP[] = {0xaa, 0xaa, 0x03, 0x00, 0x40, 0x96, 0x00, 0x02};
9486+UCHAR EAPOL_LLC_SNAP[]= {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8e};
9487+UCHAR EAPOL[] = {0x88, 0x8e};
9488+UCHAR TPID[] = {0x81, 0x00}; /* VLAN related */
9489+
9490+UCHAR IPX[] = {0x81, 0x37};
9491+UCHAR APPLE_TALK[] = {0x80, 0xf3};
9492+UCHAR RateIdToPlcpSignal[12] = {
9493+ 0, /* RATE_1 */ 1, /* RATE_2 */ 2, /* RATE_5_5 */ 3, /* RATE_11 */ // see BBP spec
9494+ 11, /* RATE_6 */ 15, /* RATE_9 */ 10, /* RATE_12 */ 14, /* RATE_18 */ // see IEEE802.11a-1999 p.14
9495+ 9, /* RATE_24 */ 13, /* RATE_36 */ 8, /* RATE_48 */ 12 /* RATE_54 */ }; // see IEEE802.11a-1999 p.14
9496+
9497+UCHAR OfdmSignalToRateId[16] = {
9498+ RATE_54, RATE_54, RATE_54, RATE_54, // OFDM PLCP Signal = 0, 1, 2, 3 respectively
9499+ RATE_54, RATE_54, RATE_54, RATE_54, // OFDM PLCP Signal = 4, 5, 6, 7 respectively
9500+ RATE_48, RATE_24, RATE_12, RATE_6, // OFDM PLCP Signal = 8, 9, 10, 11 respectively
9501+ RATE_54, RATE_36, RATE_18, RATE_9, // OFDM PLCP Signal = 12, 13, 14, 15 respectively
9502+};
9503+
9504+UCHAR OfdmRateToRxwiMCS[12] = {
9505+ 0, 0, 0, 0,
9506+ 0, 1, 2, 3, // OFDM rate 6,9,12,18 = rxwi mcs 0,1,2,3
9507+ 4, 5, 6, 7, // OFDM rate 24,36,48,54 = rxwi mcs 4,5,6,7
9508+};
9509+UCHAR RxwiMCSToOfdmRate[12] = {
9510+ RATE_6, RATE_9, RATE_12, RATE_18,
9511+ RATE_24, RATE_36, RATE_48, RATE_54, // OFDM rate 6,9,12,18 = rxwi mcs 0,1,2,3
9512+ 4, 5, 6, 7, // OFDM rate 24,36,48,54 = rxwi mcs 4,5,6,7
9513+};
9514+
9515+char* MCSToMbps[] = {"1Mbps","2Mbps","5.5Mbps","11Mbps","06Mbps","09Mbps","12Mbps","18Mbps","24Mbps","36Mbps","48Mbps","54Mbps","MM-0","MM-1","MM-2","MM-3","MM-4","MM-5","MM-6","MM-7","MM-8","MM-9","MM-10","MM-11","MM-12","MM-13","MM-14","MM-15","MM-32","ee1","ee2","ee3"};
9516+
9517+UCHAR default_cwmin[]={CW_MIN_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS-1, CW_MIN_IN_BITS-2};
9518+//UCHAR default_cwmax[]={CW_MAX_IN_BITS, CW_MAX_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS-1};
9519+UCHAR default_sta_aifsn[]={3,7,2,2};
9520+
9521+UCHAR MapUserPriorityToAccessCategory[8] = {QID_AC_BE, QID_AC_BK, QID_AC_BK, QID_AC_BE, QID_AC_VI, QID_AC_VI, QID_AC_VO, QID_AC_VO};
9522+
9523+
9524+/*
9525+ ========================================================================
9526+
9527+ Routine Description:
9528+ API for MLME to transmit management frame to AP (BSS Mode)
9529+ or station (IBSS Mode)
9530+
9531+ Arguments:
9532+ pAd Pointer to our adapter
9533+ pData Pointer to the outgoing 802.11 frame
9534+ Length Size of outgoing management frame
9535+
9536+ Return Value:
9537+ NDIS_STATUS_FAILURE
9538+ NDIS_STATUS_PENDING
9539+ NDIS_STATUS_SUCCESS
9540+
9541+ IRQL = PASSIVE_LEVEL
9542+ IRQL = DISPATCH_LEVEL
9543+
9544+ Note:
9545+
9546+ ========================================================================
9547+*/
9548+NDIS_STATUS MiniportMMRequest(
9549+ IN PRTMP_ADAPTER pAd,
9550+ IN UCHAR QueIdx,
9551+ IN PUCHAR pData,
9552+ IN UINT Length)
9553+{
9554+ PNDIS_PACKET pPacket;
9555+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
9556+ ULONG FreeNum;
9557+ UCHAR IrqState;
9558+ UCHAR rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; //RTMP_HW_HDR_LEN];
9559+
9560+ ASSERT(Length <= MGMT_DMA_BUFFER_SIZE);
9561+
9562+ QueIdx=3;
9563+
9564+ // 2860C use Tx Ring
9565+
9566+ IrqState = pAd->irq_disabled;
9567+
9568+ do
9569+ {
9570+ // Reset is in progress, stop immediately
9571+ if ( RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
9572+ RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)||
9573+ !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
9574+ {
9575+ Status = NDIS_STATUS_FAILURE;
9576+ break;
9577+ }
9578+
9579+ // Check Free priority queue
9580+ // Since we use PBF Queue2 for management frame. Its corresponding DMA ring should be using TxRing.
9581+
9582+ // 2860C use Tx Ring
9583+ if (pAd->MACVersion == 0x28600100)
9584+ {
9585+ FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
9586+ }
9587+ else
9588+ {
9589+ FreeNum = GET_MGMTRING_FREENO(pAd);
9590+ }
9591+
9592+ if ((FreeNum > 0))
9593+ {
9594+ // We need to reserve space for rtmp hardware header. i.e., TxWI for RT2860 and TxInfo+TxWI for RT2870
9595+ NdisZeroMemory(&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE));
9596+ Status = RTMPAllocateNdisPacket(pAd, &pPacket, (PUCHAR)&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE), pData, Length);
9597+ if (Status != NDIS_STATUS_SUCCESS)
9598+ {
9599+ DBGPRINT(RT_DEBUG_WARN, ("MiniportMMRequest (error:: can't allocate NDIS PACKET)\n"));
9600+ break;
9601+ }
9602+
9603+ //pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
9604+ //pAd->CommonCfg.MlmeRate = RATE_2;
9605+
9606+
9607+ Status = MlmeHardTransmit(pAd, QueIdx, pPacket);
9608+ if (Status != NDIS_STATUS_SUCCESS)
9609+ RTMPFreeNdisPacket(pAd, pPacket);
9610+ }
9611+ else
9612+ {
9613+ pAd->RalinkCounters.MgmtRingFullCount++;
9614+ DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in MgmtRing, MgmtRingFullCount=%ld!\n",
9615+ QueIdx, pAd->RalinkCounters.MgmtRingFullCount));
9616+ }
9617+
9618+ } while (FALSE);
9619+
9620+
9621+ return Status;
9622+}
9623+
9624+
9625+
9626+NDIS_STATUS MlmeDataHardTransmit(
9627+ IN PRTMP_ADAPTER pAd,
9628+ IN UCHAR QueIdx,
9629+ IN PNDIS_PACKET pPacket);
9630+
9631+#define MAX_DATAMM_RETRY 3
9632+/*
9633+ ========================================================================
9634+
9635+ Routine Description:
9636+ API for MLME to transmit management frame to AP (BSS Mode)
9637+ or station (IBSS Mode)
9638+
9639+ Arguments:
9640+ pAd Pointer to our adapter
9641+ pData Pointer to the outgoing 802.11 frame
9642+ Length Size of outgoing management frame
9643+
9644+ Return Value:
9645+ NDIS_STATUS_FAILURE
9646+ NDIS_STATUS_PENDING
9647+ NDIS_STATUS_SUCCESS
9648+
9649+ IRQL = PASSIVE_LEVEL
9650+ IRQL = DISPATCH_LEVEL
9651+
9652+ Note:
9653+
9654+ ========================================================================
9655+*/
9656+NDIS_STATUS MiniportDataMMRequest(
9657+ IN PRTMP_ADAPTER pAd,
9658+ IN UCHAR QueIdx,
9659+ IN PUCHAR pData,
9660+ IN UINT Length)
9661+{
9662+ PNDIS_PACKET pPacket;
9663+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
9664+ ULONG FreeNum;
9665+ int retry = 0;
9666+ UCHAR IrqState;
9667+ UCHAR rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; //RTMP_HW_HDR_LEN];
9668+
9669+ ASSERT(Length <= MGMT_DMA_BUFFER_SIZE);
9670+
9671+ // 2860C use Tx Ring
9672+ IrqState = pAd->irq_disabled;
9673+
9674+ do
9675+ {
9676+ // Reset is in progress, stop immediately
9677+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
9678+ RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)||
9679+ !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
9680+ {
9681+ Status = NDIS_STATUS_FAILURE;
9682+ break;
9683+ }
9684+
9685+ // Check Free priority queue
9686+ // Since we use PBF Queue2 for management frame. Its corresponding DMA ring should be using TxRing.
9687+
9688+ // 2860C use Tx Ring
9689+
9690+ // free Tx(QueIdx) resources
9691+ FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
9692+
9693+ if ((FreeNum > 0))
9694+ {
9695+ // We need to reserve space for rtmp hardware header. i.e., TxWI for RT2860 and TxInfo+TxWI for RT2870
9696+ NdisZeroMemory(&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE));
9697+ Status = RTMPAllocateNdisPacket(pAd, &pPacket, (PUCHAR)&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE), pData, Length);
9698+ if (Status != NDIS_STATUS_SUCCESS)
9699+ {
9700+ DBGPRINT(RT_DEBUG_WARN, ("MiniportMMRequest (error:: can't allocate NDIS PACKET)\n"));
9701+ break;
9702+ }
9703+
9704+ //pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
9705+ //pAd->CommonCfg.MlmeRate = RATE_2;
9706+
9707+
9708+ Status = MlmeDataHardTransmit(pAd, QueIdx, pPacket);
9709+ if (Status != NDIS_STATUS_SUCCESS)
9710+ RTMPFreeNdisPacket(pAd, pPacket);
9711+ retry = MAX_DATAMM_RETRY;
9712+ }
9713+ else
9714+ {
9715+ retry ++;
9716+
9717+ printk("retry %d\n", retry);
9718+ pAd->RalinkCounters.MgmtRingFullCount++;
9719+
9720+ if (retry >= MAX_DATAMM_RETRY)
9721+ {
9722+ DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in DataRing, MgmtRingFullCount=%ld!\n",
9723+ QueIdx, pAd->RalinkCounters.MgmtRingFullCount));
9724+ }
9725+ }
9726+
9727+ } while (retry < MAX_DATAMM_RETRY);
9728+
9729+
9730+ return Status;
9731+}
9732+
9733+
9734+
9735+
9736+
9737+
9738+/*
9739+ ========================================================================
9740+
9741+ Routine Description:
9742+ Copy frame from waiting queue into relative ring buffer and set
9743+ appropriate ASIC register to kick hardware transmit function
9744+
9745+ Arguments:
9746+ pAd Pointer to our adapter
9747+ pBuffer Pointer to memory of outgoing frame
9748+ Length Size of outgoing management frame
9749+
9750+ Return Value:
9751+ NDIS_STATUS_FAILURE
9752+ NDIS_STATUS_PENDING
9753+ NDIS_STATUS_SUCCESS
9754+
9755+ IRQL = PASSIVE_LEVEL
9756+ IRQL = DISPATCH_LEVEL
9757+
9758+ Note:
9759+
9760+ ========================================================================
9761+*/
9762+NDIS_STATUS MlmeHardTransmit(
9763+ IN PRTMP_ADAPTER pAd,
9764+ IN UCHAR QueIdx,
9765+ IN PNDIS_PACKET pPacket)
9766+{
9767+ if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
9768+#ifdef CARRIER_DETECTION_SUPPORT
9769+#endif // CARRIER_DETECTION_SUPPORT //
9770+ )
9771+ {
9772+ return NDIS_STATUS_FAILURE;
9773+ }
9774+
9775+ return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
9776+
9777+}
9778+
9779+NDIS_STATUS MlmeDataHardTransmit(
9780+ IN PRTMP_ADAPTER pAd,
9781+ IN UCHAR QueIdx,
9782+ IN PNDIS_PACKET pPacket)
9783+{
9784+ if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
9785+#ifdef CARRIER_DETECTION_SUPPORT
9786+#endif // CARRIER_DETECTION_SUPPORT //
9787+ )
9788+ {
9789+ return NDIS_STATUS_FAILURE;
9790+ }
9791+
9792+#ifdef RT2870
9793+ return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
9794+#endif // RT2870 //
9795+}
9796+
9797+
9798+
9799+
9800+
9801+NDIS_STATUS MlmeHardTransmitMgmtRing(
9802+ IN PRTMP_ADAPTER pAd,
9803+ IN UCHAR QueIdx,
9804+ IN PNDIS_PACKET pPacket)
9805+{
9806+ PACKET_INFO PacketInfo;
9807+ PUCHAR pSrcBufVA;
9808+ UINT SrcBufLen;
9809+ PHEADER_802_11 pHeader_802_11;
9810+ BOOLEAN bAckRequired, bInsertTimestamp;
9811+ UCHAR MlmeRate;
9812+ PTXWI_STRUC pFirstTxWI;
9813+ MAC_TABLE_ENTRY *pMacEntry = NULL;
9814+
9815+ RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
9816+
9817+ // Make sure MGMT ring resource won't be used by other threads
9818+// sample, for IRQ LOCK -> SEM LOCK
9819+// IrqState = pAd->irq_disabled;
9820+// if (!IrqState)
9821+ RTMP_SEM_LOCK(&pAd->MgmtRingLock);
9822+
9823+
9824+ if (pSrcBufVA == NULL)
9825+ {
9826+ // The buffer shouldn't be NULL
9827+// if (!IrqState)
9828+ RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
9829+ return NDIS_STATUS_FAILURE;
9830+ }
9831+
9832+#ifdef CONFIG_STA_SUPPORT
9833+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
9834+ {
9835+ // outgoing frame always wakeup PHY to prevent frame lost
9836+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
9837+ AsicForceWakeup(pAd, TRUE);
9838+ }
9839+#endif // CONFIG_STA_SUPPORT //
9840+
9841+ pFirstTxWI = (PTXWI_STRUC)(pSrcBufVA + TXINFO_SIZE);
9842+ pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE); //TXWI_SIZE);
9843+
9844+ if (pHeader_802_11->Addr1[0] & 0x01)
9845+ {
9846+ MlmeRate = pAd->CommonCfg.BasicMlmeRate;
9847+ }
9848+ else
9849+ {
9850+ MlmeRate = pAd->CommonCfg.MlmeRate;
9851+ }
9852+
9853+ // Verify Mlme rate for a / g bands.
9854+ if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) // 11A band
9855+ MlmeRate = RATE_6;
9856+
9857+ if ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
9858+ (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL))
9859+ {
9860+ pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1);
9861+ }
9862+
9863+#ifdef CONFIG_STA_SUPPORT
9864+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
9865+ {
9866+ // Fixed W52 with Activity scan issue in ABG_MIXED and ABGN_MIXED mode.
9867+ if (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED
9868+#ifdef DOT11_N_SUPPORT
9869+ || pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED
9870+#endif // DOT11_N_SUPPORT //
9871+ )
9872+ {
9873+ if (pAd->LatchRfRegs.Channel > 14)
9874+ pAd->CommonCfg.MlmeTransmit.field.MODE = 1;
9875+ else
9876+ pAd->CommonCfg.MlmeTransmit.field.MODE = 0;
9877+ }
9878+ }
9879+#endif // CONFIG_STA_SUPPORT //
9880+
9881+ //
9882+ // Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE)
9883+ // Snice it's been set to 0 while on MgtMacHeaderInit
9884+ // By the way this will cause frame to be send on PWR_SAVE failed.
9885+ //
9886+ // pHeader_802_11->FC.PwrMgmt = 0; // (pAd->StaCfg.Psm == PWR_SAVE);
9887+ //
9888+ // In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame
9889+#ifdef CONFIG_STA_SUPPORT
9890+ // Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD
9891+ if ((pHeader_802_11->FC.Type != BTYPE_DATA) && (pHeader_802_11->FC.Type != BTYPE_CNTL))
9892+ {
9893+ if ((pAd->StaCfg.Psm == PWR_SAVE) &&
9894+ (pHeader_802_11->FC.SubType == SUBTYPE_ACTION))
9895+ pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
9896+ else
9897+ pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE;
9898+ }
9899+#endif // CONFIG_STA_SUPPORT //
9900+
9901+ bInsertTimestamp = FALSE;
9902+ if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL
9903+ {
9904+#ifdef CONFIG_STA_SUPPORT
9905+ //Set PM bit in ps-poll, to fix WLK 1.2 PowerSaveMode_ext failure issue.
9906+ if ((pAd->OpMode == OPMODE_STA) && (pHeader_802_11->FC.SubType == SUBTYPE_PS_POLL))
9907+ {
9908+ pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
9909+ }
9910+#endif // CONFIG_STA_SUPPORT //
9911+ bAckRequired = FALSE;
9912+ }
9913+ else // BTYPE_MGMT or BTYPE_DATA(must be NULL frame)
9914+ {
9915+ //pAd->Sequence++;
9916+ //pHeader_802_11->Sequence = pAd->Sequence;
9917+
9918+ if (pHeader_802_11->Addr1[0] & 0x01) // MULTICAST, BROADCAST
9919+ {
9920+ bAckRequired = FALSE;
9921+ pHeader_802_11->Duration = 0;
9922+ }
9923+ else
9924+ {
9925+ bAckRequired = TRUE;
9926+ pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14);
9927+ if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP)
9928+ {
9929+ bInsertTimestamp = TRUE;
9930+ }
9931+ }
9932+ }
9933+
9934+ pHeader_802_11->Sequence = pAd->Sequence++;
9935+ if (pAd->Sequence >0xfff)
9936+ pAd->Sequence = 0;
9937+
9938+ // Before radar detection done, mgmt frame can not be sent but probe req
9939+ // Because we need to use probe req to trigger driver to send probe req in passive scan
9940+ if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ)
9941+ && (pAd->CommonCfg.bIEEE80211H == 1)
9942+ && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE))
9943+ {
9944+ DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n"));
9945+// if (!IrqState)
9946+ RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
9947+ return (NDIS_STATUS_FAILURE);
9948+ }
9949+
9950+#ifdef RT_BIG_ENDIAN
9951+ RTMPFrameEndianChange(pAd, (PUCHAR)pHeader_802_11, DIR_WRITE, FALSE);
9952+#endif
9953+
9954+ //
9955+ // fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET
9956+ // should always has only one ohysical buffer, and the whole frame size equals
9957+ // to the first scatter buffer size
9958+ //
9959+
9960+ // Initialize TX Descriptor
9961+ // For inter-frame gap, the number is for this frame and next frame
9962+ // For MLME rate, we will fix as 2Mb to match other vendor's implement
9963+// pAd->CommonCfg.MlmeTransmit.field.MODE = 1;
9964+
9965+// management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not.
9966+ if (pMacEntry == NULL)
9967+ {
9968+ RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE,
9969+ 0, RESERVED_WCID, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE), PID_MGMT, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
9970+ }
9971+ else
9972+ {
9973+ RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE,
9974+ bInsertTimestamp, FALSE, bAckRequired, FALSE,
9975+ 0, pMacEntry->Aid, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE),
9976+ pMacEntry->MaxHTPhyMode.field.MCS, 0,
9977+ (UCHAR)pMacEntry->MaxHTPhyMode.field.MCS,
9978+ IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
9979+ }
9980+
9981+#ifdef RT_BIG_ENDIAN
9982+ RTMPWIEndianChange((PUCHAR)pFirstTxWI, TYPE_TXWI);
9983+#endif
9984+
9985+ // Now do hardware-depened kick out.
9986+ HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen);
9987+
9988+ // Make sure to release MGMT ring resource
9989+// if (!IrqState)
9990+ RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
9991+ return NDIS_STATUS_SUCCESS;
9992+}
9993+
9994+
9995+/********************************************************************************
9996+
9997+ New DeQueue Procedures.
9998+
9999+ ********************************************************************************/
10000+
10001+#define DEQUEUE_LOCK(lock, bIntContext, IrqFlags) \
10002+ do{ \
10003+ if (bIntContext == FALSE) \
10004+ RTMP_IRQ_LOCK((lock), IrqFlags); \
10005+ }while(0)
10006+
10007+#define DEQUEUE_UNLOCK(lock, bIntContext, IrqFlags) \
10008+ do{ \
10009+ if (bIntContext == FALSE) \
10010+ RTMP_IRQ_UNLOCK((lock), IrqFlags); \
10011+ }while(0)
10012+
10013+
10014+/*
10015+ ========================================================================
10016+ Tx Path design algorithm:
10017+ Basically, we divide the packets into four types, Broadcast/Multicast, 11N Rate(AMPDU, AMSDU, Normal), B/G Rate(ARALINK, Normal),
10018+ Specific Packet Type. Following show the classification rule and policy for each kinds of packets.
10019+ Classification Rule=>
10020+ Multicast: (*addr1 & 0x01) == 0x01
10021+ Specific : bDHCPFrame, bARPFrame, bEAPOLFrame, etc.
10022+ 11N Rate : If peer support HT
10023+ (1).AMPDU -- If TXBA is negotiated.
10024+ (2).AMSDU -- If AMSDU is capable for both peer and ourself.
10025+ *). AMSDU can embedded in a AMPDU, but now we didn't support it.
10026+ (3).Normal -- Other packets which send as 11n rate.
10027+
10028+ B/G Rate : If peer is b/g only.
10029+ (1).ARALINK-- If both of peer/us supprot Ralink proprietary Aggregation and the TxRate is large than RATE_6
10030+ (2).Normal -- Other packets which send as b/g rate.
10031+ Fragment:
10032+ The packet must be unicast, NOT A-RALINK, NOT A-MSDU, NOT 11n, then can consider about fragment.
10033+
10034+ Classified Packet Handle Rule=>
10035+ Multicast:
10036+ No ACK, //pTxBlk->bAckRequired = FALSE;
10037+ No WMM, //pTxBlk->bWMM = FALSE;
10038+ No piggyback, //pTxBlk->bPiggyBack = FALSE;
10039+ Force LowRate, //pTxBlk->bForceLowRate = TRUE;
10040+ Specific : Basically, for specific packet, we should handle it specifically, but now all specific packets are use
10041+ the same policy to handle it.
10042+ Force LowRate, //pTxBlk->bForceLowRate = TRUE;
10043+
10044+ 11N Rate :
10045+ No piggyback, //pTxBlk->bPiggyBack = FALSE;
10046+
10047+ (1).AMSDU
10048+ pTxBlk->bWMM = TRUE;
10049+ (2).AMPDU
10050+ pTxBlk->bWMM = TRUE;
10051+ (3).Normal
10052+
10053+ B/G Rate :
10054+ (1).ARALINK
10055+
10056+ (2).Normal
10057+ ========================================================================
10058+*/
10059+static UCHAR TxPktClassification(
10060+ IN RTMP_ADAPTER *pAd,
10061+ IN PNDIS_PACKET pPacket)
10062+{
10063+ UCHAR TxFrameType = TX_UNKOWN_FRAME;
10064+ UCHAR Wcid;
10065+ MAC_TABLE_ENTRY *pMacEntry = NULL;
10066+#ifdef DOT11_N_SUPPORT
10067+ BOOLEAN bHTRate = FALSE;
10068+#endif // DOT11_N_SUPPORT //
10069+
10070+ Wcid = RTMP_GET_PACKET_WCID(pPacket);
10071+ if (Wcid == MCAST_WCID)
10072+ { // Handle for RA is Broadcast/Multicast Address.
10073+ return TX_MCAST_FRAME;
10074+ }
10075+
10076+ // Handle for unicast packets
10077+ pMacEntry = &pAd->MacTab.Content[Wcid];
10078+ if (RTMP_GET_PACKET_LOWRATE(pPacket))
10079+ { // It's a specific packet need to force low rate, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame
10080+ TxFrameType = TX_LEGACY_FRAME;
10081+ }
10082+#ifdef DOT11_N_SUPPORT
10083+ else if (IS_HT_RATE(pMacEntry))
10084+ { // it's a 11n capable packet
10085+
10086+ // Depends on HTPhyMode to check if the peer support the HTRate transmission.
10087+ // Currently didn't support A-MSDU embedded in A-MPDU
10088+ bHTRate = TRUE;
10089+ if (RTMP_GET_PACKET_MOREDATA(pPacket) || (pMacEntry->PsMode == PWR_SAVE))
10090+ TxFrameType = TX_LEGACY_FRAME;
10091+#ifdef UAPSD_AP_SUPPORT
10092+ else if (RTMP_GET_PACKET_EOSP(pPacket))
10093+ TxFrameType = TX_LEGACY_FRAME;
10094+#endif // UAPSD_AP_SUPPORT //
10095+ else if((pMacEntry->TXBAbitmap & (1<<(RTMP_GET_PACKET_UP(pPacket)))) != 0)
10096+ return TX_AMPDU_FRAME;
10097+ else if(CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AMSDU_INUSED))
10098+ return TX_AMSDU_FRAME;
10099+ else
10100+ TxFrameType = TX_LEGACY_FRAME;
10101+ }
10102+#endif // DOT11_N_SUPPORT //
10103+ else
10104+ { // it's a legacy b/g packet.
10105+ if ((CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE) && pAd->CommonCfg.bAggregationCapable) &&
10106+ (RTMP_GET_PACKET_TXRATE(pPacket) >= RATE_6) &&
10107+ (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))))
10108+ { // if peer support Ralink Aggregation, we use it.
10109+ TxFrameType = TX_RALINK_FRAME;
10110+ }
10111+ else
10112+ {
10113+ TxFrameType = TX_LEGACY_FRAME;
10114+ }
10115+ }
10116+
10117+ // Currently, our fragment only support when a unicast packet send as NOT-ARALINK, NOT-AMSDU and NOT-AMPDU.
10118+ if ((RTMP_GET_PACKET_FRAGMENTS(pPacket) > 1) && (TxFrameType == TX_LEGACY_FRAME))
10119+ TxFrameType = TX_FRAG_FRAME;
10120+
10121+ return TxFrameType;
10122+}
10123+
10124+
10125+BOOLEAN RTMP_FillTxBlkInfo(
10126+ IN RTMP_ADAPTER *pAd,
10127+ IN TX_BLK *pTxBlk)
10128+{
10129+ PACKET_INFO PacketInfo;
10130+ PNDIS_PACKET pPacket;
10131+ PMAC_TABLE_ENTRY pMacEntry = NULL;
10132+
10133+ pPacket = pTxBlk->pPacket;
10134+ RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen);
10135+
10136+ pTxBlk->Wcid = RTMP_GET_PACKET_WCID(pPacket);
10137+ pTxBlk->apidx = RTMP_GET_PACKET_IF(pPacket);
10138+ pTxBlk->UserPriority = RTMP_GET_PACKET_UP(pPacket);
10139+ pTxBlk->FrameGap = IFS_HTTXOP; // ASIC determine Frame Gap
10140+
10141+ if (RTMP_GET_PACKET_CLEAR_EAP_FRAME(pTxBlk->pPacket))
10142+ TX_BLK_SET_FLAG(pTxBlk, fTX_bClearEAPFrame);
10143+ else
10144+ TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bClearEAPFrame);
10145+
10146+ // Default to clear this flag
10147+ TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bForceNonQoS);
10148+
10149+
10150+ if (pTxBlk->Wcid == MCAST_WCID)
10151+ {
10152+ pTxBlk->pMacEntry = NULL;
10153+ {
10154+#ifdef MCAST_RATE_SPECIFIC
10155+ PUCHAR pDA = GET_OS_PKT_DATAPTR(pPacket);
10156+ if (((*pDA & 0x01) == 0x01) && (*pDA != 0xff))
10157+ pTxBlk->pTransmit = &pAd->CommonCfg.MCastPhyMode;
10158+ else
10159+#endif // MCAST_RATE_SPECIFIC //
10160+ pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
10161+ }
10162+
10163+ TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired); // AckRequired = FALSE, when broadcast packet in Adhoc mode.
10164+ //TX_BLK_SET_FLAG(pTxBlk, fTX_bForceLowRate);
10165+ TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAllowFrag);
10166+ TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
10167+ if (RTMP_GET_PACKET_MOREDATA(pPacket))
10168+ {
10169+ TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
10170+ }
10171+
10172+ }
10173+ else
10174+ {
10175+ pTxBlk->pMacEntry = &pAd->MacTab.Content[pTxBlk->Wcid];
10176+ pTxBlk->pTransmit = &pTxBlk->pMacEntry->HTPhyMode;
10177+
10178+ pMacEntry = pTxBlk->pMacEntry;
10179+
10180+
10181+ // For all unicast packets, need Ack unless the Ack Policy is not set as NORMAL_ACK.
10182+ if (pAd->CommonCfg.AckPolicy[pTxBlk->QueIdx] != NORMAL_ACK)
10183+ TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired);
10184+ else
10185+ TX_BLK_SET_FLAG(pTxBlk, fTX_bAckRequired);
10186+
10187+ {
10188+
10189+#ifdef CONFIG_STA_SUPPORT
10190+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
10191+ {
10192+
10193+ // If support WMM, enable it.
10194+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
10195+ CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))
10196+ TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM);
10197+
10198+// if (pAd->StaCfg.bAutoTxRateSwitch)
10199+// TX_BLK_SET_FLAG(pTxBlk, fTX_AutoRateSwitch);
10200+ }
10201+#endif // CONFIG_STA_SUPPORT //
10202+ }
10203+
10204+ if (pTxBlk->TxFrameType == TX_LEGACY_FRAME)
10205+ {
10206+ if ( (RTMP_GET_PACKET_LOWRATE(pPacket)) ||
10207+ ((pAd->OpMode == OPMODE_AP) && (pMacEntry->MaxHTPhyMode.field.MODE == MODE_CCK) && (pMacEntry->MaxHTPhyMode.field.MCS == RATE_1)))
10208+ { // Specific packet, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame, need force low rate.
10209+ pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
10210+#ifdef DOT11_N_SUPPORT
10211+ // Modify the WMM bit for ICV issue. If we have a packet with EOSP field need to set as 1, how to handle it???
10212+ if (IS_HT_STA(pTxBlk->pMacEntry) &&
10213+ (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_RALINK_CHIPSET)) &&
10214+ ((pAd->CommonCfg.bRdg == TRUE) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_RDG_CAPABLE)))
10215+ {
10216+ TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
10217+ TX_BLK_SET_FLAG(pTxBlk, fTX_bForceNonQoS);
10218+ }
10219+#endif // DOT11_N_SUPPORT //
10220+ }
10221+
10222+#ifdef DOT11_N_SUPPORT
10223+ if ( (IS_HT_RATE(pMacEntry) == FALSE) &&
10224+ (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE)))
10225+ { // Currently piggy-back only support when peer is operate in b/g mode.
10226+ TX_BLK_SET_FLAG(pTxBlk, fTX_bPiggyBack);
10227+ }
10228+#endif // DOT11_N_SUPPORT //
10229+
10230+ if (RTMP_GET_PACKET_MOREDATA(pPacket))
10231+ {
10232+ TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
10233+ }
10234+#ifdef UAPSD_AP_SUPPORT
10235+ if (RTMP_GET_PACKET_EOSP(pPacket))
10236+ {
10237+ TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM_UAPSD_EOSP);
10238+ }
10239+#endif // UAPSD_AP_SUPPORT //
10240+ }
10241+ else if (pTxBlk->TxFrameType == TX_FRAG_FRAME)
10242+ {
10243+ TX_BLK_SET_FLAG(pTxBlk, fTX_bAllowFrag);
10244+ }
10245+
10246+ pMacEntry->DebugTxCount++;
10247+ }
10248+
10249+ return TRUE;
10250+
10251+FillTxBlkErr:
10252+ return FALSE;
10253+}
10254+
10255+
10256+BOOLEAN CanDoAggregateTransmit(
10257+ IN RTMP_ADAPTER *pAd,
10258+ IN NDIS_PACKET *pPacket,
10259+ IN TX_BLK *pTxBlk)
10260+{
10261+
10262+ //printk("Check if can do aggregation! TxFrameType=%d!\n", pTxBlk->TxFrameType);
10263+
10264+ if (RTMP_GET_PACKET_WCID(pPacket) == MCAST_WCID)
10265+ return FALSE;
10266+
10267+ if (RTMP_GET_PACKET_DHCP(pPacket) ||
10268+ RTMP_GET_PACKET_EAPOL(pPacket) ||
10269+ RTMP_GET_PACKET_WAI(pPacket))
10270+ return FALSE;
10271+
10272+ if ((pTxBlk->TxFrameType == TX_AMSDU_FRAME) &&
10273+ ((pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket))> (RX_BUFFER_AGGRESIZE - 100)))
10274+ { // For AMSDU, allow the packets with total length < max-amsdu size
10275+ return FALSE;
10276+ }
10277+
10278+ if ((pTxBlk->TxFrameType == TX_RALINK_FRAME) &&
10279+ (pTxBlk->TxPacketList.Number == 2))
10280+ { // For RALINK-Aggregation, allow two frames in one batch.
10281+ return FALSE;
10282+ }
10283+
10284+#ifdef CONFIG_STA_SUPPORT
10285+ if ((INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) // must be unicast to AP
10286+ return TRUE;
10287+ else
10288+#endif // CONFIG_STA_SUPPORT //
10289+ return FALSE;
10290+
10291+}
10292+
10293+
10294+/*
10295+ ========================================================================
10296+
10297+ Routine Description:
10298+ To do the enqueue operation and extract the first item of waiting
10299+ list. If a number of available shared memory segments could meet
10300+ the request of extracted item, the extracted item will be fragmented
10301+ into shared memory segments.
10302+
10303+ Arguments:
10304+ pAd Pointer to our adapter
10305+ pQueue Pointer to Waiting Queue
10306+
10307+ Return Value:
10308+ None
10309+
10310+ IRQL = DISPATCH_LEVEL
10311+
10312+ Note:
10313+
10314+ ========================================================================
10315+*/
10316+VOID RTMPDeQueuePacket(
10317+ IN PRTMP_ADAPTER pAd,
10318+ IN BOOLEAN bIntContext,
10319+ IN UCHAR QIdx, /* BulkOutPipeId */
10320+ IN UCHAR Max_Tx_Packets)
10321+{
10322+ PQUEUE_ENTRY pEntry = NULL;
10323+ PNDIS_PACKET pPacket;
10324+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
10325+ UCHAR Count=0;
10326+ PQUEUE_HEADER pQueue;
10327+ ULONG FreeNumber[NUM_OF_TX_RING];
10328+ UCHAR QueIdx, sQIdx, eQIdx;
10329+ unsigned long IrqFlags = 0;
10330+ BOOLEAN hasTxDesc = FALSE;
10331+ TX_BLK TxBlk;
10332+ TX_BLK *pTxBlk;
10333+
10334+#ifdef DBG_DIAGNOSE
10335+ BOOLEAN firstRound;
10336+ RtmpDiagStruct *pDiagStruct = &pAd->DiagStruct;
10337+#endif
10338+
10339+
10340+ if (QIdx == NUM_OF_TX_RING)
10341+ {
10342+ sQIdx = 0;
10343+//PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
10344+#ifdef CONFIG_STA_SUPPORT
10345+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
10346+ eQIdx = 3; // 4 ACs, start from 0.
10347+#endif // CONFIG_STA_SUPPORT //
10348+ }
10349+ else
10350+ {
10351+ sQIdx = eQIdx = QIdx;
10352+ }
10353+
10354+ for (QueIdx=sQIdx; QueIdx <= eQIdx; QueIdx++)
10355+ {
10356+ Count=0;
10357+
10358+ RT28XX_START_DEQUEUE(pAd, QueIdx, IrqFlags);
10359+
10360+#ifdef DBG_DIAGNOSE
10361+ firstRound = ((QueIdx == 0) ? TRUE : FALSE);
10362+#endif // DBG_DIAGNOSE //
10363+
10364+ while (1)
10365+ {
10366+ if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS |
10367+ fRTMP_ADAPTER_RADIO_OFF |
10368+ fRTMP_ADAPTER_RESET_IN_PROGRESS |
10369+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
10370+ fRTMP_ADAPTER_NIC_NOT_EXIST))))
10371+ {
10372+ RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
10373+ return;
10374+ }
10375+
10376+ if (Count >= Max_Tx_Packets)
10377+ break;
10378+
10379+ DEQUEUE_LOCK(&pAd->irq_lock, bIntContext, IrqFlags);
10380+ if (&pAd->TxSwQueue[QueIdx] == NULL)
10381+ {
10382+#ifdef DBG_DIAGNOSE
10383+ if (firstRound == TRUE)
10384+ pDiagStruct->TxSWQueCnt[pDiagStruct->ArrayCurIdx][0]++;
10385+#endif // DBG_DIAGNOSE //
10386+ DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
10387+ break;
10388+ }
10389+
10390+
10391+ // probe the Queue Head
10392+ pQueue = &pAd->TxSwQueue[QueIdx];
10393+ if ((pEntry = pQueue->Head) == NULL)
10394+ {
10395+ DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
10396+ break;
10397+ }
10398+
10399+ pTxBlk = &TxBlk;
10400+ NdisZeroMemory((PUCHAR)pTxBlk, sizeof(TX_BLK));
10401+ //InitializeQueueHeader(&pTxBlk->TxPacketList); // Didn't need it because we already memzero it.
10402+ pTxBlk->QueIdx = QueIdx;
10403+
10404+ pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
10405+
10406+ // Early check to make sure we have enoguh Tx Resource.
10407+ hasTxDesc = RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket);
10408+ if (!hasTxDesc)
10409+ {
10410+ pAd->PrivateInfo.TxRingFullCnt++;
10411+
10412+ DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
10413+
10414+ break;
10415+ }
10416+
10417+ pTxBlk->TxFrameType = TxPktClassification(pAd, pPacket);
10418+ pEntry = RemoveHeadQueue(pQueue);
10419+ pTxBlk->TotalFrameNum++;
10420+ pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket); // The real fragment number maybe vary
10421+ pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket);
10422+ pTxBlk->pPacket = pPacket;
10423+ InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket));
10424+
10425+ if (pTxBlk->TxFrameType == TX_RALINK_FRAME || pTxBlk->TxFrameType == TX_AMSDU_FRAME)
10426+ {
10427+ // Enhance SW Aggregation Mechanism
10428+ if (NEED_QUEUE_BACK_FOR_AGG(pAd, QueIdx, FreeNumber[QueIdx], pTxBlk->TxFrameType))
10429+ {
10430+ InsertHeadQueue(pQueue, PACKET_TO_QUEUE_ENTRY(pPacket));
10431+ DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
10432+ break;
10433+ }
10434+
10435+ do{
10436+ if((pEntry = pQueue->Head) == NULL)
10437+ break;
10438+
10439+ // For TX_AMSDU_FRAME/TX_RALINK_FRAME, Need to check if next pakcet can do aggregation.
10440+ pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
10441+ FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
10442+ hasTxDesc = RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket);
10443+ if ((hasTxDesc == FALSE) || (CanDoAggregateTransmit(pAd, pPacket, pTxBlk) == FALSE))
10444+ break;
10445+
10446+ //Remove the packet from the TxSwQueue and insert into pTxBlk
10447+ pEntry = RemoveHeadQueue(pQueue);
10448+ ASSERT(pEntry);
10449+ pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
10450+ pTxBlk->TotalFrameNum++;
10451+ pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket); // The real fragment number maybe vary
10452+ pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket);
10453+ InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket));
10454+ }while(1);
10455+
10456+ if (pTxBlk->TxPacketList.Number == 1)
10457+ pTxBlk->TxFrameType = TX_LEGACY_FRAME;
10458+ }
10459+
10460+#ifdef RT2870
10461+ DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
10462+#endif // RT2870 //
10463+
10464+ Count += pTxBlk->TxPacketList.Number;
10465+
10466+ // Do HardTransmit now.
10467+#ifdef CONFIG_STA_SUPPORT
10468+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
10469+ Status = STAHardTransmit(pAd, pTxBlk, QueIdx);
10470+#endif // CONFIG_STA_SUPPORT //
10471+ }
10472+
10473+ RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
10474+
10475+#ifdef RT2870
10476+ if (!hasTxDesc)
10477+ RTUSBKickBulkOut(pAd);
10478+#endif // RT2870 //
10479+
10480+#ifdef BLOCK_NET_IF
10481+ if ((pAd->blockQueueTab[QueIdx].SwTxQueueBlockFlag == TRUE)
10482+ && (pAd->TxSwQueue[QueIdx].Number < 1))
10483+ {
10484+ releaseNetIf(&pAd->blockQueueTab[QueIdx]);
10485+ }
10486+#endif // BLOCK_NET_IF //
10487+
10488+ }
10489+
10490+}
10491+
10492+
10493+/*
10494+ ========================================================================
10495+
10496+ Routine Description:
10497+ Calculates the duration which is required to transmit out frames
10498+ with given size and specified rate.
10499+
10500+ Arguments:
10501+ pAd Pointer to our adapter
10502+ Rate Transmit rate
10503+ Size Frame size in units of byte
10504+
10505+ Return Value:
10506+ Duration number in units of usec
10507+
10508+ IRQL = PASSIVE_LEVEL
10509+ IRQL = DISPATCH_LEVEL
10510+
10511+ Note:
10512+
10513+ ========================================================================
10514+*/
10515+USHORT RTMPCalcDuration(
10516+ IN PRTMP_ADAPTER pAd,
10517+ IN UCHAR Rate,
10518+ IN ULONG Size)
10519+{
10520+ ULONG Duration = 0;
10521+
10522+ if (Rate < RATE_FIRST_OFDM_RATE) // CCK
10523+ {
10524+ if ((Rate > RATE_1) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED))
10525+ Duration = 96; // 72+24 preamble+plcp
10526+ else
10527+ Duration = 192; // 144+48 preamble+plcp
10528+
10529+ Duration += (USHORT)((Size << 4) / RateIdTo500Kbps[Rate]);
10530+ if ((Size << 4) % RateIdTo500Kbps[Rate])
10531+ Duration ++;
10532+ }
10533+ else if (Rate <= RATE_LAST_OFDM_RATE)// OFDM rates
10534+ {
10535+ Duration = 20 + 6; // 16+4 preamble+plcp + Signal Extension
10536+ Duration += 4 * (USHORT)((11 + Size * 4) / RateIdTo500Kbps[Rate]);
10537+ if ((11 + Size * 4) % RateIdTo500Kbps[Rate])
10538+ Duration += 4;
10539+ }
10540+ else //mimo rate
10541+ {
10542+ Duration = 20 + 6; // 16+4 preamble+plcp + Signal Extension
10543+ }
10544+
10545+ return (USHORT)Duration;
10546+}
10547+
10548+
10549+/*
10550+ ========================================================================
10551+
10552+ Routine Description:
10553+ Calculates the duration which is required to transmit out frames
10554+ with given size and specified rate.
10555+
10556+ Arguments:
10557+ pTxWI Pointer to head of each MPDU to HW.
10558+ Ack Setting for Ack requirement bit
10559+ Fragment Setting for Fragment bit
10560+ RetryMode Setting for retry mode
10561+ Ifs Setting for IFS gap
10562+ Rate Setting for transmit rate
10563+ Service Setting for service
10564+ Length Frame length
10565+ TxPreamble Short or Long preamble when using CCK rates
10566+ QueIdx - 0-3, according to 802.11e/d4.4 June/2003
10567+
10568+ Return Value:
10569+ None
10570+
10571+ IRQL = PASSIVE_LEVEL
10572+ IRQL = DISPATCH_LEVEL
10573+
10574+ See also : BASmartHardTransmit() !!!
10575+
10576+ ========================================================================
10577+*/
10578+VOID RTMPWriteTxWI(
10579+ IN PRTMP_ADAPTER pAd,
10580+ IN PTXWI_STRUC pOutTxWI,
10581+ IN BOOLEAN FRAG,
10582+ IN BOOLEAN CFACK,
10583+ IN BOOLEAN InsTimestamp,
10584+ IN BOOLEAN AMPDU,
10585+ IN BOOLEAN Ack,
10586+ IN BOOLEAN NSeq, // HW new a sequence.
10587+ IN UCHAR BASize,
10588+ IN UCHAR WCID,
10589+ IN ULONG Length,
10590+ IN UCHAR PID,
10591+ IN UCHAR TID,
10592+ IN UCHAR TxRate,
10593+ IN UCHAR Txopmode,
10594+ IN BOOLEAN CfAck,
10595+ IN HTTRANSMIT_SETTING *pTransmit)
10596+{
10597+ PMAC_TABLE_ENTRY pMac = NULL;
10598+ TXWI_STRUC TxWI;
10599+ PTXWI_STRUC pTxWI;
10600+
10601+ if (WCID < MAX_LEN_OF_MAC_TABLE)
10602+ pMac = &pAd->MacTab.Content[WCID];
10603+
10604+ //
10605+ // Always use Long preamble before verifiation short preamble functionality works well.
10606+ // Todo: remove the following line if short preamble functionality works
10607+ //
10608+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
10609+ NdisZeroMemory(&TxWI, TXWI_SIZE);
10610+ pTxWI = &TxWI;
10611+
10612+ pTxWI->FRAG= FRAG;
10613+
10614+ pTxWI->CFACK = CFACK;
10615+ pTxWI->TS= InsTimestamp;
10616+ pTxWI->AMPDU = AMPDU;
10617+ pTxWI->ACK = Ack;
10618+ pTxWI->txop= Txopmode;
10619+
10620+ pTxWI->NSEQ = NSeq;
10621+ // John tune the performace with Intel Client in 20 MHz performance
10622+#ifdef DOT11_N_SUPPORT
10623+ BASize = pAd->CommonCfg.TxBASize;
10624+
10625+ if( BASize >7 )
10626+ BASize =7;
10627+ pTxWI->BAWinSize = BASize;
10628+ pTxWI->ShortGI = pTransmit->field.ShortGI;
10629+ pTxWI->STBC = pTransmit->field.STBC;
10630+#endif // DOT11_N_SUPPORT //
10631+
10632+ pTxWI->WirelessCliID = WCID;
10633+ pTxWI->MPDUtotalByteCount = Length;
10634+ pTxWI->PacketId = PID;
10635+
10636+ // If CCK or OFDM, BW must be 20
10637+ pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
10638+#ifdef DOT11N_DRAFT3
10639+ if (pTxWI->BW)
10640+ pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
10641+#endif // DOT11N_DRAFT3 //
10642+
10643+ pTxWI->MCS = pTransmit->field.MCS;
10644+ pTxWI->PHYMODE = pTransmit->field.MODE;
10645+ pTxWI->CFACK = CfAck;
10646+
10647+#ifdef DOT11_N_SUPPORT
10648+ if (pMac)
10649+ {
10650+ if (pAd->CommonCfg.bMIMOPSEnable)
10651+ {
10652+ if ((pMac->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
10653+ {
10654+ // Dynamic MIMO Power Save Mode
10655+ pTxWI->MIMOps = 1;
10656+ }
10657+ else if (pMac->MmpsMode == MMPS_STATIC)
10658+ {
10659+ // Static MIMO Power Save Mode
10660+ if (pTransmit->field.MODE >= MODE_HTMIX && pTransmit->field.MCS > 7)
10661+ {
10662+ pTxWI->MCS = 7;
10663+ pTxWI->MIMOps = 0;
10664+ }
10665+ }
10666+ }
10667+ //pTxWI->MIMOps = (pMac->PsMode == PWR_MMPS)? 1:0;
10668+ if (pMac->bIAmBadAtheros && (pMac->WepStatus != Ndis802_11WEPDisabled))
10669+ {
10670+ pTxWI->MpduDensity = 7;
10671+ }
10672+ else
10673+ {
10674+ pTxWI->MpduDensity = pMac->MpduDensity;
10675+ }
10676+ }
10677+#endif // DOT11_N_SUPPORT //
10678+
10679+ pTxWI->PacketId = pTxWI->MCS;
10680+ NdisMoveMemory(pOutTxWI, &TxWI, sizeof(TXWI_STRUC));
10681+}
10682+
10683+
10684+VOID RTMPWriteTxWI_Data(
10685+ IN PRTMP_ADAPTER pAd,
10686+ IN OUT PTXWI_STRUC pTxWI,
10687+ IN TX_BLK *pTxBlk)
10688+{
10689+ HTTRANSMIT_SETTING *pTransmit;
10690+ PMAC_TABLE_ENTRY pMacEntry;
10691+#ifdef DOT11_N_SUPPORT
10692+ UCHAR BASize;
10693+#endif // DOT11_N_SUPPORT //
10694+
10695+
10696+ ASSERT(pTxWI);
10697+
10698+ pTransmit = pTxBlk->pTransmit;
10699+ pMacEntry = pTxBlk->pMacEntry;
10700+
10701+
10702+ //
10703+ // Always use Long preamble before verifiation short preamble functionality works well.
10704+ // Todo: remove the following line if short preamble functionality works
10705+ //
10706+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
10707+ NdisZeroMemory(pTxWI, TXWI_SIZE);
10708+
10709+ pTxWI->FRAG = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag);
10710+ pTxWI->ACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAckRequired);
10711+ pTxWI->txop = pTxBlk->FrameGap;
10712+
10713+#ifdef CONFIG_STA_SUPPORT
10714+#ifdef QOS_DLS_SUPPORT
10715+ if (pMacEntry &&
10716+ (pAd->StaCfg.BssType == BSS_INFRA) &&
10717+ (pMacEntry->ValidAsDls == TRUE))
10718+ pTxWI->WirelessCliID = BSSID_WCID;
10719+ else
10720+#endif // QOS_DLS_SUPPORT //
10721+#endif // CONFIG_STA_SUPPORT //
10722+ pTxWI->WirelessCliID = pTxBlk->Wcid;
10723+
10724+ pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
10725+ pTxWI->CFACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bPiggyBack);
10726+
10727+ // If CCK or OFDM, BW must be 20
10728+ pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
10729+#ifdef DOT11_N_SUPPORT
10730+#ifdef DOT11N_DRAFT3
10731+ if (pTxWI->BW)
10732+ pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
10733+#endif // DOT11N_DRAFT3 //
10734+ pTxWI->AMPDU = ((pTxBlk->TxFrameType == TX_AMPDU_FRAME) ? TRUE : FALSE);
10735+
10736+ // John tune the performace with Intel Client in 20 MHz performance
10737+ BASize = pAd->CommonCfg.TxBASize;
10738+ if((pTxBlk->TxFrameType == TX_AMPDU_FRAME) && (pMacEntry))
10739+ {
10740+ UCHAR RABAOriIdx = 0; //The RA's BA Originator table index.
10741+
10742+ RABAOriIdx = pTxBlk->pMacEntry->BAOriWcidArray[pTxBlk->UserPriority];
10743+ BASize = pAd->BATable.BAOriEntry[RABAOriIdx].BAWinSize;
10744+ }
10745+
10746+ pTxWI->TxBF = pTransmit->field.TxBF;
10747+ pTxWI->BAWinSize = BASize;
10748+ pTxWI->ShortGI = pTransmit->field.ShortGI;
10749+ pTxWI->STBC = pTransmit->field.STBC;
10750+#endif // DOT11_N_SUPPORT //
10751+
10752+ pTxWI->MCS = pTransmit->field.MCS;
10753+ pTxWI->PHYMODE = pTransmit->field.MODE;
10754+
10755+#ifdef DOT11_N_SUPPORT
10756+ if (pMacEntry)
10757+ {
10758+ if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
10759+ {
10760+ // Dynamic MIMO Power Save Mode
10761+ pTxWI->MIMOps = 1;
10762+ }
10763+ else if (pMacEntry->MmpsMode == MMPS_STATIC)
10764+ {
10765+ // Static MIMO Power Save Mode
10766+ if (pTransmit->field.MODE >= MODE_HTMIX && pTransmit->field.MCS > 7)
10767+ {
10768+ pTxWI->MCS = 7;
10769+ pTxWI->MIMOps = 0;
10770+ }
10771+ }
10772+
10773+ if (pMacEntry->bIAmBadAtheros && (pMacEntry->WepStatus != Ndis802_11WEPDisabled))
10774+ {
10775+ pTxWI->MpduDensity = 7;
10776+ }
10777+ else
10778+ {
10779+ pTxWI->MpduDensity = pMacEntry->MpduDensity;
10780+ }
10781+ }
10782+#endif // DOT11_N_SUPPORT //
10783+
10784+#ifdef DBG_DIAGNOSE
10785+ if (pTxBlk->QueIdx== 0)
10786+ {
10787+ pAd->DiagStruct.TxDataCnt[pAd->DiagStruct.ArrayCurIdx]++;
10788+ pAd->DiagStruct.TxMcsCnt[pAd->DiagStruct.ArrayCurIdx][pTxWI->MCS]++;
10789+ }
10790+#endif // DBG_DIAGNOSE //
10791+
10792+ // for rate adapation
10793+ pTxWI->PacketId = pTxWI->MCS;
10794+#ifdef INF_AMAZON_SE
10795+/*Iverson patch for WMM A5-T07 ,WirelessStaToWirelessSta do not bulk out aggregate */
10796+ if( RTMP_GET_PACKET_NOBULKOUT(pTxBlk->pPacket))
10797+ {
10798+ if(pTxWI->PHYMODE == MODE_CCK)
10799+ {
10800+ pTxWI->PacketId = 6;
10801+ }
10802+ }
10803+#endif // INF_AMAZON_SE //
10804+}
10805+
10806+
10807+VOID RTMPWriteTxWI_Cache(
10808+ IN PRTMP_ADAPTER pAd,
10809+ IN OUT PTXWI_STRUC pTxWI,
10810+ IN TX_BLK *pTxBlk)
10811+{
10812+ PHTTRANSMIT_SETTING /*pTxHTPhyMode,*/ pTransmit;
10813+ PMAC_TABLE_ENTRY pMacEntry;
10814+
10815+ //
10816+ // update TXWI
10817+ //
10818+ pMacEntry = pTxBlk->pMacEntry;
10819+ pTransmit = pTxBlk->pTransmit;
10820+
10821+ //if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))
10822+ //if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pMacEntry))
10823+ //if (TX_BLK_TEST_FLAG(pTxBlk, fTX_AutoRateSwitch))
10824+ if (pMacEntry->bAutoTxRateSwitch)
10825+ {
10826+ pTxWI->txop = IFS_HTTXOP;
10827+
10828+ // If CCK or OFDM, BW must be 20
10829+ pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
10830+ pTxWI->ShortGI = pTransmit->field.ShortGI;
10831+ pTxWI->STBC = pTransmit->field.STBC;
10832+
10833+ pTxWI->MCS = pTransmit->field.MCS;
10834+ pTxWI->PHYMODE = pTransmit->field.MODE;
10835+
10836+ // set PID for TxRateSwitching
10837+ pTxWI->PacketId = pTransmit->field.MCS;
10838+ }
10839+
10840+#ifdef DOT11_N_SUPPORT
10841+ pTxWI->AMPDU = ((pMacEntry->NoBADataCountDown == 0) ? TRUE: FALSE);
10842+ pTxWI->MIMOps = 0;
10843+
10844+#ifdef DOT11N_DRAFT3
10845+ if (pTxWI->BW)
10846+ pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
10847+#endif // DOT11N_DRAFT3 //
10848+
10849+ if (pAd->CommonCfg.bMIMOPSEnable)
10850+ {
10851+ // MIMO Power Save Mode
10852+ if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
10853+ {
10854+ // Dynamic MIMO Power Save Mode
10855+ pTxWI->MIMOps = 1;
10856+ }
10857+ else if (pMacEntry->MmpsMode == MMPS_STATIC)
10858+ {
10859+ // Static MIMO Power Save Mode
10860+ if ((pTransmit->field.MODE >= MODE_HTMIX) && (pTransmit->field.MCS > 7))
10861+ {
10862+ pTxWI->MCS = 7;
10863+ pTxWI->MIMOps = 0;
10864+ }
10865+ }
10866+ }
10867+#endif // DOT11_N_SUPPORT //
10868+
10869+#ifdef DBG_DIAGNOSE
10870+ if (pTxBlk->QueIdx== 0)
10871+ {
10872+ pAd->DiagStruct.TxDataCnt[pAd->DiagStruct.ArrayCurIdx]++;
10873+ pAd->DiagStruct.TxMcsCnt[pAd->DiagStruct.ArrayCurIdx][pTxWI->MCS]++;
10874+ }
10875+#endif // DBG_DIAGNOSE //
10876+
10877+ pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
10878+
10879+}
10880+
10881+
10882+/*
10883+ ========================================================================
10884+
10885+ Routine Description:
10886+ Calculates the duration which is required to transmit out frames
10887+ with given size and specified rate.
10888+
10889+ Arguments:
10890+ pTxD Pointer to transmit descriptor
10891+ Ack Setting for Ack requirement bit
10892+ Fragment Setting for Fragment bit
10893+ RetryMode Setting for retry mode
10894+ Ifs Setting for IFS gap
10895+ Rate Setting for transmit rate
10896+ Service Setting for service
10897+ Length Frame length
10898+ TxPreamble Short or Long preamble when using CCK rates
10899+ QueIdx - 0-3, according to 802.11e/d4.4 June/2003
10900+
10901+ Return Value:
10902+ None
10903+
10904+ IRQL = PASSIVE_LEVEL
10905+ IRQL = DISPATCH_LEVEL
10906+
10907+ ========================================================================
10908+*/
10909+VOID RTMPWriteTxDescriptor(
10910+ IN PRTMP_ADAPTER pAd,
10911+ IN PTXD_STRUC pTxD,
10912+ IN BOOLEAN bWIV,
10913+ IN UCHAR QueueSEL)
10914+{
10915+ //
10916+ // Always use Long preamble before verifiation short preamble functionality works well.
10917+ // Todo: remove the following line if short preamble functionality works
10918+ //
10919+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
10920+
10921+ pTxD->WIV = (bWIV) ? 1: 0;
10922+ pTxD->QSEL= (QueueSEL);
10923+ if (pAd->bGenOneHCCA == TRUE)
10924+ pTxD->QSEL= FIFO_HCCA;
10925+ pTxD->DMADONE = 0;
10926+}
10927+
10928+
10929+// should be called only when -
10930+// 1. MEADIA_CONNECTED
10931+// 2. AGGREGATION_IN_USED
10932+// 3. Fragmentation not in used
10933+// 4. either no previous frame (pPrevAddr1=NULL) .OR. previoud frame is aggregatible
10934+BOOLEAN TxFrameIsAggregatible(
10935+ IN PRTMP_ADAPTER pAd,
10936+ IN PUCHAR pPrevAddr1,
10937+ IN PUCHAR p8023hdr)
10938+{
10939+
10940+ // can't aggregate EAPOL (802.1x) frame
10941+ if ((p8023hdr[12] == 0x88) && (p8023hdr[13] == 0x8e))
10942+ return FALSE;
10943+
10944+ // can't aggregate multicast/broadcast frame
10945+ if (p8023hdr[0] & 0x01)
10946+ return FALSE;
10947+
10948+ if (INFRA_ON(pAd)) // must be unicast to AP
10949+ return TRUE;
10950+ else if ((pPrevAddr1 == NULL) || MAC_ADDR_EQUAL(pPrevAddr1, p8023hdr)) // unicast to same STA
10951+ return TRUE;
10952+ else
10953+ return FALSE;
10954+}
10955+
10956+
10957+/*
10958+ ========================================================================
10959+
10960+ Routine Description:
10961+ Check the MSDU Aggregation policy
10962+ 1.HT aggregation is A-MSDU
10963+ 2.legaacy rate aggregation is software aggregation by Ralink.
10964+
10965+ Arguments:
10966+
10967+ Return Value:
10968+
10969+ Note:
10970+
10971+ ========================================================================
10972+*/
10973+BOOLEAN PeerIsAggreOn(
10974+ IN PRTMP_ADAPTER pAd,
10975+ IN ULONG TxRate,
10976+ IN PMAC_TABLE_ENTRY pMacEntry)
10977+{
10978+ ULONG AFlags = (fCLIENT_STATUS_AMSDU_INUSED | fCLIENT_STATUS_AGGREGATION_CAPABLE);
10979+
10980+ if (pMacEntry != NULL && CLIENT_STATUS_TEST_FLAG(pMacEntry, AFlags))
10981+ {
10982+#ifdef DOT11_N_SUPPORT
10983+ if (pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
10984+ {
10985+ return TRUE;
10986+ }
10987+#endif // DOT11_N_SUPPORT //
10988+
10989+#ifdef AGGREGATION_SUPPORT
10990+ if (TxRate >= RATE_6 && pAd->CommonCfg.bAggregationCapable && (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))))
10991+ { // legacy Ralink Aggregation support
10992+ return TRUE;
10993+ }
10994+#endif // AGGREGATION_SUPPORT //
10995+ }
10996+
10997+ return FALSE;
10998+
10999+}
11000+
11001+
11002+/*
11003+ ========================================================================
11004+
11005+ Routine Description:
11006+ Check and fine the packet waiting in SW queue with highest priority
11007+
11008+ Arguments:
11009+ pAd Pointer to our adapter
11010+
11011+ Return Value:
11012+ pQueue Pointer to Waiting Queue
11013+
11014+ IRQL = DISPATCH_LEVEL
11015+
11016+ Note:
11017+
11018+ ========================================================================
11019+*/
11020+PQUEUE_HEADER RTMPCheckTxSwQueue(
11021+ IN PRTMP_ADAPTER pAd,
11022+ OUT PUCHAR pQueIdx)
11023+{
11024+
11025+ ULONG Number;
11026+ // 2004-11-15 to be removed. test aggregation only
11027+// if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)) && (*pNumber < 2))
11028+// return NULL;
11029+
11030+ Number = pAd->TxSwQueue[QID_AC_BK].Number
11031+ + pAd->TxSwQueue[QID_AC_BE].Number
11032+ + pAd->TxSwQueue[QID_AC_VI].Number
11033+ + pAd->TxSwQueue[QID_AC_VO].Number
11034+ + pAd->TxSwQueue[QID_HCCA].Number;
11035+
11036+ if (pAd->TxSwQueue[QID_AC_VO].Head != NULL)
11037+ {
11038+ *pQueIdx = QID_AC_VO;
11039+ return (&pAd->TxSwQueue[QID_AC_VO]);
11040+ }
11041+ else if (pAd->TxSwQueue[QID_AC_VI].Head != NULL)
11042+ {
11043+ *pQueIdx = QID_AC_VI;
11044+ return (&pAd->TxSwQueue[QID_AC_VI]);
11045+ }
11046+ else if (pAd->TxSwQueue[QID_AC_BE].Head != NULL)
11047+ {
11048+ *pQueIdx = QID_AC_BE;
11049+ return (&pAd->TxSwQueue[QID_AC_BE]);
11050+ }
11051+ else if (pAd->TxSwQueue[QID_AC_BK].Head != NULL)
11052+ {
11053+ *pQueIdx = QID_AC_BK;
11054+ return (&pAd->TxSwQueue[QID_AC_BK]);
11055+ }
11056+ else if (pAd->TxSwQueue[QID_HCCA].Head != NULL)
11057+ {
11058+ *pQueIdx = QID_HCCA;
11059+ return (&pAd->TxSwQueue[QID_HCCA]);
11060+ }
11061+
11062+ // No packet pending in Tx Sw queue
11063+ *pQueIdx = QID_AC_BK;
11064+
11065+ return (NULL);
11066+}
11067+
11068+
11069+
11070+/*
11071+ ========================================================================
11072+
11073+ Routine Description:
11074+ Suspend MSDU transmission
11075+
11076+ Arguments:
11077+ pAd Pointer to our adapter
11078+
11079+ Return Value:
11080+ None
11081+
11082+ Note:
11083+
11084+ ========================================================================
11085+*/
11086+VOID RTMPSuspendMsduTransmission(
11087+ IN PRTMP_ADAPTER pAd)
11088+{
11089+ DBGPRINT(RT_DEBUG_TRACE,("SCANNING, suspend MSDU transmission ...\n"));
11090+
11091+
11092+ //
11093+ // Before BSS_SCAN_IN_PROGRESS, we need to keep Current R66 value and
11094+ // use Lowbound as R66 value on ScanNextChannel(...)
11095+ //
11096+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
11097+
11098+ // set BBP_R66 to 0x30/0x40 when scanning (AsicSwitchChannel will set R66 according to channel when scanning)
11099+ //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x26 + GET_LNA_GAIN(pAd)));
11100+ RTMPSetAGCInitValue(pAd, BW_20);
11101+
11102+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
11103+ //RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x000f0000); // abort all TX rings
11104+}
11105+
11106+
11107+/*
11108+ ========================================================================
11109+
11110+ Routine Description:
11111+ Resume MSDU transmission
11112+
11113+ Arguments:
11114+ pAd Pointer to our adapter
11115+
11116+ Return Value:
11117+ None
11118+
11119+ IRQL = DISPATCH_LEVEL
11120+
11121+ Note:
11122+
11123+ ========================================================================
11124+*/
11125+VOID RTMPResumeMsduTransmission(
11126+ IN PRTMP_ADAPTER pAd)
11127+{
11128+// UCHAR IrqState;
11129+
11130+ DBGPRINT(RT_DEBUG_TRACE,("SCAN done, resume MSDU transmission ...\n"));
11131+
11132+
11133+ // After finish BSS_SCAN_IN_PROGRESS, we need to restore Current R66 value
11134+ // R66 should not be 0
11135+ if (pAd->BbpTuning.R66CurrentValue == 0)
11136+ {
11137+ pAd->BbpTuning.R66CurrentValue = 0x38;
11138+ DBGPRINT_ERR(("RTMPResumeMsduTransmission, R66CurrentValue=0...\n"));
11139+ }
11140+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, pAd->BbpTuning.R66CurrentValue);
11141+
11142+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
11143+// sample, for IRQ LOCK to SEM LOCK
11144+// IrqState = pAd->irq_disabled;
11145+// if (IrqState)
11146+// RTMPDeQueuePacket(pAd, TRUE, NUM_OF_TX_RING, MAX_TX_PROCESS);
11147+// else
11148+ RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
11149+}
11150+
11151+
11152+UINT deaggregate_AMSDU_announce(
11153+ IN PRTMP_ADAPTER pAd,
11154+ PNDIS_PACKET pPacket,
11155+ IN PUCHAR pData,
11156+ IN ULONG DataSize)
11157+{
11158+ USHORT PayloadSize;
11159+ USHORT SubFrameSize;
11160+ PHEADER_802_3 pAMSDUsubheader;
11161+ UINT nMSDU;
11162+ UCHAR Header802_3[14];
11163+
11164+ PUCHAR pPayload, pDA, pSA, pRemovedLLCSNAP;
11165+ PNDIS_PACKET pClonePacket;
11166+
11167+
11168+
11169+ nMSDU = 0;
11170+
11171+ while (DataSize > LENGTH_802_3)
11172+ {
11173+
11174+ nMSDU++;
11175+
11176+ //hex_dump("subheader", pData, 64);
11177+ pAMSDUsubheader = (PHEADER_802_3)pData;
11178+ //pData += LENGTH_802_3;
11179+ PayloadSize = pAMSDUsubheader->Octet[1] + (pAMSDUsubheader->Octet[0]<<8);
11180+ SubFrameSize = PayloadSize + LENGTH_802_3;
11181+
11182+
11183+ if ((DataSize < SubFrameSize) || (PayloadSize > 1518 ))
11184+ {
11185+ break;
11186+ }
11187+
11188+ //printk("%d subframe: Size = %d\n", nMSDU, PayloadSize);
11189+
11190+ pPayload = pData + LENGTH_802_3;
11191+ pDA = pData;
11192+ pSA = pData + MAC_ADDR_LEN;
11193+
11194+ // convert to 802.3 header
11195+ CONVERT_TO_802_3(Header802_3, pDA, pSA, pPayload, PayloadSize, pRemovedLLCSNAP);
11196+
11197+#ifdef CONFIG_STA_SUPPORT
11198+ if ((Header802_3[12] == 0x88) && (Header802_3[13] == 0x8E) )
11199+ {
11200+ // avoid local heap overflow, use dyanamic allocation
11201+ MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
11202+ memmove(Elem->Msg+(LENGTH_802_11 + LENGTH_802_1_H), pPayload, PayloadSize);
11203+ Elem->MsgLen = LENGTH_802_11 + LENGTH_802_1_H + PayloadSize;
11204+ WpaEAPOLKeyAction(pAd, Elem);
11205+ kfree(Elem);
11206+ }
11207+#endif // CONFIG_STA_SUPPORT //
11208+
11209+#ifdef CONFIG_STA_SUPPORT
11210+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
11211+ {
11212+ if (pRemovedLLCSNAP)
11213+ {
11214+ pPayload -= LENGTH_802_3;
11215+ PayloadSize += LENGTH_802_3;
11216+ NdisMoveMemory(pPayload, &Header802_3[0], LENGTH_802_3);
11217+ }
11218+ }
11219+#endif // CONFIG_STA_SUPPORT //
11220+
11221+ pClonePacket = ClonePacket(pAd, pPacket, pPayload, PayloadSize);
11222+ if (pClonePacket)
11223+ {
11224+#ifdef CONFIG_STA_SUPPORT
11225+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
11226+ ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pClonePacket, RTMP_GET_PACKET_IF(pPacket));
11227+#endif // CONFIG_STA_SUPPORT //
11228+ }
11229+
11230+
11231+ // A-MSDU has padding to multiple of 4 including subframe header.
11232+ // align SubFrameSize up to multiple of 4
11233+ SubFrameSize = (SubFrameSize+3)&(~0x3);
11234+
11235+
11236+ if (SubFrameSize > 1528 || SubFrameSize < 32)
11237+ {
11238+ break;
11239+ }
11240+
11241+ if (DataSize > SubFrameSize)
11242+ {
11243+ pData += SubFrameSize;
11244+ DataSize -= SubFrameSize;
11245+ }
11246+ else
11247+ {
11248+ // end of A-MSDU
11249+ DataSize = 0;
11250+ }
11251+ }
11252+
11253+ // finally release original rx packet
11254+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
11255+
11256+ return nMSDU;
11257+}
11258+
11259+
11260+UINT BA_Reorder_AMSDU_Annnounce(
11261+ IN PRTMP_ADAPTER pAd,
11262+ IN PNDIS_PACKET pPacket)
11263+{
11264+ PUCHAR pData;
11265+ USHORT DataSize;
11266+ UINT nMSDU = 0;
11267+
11268+ pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
11269+ DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
11270+
11271+ nMSDU = deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize);
11272+
11273+ return nMSDU;
11274+}
11275+
11276+
11277+/*
11278+ ==========================================================================
11279+ Description:
11280+ Look up the MAC address in the MAC table. Return NULL if not found.
11281+ Return:
11282+ pEntry - pointer to the MAC entry; NULL is not found
11283+ ==========================================================================
11284+*/
11285+MAC_TABLE_ENTRY *MacTableLookup(
11286+ IN PRTMP_ADAPTER pAd,
11287+ PUCHAR pAddr)
11288+{
11289+ ULONG HashIdx;
11290+ MAC_TABLE_ENTRY *pEntry = NULL;
11291+
11292+ HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
11293+ pEntry = pAd->MacTab.Hash[HashIdx];
11294+
11295+ while (pEntry && (pEntry->ValidAsCLI || pEntry->ValidAsWDS || pEntry->ValidAsApCli || pEntry->ValidAsMesh))
11296+ {
11297+ if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
11298+ {
11299+ break;
11300+ }
11301+ else
11302+ pEntry = pEntry->pNext;
11303+ }
11304+
11305+ return pEntry;
11306+}
11307+
11308+MAC_TABLE_ENTRY *MacTableInsertEntry(
11309+ IN PRTMP_ADAPTER pAd,
11310+ IN PUCHAR pAddr,
11311+ IN UCHAR apidx,
11312+ IN BOOLEAN CleanAll)
11313+{
11314+ UCHAR HashIdx;
11315+ int i, FirstWcid;
11316+ MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
11317+// USHORT offset;
11318+// ULONG addr;
11319+
11320+ // if FULL, return
11321+ if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
11322+ return NULL;
11323+
11324+ FirstWcid = 1;
11325+#ifdef CONFIG_STA_SUPPORT
11326+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
11327+ if (pAd->StaCfg.BssType == BSS_INFRA)
11328+ FirstWcid = 2;
11329+#endif // CONFIG_STA_SUPPORT //
11330+
11331+ // allocate one MAC entry
11332+ NdisAcquireSpinLock(&pAd->MacTabLock);
11333+ for (i = FirstWcid; i< MAX_LEN_OF_MAC_TABLE; i++) // skip entry#0 so that "entry index == AID" for fast lookup
11334+ {
11335+ // pick up the first available vacancy
11336+ if ((pAd->MacTab.Content[i].ValidAsCLI == FALSE) &&
11337+ (pAd->MacTab.Content[i].ValidAsWDS == FALSE) &&
11338+ (pAd->MacTab.Content[i].ValidAsApCli== FALSE) &&
11339+ (pAd->MacTab.Content[i].ValidAsMesh == FALSE)
11340+#ifdef CONFIG_STA_SUPPORT
11341+#ifdef QOS_DLS_SUPPORT
11342+ && (pAd->MacTab.Content[i].ValidAsDls == FALSE)
11343+#endif // QOS_DLS_SUPPORT //
11344+#endif // CONFIG_STA_SUPPORT //
11345+ )
11346+ {
11347+ pEntry = &pAd->MacTab.Content[i];
11348+ if (CleanAll == TRUE)
11349+ {
11350+ pEntry->MaxSupportedRate = RATE_11;
11351+ pEntry->CurrTxRate = RATE_11;
11352+ NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
11353+ pEntry->PairwiseKey.KeyLen = 0;
11354+ pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
11355+ }
11356+#ifdef CONFIG_STA_SUPPORT
11357+#ifdef QOS_DLS_SUPPORT
11358+ if (apidx >= MIN_NET_DEVICE_FOR_DLS)
11359+ {
11360+ pEntry->ValidAsCLI = FALSE;
11361+ pEntry->ValidAsWDS = FALSE;
11362+ pEntry->ValidAsApCli = FALSE;
11363+ pEntry->ValidAsMesh = FALSE;
11364+ pEntry->ValidAsDls = TRUE;
11365+ pEntry->isCached = FALSE;
11366+ }
11367+ else
11368+#endif // QOS_DLS_SUPPORT //
11369+#endif // CONFIG_STA_SUPPORT //
11370+ {
11371+
11372+#ifdef CONFIG_STA_SUPPORT
11373+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
11374+ {
11375+ pEntry->ValidAsCLI = TRUE;
11376+ pEntry->ValidAsWDS = FALSE;
11377+ pEntry->ValidAsApCli = FALSE;
11378+ pEntry->ValidAsMesh = FALSE;
11379+ pEntry->ValidAsDls = FALSE;
11380+ }
11381+#endif // CONFIG_STA_SUPPORT //
11382+ }
11383+
11384+ pEntry->bIAmBadAtheros = FALSE;
11385+ pEntry->pAd = pAd;
11386+ pEntry->CMTimerRunning = FALSE;
11387+ pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
11388+ pEntry->RSNIE_Len = 0;
11389+ NdisZeroMemory(pEntry->R_Counter, sizeof(pEntry->R_Counter));
11390+ pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;
11391+
11392+ if (pEntry->ValidAsMesh)
11393+ pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_MESH);
11394+ else if (pEntry->ValidAsApCli)
11395+ pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_APCLI);
11396+ else if (pEntry->ValidAsWDS)
11397+ pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_WDS);
11398+#ifdef CONFIG_STA_SUPPORT
11399+#ifdef QOS_DLS_SUPPORT
11400+ else if (pEntry->ValidAsDls)
11401+ pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_DLS);
11402+#endif // QOS_DLS_SUPPORT //
11403+#endif // CONFIG_STA_SUPPORT //
11404+ else
11405+ pEntry->apidx = apidx;
11406+
11407+ {
11408+
11409+#ifdef CONFIG_STA_SUPPORT
11410+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
11411+ {
11412+ pEntry->AuthMode = pAd->StaCfg.AuthMode;
11413+ pEntry->WepStatus = pAd->StaCfg.WepStatus;
11414+ pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
11415+ }
11416+#endif // CONFIG_STA_SUPPORT //
11417+ }
11418+
11419+ pEntry->GTKState = REKEY_NEGOTIATING;
11420+ pEntry->PairwiseKey.KeyLen = 0;
11421+ pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
11422+#ifdef CONFIG_STA_SUPPORT
11423+#ifdef QOS_DLS_SUPPORT
11424+ if (pEntry->ValidAsDls == TRUE)
11425+ pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
11426+ else
11427+#endif //QOS_DLS_SUPPORT
11428+#endif // CONFIG_STA_SUPPORT //
11429+ pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
11430+ pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND;
11431+ COPY_MAC_ADDR(pEntry->Addr, pAddr);
11432+ pEntry->Sst = SST_NOT_AUTH;
11433+ pEntry->AuthState = AS_NOT_AUTH;
11434+ pEntry->Aid = (USHORT)i; //0;
11435+ pEntry->CapabilityInfo = 0;
11436+ pEntry->PsMode = PWR_ACTIVE;
11437+ pEntry->PsQIdleCount = 0;
11438+ pEntry->NoDataIdleCount = 0;
11439+ pEntry->ContinueTxFailCnt = 0;
11440+ InitializeQueueHeader(&pEntry->PsQueue);
11441+
11442+
11443+ pAd->MacTab.Size ++;
11444+
11445+ // Add this entry into ASIC RX WCID search table
11446+ RT28XX_STA_ENTRY_ADD(pAd, pEntry);
11447+
11448+
11449+
11450+ DBGPRINT(RT_DEBUG_TRACE, ("MacTableInsertEntry - allocate entry #%d, Total= %d\n",i, pAd->MacTab.Size));
11451+ break;
11452+ }
11453+ }
11454+
11455+ // add this MAC entry into HASH table
11456+ if (pEntry)
11457+ {
11458+ HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
11459+ if (pAd->MacTab.Hash[HashIdx] == NULL)
11460+ {
11461+ pAd->MacTab.Hash[HashIdx] = pEntry;
11462+ }
11463+ else
11464+ {
11465+ pCurrEntry = pAd->MacTab.Hash[HashIdx];
11466+ while (pCurrEntry->pNext != NULL)
11467+ pCurrEntry = pCurrEntry->pNext;
11468+ pCurrEntry->pNext = pEntry;
11469+ }
11470+ }
11471+
11472+ NdisReleaseSpinLock(&pAd->MacTabLock);
11473+ return pEntry;
11474+}
11475+
11476+/*
11477+ ==========================================================================
11478+ Description:
11479+ Delete a specified client from MAC table
11480+ ==========================================================================
11481+ */
11482+BOOLEAN MacTableDeleteEntry(
11483+ IN PRTMP_ADAPTER pAd,
11484+ IN USHORT wcid,
11485+ IN PUCHAR pAddr)
11486+{
11487+ USHORT HashIdx;
11488+ MAC_TABLE_ENTRY *pEntry, *pPrevEntry, *pProbeEntry;
11489+ BOOLEAN Cancelled;
11490+ //USHORT offset; // unused variable
11491+ //UCHAR j; // unused variable
11492+
11493+ if (wcid >= MAX_LEN_OF_MAC_TABLE)
11494+ return FALSE;
11495+
11496+ NdisAcquireSpinLock(&pAd->MacTabLock);
11497+
11498+ HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
11499+ //pEntry = pAd->MacTab.Hash[HashIdx];
11500+ pEntry = &pAd->MacTab.Content[wcid];
11501+
11502+ if (pEntry && (pEntry->ValidAsCLI || pEntry->ValidAsApCli || pEntry->ValidAsWDS || pEntry->ValidAsMesh
11503+#ifdef CONFIG_STA_SUPPORT
11504+#ifdef QOS_DLS_SUPPORT
11505+ || pEntry->ValidAsDls
11506+#endif // QOS_DLS_SUPPORT //
11507+#endif // CONFIG_STA_SUPPORT //
11508+ ))
11509+ {
11510+ if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
11511+ {
11512+
11513+ // Delete this entry from ASIC on-chip WCID Table
11514+ RT28XX_STA_ENTRY_MAC_RESET(pAd, wcid);
11515+
11516+#ifdef DOT11_N_SUPPORT
11517+ // free resources of BA
11518+ BASessionTearDownALL(pAd, pEntry->Aid);
11519+#endif // DOT11_N_SUPPORT //
11520+
11521+
11522+ pPrevEntry = NULL;
11523+ pProbeEntry = pAd->MacTab.Hash[HashIdx];
11524+ ASSERT(pProbeEntry);
11525+
11526+ // update Hash list
11527+ do
11528+ {
11529+ if (pProbeEntry == pEntry)
11530+ {
11531+ if (pPrevEntry == NULL)
11532+ {
11533+ pAd->MacTab.Hash[HashIdx] = pEntry->pNext;
11534+ }
11535+ else
11536+ {
11537+ pPrevEntry->pNext = pEntry->pNext;
11538+ }
11539+ break;
11540+ }
11541+
11542+ pPrevEntry = pProbeEntry;
11543+ pProbeEntry = pProbeEntry->pNext;
11544+ } while (pProbeEntry);
11545+
11546+ // not found !!!
11547+ ASSERT(pProbeEntry != NULL);
11548+
11549+ RT28XX_STA_ENTRY_KEY_DEL(pAd, BSS0, wcid);
11550+
11551+
11552+ if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE)
11553+ {
11554+ RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled);
11555+ pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
11556+ }
11557+
11558+
11559+ NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
11560+ pAd->MacTab.Size --;
11561+ DBGPRINT(RT_DEBUG_TRACE, ("MacTableDeleteEntry1 - Total= %d\n", pAd->MacTab.Size));
11562+ }
11563+ else
11564+ {
11565+ printk("\n%s: Impossible Wcid = %d !!!!!\n", __FUNCTION__, wcid);
11566+ }
11567+ }
11568+
11569+ NdisReleaseSpinLock(&pAd->MacTabLock);
11570+
11571+ //Reset operating mode when no Sta.
11572+ if (pAd->MacTab.Size == 0)
11573+ {
11574+#ifdef DOT11_N_SUPPORT
11575+ pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode = 0;
11576+#endif // DOT11_N_SUPPORT //
11577+ //AsicUpdateProtect(pAd, 0 /*pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode*/, (ALLN_SETPROTECT), TRUE, 0 /*pAd->MacTab.fAnyStationNonGF*/);
11578+ RT28XX_UPDATE_PROTECT(pAd); // edit by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
11579+ }
11580+
11581+ return TRUE;
11582+}
11583+
11584+
11585+/*
11586+ ==========================================================================
11587+ Description:
11588+ This routine reset the entire MAC table. All packets pending in
11589+ the power-saving queues are freed here.
11590+ ==========================================================================
11591+ */
11592+VOID MacTableReset(
11593+ IN PRTMP_ADAPTER pAd)
11594+{
11595+ int i;
11596+
11597+ DBGPRINT(RT_DEBUG_TRACE, ("MacTableReset\n"));
11598+ //NdisAcquireSpinLock(&pAd->MacTabLock);
11599+
11600+ for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
11601+ {
11602+ if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
11603+ {
11604+
11605+#ifdef DOT11_N_SUPPORT
11606+ // free resources of BA
11607+ BASessionTearDownALL(pAd, i);
11608+#endif // DOT11_N_SUPPORT //
11609+
11610+ pAd->MacTab.Content[i].ValidAsCLI = FALSE;
11611+
11612+
11613+
11614+#ifdef RT2870
11615+ NdisZeroMemory(pAd->MacTab.Content[i].Addr, 6);
11616+ RT28XX_STA_ENTRY_MAC_RESET(pAd, i);
11617+#endif // RT2870 //
11618+
11619+ //AsicDelWcidTab(pAd, i);
11620+ }
11621+ }
11622+
11623+ return;
11624+}
11625+
11626+/*
11627+ ==========================================================================
11628+ Description:
11629+
11630+ IRQL = DISPATCH_LEVEL
11631+
11632+ ==========================================================================
11633+*/
11634+VOID AssocParmFill(
11635+ IN PRTMP_ADAPTER pAd,
11636+ IN OUT MLME_ASSOC_REQ_STRUCT *AssocReq,
11637+ IN PUCHAR pAddr,
11638+ IN USHORT CapabilityInfo,
11639+ IN ULONG Timeout,
11640+ IN USHORT ListenIntv)
11641+{
11642+ COPY_MAC_ADDR(AssocReq->Addr, pAddr);
11643+ // Add mask to support 802.11b mode only
11644+ AssocReq->CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO; // not cf-pollable, not cf-poll-request
11645+ AssocReq->Timeout = Timeout;
11646+ AssocReq->ListenIntv = ListenIntv;
11647+}
11648+
11649+
11650+/*
11651+ ==========================================================================
11652+ Description:
11653+
11654+ IRQL = DISPATCH_LEVEL
11655+
11656+ ==========================================================================
11657+*/
11658+VOID DisassocParmFill(
11659+ IN PRTMP_ADAPTER pAd,
11660+ IN OUT MLME_DISASSOC_REQ_STRUCT *DisassocReq,
11661+ IN PUCHAR pAddr,
11662+ IN USHORT Reason)
11663+{
11664+ COPY_MAC_ADDR(DisassocReq->Addr, pAddr);
11665+ DisassocReq->Reason = Reason;
11666+}
11667+
11668+
11669+/*
11670+ ========================================================================
11671+
11672+ Routine Description:
11673+ Check the out going frame, if this is an DHCP or ARP datagram
11674+ will be duplicate another frame at low data rate transmit.
11675+
11676+ Arguments:
11677+ pAd Pointer to our adapter
11678+ pPacket Pointer to outgoing Ndis frame
11679+
11680+ Return Value:
11681+ TRUE To be duplicate at Low data rate transmit. (1mb)
11682+ FALSE Do nothing.
11683+
11684+ IRQL = DISPATCH_LEVEL
11685+
11686+ Note:
11687+
11688+ MAC header + IP Header + UDP Header
11689+ 14 Bytes 20 Bytes
11690+
11691+ UDP Header
11692+ 00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|
11693+ Source Port
11694+ 16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|
11695+ Destination Port
11696+
11697+ port 0x43 means Bootstrap Protocol, server.
11698+ Port 0x44 means Bootstrap Protocol, client.
11699+
11700+ ========================================================================
11701+*/
11702+
11703+BOOLEAN RTMPCheckDHCPFrame(
11704+ IN PRTMP_ADAPTER pAd,
11705+ IN PNDIS_PACKET pPacket)
11706+{
11707+ PACKET_INFO PacketInfo;
11708+ ULONG NumberOfBytesRead = 0;
11709+ ULONG CurrentOffset = 0;
11710+ PVOID pVirtualAddress = NULL;
11711+ UINT NdisBufferLength;
11712+ PUCHAR pSrc;
11713+ USHORT Protocol;
11714+ UCHAR ByteOffset36 = 0;
11715+ UCHAR ByteOffset38 = 0;
11716+ BOOLEAN ReadFirstParm = TRUE;
11717+
11718+ RTMP_QueryPacketInfo(pPacket, &PacketInfo, (PUCHAR *)&pVirtualAddress, &NdisBufferLength);
11719+
11720+ NumberOfBytesRead += NdisBufferLength;
11721+ pSrc = (PUCHAR) pVirtualAddress;
11722+ Protocol = *(pSrc + 12) * 256 + *(pSrc + 13);
11723+
11724+ //
11725+ // Check DHCP & BOOTP protocol
11726+ //
11727+ while (NumberOfBytesRead <= PacketInfo.TotalPacketLength)
11728+ {
11729+ if ((NumberOfBytesRead >= 35) && (ReadFirstParm == TRUE))
11730+ {
11731+ CurrentOffset = 35 - (NumberOfBytesRead - NdisBufferLength);
11732+ ByteOffset36 = *(pSrc + CurrentOffset);
11733+ ReadFirstParm = FALSE;
11734+ }
11735+
11736+ if (NumberOfBytesRead >= 37)
11737+ {
11738+ CurrentOffset = 37 - (NumberOfBytesRead - NdisBufferLength);
11739+ ByteOffset38 = *(pSrc + CurrentOffset);
11740+ //End of Read
11741+ break;
11742+ }
11743+ return FALSE;
11744+ }
11745+
11746+ // Check for DHCP & BOOTP protocol
11747+ if ((ByteOffset36 != 0x44) || (ByteOffset38 != 0x43))
11748+ {
11749+ //
11750+ // 2054 (hex 0806) for ARP datagrams
11751+ // if this packet is not ARP datagrams, then do nothing
11752+ // ARP datagrams will also be duplicate at 1mb broadcast frames
11753+ //
11754+ if (Protocol != 0x0806 )
11755+ return FALSE;
11756+ }
11757+
11758+ return TRUE;
11759+}
11760+
11761+
11762+BOOLEAN RTMPCheckEtherType(
11763+ IN PRTMP_ADAPTER pAd,
11764+ IN PNDIS_PACKET pPacket)
11765+{
11766+ USHORT TypeLen;
11767+ UCHAR Byte0, Byte1;
11768+ PUCHAR pSrcBuf;
11769+ UINT32 pktLen;
11770+ UINT16 srcPort, dstPort;
11771+ BOOLEAN status = TRUE;
11772+
11773+
11774+ pSrcBuf = GET_OS_PKT_DATAPTR(pPacket);
11775+ pktLen = GET_OS_PKT_LEN(pPacket);
11776+
11777+ ASSERT(pSrcBuf);
11778+
11779+ RTMP_SET_PACKET_SPECIFIC(pPacket, 0);
11780+
11781+ // get Ethernet protocol field
11782+ TypeLen = (pSrcBuf[12] << 8) + pSrcBuf[13];
11783+
11784+ pSrcBuf += LENGTH_802_3; // Skip the Ethernet Header.
11785+
11786+ if (TypeLen <= 1500)
11787+ { // 802.3, 802.3 LLC
11788+ /*
11789+ DestMAC(6) + SrcMAC(6) + Lenght(2) +
11790+ DSAP(1) + SSAP(1) + Control(1) +
11791+ if the DSAP = 0xAA, SSAP=0xAA, Contorl = 0x03, it has a 5-bytes SNAP header.
11792+ => + SNAP (5, OriginationID(3) + etherType(2))
11793+ */
11794+ if (pSrcBuf[0] == 0xAA && pSrcBuf[1] == 0xAA && pSrcBuf[2] == 0x03)
11795+ {
11796+ Sniff2BytesFromNdisBuffer(pSrcBuf, 6, &Byte0, &Byte1);
11797+ RTMP_SET_PACKET_LLCSNAP(pPacket, 1);
11798+ TypeLen = (USHORT)((Byte0 << 8) + Byte1);
11799+ pSrcBuf += 8; // Skip this LLC/SNAP header
11800+ }
11801+ else
11802+ {
11803+ //It just has 3-byte LLC header, maybe a legacy ether type frame. we didn't handle it.
11804+ }
11805+ }
11806+
11807+ // If it's a VLAN packet, get the real Type/Length field.
11808+ if (TypeLen == 0x8100)
11809+ {
11810+ /* 0x8100 means VLAN packets */
11811+
11812+ /* Dest. MAC Address (6-bytes) +
11813+ Source MAC Address (6-bytes) +
11814+ Length/Type = 802.1Q Tag Type (2-byte) +
11815+ Tag Control Information (2-bytes) +
11816+ Length / Type (2-bytes) +
11817+ data payload (0-n bytes) +
11818+ Pad (0-p bytes) +
11819+ Frame Check Sequence (4-bytes) */
11820+
11821+ RTMP_SET_PACKET_VLAN(pPacket, 1);
11822+ Sniff2BytesFromNdisBuffer(pSrcBuf, 2, &Byte0, &Byte1);
11823+ TypeLen = (USHORT)((Byte0 << 8) + Byte1);
11824+
11825+ pSrcBuf += 4; // Skip the VLAN Header.
11826+ }
11827+
11828+ switch (TypeLen)
11829+ {
11830+ case 0x0800:
11831+ {
11832+ ASSERT((pktLen > 34));
11833+ if (*(pSrcBuf + 9) == 0x11)
11834+ { // udp packet
11835+ ASSERT((pktLen > 34)); // 14 for ethernet header, 20 for IP header
11836+
11837+ pSrcBuf += 20; // Skip the IP header
11838+ srcPort = OS_NTOHS(*((UINT16 *)pSrcBuf));
11839+ dstPort = OS_NTOHS(*((UINT16 *)(pSrcBuf +2)));
11840+
11841+ if ((srcPort==0x44 && dstPort==0x43) || (srcPort==0x43 && dstPort==0x44))
11842+ { //It's a BOOTP/DHCP packet
11843+ RTMP_SET_PACKET_DHCP(pPacket, 1);
11844+ }
11845+ }
11846+ }
11847+ break;
11848+ case 0x0806:
11849+ {
11850+ //ARP Packet.
11851+ RTMP_SET_PACKET_DHCP(pPacket, 1);
11852+ }
11853+ break;
11854+ case 0x888e:
11855+ {
11856+ // EAPOL Packet.
11857+ RTMP_SET_PACKET_EAPOL(pPacket, 1);
11858+ }
11859+ break;
11860+ default:
11861+ status = FALSE;
11862+ break;
11863+ }
11864+
11865+ return status;
11866+
11867+}
11868+
11869+
11870+
11871+VOID Update_Rssi_Sample(
11872+ IN PRTMP_ADAPTER pAd,
11873+ IN RSSI_SAMPLE *pRssi,
11874+ IN PRXWI_STRUC pRxWI)
11875+ {
11876+ CHAR rssi0 = pRxWI->RSSI0;
11877+ CHAR rssi1 = pRxWI->RSSI1;
11878+ CHAR rssi2 = pRxWI->RSSI2;
11879+
11880+ if (rssi0 != 0)
11881+ {
11882+ pRssi->LastRssi0 = ConvertToRssi(pAd, (CHAR)rssi0, RSSI_0);
11883+ pRssi->AvgRssi0X8 = (pRssi->AvgRssi0X8 - pRssi->AvgRssi0) + pRssi->LastRssi0;
11884+ pRssi->AvgRssi0 = pRssi->AvgRssi0X8 >> 3;
11885+ }
11886+
11887+ if (rssi1 != 0)
11888+ {
11889+ pRssi->LastRssi1 = ConvertToRssi(pAd, (CHAR)rssi1, RSSI_1);
11890+ pRssi->AvgRssi1X8 = (pRssi->AvgRssi1X8 - pRssi->AvgRssi1) + pRssi->LastRssi1;
11891+ pRssi->AvgRssi1 = pRssi->AvgRssi1X8 >> 3;
11892+ }
11893+
11894+ if (rssi2 != 0)
11895+ {
11896+ pRssi->LastRssi2 = ConvertToRssi(pAd, (CHAR)rssi2, RSSI_2);
11897+ pRssi->AvgRssi2X8 = (pRssi->AvgRssi2X8 - pRssi->AvgRssi2) + pRssi->LastRssi2;
11898+ pRssi->AvgRssi2 = pRssi->AvgRssi2X8 >> 3;
11899+ }
11900+}
11901+
11902+
11903+
11904+// Normal legacy Rx packet indication
11905+VOID Indicate_Legacy_Packet(
11906+ IN PRTMP_ADAPTER pAd,
11907+ IN RX_BLK *pRxBlk,
11908+ IN UCHAR FromWhichBSSID)
11909+{
11910+ PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
11911+ UCHAR Header802_3[LENGTH_802_3];
11912+
11913+ // 1. get 802.3 Header
11914+ // 2. remove LLC
11915+ // a. pointer pRxBlk->pData to payload
11916+ // b. modify pRxBlk->DataSize
11917+#ifdef CONFIG_STA_SUPPORT
11918+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
11919+ RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
11920+#endif // CONFIG_STA_SUPPORT //
11921+
11922+ if (pRxBlk->DataSize > MAX_RX_PKT_LEN)
11923+ {
11924+ // release packet
11925+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
11926+ return;
11927+ }
11928+
11929+
11930+ STATS_INC_RX_PACKETS(pAd, FromWhichBSSID);
11931+
11932+#ifdef RT2870
11933+#ifdef DOT11_N_SUPPORT
11934+ if (pAd->CommonCfg.bDisableReordering == 0)
11935+ {
11936+ PBA_REC_ENTRY pBAEntry;
11937+ ULONG Now32;
11938+ UCHAR Wcid = pRxBlk->pRxWI->WirelessCliID;
11939+ UCHAR TID = pRxBlk->pRxWI->TID;
11940+ USHORT Idx;
11941+
11942+#define REORDERING_PACKET_TIMEOUT ((100 * HZ)/1000) // system ticks -- 100 ms
11943+
11944+ if (Wcid < MAX_LEN_OF_MAC_TABLE)
11945+ {
11946+ Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
11947+ if (Idx != 0)
11948+ {
11949+ pBAEntry = &pAd->BATable.BARecEntry[Idx];
11950+ // update last rx time
11951+ NdisGetSystemUpTime(&Now32);
11952+ if ((pBAEntry->list.qlen > 0) &&
11953+ RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(REORDERING_PACKET_TIMEOUT)))
11954+ )
11955+ {
11956+ printk("Indicate_Legacy_Packet():flush reordering_timeout_mpdus! RxWI->Flags=%d, pRxWI.TID=%d, RxD->AMPDU=%d!\n", pRxBlk->Flags, pRxBlk->pRxWI->TID, pRxBlk->RxD.AMPDU);
11957+ hex_dump("Dump the legacy Packet:", GET_OS_PKT_DATAPTR(pRxBlk->pRxPacket), 64);
11958+ ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32);
11959+ }
11960+ }
11961+ }
11962+ }
11963+#endif // DOT11_N_SUPPORT //
11964+#endif // RT2870 //
11965+
11966+ wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
11967+
11968+ //
11969+ // pass this 802.3 packet to upper layer or forward this packet to WM directly
11970+ //
11971+#ifdef CONFIG_STA_SUPPORT
11972+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
11973+ ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxPacket, FromWhichBSSID);
11974+#endif // CONFIG_STA_SUPPORT //
11975+
11976+}
11977+
11978+
11979+// Normal, AMPDU or AMSDU
11980+VOID CmmRxnonRalinkFrameIndicate(
11981+ IN PRTMP_ADAPTER pAd,
11982+ IN RX_BLK *pRxBlk,
11983+ IN UCHAR FromWhichBSSID)
11984+{
11985+#ifdef DOT11_N_SUPPORT
11986+ if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU) && (pAd->CommonCfg.bDisableReordering == 0))
11987+ {
11988+ Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID);
11989+ }
11990+ else
11991+#endif // DOT11_N_SUPPORT //
11992+ {
11993+#ifdef DOT11_N_SUPPORT
11994+ if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU))
11995+ {
11996+ // handle A-MSDU
11997+ Indicate_AMSDU_Packet(pAd, pRxBlk, FromWhichBSSID);
11998+ }
11999+ else
12000+#endif // DOT11_N_SUPPORT //
12001+ {
12002+ Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
12003+ }
12004+ }
12005+}
12006+
12007+
12008+VOID CmmRxRalinkFrameIndicate(
12009+ IN PRTMP_ADAPTER pAd,
12010+ IN MAC_TABLE_ENTRY *pEntry,
12011+ IN RX_BLK *pRxBlk,
12012+ IN UCHAR FromWhichBSSID)
12013+{
12014+ UCHAR Header802_3[LENGTH_802_3];
12015+ UINT16 Msdu2Size;
12016+ UINT16 Payload1Size, Payload2Size;
12017+ PUCHAR pData2;
12018+ PNDIS_PACKET pPacket2 = NULL;
12019+
12020+
12021+
12022+ Msdu2Size = *(pRxBlk->pData) + (*(pRxBlk->pData+1) << 8);
12023+
12024+ if ((Msdu2Size <= 1536) && (Msdu2Size < pRxBlk->DataSize))
12025+ {
12026+ /* skip two byte MSDU2 len */
12027+ pRxBlk->pData += 2;
12028+ pRxBlk->DataSize -= 2;
12029+ }
12030+ else
12031+ {
12032+ // release packet
12033+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
12034+ return;
12035+ }
12036+
12037+ // get 802.3 Header and remove LLC
12038+#ifdef CONFIG_STA_SUPPORT
12039+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
12040+ RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
12041+#endif // CONFIG_STA_SUPPORT //
12042+
12043+
12044+ ASSERT(pRxBlk->pRxPacket);
12045+
12046+ // Ralink Aggregation frame
12047+ pAd->RalinkCounters.OneSecRxAggregationCount ++;
12048+ Payload1Size = pRxBlk->DataSize - Msdu2Size;
12049+ Payload2Size = Msdu2Size - LENGTH_802_3;
12050+
12051+ pData2 = pRxBlk->pData + Payload1Size + LENGTH_802_3;
12052+#ifdef CONFIG_STA_SUPPORT
12053+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
12054+ pPacket2 = duplicate_pkt(pAd, (pData2-LENGTH_802_3), LENGTH_802_3, pData2, Payload2Size, FromWhichBSSID);
12055+#endif // CONFIG_STA_SUPPORT //
12056+
12057+ if (!pPacket2)
12058+ {
12059+ // release packet
12060+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
12061+ return;
12062+ }
12063+
12064+ // update payload size of 1st packet
12065+ pRxBlk->DataSize = Payload1Size;
12066+ wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
12067+
12068+#ifdef CONFIG_STA_SUPPORT
12069+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
12070+ ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxBlk->pRxPacket, FromWhichBSSID);
12071+#endif // CONFIG_STA_SUPPORT //
12072+
12073+ if (pPacket2)
12074+ {
12075+#ifdef CONFIG_STA_SUPPORT
12076+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
12077+ ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket2, FromWhichBSSID);
12078+#endif // CONFIG_STA_SUPPORT //
12079+ }
12080+}
12081+
12082+
12083+#define RESET_FRAGFRAME(_fragFrame) \
12084+ { \
12085+ _fragFrame.RxSize = 0; \
12086+ _fragFrame.Sequence = 0; \
12087+ _fragFrame.LastFrag = 0; \
12088+ _fragFrame.Flags = 0; \
12089+ }
12090+
12091+
12092+PNDIS_PACKET RTMPDeFragmentDataFrame(
12093+ IN PRTMP_ADAPTER pAd,
12094+ IN RX_BLK *pRxBlk)
12095+{
12096+ PHEADER_802_11 pHeader = pRxBlk->pHeader;
12097+ PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
12098+ UCHAR *pData = pRxBlk->pData;
12099+ USHORT DataSize = pRxBlk->DataSize;
12100+ PNDIS_PACKET pRetPacket = NULL;
12101+ UCHAR *pFragBuffer = NULL;
12102+ BOOLEAN bReassDone = FALSE;
12103+ UCHAR HeaderRoom = 0;
12104+
12105+
12106+ ASSERT(pHeader);
12107+
12108+ HeaderRoom = pData - (UCHAR *)pHeader;
12109+
12110+ // Re-assemble the fragmented packets
12111+ if (pHeader->Frag == 0) // Frag. Number is 0 : First frag or only one pkt
12112+ {
12113+ // the first pkt of fragment, record it.
12114+ if (pHeader->FC.MoreFrag)
12115+ {
12116+ ASSERT(pAd->FragFrame.pFragPacket);
12117+ pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
12118+ pAd->FragFrame.RxSize = DataSize + HeaderRoom;
12119+ NdisMoveMemory(pFragBuffer, pHeader, pAd->FragFrame.RxSize);
12120+ pAd->FragFrame.Sequence = pHeader->Sequence;
12121+ pAd->FragFrame.LastFrag = pHeader->Frag; // Should be 0
12122+ ASSERT(pAd->FragFrame.LastFrag == 0);
12123+ goto done; // end of processing this frame
12124+ }
12125+ }
12126+ else //Middle & End of fragment
12127+ {
12128+ if ((pHeader->Sequence != pAd->FragFrame.Sequence) ||
12129+ (pHeader->Frag != (pAd->FragFrame.LastFrag + 1)))
12130+ {
12131+ // Fragment is not the same sequence or out of fragment number order
12132+ // Reset Fragment control blk
12133+ RESET_FRAGFRAME(pAd->FragFrame);
12134+ DBGPRINT(RT_DEBUG_ERROR, ("Fragment is not the same sequence or out of fragment number order.\n"));
12135+ goto done; // give up this frame
12136+ }
12137+ else if ((pAd->FragFrame.RxSize + DataSize) > MAX_FRAME_SIZE)
12138+ {
12139+ // Fragment frame is too large, it exeeds the maximum frame size.
12140+ // Reset Fragment control blk
12141+ RESET_FRAGFRAME(pAd->FragFrame);
12142+ DBGPRINT(RT_DEBUG_ERROR, ("Fragment frame is too large, it exeeds the maximum frame size.\n"));
12143+ goto done; // give up this frame
12144+ }
12145+
12146+ //
12147+ // Broadcom AP(BCM94704AGR) will send out LLC in fragment's packet, LLC only can accpet at first fragment.
12148+ // In this case, we will dropt it.
12149+ //
12150+ if (NdisEqualMemory(pData, SNAP_802_1H, sizeof(SNAP_802_1H)))
12151+ {
12152+ DBGPRINT(RT_DEBUG_ERROR, ("Find another LLC at Middle or End fragment(SN=%d, Frag=%d)\n", pHeader->Sequence, pHeader->Frag));
12153+ goto done; // give up this frame
12154+ }
12155+
12156+ pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
12157+
12158+ // concatenate this fragment into the re-assembly buffer
12159+ NdisMoveMemory((pFragBuffer + pAd->FragFrame.RxSize), pData, DataSize);
12160+ pAd->FragFrame.RxSize += DataSize;
12161+ pAd->FragFrame.LastFrag = pHeader->Frag; // Update fragment number
12162+
12163+ // Last fragment
12164+ if (pHeader->FC.MoreFrag == FALSE)
12165+ {
12166+ bReassDone = TRUE;
12167+ }
12168+ }
12169+
12170+done:
12171+ // always release rx fragmented packet
12172+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
12173+
12174+ // return defragmented packet if packet is reassembled completely
12175+ // otherwise return NULL
12176+ if (bReassDone)
12177+ {
12178+ PNDIS_PACKET pNewFragPacket;
12179+
12180+ // allocate a new packet buffer for fragment
12181+ pNewFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
12182+ if (pNewFragPacket)
12183+ {
12184+ // update RxBlk
12185+ pRetPacket = pAd->FragFrame.pFragPacket;
12186+ pAd->FragFrame.pFragPacket = pNewFragPacket;
12187+ pRxBlk->pHeader = (PHEADER_802_11) GET_OS_PKT_DATAPTR(pRetPacket);
12188+ pRxBlk->pData = (UCHAR *)pRxBlk->pHeader + HeaderRoom;
12189+ pRxBlk->DataSize = pAd->FragFrame.RxSize - HeaderRoom;
12190+ pRxBlk->pRxPacket = pRetPacket;
12191+ }
12192+ else
12193+ {
12194+ RESET_FRAGFRAME(pAd->FragFrame);
12195+ }
12196+ }
12197+
12198+ return pRetPacket;
12199+}
12200+
12201+
12202+VOID Indicate_AMSDU_Packet(
12203+ IN PRTMP_ADAPTER pAd,
12204+ IN RX_BLK *pRxBlk,
12205+ IN UCHAR FromWhichBSSID)
12206+{
12207+ UINT nMSDU;
12208+
12209+ update_os_packet_info(pAd, pRxBlk, FromWhichBSSID);
12210+ RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID);
12211+ nMSDU = deaggregate_AMSDU_announce(pAd, pRxBlk->pRxPacket, pRxBlk->pData, pRxBlk->DataSize);
12212+}
12213+
12214+VOID Indicate_EAPOL_Packet(
12215+ IN PRTMP_ADAPTER pAd,
12216+ IN RX_BLK *pRxBlk,
12217+ IN UCHAR FromWhichBSSID)
12218+{
12219+ MAC_TABLE_ENTRY *pEntry = NULL;
12220+
12221+
12222+#ifdef CONFIG_STA_SUPPORT
12223+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
12224+ {
12225+ pEntry = &pAd->MacTab.Content[BSSID_WCID];
12226+ STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
12227+ return;
12228+ }
12229+#endif // CONFIG_STA_SUPPORT //
12230+
12231+ if (pEntry == NULL)
12232+ {
12233+ DBGPRINT(RT_DEBUG_WARN, ("Indicate_EAPOL_Packet: drop and release the invalid packet.\n"));
12234+ // release packet
12235+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
12236+ return;
12237+ }
12238+}
12239+
12240+#define BCN_TBTT_OFFSET 64 //defer 64 us
12241+VOID ReSyncBeaconTime(
12242+ IN PRTMP_ADAPTER pAd)
12243+{
12244+
12245+ UINT32 Offset;
12246+
12247+
12248+ Offset = (pAd->TbttTickCount) % (BCN_TBTT_OFFSET);
12249+
12250+ pAd->TbttTickCount++;
12251+
12252+ //
12253+ // The updated BeaconInterval Value will affect Beacon Interval after two TBTT
12254+ // beacasue the original BeaconInterval had been loaded into next TBTT_TIMER
12255+ //
12256+ if (Offset == (BCN_TBTT_OFFSET-2))
12257+ {
12258+ BCN_TIME_CFG_STRUC csr;
12259+ RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
12260+ csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod << 4) - 1 ; // ASIC register in units of 1/16 TU = 64us
12261+ RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
12262+ }
12263+ else
12264+ {
12265+ if (Offset == (BCN_TBTT_OFFSET-1))
12266+ {
12267+ BCN_TIME_CFG_STRUC csr;
12268+
12269+ RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
12270+ csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod) << 4; // ASIC register in units of 1/16 TU
12271+ RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
12272+ }
12273+ }
12274+}
12275+
12276--- /dev/null
12277+++ b/drivers/staging/rt3070/common/cmm_info.c
12278@@ -0,0 +1,3395 @@
12279+/*
12280+ *************************************************************************
12281+ * Ralink Tech Inc.
12282+ * 5F., No.36, Taiyuan St., Jhubei City,
12283+ * Hsinchu County 302,
12284+ * Taiwan, R.O.C.
12285+ *
12286+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
12287+ *
12288+ * This program is free software; you can redistribute it and/or modify *
12289+ * it under the terms of the GNU General Public License as published by *
12290+ * the Free Software Foundation; either version 2 of the License, or *
12291+ * (at your option) any later version. *
12292+ * *
12293+ * This program is distributed in the hope that it will be useful, *
12294+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12295+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12296+ * GNU General Public License for more details. *
12297+ * *
12298+ * You should have received a copy of the GNU General Public License *
12299+ * along with this program; if not, write to the *
12300+ * Free Software Foundation, Inc., *
12301+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
12302+ * *
12303+ *************************************************************************
12304+*/
12305+
12306+#include "../rt_config.h"
12307+
12308+INT Show_SSID_Proc(
12309+ IN PRTMP_ADAPTER pAd,
12310+ OUT PUCHAR pBuf);
12311+
12312+INT Show_WirelessMode_Proc(
12313+ IN PRTMP_ADAPTER pAd,
12314+ OUT PUCHAR pBuf);
12315+
12316+INT Show_TxBurst_Proc(
12317+ IN PRTMP_ADAPTER pAd,
12318+ OUT PUCHAR pBuf);
12319+
12320+INT Show_TxPreamble_Proc(
12321+ IN PRTMP_ADAPTER pAd,
12322+ OUT PUCHAR pBuf);
12323+
12324+INT Show_TxPower_Proc(
12325+ IN PRTMP_ADAPTER pAd,
12326+ OUT PUCHAR pBuf);
12327+
12328+INT Show_Channel_Proc(
12329+ IN PRTMP_ADAPTER pAd,
12330+ OUT PUCHAR pBuf);
12331+
12332+INT Show_BGProtection_Proc(
12333+ IN PRTMP_ADAPTER pAd,
12334+ OUT PUCHAR pBuf);
12335+
12336+INT Show_RTSThreshold_Proc(
12337+ IN PRTMP_ADAPTER pAd,
12338+ OUT PUCHAR pBuf);
12339+
12340+INT Show_FragThreshold_Proc(
12341+ IN PRTMP_ADAPTER pAd,
12342+ OUT PUCHAR pBuf);
12343+
12344+#ifdef DOT11_N_SUPPORT
12345+INT Show_HtBw_Proc(
12346+ IN PRTMP_ADAPTER pAd,
12347+ OUT PUCHAR pBuf);
12348+
12349+INT Show_HtMcs_Proc(
12350+ IN PRTMP_ADAPTER pAd,
12351+ OUT PUCHAR pBuf);
12352+
12353+INT Show_HtGi_Proc(
12354+ IN PRTMP_ADAPTER pAd,
12355+ OUT PUCHAR pBuf);
12356+
12357+INT Show_HtOpMode_Proc(
12358+ IN PRTMP_ADAPTER pAd,
12359+ OUT PUCHAR pBuf);
12360+
12361+INT Show_HtExtcha_Proc(
12362+ IN PRTMP_ADAPTER pAd,
12363+ OUT PUCHAR pBuf);
12364+
12365+INT Show_HtMpduDensity_Proc(
12366+ IN PRTMP_ADAPTER pAd,
12367+ OUT PUCHAR pBuf);
12368+
12369+INT Show_HtBaWinSize_Proc(
12370+ IN PRTMP_ADAPTER pAd,
12371+ OUT PUCHAR pBuf);
12372+
12373+INT Show_HtRdg_Proc(
12374+ IN PRTMP_ADAPTER pAd,
12375+ OUT PUCHAR pBuf);
12376+
12377+INT Show_HtAmsdu_Proc(
12378+ IN PRTMP_ADAPTER pAd,
12379+ OUT PUCHAR pBuf);
12380+
12381+INT Show_HtAutoBa_Proc(
12382+ IN PRTMP_ADAPTER pAd,
12383+ OUT PUCHAR pBuf);
12384+#endif // DOT11_N_SUPPORT //
12385+
12386+INT Show_CountryRegion_Proc(
12387+ IN PRTMP_ADAPTER pAd,
12388+ OUT PUCHAR pBuf);
12389+
12390+INT Show_CountryRegionABand_Proc(
12391+ IN PRTMP_ADAPTER pAd,
12392+ OUT PUCHAR pBuf);
12393+
12394+INT Show_CountryCode_Proc(
12395+ IN PRTMP_ADAPTER pAd,
12396+ OUT PUCHAR pBuf);
12397+
12398+#ifdef AGGREGATION_SUPPORT
12399+INT Show_PktAggregate_Proc(
12400+ IN PRTMP_ADAPTER pAd,
12401+ OUT PUCHAR pBuf);
12402+#endif // AGGREGATION_SUPPORT //
12403+
12404+#ifdef WMM_SUPPORT
12405+INT Show_WmmCapable_Proc(
12406+ IN PRTMP_ADAPTER pAd,
12407+ OUT PUCHAR pBuf);
12408+#endif // WMM_SUPPORT //
12409+
12410+INT Show_IEEE80211H_Proc(
12411+ IN PRTMP_ADAPTER pAd,
12412+ OUT PUCHAR pBuf);
12413+
12414+#ifdef CONFIG_STA_SUPPORT
12415+INT Show_NetworkType_Proc(
12416+ IN PRTMP_ADAPTER pAd,
12417+ OUT PUCHAR pBuf);
12418+#endif // CONFIG_STA_SUPPORT //
12419+
12420+INT Show_AuthMode_Proc(
12421+ IN PRTMP_ADAPTER pAd,
12422+ OUT PUCHAR pBuf);
12423+
12424+INT Show_EncrypType_Proc(
12425+ IN PRTMP_ADAPTER pAd,
12426+ OUT PUCHAR pBuf);
12427+
12428+INT Show_DefaultKeyID_Proc(
12429+ IN PRTMP_ADAPTER pAd,
12430+ OUT PUCHAR pBuf);
12431+
12432+INT Show_Key1_Proc(
12433+ IN PRTMP_ADAPTER pAd,
12434+ OUT PUCHAR pBuf);
12435+
12436+INT Show_Key2_Proc(
12437+ IN PRTMP_ADAPTER pAd,
12438+ OUT PUCHAR pBuf);
12439+
12440+INT Show_Key3_Proc(
12441+ IN PRTMP_ADAPTER pAd,
12442+ OUT PUCHAR pBuf);
12443+
12444+INT Show_Key4_Proc(
12445+ IN PRTMP_ADAPTER pAd,
12446+ OUT PUCHAR pBuf);
12447+
12448+INT Show_WPAPSK_Proc(
12449+ IN PRTMP_ADAPTER pAd,
12450+ OUT PUCHAR pBuf);
12451+
12452+static struct {
12453+ CHAR *name;
12454+ INT (*show_proc)(PRTMP_ADAPTER pAdapter, PUCHAR arg);
12455+} *PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC, RTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC[] = {
12456+ {"SSID", Show_SSID_Proc},
12457+ {"WirelessMode", Show_WirelessMode_Proc},
12458+ {"TxBurst", Show_TxBurst_Proc},
12459+ {"TxPreamble", Show_TxPreamble_Proc},
12460+ {"TxPower", Show_TxPower_Proc},
12461+ {"Channel", Show_Channel_Proc},
12462+ {"BGProtection", Show_BGProtection_Proc},
12463+ {"RTSThreshold", Show_RTSThreshold_Proc},
12464+ {"FragThreshold", Show_FragThreshold_Proc},
12465+#ifdef DOT11_N_SUPPORT
12466+ {"HtBw", Show_HtBw_Proc},
12467+ {"HtMcs", Show_HtMcs_Proc},
12468+ {"HtGi", Show_HtGi_Proc},
12469+ {"HtOpMode", Show_HtOpMode_Proc},
12470+ {"HtExtcha", Show_HtExtcha_Proc},
12471+ {"HtMpduDensity", Show_HtMpduDensity_Proc},
12472+ {"HtBaWinSize", Show_HtBaWinSize_Proc},
12473+ {"HtRdg", Show_HtRdg_Proc},
12474+ {"HtAmsdu", Show_HtAmsdu_Proc},
12475+ {"HtAutoBa", Show_HtAutoBa_Proc},
12476+#endif // DOT11_N_SUPPORT //
12477+ {"CountryRegion", Show_CountryRegion_Proc},
12478+ {"CountryRegionABand", Show_CountryRegionABand_Proc},
12479+ {"CountryCode", Show_CountryCode_Proc},
12480+#ifdef AGGREGATION_SUPPORT
12481+ {"PktAggregate", Show_PktAggregate_Proc},
12482+#endif
12483+
12484+#ifdef WMM_SUPPORT
12485+ {"WmmCapable", Show_WmmCapable_Proc},
12486+#endif
12487+ {"IEEE80211H", Show_IEEE80211H_Proc},
12488+#ifdef CONFIG_STA_SUPPORT
12489+ {"NetworkType", Show_NetworkType_Proc},
12490+#endif // CONFIG_STA_SUPPORT //
12491+ {"AuthMode", Show_AuthMode_Proc},
12492+ {"EncrypType", Show_EncrypType_Proc},
12493+ {"DefaultKeyID", Show_DefaultKeyID_Proc},
12494+ {"Key1", Show_Key1_Proc},
12495+ {"Key2", Show_Key2_Proc},
12496+ {"Key3", Show_Key3_Proc},
12497+ {"Key4", Show_Key4_Proc},
12498+ {"WPAPSK", Show_WPAPSK_Proc},
12499+ {NULL, NULL}
12500+};
12501+
12502+/*
12503+ ==========================================================================
12504+ Description:
12505+ Get Driver version.
12506+
12507+ Return:
12508+ ==========================================================================
12509+*/
12510+INT Set_DriverVersion_Proc(
12511+ IN PRTMP_ADAPTER pAd,
12512+ IN PUCHAR arg)
12513+{
12514+
12515+#ifdef CONFIG_STA_SUPPORT
12516+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
12517+ DBGPRINT(RT_DEBUG_TRACE, ("Driver version-%s\n", STA_DRIVER_VERSION));
12518+#endif // CONFIG_STA_SUPPORT //
12519+
12520+ return TRUE;
12521+}
12522+
12523+/*
12524+ ==========================================================================
12525+ Description:
12526+ Set Country Region.
12527+ This command will not work, if the field of CountryRegion in eeprom is programmed.
12528+ Return:
12529+ TRUE if all parameters are OK, FALSE otherwise
12530+ ==========================================================================
12531+*/
12532+INT Set_CountryRegion_Proc(
12533+ IN PRTMP_ADAPTER pAd,
12534+ IN PUCHAR arg)
12535+{
12536+ ULONG region;
12537+
12538+ region = simple_strtol(arg, 0, 10);
12539+
12540+#ifdef EXT_BUILD_CHANNEL_LIST
12541+ return -EOPNOTSUPP;
12542+#endif // EXT_BUILD_CHANNEL_LIST //
12543+
12544+ // Country can be set only when EEPROM not programmed
12545+ if (pAd->CommonCfg.CountryRegion & 0x80)
12546+ {
12547+ DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegion_Proc::parameter of CountryRegion in eeprom is programmed \n"));
12548+ return FALSE;
12549+ }
12550+
12551+ if((region >= 0) && (region <= REGION_MAXIMUM_BG_BAND))
12552+ {
12553+ pAd->CommonCfg.CountryRegion = (UCHAR) region;
12554+ }
12555+ else if (region == REGION_31_BG_BAND)
12556+ {
12557+ pAd->CommonCfg.CountryRegion = (UCHAR) region;
12558+ }
12559+ else
12560+ {
12561+ DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegion_Proc::parameters out of range\n"));
12562+ return FALSE;
12563+ }
12564+
12565+ // if set country region, driver needs to be reset
12566+ BuildChannelList(pAd);
12567+
12568+ DBGPRINT(RT_DEBUG_TRACE, ("Set_CountryRegion_Proc::(CountryRegion=%d)\n", pAd->CommonCfg.CountryRegion));
12569+
12570+ return TRUE;
12571+}
12572+
12573+/*
12574+ ==========================================================================
12575+ Description:
12576+ Set Country Region for A band.
12577+ This command will not work, if the field of CountryRegion in eeprom is programmed.
12578+ Return:
12579+ TRUE if all parameters are OK, FALSE otherwise
12580+ ==========================================================================
12581+*/
12582+INT Set_CountryRegionABand_Proc(
12583+ IN PRTMP_ADAPTER pAd,
12584+ IN PUCHAR arg)
12585+{
12586+ ULONG region;
12587+
12588+ region = simple_strtol(arg, 0, 10);
12589+
12590+#ifdef EXT_BUILD_CHANNEL_LIST
12591+ return -EOPNOTSUPP;
12592+#endif // EXT_BUILD_CHANNEL_LIST //
12593+
12594+ // Country can be set only when EEPROM not programmed
12595+ if (pAd->CommonCfg.CountryRegionForABand & 0x80)
12596+ {
12597+ DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegionABand_Proc::parameter of CountryRegion in eeprom is programmed \n"));
12598+ return FALSE;
12599+ }
12600+
12601+ if((region >= 0) && (region <= REGION_MAXIMUM_A_BAND))
12602+ {
12603+ pAd->CommonCfg.CountryRegionForABand = (UCHAR) region;
12604+ }
12605+ else
12606+ {
12607+ DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegionABand_Proc::parameters out of range\n"));
12608+ return FALSE;
12609+ }
12610+
12611+ // if set country region, driver needs to be reset
12612+ BuildChannelList(pAd);
12613+
12614+ DBGPRINT(RT_DEBUG_TRACE, ("Set_CountryRegionABand_Proc::(CountryRegion=%d)\n", pAd->CommonCfg.CountryRegionForABand));
12615+
12616+ return TRUE;
12617+}
12618+
12619+/*
12620+ ==========================================================================
12621+ Description:
12622+ Set Wireless Mode
12623+ Return:
12624+ TRUE if all parameters are OK, FALSE otherwise
12625+ ==========================================================================
12626+*/
12627+INT Set_WirelessMode_Proc(
12628+ IN PRTMP_ADAPTER pAd,
12629+ IN PUCHAR arg)
12630+{
12631+ ULONG WirelessMode;
12632+ INT success = TRUE;
12633+
12634+ WirelessMode = simple_strtol(arg, 0, 10);
12635+
12636+
12637+#ifdef CONFIG_STA_SUPPORT
12638+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
12639+ {
12640+ INT MaxPhyMode = PHY_11G;
12641+
12642+#ifdef DOT11_N_SUPPORT
12643+ MaxPhyMode = PHY_11N_5G;
12644+#endif // DOT11_N_SUPPORT //
12645+
12646+ if (WirelessMode <= MaxPhyMode)
12647+ {
12648+ RTMPSetPhyMode(pAd, WirelessMode);
12649+#ifdef DOT11_N_SUPPORT
12650+ if (WirelessMode >= PHY_11ABGN_MIXED)
12651+ {
12652+ pAd->CommonCfg.BACapability.field.AutoBA = TRUE;
12653+ pAd->CommonCfg.REGBACapability.field.AutoBA = TRUE;
12654+ }
12655+ else
12656+ {
12657+ pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
12658+ pAd->CommonCfg.REGBACapability.field.AutoBA = FALSE;
12659+ }
12660+#endif // DOT11_N_SUPPORT //
12661+ // Set AdhocMode rates
12662+ if (pAd->StaCfg.BssType == BSS_ADHOC)
12663+ {
12664+ MlmeUpdateTxRates(pAd, FALSE, 0);
12665+ MakeIbssBeacon(pAd); // re-build BEACON frame
12666+ AsicEnableIbssSync(pAd); // copy to on-chip memory
12667+ }
12668+ }
12669+ else
12670+ {
12671+ success = FALSE;
12672+ }
12673+ }
12674+#endif // CONFIG_STA_SUPPORT //
12675+
12676+ // it is needed to set SSID to take effect
12677+ if (success == TRUE)
12678+ {
12679+#ifdef DOT11_N_SUPPORT
12680+ SetCommonHT(pAd);
12681+#endif // DOT11_N_SUPPORT //
12682+ DBGPRINT(RT_DEBUG_TRACE, ("Set_WirelessMode_Proc::(=%ld)\n", WirelessMode));
12683+ }
12684+ else
12685+ {
12686+ DBGPRINT(RT_DEBUG_ERROR, ("Set_WirelessMode_Proc::parameters out of range\n"));
12687+ }
12688+
12689+ return success;
12690+}
12691+
12692+/*
12693+ ==========================================================================
12694+ Description:
12695+ Set Channel
12696+ Return:
12697+ TRUE if all parameters are OK, FALSE otherwise
12698+ ==========================================================================
12699+*/
12700+INT Set_Channel_Proc(
12701+ IN PRTMP_ADAPTER pAd,
12702+ IN PUCHAR arg)
12703+{
12704+ INT success = TRUE;
12705+ UCHAR Channel;
12706+
12707+ Channel = (UCHAR) simple_strtol(arg, 0, 10);
12708+
12709+ // check if this channel is valid
12710+ if (ChannelSanity(pAd, Channel) == TRUE)
12711+ {
12712+#ifdef CONFIG_STA_SUPPORT
12713+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
12714+ {
12715+ pAd->CommonCfg.Channel = Channel;
12716+
12717+ if (MONITOR_ON(pAd))
12718+ {
12719+#ifdef DOT11_N_SUPPORT
12720+ N_ChannelCheck(pAd);
12721+ if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
12722+ pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
12723+ {
12724+ N_SetCenCh(pAd);
12725+ AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
12726+ AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
12727+ DBGPRINT(RT_DEBUG_TRACE, ("BW_40, control_channel(%d), CentralChannel(%d) \n",
12728+ pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
12729+ }
12730+ else
12731+#endif // DOT11_N_SUPPORT //
12732+ {
12733+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
12734+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
12735+ DBGPRINT(RT_DEBUG_TRACE, ("BW_20, Channel(%d)\n", pAd->CommonCfg.Channel));
12736+ }
12737+ }
12738+ }
12739+#endif // CONFIG_STA_SUPPORT //
12740+ success = TRUE;
12741+ }
12742+ else
12743+ {
12744+
12745+#ifdef CONFIG_STA_SUPPORT
12746+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
12747+ success = FALSE;
12748+#endif // CONFIG_STA_SUPPORT //
12749+ }
12750+
12751+
12752+ if (success == TRUE)
12753+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Channel_Proc::(Channel=%d)\n", pAd->CommonCfg.Channel));
12754+
12755+ return success;
12756+}
12757+
12758+/*
12759+ ==========================================================================
12760+ Description:
12761+ Set Short Slot Time Enable or Disable
12762+ Return:
12763+ TRUE if all parameters are OK, FALSE otherwise
12764+ ==========================================================================
12765+*/
12766+INT Set_ShortSlot_Proc(
12767+ IN PRTMP_ADAPTER pAd,
12768+ IN PUCHAR arg)
12769+{
12770+ ULONG ShortSlot;
12771+
12772+ ShortSlot = simple_strtol(arg, 0, 10);
12773+
12774+ if (ShortSlot == 1)
12775+ pAd->CommonCfg.bUseShortSlotTime = TRUE;
12776+ else if (ShortSlot == 0)
12777+ pAd->CommonCfg.bUseShortSlotTime = FALSE;
12778+ else
12779+ return FALSE; //Invalid argument
12780+
12781+ DBGPRINT(RT_DEBUG_TRACE, ("Set_ShortSlot_Proc::(ShortSlot=%d)\n", pAd->CommonCfg.bUseShortSlotTime));
12782+
12783+ return TRUE;
12784+}
12785+
12786+/*
12787+ ==========================================================================
12788+ Description:
12789+ Set Tx power
12790+ Return:
12791+ TRUE if all parameters are OK, FALSE otherwise
12792+ ==========================================================================
12793+*/
12794+INT Set_TxPower_Proc(
12795+ IN PRTMP_ADAPTER pAd,
12796+ IN PUCHAR arg)
12797+{
12798+ ULONG TxPower;
12799+ INT success = FALSE;
12800+
12801+ TxPower = (ULONG) simple_strtol(arg, 0, 10);
12802+ if (TxPower <= 100)
12803+ {
12804+
12805+#ifdef CONFIG_STA_SUPPORT
12806+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
12807+ {
12808+ pAd->CommonCfg.TxPowerDefault = TxPower;
12809+ pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
12810+ }
12811+#endif // CONFIG_STA_SUPPORT //
12812+ success = TRUE;
12813+ }
12814+ else
12815+ success = FALSE;
12816+
12817+ DBGPRINT(RT_DEBUG_TRACE, ("Set_TxPower_Proc::(TxPowerPercentage=%ld)\n", pAd->CommonCfg.TxPowerPercentage));
12818+
12819+ return success;
12820+}
12821+
12822+/*
12823+ ==========================================================================
12824+ Description:
12825+ Set 11B/11G Protection
12826+ Return:
12827+ TRUE if all parameters are OK, FALSE otherwise
12828+ ==========================================================================
12829+*/
12830+INT Set_BGProtection_Proc(
12831+ IN PRTMP_ADAPTER pAd,
12832+ IN PUCHAR arg)
12833+{
12834+ switch (simple_strtol(arg, 0, 10))
12835+ {
12836+ case 0: //AUTO
12837+ pAd->CommonCfg.UseBGProtection = 0;
12838+ break;
12839+ case 1: //Always On
12840+ pAd->CommonCfg.UseBGProtection = 1;
12841+ break;
12842+ case 2: //Always OFF
12843+ pAd->CommonCfg.UseBGProtection = 2;
12844+ break;
12845+ default: //Invalid argument
12846+ return FALSE;
12847+ }
12848+
12849+
12850+ DBGPRINT(RT_DEBUG_TRACE, ("Set_BGProtection_Proc::(BGProtection=%ld)\n", pAd->CommonCfg.UseBGProtection));
12851+
12852+ return TRUE;
12853+}
12854+
12855+/*
12856+ ==========================================================================
12857+ Description:
12858+ Set TxPreamble
12859+ Return:
12860+ TRUE if all parameters are OK, FALSE otherwise
12861+ ==========================================================================
12862+*/
12863+INT Set_TxPreamble_Proc(
12864+ IN PRTMP_ADAPTER pAd,
12865+ IN PUCHAR arg)
12866+{
12867+ RT_802_11_PREAMBLE Preamble;
12868+
12869+ Preamble = simple_strtol(arg, 0, 10);
12870+
12871+
12872+ switch (Preamble)
12873+ {
12874+ case Rt802_11PreambleShort:
12875+ pAd->CommonCfg.TxPreamble = Preamble;
12876+#ifdef CONFIG_STA_SUPPORT
12877+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
12878+ MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
12879+#endif // CONFIG_STA_SUPPORT //
12880+ break;
12881+ case Rt802_11PreambleLong:
12882+#ifdef CONFIG_STA_SUPPORT
12883+ case Rt802_11PreambleAuto:
12884+ // if user wants AUTO, initialize to LONG here, then change according to AP's
12885+ // capability upon association.
12886+#endif // CONFIG_STA_SUPPORT //
12887+ pAd->CommonCfg.TxPreamble = Preamble;
12888+#ifdef CONFIG_STA_SUPPORT
12889+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
12890+ MlmeSetTxPreamble(pAd, Rt802_11PreambleLong);
12891+#endif // CONFIG_STA_SUPPORT //
12892+ break;
12893+ default: //Invalid argument
12894+ return FALSE;
12895+ }
12896+
12897+ DBGPRINT(RT_DEBUG_TRACE, ("Set_TxPreamble_Proc::(TxPreamble=%ld)\n", pAd->CommonCfg.TxPreamble));
12898+
12899+ return TRUE;
12900+}
12901+
12902+/*
12903+ ==========================================================================
12904+ Description:
12905+ Set RTS Threshold
12906+ Return:
12907+ TRUE if all parameters are OK, FALSE otherwise
12908+ ==========================================================================
12909+*/
12910+INT Set_RTSThreshold_Proc(
12911+ IN PRTMP_ADAPTER pAd,
12912+ IN PUCHAR arg)
12913+{
12914+ NDIS_802_11_RTS_THRESHOLD RtsThresh;
12915+
12916+ RtsThresh = simple_strtol(arg, 0, 10);
12917+
12918+ if((RtsThresh > 0) && (RtsThresh <= MAX_RTS_THRESHOLD))
12919+ pAd->CommonCfg.RtsThreshold = (USHORT)RtsThresh;
12920+#ifdef CONFIG_STA_SUPPORT
12921+ else if (RtsThresh == 0)
12922+ pAd->CommonCfg.RtsThreshold = MAX_RTS_THRESHOLD;
12923+#endif // CONFIG_STA_SUPPORT //
12924+ else
12925+ return FALSE; //Invalid argument
12926+
12927+ DBGPRINT(RT_DEBUG_TRACE, ("Set_RTSThreshold_Proc::(RTSThreshold=%d)\n", pAd->CommonCfg.RtsThreshold));
12928+
12929+ return TRUE;
12930+}
12931+
12932+/*
12933+ ==========================================================================
12934+ Description:
12935+ Set Fragment Threshold
12936+ Return:
12937+ TRUE if all parameters are OK, FALSE otherwise
12938+ ==========================================================================
12939+*/
12940+INT Set_FragThreshold_Proc(
12941+ IN PRTMP_ADAPTER pAd,
12942+ IN PUCHAR arg)
12943+{
12944+ NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh;
12945+
12946+ FragThresh = simple_strtol(arg, 0, 10);
12947+
12948+ if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD)
12949+ {
12950+ //Illegal FragThresh so we set it to default
12951+ pAd->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD;
12952+ }
12953+ else if (FragThresh % 2 == 1)
12954+ {
12955+ // The length of each fragment shall always be an even number of octets, except for the last fragment
12956+ // of an MSDU or MMPDU, which may be either an even or an odd number of octets.
12957+ pAd->CommonCfg.FragmentThreshold = (USHORT)(FragThresh - 1);
12958+ }
12959+ else
12960+ {
12961+ pAd->CommonCfg.FragmentThreshold = (USHORT)FragThresh;
12962+ }
12963+
12964+#ifdef CONFIG_STA_SUPPORT
12965+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
12966+ {
12967+ if (pAd->CommonCfg.FragmentThreshold == MAX_FRAG_THRESHOLD)
12968+ pAd->CommonCfg.bUseZeroToDisableFragment = TRUE;
12969+ else
12970+ pAd->CommonCfg.bUseZeroToDisableFragment = FALSE;
12971+ }
12972+#endif // CONFIG_STA_SUPPORT //
12973+
12974+ DBGPRINT(RT_DEBUG_TRACE, ("Set_FragThreshold_Proc::(FragThreshold=%d)\n", pAd->CommonCfg.FragmentThreshold));
12975+
12976+ return TRUE;
12977+}
12978+
12979+/*
12980+ ==========================================================================
12981+ Description:
12982+ Set TxBurst
12983+ Return:
12984+ TRUE if all parameters are OK, FALSE otherwise
12985+ ==========================================================================
12986+*/
12987+INT Set_TxBurst_Proc(
12988+ IN PRTMP_ADAPTER pAd,
12989+ IN PUCHAR arg)
12990+{
12991+ ULONG TxBurst;
12992+
12993+ TxBurst = simple_strtol(arg, 0, 10);
12994+ if (TxBurst == 1)
12995+ pAd->CommonCfg.bEnableTxBurst = TRUE;
12996+ else if (TxBurst == 0)
12997+ pAd->CommonCfg.bEnableTxBurst = FALSE;
12998+ else
12999+ return FALSE; //Invalid argument
13000+
13001+ DBGPRINT(RT_DEBUG_TRACE, ("Set_TxBurst_Proc::(TxBurst=%d)\n", pAd->CommonCfg.bEnableTxBurst));
13002+
13003+ return TRUE;
13004+}
13005+
13006+#ifdef AGGREGATION_SUPPORT
13007+/*
13008+ ==========================================================================
13009+ Description:
13010+ Set TxBurst
13011+ Return:
13012+ TRUE if all parameters are OK, FALSE otherwise
13013+ ==========================================================================
13014+*/
13015+INT Set_PktAggregate_Proc(
13016+ IN PRTMP_ADAPTER pAd,
13017+ IN PUCHAR arg)
13018+{
13019+ ULONG aggre;
13020+
13021+ aggre = simple_strtol(arg, 0, 10);
13022+
13023+ if (aggre == 1)
13024+ pAd->CommonCfg.bAggregationCapable = TRUE;
13025+ else if (aggre == 0)
13026+ pAd->CommonCfg.bAggregationCapable = FALSE;
13027+ else
13028+ return FALSE; //Invalid argument
13029+
13030+
13031+ DBGPRINT(RT_DEBUG_TRACE, ("Set_PktAggregate_Proc::(AGGRE=%d)\n", pAd->CommonCfg.bAggregationCapable));
13032+
13033+ return TRUE;
13034+}
13035+#endif
13036+
13037+/*
13038+ ==========================================================================
13039+ Description:
13040+ Set IEEE80211H.
13041+ This parameter is 1 when needs radar detection, otherwise 0
13042+ Return:
13043+ TRUE if all parameters are OK, FALSE otherwise
13044+ ==========================================================================
13045+*/
13046+INT Set_IEEE80211H_Proc(
13047+ IN PRTMP_ADAPTER pAd,
13048+ IN PUCHAR arg)
13049+{
13050+ ULONG ieee80211h;
13051+
13052+ ieee80211h = simple_strtol(arg, 0, 10);
13053+
13054+ if (ieee80211h == 1)
13055+ pAd->CommonCfg.bIEEE80211H = TRUE;
13056+ else if (ieee80211h == 0)
13057+ pAd->CommonCfg.bIEEE80211H = FALSE;
13058+ else
13059+ return FALSE; //Invalid argument
13060+
13061+ DBGPRINT(RT_DEBUG_TRACE, ("Set_IEEE80211H_Proc::(IEEE80211H=%d)\n", pAd->CommonCfg.bIEEE80211H));
13062+
13063+ return TRUE;
13064+}
13065+
13066+
13067+#ifdef DBG
13068+/*
13069+ ==========================================================================
13070+ Description:
13071+ For Debug information
13072+ Return:
13073+ TRUE if all parameters are OK, FALSE otherwise
13074+ ==========================================================================
13075+*/
13076+INT Set_Debug_Proc(
13077+ IN PRTMP_ADAPTER pAd,
13078+ IN PUCHAR arg)
13079+{
13080+ DBGPRINT(RT_DEBUG_TRACE, ("==> Set_Debug_Proc *******************\n"));
13081+
13082+ if(simple_strtol(arg, 0, 10) <= RT_DEBUG_LOUD)
13083+ RTDebugLevel = simple_strtol(arg, 0, 10);
13084+
13085+ DBGPRINT(RT_DEBUG_TRACE, ("<== Set_Debug_Proc(RTDebugLevel = %ld)\n", RTDebugLevel));
13086+
13087+ return TRUE;
13088+}
13089+#endif
13090+
13091+INT Show_DescInfo_Proc(
13092+ IN PRTMP_ADAPTER pAd,
13093+ IN PUCHAR arg)
13094+{
13095+
13096+ return TRUE;
13097+}
13098+
13099+/*
13100+ ==========================================================================
13101+ Description:
13102+ Reset statistics counter
13103+
13104+ Arguments:
13105+ pAdapter Pointer to our adapter
13106+ arg
13107+
13108+ Return:
13109+ TRUE if all parameters are OK, FALSE otherwise
13110+ ==========================================================================
13111+*/
13112+INT Set_ResetStatCounter_Proc(
13113+ IN PRTMP_ADAPTER pAd,
13114+ IN PUCHAR arg)
13115+{
13116+ //UCHAR i;
13117+ //MAC_TABLE_ENTRY *pEntry;
13118+
13119+ DBGPRINT(RT_DEBUG_TRACE, ("==>Set_ResetStatCounter_Proc\n"));
13120+
13121+ // add the most up-to-date h/w raw counters into software counters
13122+ NICUpdateRawCounters(pAd);
13123+
13124+ NdisZeroMemory(&pAd->WlanCounters, sizeof(COUNTER_802_11));
13125+ NdisZeroMemory(&pAd->Counters8023, sizeof(COUNTER_802_3));
13126+ NdisZeroMemory(&pAd->RalinkCounters, sizeof(COUNTER_RALINK));
13127+
13128+ return TRUE;
13129+}
13130+
13131+BOOLEAN RTMPCheckStrPrintAble(
13132+ IN CHAR *pInPutStr,
13133+ IN UCHAR strLen)
13134+{
13135+ UCHAR i=0;
13136+
13137+ for (i=0; i<strLen; i++)
13138+ {
13139+ if ((pInPutStr[i] < 0x21) ||
13140+ (pInPutStr[i] > 0x7E))
13141+ return FALSE;
13142+ }
13143+
13144+ return TRUE;
13145+}
13146+
13147+/*
13148+ ========================================================================
13149+
13150+ Routine Description:
13151+ Remove WPA Key process
13152+
13153+ Arguments:
13154+ pAd Pointer to our adapter
13155+ pBuf Pointer to the where the key stored
13156+
13157+ Return Value:
13158+ NDIS_SUCCESS Add key successfully
13159+
13160+ IRQL = DISPATCH_LEVEL
13161+
13162+ Note:
13163+
13164+ ========================================================================
13165+*/
13166+#ifdef CONFIG_STA_SUPPORT
13167+VOID RTMPSetDesiredRates(
13168+ IN PRTMP_ADAPTER pAdapter,
13169+ IN LONG Rates)
13170+{
13171+ NDIS_802_11_RATES aryRates;
13172+
13173+ memset(&aryRates, 0x00, sizeof(NDIS_802_11_RATES));
13174+ switch (pAdapter->CommonCfg.PhyMode)
13175+ {
13176+ case PHY_11A: // A only
13177+ switch (Rates)
13178+ {
13179+ case 6000000: //6M
13180+ aryRates[0] = 0x0c; // 6M
13181+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_0;
13182+ break;
13183+ case 9000000: //9M
13184+ aryRates[0] = 0x12; // 9M
13185+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_1;
13186+ break;
13187+ case 12000000: //12M
13188+ aryRates[0] = 0x18; // 12M
13189+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_2;
13190+ break;
13191+ case 18000000: //18M
13192+ aryRates[0] = 0x24; // 18M
13193+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_3;
13194+ break;
13195+ case 24000000: //24M
13196+ aryRates[0] = 0x30; // 24M
13197+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_4;
13198+ break;
13199+ case 36000000: //36M
13200+ aryRates[0] = 0x48; // 36M
13201+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_5;
13202+ break;
13203+ case 48000000: //48M
13204+ aryRates[0] = 0x60; // 48M
13205+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_6;
13206+ break;
13207+ case 54000000: //54M
13208+ aryRates[0] = 0x6c; // 54M
13209+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_7;
13210+ break;
13211+ case -1: //Auto
13212+ default:
13213+ aryRates[0] = 0x6c; // 54Mbps
13214+ aryRates[1] = 0x60; // 48Mbps
13215+ aryRates[2] = 0x48; // 36Mbps
13216+ aryRates[3] = 0x30; // 24Mbps
13217+ aryRates[4] = 0x24; // 18M
13218+ aryRates[5] = 0x18; // 12M
13219+ aryRates[6] = 0x12; // 9M
13220+ aryRates[7] = 0x0c; // 6M
13221+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
13222+ break;
13223+ }
13224+ break;
13225+ case PHY_11BG_MIXED: // B/G Mixed
13226+ case PHY_11B: // B only
13227+ case PHY_11ABG_MIXED: // A/B/G Mixed
13228+ default:
13229+ switch (Rates)
13230+ {
13231+ case 1000000: //1M
13232+ aryRates[0] = 0x02;
13233+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_0;
13234+ break;
13235+ case 2000000: //2M
13236+ aryRates[0] = 0x04;
13237+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_1;
13238+ break;
13239+ case 5000000: //5.5M
13240+ aryRates[0] = 0x0b; // 5.5M
13241+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_2;
13242+ break;
13243+ case 11000000: //11M
13244+ aryRates[0] = 0x16; // 11M
13245+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_3;
13246+ break;
13247+ case 6000000: //6M
13248+ aryRates[0] = 0x0c; // 6M
13249+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_0;
13250+ break;
13251+ case 9000000: //9M
13252+ aryRates[0] = 0x12; // 9M
13253+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_1;
13254+ break;
13255+ case 12000000: //12M
13256+ aryRates[0] = 0x18; // 12M
13257+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_2;
13258+ break;
13259+ case 18000000: //18M
13260+ aryRates[0] = 0x24; // 18M
13261+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_3;
13262+ break;
13263+ case 24000000: //24M
13264+ aryRates[0] = 0x30; // 24M
13265+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_4;
13266+ break;
13267+ case 36000000: //36M
13268+ aryRates[0] = 0x48; // 36M
13269+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_5;
13270+ break;
13271+ case 48000000: //48M
13272+ aryRates[0] = 0x60; // 48M
13273+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_6;
13274+ break;
13275+ case 54000000: //54M
13276+ aryRates[0] = 0x6c; // 54M
13277+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_7;
13278+ break;
13279+ case -1: //Auto
13280+ default:
13281+ if (pAdapter->CommonCfg.PhyMode == PHY_11B)
13282+ { //B Only
13283+ aryRates[0] = 0x16; // 11Mbps
13284+ aryRates[1] = 0x0b; // 5.5Mbps
13285+ aryRates[2] = 0x04; // 2Mbps
13286+ aryRates[3] = 0x02; // 1Mbps
13287+ }
13288+ else
13289+ { //(B/G) Mixed or (A/B/G) Mixed
13290+ aryRates[0] = 0x6c; // 54Mbps
13291+ aryRates[1] = 0x60; // 48Mbps
13292+ aryRates[2] = 0x48; // 36Mbps
13293+ aryRates[3] = 0x30; // 24Mbps
13294+ aryRates[4] = 0x16; // 11Mbps
13295+ aryRates[5] = 0x0b; // 5.5Mbps
13296+ aryRates[6] = 0x04; // 2Mbps
13297+ aryRates[7] = 0x02; // 1Mbps
13298+ }
13299+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
13300+ break;
13301+ }
13302+ break;
13303+ }
13304+
13305+ NdisZeroMemory(pAdapter->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
13306+ NdisMoveMemory(pAdapter->CommonCfg.DesireRate, &aryRates, sizeof(NDIS_802_11_RATES));
13307+ DBGPRINT(RT_DEBUG_TRACE, (" RTMPSetDesiredRates (%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x)\n",
13308+ pAdapter->CommonCfg.DesireRate[0],pAdapter->CommonCfg.DesireRate[1],
13309+ pAdapter->CommonCfg.DesireRate[2],pAdapter->CommonCfg.DesireRate[3],
13310+ pAdapter->CommonCfg.DesireRate[4],pAdapter->CommonCfg.DesireRate[5],
13311+ pAdapter->CommonCfg.DesireRate[6],pAdapter->CommonCfg.DesireRate[7] ));
13312+ // Changing DesiredRate may affect the MAX TX rate we used to TX frames out
13313+ MlmeUpdateTxRates(pAdapter, FALSE, 0);
13314+}
13315+
13316+NDIS_STATUS RTMPWPARemoveKeyProc(
13317+ IN PRTMP_ADAPTER pAd,
13318+ IN PVOID pBuf)
13319+{
13320+ PNDIS_802_11_REMOVE_KEY pKey;
13321+ ULONG KeyIdx;
13322+ NDIS_STATUS Status = NDIS_STATUS_FAILURE;
13323+ BOOLEAN bTxKey; // Set the key as transmit key
13324+ BOOLEAN bPairwise; // Indicate the key is pairwise key
13325+ BOOLEAN bKeyRSC; // indicate the receive SC set by KeyRSC value.
13326+ // Otherwise, it will set by the NIC.
13327+ BOOLEAN bAuthenticator; // indicate key is set by authenticator.
13328+ INT i;
13329+
13330+ DBGPRINT(RT_DEBUG_TRACE,("---> RTMPWPARemoveKeyProc\n"));
13331+
13332+ pKey = (PNDIS_802_11_REMOVE_KEY) pBuf;
13333+ KeyIdx = pKey->KeyIndex & 0xff;
13334+ // Bit 31 of Add-key, Tx Key
13335+ bTxKey = (pKey->KeyIndex & 0x80000000) ? TRUE : FALSE;
13336+ // Bit 30 of Add-key PairwiseKey
13337+ bPairwise = (pKey->KeyIndex & 0x40000000) ? TRUE : FALSE;
13338+ // Bit 29 of Add-key KeyRSC
13339+ bKeyRSC = (pKey->KeyIndex & 0x20000000) ? TRUE : FALSE;
13340+ // Bit 28 of Add-key Authenticator
13341+ bAuthenticator = (pKey->KeyIndex & 0x10000000) ? TRUE : FALSE;
13342+
13343+ // 1. If bTx is TRUE, return failure information
13344+ if (bTxKey == TRUE)
13345+ return(NDIS_STATUS_INVALID_DATA);
13346+
13347+ // 2. Check Pairwise Key
13348+ if (bPairwise)
13349+ {
13350+ // a. If BSSID is broadcast, remove all pairwise keys.
13351+ // b. If not broadcast, remove the pairwise specified by BSSID
13352+ for (i = 0; i < SHARE_KEY_NUM; i++)
13353+ {
13354+ if (MAC_ADDR_EQUAL(pAd->SharedKey[BSS0][i].BssId, pKey->BSSID))
13355+ {
13356+ DBGPRINT(RT_DEBUG_TRACE,("RTMPWPARemoveKeyProc(KeyIdx=%d)\n", i));
13357+ pAd->SharedKey[BSS0][i].KeyLen = 0;
13358+ pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_NONE;
13359+ AsicRemoveSharedKeyEntry(pAd, BSS0, (UCHAR)i);
13360+ Status = NDIS_STATUS_SUCCESS;
13361+ break;
13362+ }
13363+ }
13364+ }
13365+ // 3. Group Key
13366+ else
13367+ {
13368+ // a. If BSSID is broadcast, remove all group keys indexed
13369+ // b. If BSSID matched, delete the group key indexed.
13370+ DBGPRINT(RT_DEBUG_TRACE,("RTMPWPARemoveKeyProc(KeyIdx=%ld)\n", KeyIdx));
13371+ pAd->SharedKey[BSS0][KeyIdx].KeyLen = 0;
13372+ pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
13373+ AsicRemoveSharedKeyEntry(pAd, BSS0, (UCHAR)KeyIdx);
13374+ Status = NDIS_STATUS_SUCCESS;
13375+ }
13376+
13377+ return (Status);
13378+}
13379+#endif // CONFIG_STA_SUPPORT //
13380+
13381+
13382+#ifdef CONFIG_STA_SUPPORT
13383+/*
13384+ ========================================================================
13385+
13386+ Routine Description:
13387+ Remove All WPA Keys
13388+
13389+ Arguments:
13390+ pAd Pointer to our adapter
13391+
13392+ Return Value:
13393+ None
13394+
13395+ IRQL = DISPATCH_LEVEL
13396+
13397+ Note:
13398+
13399+ ========================================================================
13400+*/
13401+VOID RTMPWPARemoveAllKeys(
13402+ IN PRTMP_ADAPTER pAd)
13403+{
13404+
13405+ UCHAR i;
13406+
13407+ DBGPRINT(RT_DEBUG_TRACE,("RTMPWPARemoveAllKeys(AuthMode=%d, WepStatus=%d)\n", pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus));
13408+
13409+ // For WEP/CKIP, there is no need to remove it, since WinXP won't set it again after
13410+ // Link up. And it will be replaced if user changed it.
13411+ if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
13412+ return;
13413+
13414+ // For WPA-None, there is no need to remove it, since WinXP won't set it again after
13415+ // Link up. And it will be replaced if user changed it.
13416+ if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
13417+ return;
13418+
13419+ // set BSSID wcid entry of the Pair-wise Key table as no-security mode
13420+ AsicRemovePairwiseKeyEntry(pAd, BSS0, BSSID_WCID);
13421+
13422+ // set all shared key mode as no-security.
13423+ for (i = 0; i < SHARE_KEY_NUM; i++)
13424+ {
13425+ DBGPRINT(RT_DEBUG_TRACE,("remove %s key #%d\n", CipherName[pAd->SharedKey[BSS0][i].CipherAlg], i));
13426+ NdisZeroMemory(&pAd->SharedKey[BSS0][i], sizeof(CIPHER_KEY));
13427+
13428+ AsicRemoveSharedKeyEntry(pAd, BSS0, i);
13429+ }
13430+
13431+}
13432+#endif // CONFIG_STA_SUPPORT //
13433+
13434+/*
13435+ ========================================================================
13436+ Routine Description:
13437+ Change NIC PHY mode. Re-association may be necessary. possible settings
13438+ include - PHY_11B, PHY_11BG_MIXED, PHY_11A, and PHY_11ABG_MIXED
13439+
13440+ Arguments:
13441+ pAd - Pointer to our adapter
13442+ phymode -
13443+
13444+ IRQL = PASSIVE_LEVEL
13445+ IRQL = DISPATCH_LEVEL
13446+
13447+ ========================================================================
13448+*/
13449+VOID RTMPSetPhyMode(
13450+ IN PRTMP_ADAPTER pAd,
13451+ IN ULONG phymode)
13452+{
13453+ INT i;
13454+ // the selected phymode must be supported by the RF IC encoded in E2PROM
13455+
13456+ pAd->CommonCfg.PhyMode = (UCHAR)phymode;
13457+
13458+ DBGPRINT(RT_DEBUG_TRACE,("RTMPSetPhyMode : PhyMode=%d, channel=%d \n", pAd->CommonCfg.PhyMode, pAd->CommonCfg.Channel));
13459+#ifdef EXT_BUILD_CHANNEL_LIST
13460+ BuildChannelListEx(pAd);
13461+#else
13462+ BuildChannelList(pAd);
13463+#endif // EXT_BUILD_CHANNEL_LIST //
13464+
13465+ // sanity check user setting
13466+ for (i = 0; i < pAd->ChannelListNum; i++)
13467+ {
13468+ if (pAd->CommonCfg.Channel == pAd->ChannelList[i].Channel)
13469+ break;
13470+ }
13471+
13472+ if (i == pAd->ChannelListNum)
13473+ {
13474+#ifdef CONFIG_STA_SUPPORT
13475+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
13476+ pAd->CommonCfg.Channel = FirstChannel(pAd);
13477+#endif // CONFIG_STA_SUPPORT //
13478+ DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetPhyMode: channel is out of range, use first channel=%d \n", pAd->CommonCfg.Channel));
13479+ }
13480+
13481+ NdisZeroMemory(pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES);
13482+ NdisZeroMemory(pAd->CommonCfg.ExtRate, MAX_LEN_OF_SUPPORTED_RATES);
13483+ NdisZeroMemory(pAd->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
13484+ switch (phymode) {
13485+ case PHY_11B:
13486+ pAd->CommonCfg.SupRate[0] = 0x82; // 1 mbps, in units of 0.5 Mbps, basic rate
13487+ pAd->CommonCfg.SupRate[1] = 0x84; // 2 mbps, in units of 0.5 Mbps, basic rate
13488+ pAd->CommonCfg.SupRate[2] = 0x8B; // 5.5 mbps, in units of 0.5 Mbps, basic rate
13489+ pAd->CommonCfg.SupRate[3] = 0x96; // 11 mbps, in units of 0.5 Mbps, basic rate
13490+ pAd->CommonCfg.SupRateLen = 4;
13491+ pAd->CommonCfg.ExtRateLen = 0;
13492+ pAd->CommonCfg.DesireRate[0] = 2; // 1 mbps, in units of 0.5 Mbps
13493+ pAd->CommonCfg.DesireRate[1] = 4; // 2 mbps, in units of 0.5 Mbps
13494+ pAd->CommonCfg.DesireRate[2] = 11; // 5.5 mbps, in units of 0.5 Mbps
13495+ pAd->CommonCfg.DesireRate[3] = 22; // 11 mbps, in units of 0.5 Mbps
13496+ //pAd->CommonCfg.HTPhyMode.field.MODE = MODE_CCK; // This MODE is only FYI. not use
13497+ break;
13498+
13499+ case PHY_11G:
13500+ case PHY_11BG_MIXED:
13501+ case PHY_11ABG_MIXED:
13502+#ifdef DOT11_N_SUPPORT
13503+ case PHY_11N_2_4G:
13504+ case PHY_11ABGN_MIXED:
13505+ case PHY_11BGN_MIXED:
13506+ case PHY_11GN_MIXED:
13507+#endif // DOT11_N_SUPPORT //
13508+ pAd->CommonCfg.SupRate[0] = 0x82; // 1 mbps, in units of 0.5 Mbps, basic rate
13509+ pAd->CommonCfg.SupRate[1] = 0x84; // 2 mbps, in units of 0.5 Mbps, basic rate
13510+ pAd->CommonCfg.SupRate[2] = 0x8B; // 5.5 mbps, in units of 0.5 Mbps, basic rate
13511+ pAd->CommonCfg.SupRate[3] = 0x96; // 11 mbps, in units of 0.5 Mbps, basic rate
13512+ pAd->CommonCfg.SupRate[4] = 0x12; // 9 mbps, in units of 0.5 Mbps
13513+ pAd->CommonCfg.SupRate[5] = 0x24; // 18 mbps, in units of 0.5 Mbps
13514+ pAd->CommonCfg.SupRate[6] = 0x48; // 36 mbps, in units of 0.5 Mbps
13515+ pAd->CommonCfg.SupRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
13516+ pAd->CommonCfg.SupRateLen = 8;
13517+ pAd->CommonCfg.ExtRate[0] = 0x0C; // 6 mbps, in units of 0.5 Mbps
13518+ pAd->CommonCfg.ExtRate[1] = 0x18; // 12 mbps, in units of 0.5 Mbps
13519+ pAd->CommonCfg.ExtRate[2] = 0x30; // 24 mbps, in units of 0.5 Mbps
13520+ pAd->CommonCfg.ExtRate[3] = 0x60; // 48 mbps, in units of 0.5 Mbps
13521+ pAd->CommonCfg.ExtRateLen = 4;
13522+ pAd->CommonCfg.DesireRate[0] = 2; // 1 mbps, in units of 0.5 Mbps
13523+ pAd->CommonCfg.DesireRate[1] = 4; // 2 mbps, in units of 0.5 Mbps
13524+ pAd->CommonCfg.DesireRate[2] = 11; // 5.5 mbps, in units of 0.5 Mbps
13525+ pAd->CommonCfg.DesireRate[3] = 22; // 11 mbps, in units of 0.5 Mbps
13526+ pAd->CommonCfg.DesireRate[4] = 12; // 6 mbps, in units of 0.5 Mbps
13527+ pAd->CommonCfg.DesireRate[5] = 18; // 9 mbps, in units of 0.5 Mbps
13528+ pAd->CommonCfg.DesireRate[6] = 24; // 12 mbps, in units of 0.5 Mbps
13529+ pAd->CommonCfg.DesireRate[7] = 36; // 18 mbps, in units of 0.5 Mbps
13530+ pAd->CommonCfg.DesireRate[8] = 48; // 24 mbps, in units of 0.5 Mbps
13531+ pAd->CommonCfg.DesireRate[9] = 72; // 36 mbps, in units of 0.5 Mbps
13532+ pAd->CommonCfg.DesireRate[10] = 96; // 48 mbps, in units of 0.5 Mbps
13533+ pAd->CommonCfg.DesireRate[11] = 108; // 54 mbps, in units of 0.5 Mbps
13534+ break;
13535+
13536+ case PHY_11A:
13537+#ifdef DOT11_N_SUPPORT
13538+ case PHY_11AN_MIXED:
13539+ case PHY_11AGN_MIXED:
13540+ case PHY_11N_5G:
13541+#endif // DOT11_N_SUPPORT //
13542+ pAd->CommonCfg.SupRate[0] = 0x8C; // 6 mbps, in units of 0.5 Mbps, basic rate
13543+ pAd->CommonCfg.SupRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
13544+ pAd->CommonCfg.SupRate[2] = 0x98; // 12 mbps, in units of 0.5 Mbps, basic rate
13545+ pAd->CommonCfg.SupRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
13546+ pAd->CommonCfg.SupRate[4] = 0xb0; // 24 mbps, in units of 0.5 Mbps, basic rate
13547+ pAd->CommonCfg.SupRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
13548+ pAd->CommonCfg.SupRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
13549+ pAd->CommonCfg.SupRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
13550+ pAd->CommonCfg.SupRateLen = 8;
13551+ pAd->CommonCfg.ExtRateLen = 0;
13552+ pAd->CommonCfg.DesireRate[0] = 12; // 6 mbps, in units of 0.5 Mbps
13553+ pAd->CommonCfg.DesireRate[1] = 18; // 9 mbps, in units of 0.5 Mbps
13554+ pAd->CommonCfg.DesireRate[2] = 24; // 12 mbps, in units of 0.5 Mbps
13555+ pAd->CommonCfg.DesireRate[3] = 36; // 18 mbps, in units of 0.5 Mbps
13556+ pAd->CommonCfg.DesireRate[4] = 48; // 24 mbps, in units of 0.5 Mbps
13557+ pAd->CommonCfg.DesireRate[5] = 72; // 36 mbps, in units of 0.5 Mbps
13558+ pAd->CommonCfg.DesireRate[6] = 96; // 48 mbps, in units of 0.5 Mbps
13559+ pAd->CommonCfg.DesireRate[7] = 108; // 54 mbps, in units of 0.5 Mbps
13560+ //pAd->CommonCfg.HTPhyMode.field.MODE = MODE_OFDM; // This MODE is only FYI. not use
13561+ break;
13562+
13563+ default:
13564+ break;
13565+ }
13566+
13567+
13568+ pAd->CommonCfg.BandState = UNKNOWN_BAND;
13569+}
13570+
13571+
13572+#ifdef DOT11_N_SUPPORT
13573+/*
13574+ ========================================================================
13575+ Routine Description:
13576+ Caller ensures we has 802.11n support.
13577+ Calls at setting HT from AP/STASetinformation
13578+
13579+ Arguments:
13580+ pAd - Pointer to our adapter
13581+ phymode -
13582+
13583+ ========================================================================
13584+*/
13585+VOID RTMPSetHT(
13586+ IN PRTMP_ADAPTER pAd,
13587+ IN OID_SET_HT_PHYMODE *pHTPhyMode)
13588+{
13589+ //ULONG *pmcs;
13590+ UINT32 Value = 0;
13591+ UCHAR BBPValue = 0;
13592+ UCHAR BBP3Value = 0;
13593+ UCHAR RxStream = pAd->CommonCfg.RxStream;
13594+
13595+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : HT_mode(%d), ExtOffset(%d), MCS(%d), BW(%d), STBC(%d), SHORTGI(%d)\n",
13596+ pHTPhyMode->HtMode, pHTPhyMode->ExtOffset,
13597+ pHTPhyMode->MCS, pHTPhyMode->BW,
13598+ pHTPhyMode->STBC, pHTPhyMode->SHORTGI));
13599+
13600+ // Don't zero supportedHyPhy structure.
13601+ RTMPZeroMemory(&pAd->CommonCfg.HtCapability, sizeof(pAd->CommonCfg.HtCapability));
13602+ RTMPZeroMemory(&pAd->CommonCfg.AddHTInfo, sizeof(pAd->CommonCfg.AddHTInfo));
13603+ RTMPZeroMemory(&pAd->CommonCfg.NewExtChanOffset, sizeof(pAd->CommonCfg.NewExtChanOffset));
13604+ RTMPZeroMemory(&pAd->CommonCfg.DesiredHtPhy, sizeof(pAd->CommonCfg.DesiredHtPhy));
13605+
13606+ if (pAd->CommonCfg.bRdg)
13607+ {
13608+ pAd->CommonCfg.HtCapability.ExtHtCapInfo.PlusHTC = 1;
13609+ pAd->CommonCfg.HtCapability.ExtHtCapInfo.RDGSupport = 1;
13610+ }
13611+ else
13612+ {
13613+ pAd->CommonCfg.HtCapability.ExtHtCapInfo.PlusHTC = 0;
13614+ pAd->CommonCfg.HtCapability.ExtHtCapInfo.RDGSupport = 0;
13615+ }
13616+
13617+ pAd->CommonCfg.HtCapability.HtCapParm.MaxRAmpduFactor = 3;
13618+ pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor = 3;
13619+
13620+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : RxBAWinLimit = %d\n", pAd->CommonCfg.BACapability.field.RxBAWinLimit));
13621+
13622+ // Mimo power save, A-MSDU size,
13623+ pAd->CommonCfg.DesiredHtPhy.AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable;
13624+ pAd->CommonCfg.DesiredHtPhy.AmsduSize = (UCHAR)pAd->CommonCfg.BACapability.field.AmsduSize;
13625+ pAd->CommonCfg.DesiredHtPhy.MimoPs = (UCHAR)pAd->CommonCfg.BACapability.field.MMPSmode;
13626+ pAd->CommonCfg.DesiredHtPhy.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
13627+
13628+ pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize;
13629+ pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode;
13630+ pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
13631+
13632+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : AMsduSize = %d, MimoPs = %d, MpduDensity = %d, MaxRAmpduFactor = %d\n",
13633+ pAd->CommonCfg.DesiredHtPhy.AmsduSize,
13634+ pAd->CommonCfg.DesiredHtPhy.MimoPs,
13635+ pAd->CommonCfg.DesiredHtPhy.MpduDensity,
13636+ pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor));
13637+
13638+ if(pHTPhyMode->HtMode == HTMODE_GF)
13639+ {
13640+ pAd->CommonCfg.HtCapability.HtCapInfo.GF = 1;
13641+ pAd->CommonCfg.DesiredHtPhy.GF = 1;
13642+ }
13643+ else
13644+ pAd->CommonCfg.DesiredHtPhy.GF = 0;
13645+
13646+ // Decide Rx MCSSet
13647+ switch (RxStream)
13648+ {
13649+ case 1:
13650+ pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff;
13651+ pAd->CommonCfg.HtCapability.MCSSet[1] = 0x00;
13652+ break;
13653+
13654+ case 2:
13655+ pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff;
13656+ pAd->CommonCfg.HtCapability.MCSSet[1] = 0xff;
13657+ break;
13658+
13659+ case 3: // 3*3
13660+ pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff;
13661+ pAd->CommonCfg.HtCapability.MCSSet[1] = 0xff;
13662+ pAd->CommonCfg.HtCapability.MCSSet[2] = 0xff;
13663+ break;
13664+ }
13665+
13666+ if (pAd->CommonCfg.bForty_Mhz_Intolerant && (pAd->CommonCfg.Channel <= 14) && (pHTPhyMode->BW == BW_40) )
13667+ {
13668+ pHTPhyMode->BW = BW_20;
13669+ pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant = 1;
13670+ }
13671+
13672+ if(pHTPhyMode->BW == BW_40)
13673+ {
13674+ pAd->CommonCfg.HtCapability.MCSSet[4] = 0x1; // MCS 32
13675+ pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth = 1;
13676+ if (pAd->CommonCfg.Channel <= 14)
13677+ pAd->CommonCfg.HtCapability.HtCapInfo.CCKmodein40 = 1;
13678+
13679+ pAd->CommonCfg.DesiredHtPhy.ChannelWidth = 1;
13680+ pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 1;
13681+ pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = (pHTPhyMode->ExtOffset == EXTCHA_BELOW)? (EXTCHA_BELOW): EXTCHA_ABOVE;
13682+ // Set Regsiter for extension channel position.
13683+ RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
13684+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBP3Value);
13685+ if ((pHTPhyMode->ExtOffset == EXTCHA_BELOW))
13686+ {
13687+ Value |= 0x1;
13688+ BBP3Value |= (0x20);
13689+ RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
13690+ }
13691+ else if ((pHTPhyMode->ExtOffset == EXTCHA_ABOVE))
13692+ {
13693+ Value &= 0xfe;
13694+ BBP3Value &= (~0x20);
13695+ RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
13696+ }
13697+
13698+ // Turn on BBP 40MHz mode now only as AP .
13699+ // Sta can turn on BBP 40MHz after connection with 40MHz AP. Sta only broadcast 40MHz capability before connection.
13700+ if ((pAd->OpMode == OPMODE_AP) || INFRA_ON(pAd) || ADHOC_ON(pAd)
13701+ )
13702+ {
13703+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
13704+ BBPValue &= (~0x18);
13705+ BBPValue |= 0x10;
13706+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
13707+
13708+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBP3Value);
13709+ pAd->CommonCfg.BBPCurrentBW = BW_40;
13710+ }
13711+ }
13712+ else
13713+ {
13714+ pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth = 0;
13715+ pAd->CommonCfg.DesiredHtPhy.ChannelWidth = 0;
13716+ pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 0;
13717+ pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = EXTCHA_NONE;
13718+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
13719+ // Turn on BBP 20MHz mode by request here.
13720+ {
13721+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
13722+ BBPValue &= (~0x18);
13723+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
13724+ pAd->CommonCfg.BBPCurrentBW = BW_20;
13725+ }
13726+ }
13727+
13728+ if(pHTPhyMode->STBC == STBC_USE)
13729+ {
13730+ pAd->CommonCfg.HtCapability.HtCapInfo.TxSTBC = 1;
13731+ pAd->CommonCfg.DesiredHtPhy.TxSTBC = 1;
13732+ pAd->CommonCfg.HtCapability.HtCapInfo.RxSTBC = 1;
13733+ pAd->CommonCfg.DesiredHtPhy.RxSTBC = 1;
13734+ }
13735+ else
13736+ {
13737+ pAd->CommonCfg.DesiredHtPhy.TxSTBC = 0;
13738+ pAd->CommonCfg.DesiredHtPhy.RxSTBC = 0;
13739+ }
13740+
13741+ if(pHTPhyMode->SHORTGI == GI_400)
13742+ {
13743+ pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor20 = 1;
13744+ pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor40 = 1;
13745+ pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 = 1;
13746+ pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 = 1;
13747+ }
13748+ else
13749+ {
13750+ pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor20 = 0;
13751+ pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor40 = 0;
13752+ pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 = 0;
13753+ pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 = 0;
13754+ }
13755+
13756+ // We support link adaptation for unsolicit MCS feedback, set to 2.
13757+ pAd->CommonCfg.HtCapability.ExtHtCapInfo.MCSFeedback = MCSFBK_NONE; //MCSFBK_UNSOLICIT;
13758+ pAd->CommonCfg.AddHTInfo.ControlChan = pAd->CommonCfg.Channel;
13759+ // 1, the extension channel above the control channel.
13760+
13761+ // EDCA parameters used for AP's own transmission
13762+ if (pAd->CommonCfg.APEdcaParm.bValid == FALSE)
13763+ {
13764+ pAd->CommonCfg.APEdcaParm.bValid = TRUE;
13765+ pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
13766+ pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
13767+ pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
13768+ pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
13769+
13770+ pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
13771+ pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
13772+ pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
13773+ pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
13774+
13775+ pAd->CommonCfg.APEdcaParm.Cwmax[0] = 6;
13776+ pAd->CommonCfg.APEdcaParm.Cwmax[1] = 10;
13777+ pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
13778+ pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
13779+
13780+ pAd->CommonCfg.APEdcaParm.Txop[0] = 0;
13781+ pAd->CommonCfg.APEdcaParm.Txop[1] = 0;
13782+ pAd->CommonCfg.APEdcaParm.Txop[2] = 94;
13783+ pAd->CommonCfg.APEdcaParm.Txop[3] = 47;
13784+ }
13785+ AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
13786+
13787+
13788+#ifdef CONFIG_STA_SUPPORT
13789+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
13790+ {
13791+ RTMPSetIndividualHT(pAd, 0);
13792+ }
13793+#endif // CONFIG_STA_SUPPORT //
13794+
13795+}
13796+
13797+/*
13798+ ========================================================================
13799+ Routine Description:
13800+ Caller ensures we has 802.11n support.
13801+ Calls at setting HT from AP/STASetinformation
13802+
13803+ Arguments:
13804+ pAd - Pointer to our adapter
13805+ phymode -
13806+
13807+ ========================================================================
13808+*/
13809+VOID RTMPSetIndividualHT(
13810+ IN PRTMP_ADAPTER pAd,
13811+ IN UCHAR apidx)
13812+{
13813+ PRT_HT_PHY_INFO pDesired_ht_phy = NULL;
13814+ UCHAR TxStream = pAd->CommonCfg.TxStream;
13815+ UCHAR DesiredMcs = MCS_AUTO;
13816+
13817+ do
13818+ {
13819+
13820+#ifdef CONFIG_STA_SUPPORT
13821+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
13822+ {
13823+ pDesired_ht_phy = &pAd->StaCfg.DesiredHtPhyInfo;
13824+ DesiredMcs = pAd->StaCfg.DesiredTransmitSetting.field.MCS;
13825+ //pAd->StaCfg.bAutoTxRateSwitch = (DesiredMcs == MCS_AUTO) ? TRUE : FALSE;
13826+ break;
13827+ }
13828+#endif // CONFIG_STA_SUPPORT //
13829+ } while (FALSE);
13830+
13831+ if (pDesired_ht_phy == NULL)
13832+ {
13833+ DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetIndividualHT: invalid apidx(%d)\n", apidx));
13834+ return;
13835+ }
13836+ RTMPZeroMemory(pDesired_ht_phy, sizeof(RT_HT_PHY_INFO));
13837+
13838+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetIndividualHT : Desired MCS = %d\n", DesiredMcs));
13839+ // Check the validity of MCS
13840+ if ((TxStream == 1) && ((DesiredMcs >= MCS_8) && (DesiredMcs <= MCS_15)))
13841+ {
13842+ DBGPRINT(RT_DEBUG_WARN, ("RTMPSetIndividualHT: MCS(%d) is invalid in 1S, reset it as MCS_7\n", DesiredMcs));
13843+ DesiredMcs = MCS_7;
13844+ }
13845+
13846+ if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_20) && (DesiredMcs == MCS_32))
13847+ {
13848+ DBGPRINT(RT_DEBUG_WARN, ("RTMPSetIndividualHT: MCS_32 is only supported in 40-MHz, reset it as MCS_0\n"));
13849+ DesiredMcs = MCS_0;
13850+ }
13851+
13852+ pDesired_ht_phy->bHtEnable = TRUE;
13853+
13854+ // Decide desired Tx MCS
13855+ switch (TxStream)
13856+ {
13857+ case 1:
13858+ if (DesiredMcs == MCS_AUTO)
13859+ {
13860+ pDesired_ht_phy->MCSSet[0]= 0xff;
13861+ pDesired_ht_phy->MCSSet[1]= 0x00;
13862+ }
13863+ else if (DesiredMcs <= MCS_7)
13864+ {
13865+ pDesired_ht_phy->MCSSet[0]= 1<<DesiredMcs;
13866+ pDesired_ht_phy->MCSSet[1]= 0x00;
13867+ }
13868+ break;
13869+
13870+ case 2:
13871+ if (DesiredMcs == MCS_AUTO)
13872+ {
13873+ pDesired_ht_phy->MCSSet[0]= 0xff;
13874+ pDesired_ht_phy->MCSSet[1]= 0xff;
13875+ }
13876+ else if (DesiredMcs <= MCS_15)
13877+ {
13878+ ULONG mode;
13879+
13880+ mode = DesiredMcs / 8;
13881+ if (mode < 2)
13882+ pDesired_ht_phy->MCSSet[mode] = (1 << (DesiredMcs - mode * 8));
13883+ }
13884+ break;
13885+
13886+ case 3: // 3*3
13887+ if (DesiredMcs == MCS_AUTO)
13888+ {
13889+ /* MCS0 ~ MCS23, 3 bytes */
13890+ pDesired_ht_phy->MCSSet[0]= 0xff;
13891+ pDesired_ht_phy->MCSSet[1]= 0xff;
13892+ pDesired_ht_phy->MCSSet[2]= 0xff;
13893+ }
13894+ else if (DesiredMcs <= MCS_23)
13895+ {
13896+ ULONG mode;
13897+
13898+ mode = DesiredMcs / 8;
13899+ if (mode < 3)
13900+ pDesired_ht_phy->MCSSet[mode] = (1 << (DesiredMcs - mode * 8));
13901+ }
13902+ break;
13903+ }
13904+
13905+ if(pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_40)
13906+ {
13907+ if (DesiredMcs == MCS_AUTO || DesiredMcs == MCS_32)
13908+ pDesired_ht_phy->MCSSet[4] = 0x1;
13909+ }
13910+
13911+ // update HT Rate setting
13912+ if (pAd->OpMode == OPMODE_STA)
13913+ MlmeUpdateHtTxRates(pAd, BSS0);
13914+ else
13915+ MlmeUpdateHtTxRates(pAd, apidx);
13916+}
13917+
13918+
13919+/*
13920+ ========================================================================
13921+ Routine Description:
13922+ Update HT IE from our capability.
13923+
13924+ Arguments:
13925+ Send all HT IE in beacon/probe rsp/assoc rsp/action frame.
13926+
13927+
13928+ ========================================================================
13929+*/
13930+VOID RTMPUpdateHTIE(
13931+ IN RT_HT_CAPABILITY *pRtHt,
13932+ IN UCHAR *pMcsSet,
13933+ OUT HT_CAPABILITY_IE *pHtCapability,
13934+ OUT ADD_HT_INFO_IE *pAddHtInfo)
13935+{
13936+ RTMPZeroMemory(pHtCapability, sizeof(HT_CAPABILITY_IE));
13937+ RTMPZeroMemory(pAddHtInfo, sizeof(ADD_HT_INFO_IE));
13938+
13939+ pHtCapability->HtCapInfo.ChannelWidth = pRtHt->ChannelWidth;
13940+ pHtCapability->HtCapInfo.MimoPs = pRtHt->MimoPs;
13941+ pHtCapability->HtCapInfo.GF = pRtHt->GF;
13942+ pHtCapability->HtCapInfo.ShortGIfor20 = pRtHt->ShortGIfor20;
13943+ pHtCapability->HtCapInfo.ShortGIfor40 = pRtHt->ShortGIfor40;
13944+ pHtCapability->HtCapInfo.TxSTBC = pRtHt->TxSTBC;
13945+ pHtCapability->HtCapInfo.RxSTBC = pRtHt->RxSTBC;
13946+ pHtCapability->HtCapInfo.AMsduSize = pRtHt->AmsduSize;
13947+ pHtCapability->HtCapParm.MaxRAmpduFactor = pRtHt->MaxRAmpduFactor;
13948+ pHtCapability->HtCapParm.MpduDensity = pRtHt->MpduDensity;
13949+
13950+ pAddHtInfo->AddHtInfo.ExtChanOffset = pRtHt->ExtChanOffset ;
13951+ pAddHtInfo->AddHtInfo.RecomWidth = pRtHt->RecomWidth;
13952+ pAddHtInfo->AddHtInfo2.OperaionMode = pRtHt->OperaionMode;
13953+ pAddHtInfo->AddHtInfo2.NonGfPresent = pRtHt->NonGfPresent;
13954+ RTMPMoveMemory(pAddHtInfo->MCSSet, /*pRtHt->MCSSet*/pMcsSet, 4); // rt2860 only support MCS max=32, no need to copy all 16 uchar.
13955+
13956+ DBGPRINT(RT_DEBUG_TRACE,("RTMPUpdateHTIE <== \n"));
13957+}
13958+#endif // DOT11_N_SUPPORT //
13959+
13960+/*
13961+ ========================================================================
13962+ Description:
13963+ Add Client security information into ASIC WCID table and IVEIV table.
13964+ Return:
13965+ ========================================================================
13966+*/
13967+VOID RTMPAddWcidAttributeEntry(
13968+ IN PRTMP_ADAPTER pAd,
13969+ IN UCHAR BssIdx,
13970+ IN UCHAR KeyIdx,
13971+ IN UCHAR CipherAlg,
13972+ IN MAC_TABLE_ENTRY *pEntry)
13973+{
13974+ UINT32 WCIDAttri = 0;
13975+ USHORT offset;
13976+ UCHAR IVEIV = 0;
13977+ USHORT Wcid = 0;
13978+
13979+ {
13980+#ifdef CONFIG_STA_SUPPORT
13981+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
13982+ {
13983+ if (BssIdx > BSS0)
13984+ {
13985+ DBGPRINT(RT_DEBUG_ERROR, ("RTMPAddWcidAttributeEntry: The BSS-index(%d) is out of range for Infra link. \n", BssIdx));
13986+ return;
13987+ }
13988+
13989+ // 1. In ADHOC mode, the AID is wcid number. And NO mesh link exists.
13990+ // 2. In Infra mode, the AID:1 MUST be wcid of infra STA.
13991+ // the AID:2~ assign to mesh link entry.
13992+ if (pEntry && ADHOC_ON(pAd))
13993+ Wcid = pEntry->Aid;
13994+ else if (pEntry && INFRA_ON(pAd))
13995+ {
13996+#ifdef QOS_DLS_SUPPORT
13997+ if (pEntry->ValidAsDls == TRUE)
13998+ Wcid = pEntry->Aid;
13999+ else
14000+#endif // QOS_DLS_SUPPORT //
14001+ Wcid = BSSID_WCID;
14002+ }
14003+ else
14004+ Wcid = MCAST_WCID;
14005+ }
14006+#endif // CONFIG_STA_SUPPORT //
14007+ }
14008+
14009+ // Update WCID attribute table
14010+ offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE);
14011+
14012+#ifdef CONFIG_STA_SUPPORT
14013+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
14014+ {
14015+ if (pEntry && pEntry->ValidAsMesh)
14016+ WCIDAttri = (CipherAlg<<1) | PAIRWISEKEYTABLE;
14017+#ifdef QOS_DLS_SUPPORT
14018+ else if ((pEntry) && (pEntry->ValidAsDls) &&
14019+ ((CipherAlg == CIPHER_TKIP) ||
14020+ (CipherAlg == CIPHER_TKIP_NO_MIC) ||
14021+ (CipherAlg == CIPHER_AES) ||
14022+ (CipherAlg == CIPHER_NONE)))
14023+ WCIDAttri = (CipherAlg<<1) | PAIRWISEKEYTABLE;
14024+#endif // QOS_DLS_SUPPORT //
14025+ else
14026+ WCIDAttri = (CipherAlg<<1) | SHAREDKEYTABLE;
14027+ }
14028+#endif // CONFIG_STA_SUPPORT //
14029+
14030+ RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
14031+
14032+
14033+ // Update IV/EIV table
14034+ offset = MAC_IVEIV_TABLE_BASE + (Wcid * HW_IVEIV_ENTRY_SIZE);
14035+
14036+ // WPA mode
14037+ if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) || (CipherAlg == CIPHER_AES))
14038+ {
14039+ // Eiv bit on. keyid always is 0 for pairwise key
14040+ IVEIV = (KeyIdx <<6) | 0x20;
14041+ }
14042+ else
14043+ {
14044+ // WEP KeyIdx is default tx key.
14045+ IVEIV = (KeyIdx << 6);
14046+ }
14047+
14048+ // For key index and ext IV bit, so only need to update the position(offset+3).
14049+#ifdef RT2870
14050+ RTUSBMultiWrite_OneByte(pAd, offset+3, &IVEIV);
14051+#endif // RT2870 //
14052+
14053+ DBGPRINT(RT_DEBUG_TRACE,("RTMPAddWcidAttributeEntry: WCID #%d, KeyIndex #%d, Alg=%s\n",Wcid, KeyIdx, CipherName[CipherAlg]));
14054+ DBGPRINT(RT_DEBUG_TRACE,(" WCIDAttri = 0x%x \n", WCIDAttri));
14055+
14056+}
14057+
14058+/*
14059+ ==========================================================================
14060+ Description:
14061+ Parse encryption type
14062+Arguments:
14063+ pAdapter Pointer to our adapter
14064+ wrq Pointer to the ioctl argument
14065+
14066+ Return Value:
14067+ None
14068+
14069+ Note:
14070+ ==========================================================================
14071+*/
14072+CHAR *GetEncryptType(CHAR enc)
14073+{
14074+ if(enc == Ndis802_11WEPDisabled)
14075+ return "NONE";
14076+ if(enc == Ndis802_11WEPEnabled)
14077+ return "WEP";
14078+ if(enc == Ndis802_11Encryption2Enabled)
14079+ return "TKIP";
14080+ if(enc == Ndis802_11Encryption3Enabled)
14081+ return "AES";
14082+ if(enc == Ndis802_11Encryption4Enabled)
14083+ return "TKIPAES";
14084+ else
14085+ return "UNKNOW";
14086+}
14087+
14088+CHAR *GetAuthMode(CHAR auth)
14089+{
14090+ if(auth == Ndis802_11AuthModeOpen)
14091+ return "OPEN";
14092+ if(auth == Ndis802_11AuthModeShared)
14093+ return "SHARED";
14094+ if(auth == Ndis802_11AuthModeAutoSwitch)
14095+ return "AUTOWEP";
14096+ if(auth == Ndis802_11AuthModeWPA)
14097+ return "WPA";
14098+ if(auth == Ndis802_11AuthModeWPAPSK)
14099+ return "WPAPSK";
14100+ if(auth == Ndis802_11AuthModeWPANone)
14101+ return "WPANONE";
14102+ if(auth == Ndis802_11AuthModeWPA2)
14103+ return "WPA2";
14104+ if(auth == Ndis802_11AuthModeWPA2PSK)
14105+ return "WPA2PSK";
14106+ if(auth == Ndis802_11AuthModeWPA1WPA2)
14107+ return "WPA1WPA2";
14108+ if(auth == Ndis802_11AuthModeWPA1PSKWPA2PSK)
14109+ return "WPA1PSKWPA2PSK";
14110+
14111+ return "UNKNOW";
14112+}
14113+
14114+#if 1 //#ifndef UCOS
14115+/*
14116+ ==========================================================================
14117+ Description:
14118+ Get site survey results
14119+ Arguments:
14120+ pAdapter Pointer to our adapter
14121+ wrq Pointer to the ioctl argument
14122+
14123+ Return Value:
14124+ None
14125+
14126+ Note:
14127+ Usage:
14128+ 1.) UI needs to wait 4 seconds after issue a site survey command
14129+ 2.) iwpriv ra0 get_site_survey
14130+ 3.) UI needs to prepare at least 4096bytes to get the results
14131+ ==========================================================================
14132+*/
14133+#define LINE_LEN (4+33+20+8+10+9+7+3) // Channel+SSID+Bssid+WepStatus+AuthMode+Signal+WiressMode+NetworkType
14134+#ifdef CONFIG_STA_SUPPORT
14135+#endif // CONFIG_STA_SUPPORT //
14136+VOID RTMPIoctlGetSiteSurvey(
14137+ IN PRTMP_ADAPTER pAdapter,
14138+ IN struct iwreq *wrq)
14139+{
14140+ CHAR *msg;
14141+ INT i=0;
14142+ INT WaitCnt;
14143+ INT Status=0;
14144+ CHAR Ssid[MAX_LEN_OF_SSID +1];
14145+ INT Rssi = 0, max_len = LINE_LEN;
14146+ UINT Rssi_Quality = 0;
14147+ NDIS_802_11_NETWORK_TYPE wireless_mode;
14148+
14149+ os_alloc_mem(NULL, (PUCHAR *)&msg, sizeof(CHAR)*((MAX_LEN_OF_BSS_TABLE)*max_len));
14150+
14151+ if (msg == NULL)
14152+ {
14153+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPIoctlGetSiteSurvey - msg memory alloc fail.\n"));
14154+ return;
14155+ }
14156+
14157+ memset(msg, 0 ,(MAX_LEN_OF_BSS_TABLE)*max_len );
14158+ memset(Ssid, 0 ,(MAX_LEN_OF_SSID +1));
14159+ sprintf(msg,"%s","\n");
14160+ sprintf(msg+strlen(msg),"%-4s%-33s%-20s%-8s%-10s%-9s%-7s%-3s\n",
14161+ "Ch", "SSID", "BSSID", "Enc", "Auth", "Siganl(%)", "W-Mode", " NT");
14162+
14163+#ifdef CONFIG_STA_SUPPORT
14164+#endif // CONFIG_STA_SUPPORT //
14165+
14166+ WaitCnt = 0;
14167+#ifdef CONFIG_STA_SUPPORT
14168+ pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
14169+ while ((ScanRunning(pAdapter) == TRUE) && (WaitCnt++ < 200))
14170+ OS_WAIT(500);
14171+#endif // CONFIG_STA_SUPPORT //
14172+
14173+ for(i=0; i<pAdapter->ScanTab.BssNr ;i++)
14174+ {
14175+ if( pAdapter->ScanTab.BssEntry[i].Channel==0)
14176+ break;
14177+
14178+ if((strlen(msg)+max_len ) >= IW_SCAN_MAX_DATA)
14179+ break;
14180+
14181+ //Channel
14182+ sprintf(msg+strlen(msg),"%-4d", pAdapter->ScanTab.BssEntry[i].Channel);
14183+ //SSID
14184+ memcpy(Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen);
14185+ Ssid[pAdapter->ScanTab.BssEntry[i].SsidLen] = '\0';
14186+ sprintf(msg+strlen(msg),"%-33s", Ssid);
14187+ //BSSID
14188+ sprintf(msg+strlen(msg),"%02x:%02x:%02x:%02x:%02x:%02x ",
14189+ pAdapter->ScanTab.BssEntry[i].Bssid[0],
14190+ pAdapter->ScanTab.BssEntry[i].Bssid[1],
14191+ pAdapter->ScanTab.BssEntry[i].Bssid[2],
14192+ pAdapter->ScanTab.BssEntry[i].Bssid[3],
14193+ pAdapter->ScanTab.BssEntry[i].Bssid[4],
14194+ pAdapter->ScanTab.BssEntry[i].Bssid[5]);
14195+ //Encryption Type
14196+ sprintf(msg+strlen(msg),"%-8s",GetEncryptType(pAdapter->ScanTab.BssEntry[i].WepStatus));
14197+ //Authentication Mode
14198+ if (pAdapter->ScanTab.BssEntry[i].WepStatus == Ndis802_11WEPEnabled)
14199+ sprintf(msg+strlen(msg),"%-10s", "UNKNOW");
14200+ else
14201+ sprintf(msg+strlen(msg),"%-10s",GetAuthMode(pAdapter->ScanTab.BssEntry[i].AuthMode));
14202+ // Rssi
14203+ Rssi = (INT)pAdapter->ScanTab.BssEntry[i].Rssi;
14204+ if (Rssi >= -50)
14205+ Rssi_Quality = 100;
14206+ else if (Rssi >= -80) // between -50 ~ -80dbm
14207+ Rssi_Quality = (UINT)(24 + ((Rssi + 80) * 26)/10);
14208+ else if (Rssi >= -90) // between -80 ~ -90dbm
14209+ Rssi_Quality = (UINT)(((Rssi + 90) * 26)/10);
14210+ else // < -84 dbm
14211+ Rssi_Quality = 0;
14212+ sprintf(msg+strlen(msg),"%-9d", Rssi_Quality);
14213+ // Wireless Mode
14214+ wireless_mode = NetworkTypeInUseSanity(&pAdapter->ScanTab.BssEntry[i]);
14215+ if (wireless_mode == Ndis802_11FH ||
14216+ wireless_mode == Ndis802_11DS)
14217+ sprintf(msg+strlen(msg),"%-7s", "11b");
14218+ else if (wireless_mode == Ndis802_11OFDM5)
14219+ sprintf(msg+strlen(msg),"%-7s", "11a");
14220+ else if (wireless_mode == Ndis802_11OFDM5_N)
14221+ sprintf(msg+strlen(msg),"%-7s", "11a/n");
14222+ else if (wireless_mode == Ndis802_11OFDM24)
14223+ sprintf(msg+strlen(msg),"%-7s", "11b/g");
14224+ else if (wireless_mode == Ndis802_11OFDM24_N)
14225+ sprintf(msg+strlen(msg),"%-7s", "11b/g/n");
14226+ else
14227+ sprintf(msg+strlen(msg),"%-7s", "unknow");
14228+ //Network Type
14229+ if (pAdapter->ScanTab.BssEntry[i].BssType == BSS_ADHOC)
14230+ sprintf(msg+strlen(msg),"%-3s", " Ad");
14231+ else
14232+ sprintf(msg+strlen(msg),"%-3s", " In");
14233+
14234+ sprintf(msg+strlen(msg),"\n");
14235+#ifdef CONFIG_STA_SUPPORT
14236+#endif // CONFIG_STA_SUPPORT //
14237+ }
14238+
14239+#ifdef CONFIG_STA_SUPPORT
14240+ pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
14241+#endif // CONFIG_STA_SUPPORT //
14242+ wrq->u.data.length = strlen(msg);
14243+ Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
14244+
14245+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPIoctlGetSiteSurvey - wrq->u.data.length = %d\n", wrq->u.data.length));
14246+ os_free_mem(NULL, (PUCHAR)msg);
14247+}
14248+
14249+
14250+#define MAC_LINE_LEN (14+4+4+10+10+10+6+6) // Addr+aid+psm+datatime+rxbyte+txbyte+current tx rate+last tx rate
14251+VOID RTMPIoctlGetMacTable(
14252+ IN PRTMP_ADAPTER pAd,
14253+ IN struct iwreq *wrq)
14254+{
14255+ INT i;
14256+ RT_802_11_MAC_TABLE MacTab;
14257+ char *msg;
14258+
14259+ MacTab.Num = 0;
14260+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
14261+ {
14262+ if (pAd->MacTab.Content[i].ValidAsCLI && (pAd->MacTab.Content[i].Sst == SST_ASSOC))
14263+ {
14264+ COPY_MAC_ADDR(MacTab.Entry[MacTab.Num].Addr, &pAd->MacTab.Content[i].Addr);
14265+ MacTab.Entry[MacTab.Num].Aid = (UCHAR)pAd->MacTab.Content[i].Aid;
14266+ MacTab.Entry[MacTab.Num].Psm = pAd->MacTab.Content[i].PsMode;
14267+#ifdef DOT11_N_SUPPORT
14268+ MacTab.Entry[MacTab.Num].MimoPs = pAd->MacTab.Content[i].MmpsMode;
14269+#endif // DOT11_N_SUPPORT //
14270+
14271+ // Fill in RSSI per entry
14272+ MacTab.Entry[MacTab.Num].AvgRssi0 = pAd->MacTab.Content[i].RssiSample.AvgRssi0;
14273+ MacTab.Entry[MacTab.Num].AvgRssi1 = pAd->MacTab.Content[i].RssiSample.AvgRssi1;
14274+ MacTab.Entry[MacTab.Num].AvgRssi2 = pAd->MacTab.Content[i].RssiSample.AvgRssi2;
14275+
14276+ // the connected time per entry
14277+ MacTab.Entry[MacTab.Num].ConnectedTime = pAd->MacTab.Content[i].StaConnectTime;
14278+ MacTab.Entry[MacTab.Num].TxRate.field.MCS = pAd->MacTab.Content[i].HTPhyMode.field.MCS;
14279+ MacTab.Entry[MacTab.Num].TxRate.field.BW = pAd->MacTab.Content[i].HTPhyMode.field.BW;
14280+ MacTab.Entry[MacTab.Num].TxRate.field.ShortGI = pAd->MacTab.Content[i].HTPhyMode.field.ShortGI;
14281+ MacTab.Entry[MacTab.Num].TxRate.field.STBC = pAd->MacTab.Content[i].HTPhyMode.field.STBC;
14282+ MacTab.Entry[MacTab.Num].TxRate.field.rsv = pAd->MacTab.Content[i].HTPhyMode.field.rsv;
14283+ MacTab.Entry[MacTab.Num].TxRate.field.MODE = pAd->MacTab.Content[i].HTPhyMode.field.MODE;
14284+ MacTab.Entry[MacTab.Num].TxRate.word = pAd->MacTab.Content[i].HTPhyMode.word;
14285+
14286+ MacTab.Num += 1;
14287+ }
14288+ }
14289+ wrq->u.data.length = sizeof(RT_802_11_MAC_TABLE);
14290+ if (copy_to_user(wrq->u.data.pointer, &MacTab, wrq->u.data.length))
14291+ {
14292+ DBGPRINT(RT_DEBUG_TRACE, ("%s: copy_to_user() fail\n", __FUNCTION__));
14293+ }
14294+
14295+ msg = (CHAR *) kmalloc(sizeof(CHAR)*(MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN), MEM_ALLOC_FLAG);
14296+ memset(msg, 0 ,MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN );
14297+ sprintf(msg,"%s","\n");
14298+ sprintf(msg+strlen(msg),"%-14s%-4s%-4s%-10s%-10s%-10s%-6s%-6s\n",
14299+ "MAC", "AID", "PSM", "LDT", "RxB", "TxB","CTxR", "LTxR");
14300+
14301+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
14302+ {
14303+ PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
14304+ if (pEntry->ValidAsCLI && (pEntry->Sst == SST_ASSOC))
14305+ {
14306+ if((strlen(msg)+MAC_LINE_LEN ) >= (MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN) )
14307+ break;
14308+ sprintf(msg+strlen(msg),"%02x%02x%02x%02x%02x%02x ",
14309+ pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
14310+ pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
14311+ sprintf(msg+strlen(msg),"%-4d", (int)pEntry->Aid);
14312+ sprintf(msg+strlen(msg),"%-4d", (int)pEntry->PsMode);
14313+ sprintf(msg+strlen(msg),"%-10d",0/*pAd->MacTab.Content[i].HSCounter.LastDataPacketTime*/); // ToDo
14314+ sprintf(msg+strlen(msg),"%-10d",0/*pAd->MacTab.Content[i].HSCounter.TotalRxByteCount*/); // ToDo
14315+ sprintf(msg+strlen(msg),"%-10d",0/*pAd->MacTab.Content[i].HSCounter.TotalTxByteCount*/); // ToDo
14316+ sprintf(msg+strlen(msg),"%-6d",RateIdToMbps[pAd->MacTab.Content[i].CurrTxRate]);
14317+ sprintf(msg+strlen(msg),"%-6d\n",0/*RateIdToMbps[pAd->MacTab.Content[i].LastTxRate]*/); // ToDo
14318+ }
14319+ }
14320+ // for compatible with old API just do the printk to console
14321+ //wrq->u.data.length = strlen(msg);
14322+ //if (copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length))
14323+ {
14324+ DBGPRINT(RT_DEBUG_TRACE, ("%s", msg));
14325+ }
14326+
14327+ kfree(msg);
14328+}
14329+#endif // UCOS //
14330+
14331+#ifdef DOT11_N_SUPPORT
14332+INT Set_BASetup_Proc(
14333+ IN PRTMP_ADAPTER pAd,
14334+ IN PUCHAR arg)
14335+{
14336+ UCHAR mac[6], tid;
14337+ char *token, sepValue[] = ":", DASH = '-';
14338+ INT i;
14339+ MAC_TABLE_ENTRY *pEntry;
14340+
14341+/*
14342+ The BASetup inupt string format should be xx:xx:xx:xx:xx:xx-d,
14343+ =>The six 2 digit hex-decimal number previous are the Mac address,
14344+ =>The seventh decimal number is the tid value.
14345+*/
14346+ //printk("\n%s\n", arg);
14347+
14348+ if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and tid value in decimal format.
14349+ return FALSE;
14350+
14351+ token = strchr(arg, DASH);
14352+ if ((token != NULL) && (strlen(token)>1))
14353+ {
14354+ tid = simple_strtol((token+1), 0, 10);
14355+ if (tid > 15)
14356+ return FALSE;
14357+
14358+ *token = '\0';
14359+ for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
14360+ {
14361+ if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
14362+ return FALSE;
14363+ AtoH(token, (PUCHAR)(&mac[i]), 1);
14364+ }
14365+ if(i != 6)
14366+ return FALSE;
14367+
14368+ printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x\n", mac[0], mac[1],
14369+ mac[2], mac[3], mac[4], mac[5], tid);
14370+
14371+ pEntry = MacTableLookup(pAd, mac);
14372+
14373+ if (pEntry) {
14374+ printk("\nSetup BA Session: Tid = %d\n", tid);
14375+ BAOriSessionSetUp(pAd, pEntry, tid, 0, 100, TRUE);
14376+ }
14377+
14378+ return TRUE;
14379+ }
14380+
14381+ return FALSE;
14382+
14383+}
14384+
14385+INT Set_BADecline_Proc(
14386+ IN PRTMP_ADAPTER pAd,
14387+ IN PUCHAR arg)
14388+{
14389+ ULONG bBADecline;
14390+
14391+ bBADecline = simple_strtol(arg, 0, 10);
14392+
14393+ if (bBADecline == 0)
14394+ {
14395+ pAd->CommonCfg.bBADecline = FALSE;
14396+ }
14397+ else if (bBADecline == 1)
14398+ {
14399+ pAd->CommonCfg.bBADecline = TRUE;
14400+ }
14401+ else
14402+ {
14403+ return FALSE; //Invalid argument
14404+ }
14405+
14406+ DBGPRINT(RT_DEBUG_TRACE, ("Set_BADecline_Proc::(BADecline=%d)\n", pAd->CommonCfg.bBADecline));
14407+
14408+ return TRUE;
14409+}
14410+
14411+INT Set_BAOriTearDown_Proc(
14412+ IN PRTMP_ADAPTER pAd,
14413+ IN PUCHAR arg)
14414+{
14415+ UCHAR mac[6], tid;
14416+ char *token, sepValue[] = ":", DASH = '-';
14417+ INT i;
14418+ MAC_TABLE_ENTRY *pEntry;
14419+
14420+ //printk("\n%s\n", arg);
14421+/*
14422+ The BAOriTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d,
14423+ =>The six 2 digit hex-decimal number previous are the Mac address,
14424+ =>The seventh decimal number is the tid value.
14425+*/
14426+ if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and tid value in decimal format.
14427+ return FALSE;
14428+
14429+ token = strchr(arg, DASH);
14430+ if ((token != NULL) && (strlen(token)>1))
14431+ {
14432+ tid = simple_strtol((token+1), 0, 10);
14433+ if (tid > NUM_OF_TID)
14434+ return FALSE;
14435+
14436+ *token = '\0';
14437+ for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
14438+ {
14439+ if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
14440+ return FALSE;
14441+ AtoH(token, (PUCHAR)(&mac[i]), 1);
14442+ }
14443+ if(i != 6)
14444+ return FALSE;
14445+
14446+ printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", mac[0], mac[1],
14447+ mac[2], mac[3], mac[4], mac[5], tid);
14448+
14449+ pEntry = MacTableLookup(pAd, mac);
14450+
14451+ if (pEntry) {
14452+ printk("\nTear down Ori BA Session: Tid = %d\n", tid);
14453+ BAOriSessionTearDown(pAd, pEntry->Aid, tid, FALSE, TRUE);
14454+ }
14455+
14456+ return TRUE;
14457+ }
14458+
14459+ return FALSE;
14460+
14461+}
14462+
14463+INT Set_BARecTearDown_Proc(
14464+ IN PRTMP_ADAPTER pAd,
14465+ IN PUCHAR arg)
14466+{
14467+ UCHAR mac[6], tid;
14468+ char *token, sepValue[] = ":", DASH = '-';
14469+ INT i;
14470+ MAC_TABLE_ENTRY *pEntry;
14471+
14472+ //printk("\n%s\n", arg);
14473+/*
14474+ The BARecTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d,
14475+ =>The six 2 digit hex-decimal number previous are the Mac address,
14476+ =>The seventh decimal number is the tid value.
14477+*/
14478+ if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and tid value in decimal format.
14479+ return FALSE;
14480+
14481+ token = strchr(arg, DASH);
14482+ if ((token != NULL) && (strlen(token)>1))
14483+ {
14484+ tid = simple_strtol((token+1), 0, 10);
14485+ if (tid > NUM_OF_TID)
14486+ return FALSE;
14487+
14488+ *token = '\0';
14489+ for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
14490+ {
14491+ if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
14492+ return FALSE;
14493+ AtoH(token, (PUCHAR)(&mac[i]), 1);
14494+ }
14495+ if(i != 6)
14496+ return FALSE;
14497+
14498+ printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", mac[0], mac[1],
14499+ mac[2], mac[3], mac[4], mac[5], tid);
14500+
14501+ pEntry = MacTableLookup(pAd, mac);
14502+
14503+ if (pEntry) {
14504+ printk("\nTear down Rec BA Session: Tid = %d\n", tid);
14505+ BARecSessionTearDown(pAd, pEntry->Aid, tid, FALSE);
14506+ }
14507+
14508+ return TRUE;
14509+ }
14510+
14511+ return FALSE;
14512+
14513+}
14514+
14515+INT Set_HtBw_Proc(
14516+ IN PRTMP_ADAPTER pAd,
14517+ IN PUCHAR arg)
14518+{
14519+ ULONG HtBw;
14520+
14521+ HtBw = simple_strtol(arg, 0, 10);
14522+ if (HtBw == BW_40)
14523+ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
14524+ else if (HtBw == BW_20)
14525+ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
14526+ else
14527+ return FALSE; //Invalid argument
14528+
14529+ SetCommonHT(pAd);
14530+
14531+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtBw_Proc::(HtBw=%d)\n", pAd->CommonCfg.RegTransmitSetting.field.BW));
14532+
14533+ return TRUE;
14534+}
14535+
14536+INT Set_HtMcs_Proc(
14537+ IN PRTMP_ADAPTER pAd,
14538+ IN PUCHAR arg)
14539+{
14540+ ULONG HtMcs, Mcs_tmp;
14541+#ifdef CONFIG_STA_SUPPORT
14542+ BOOLEAN bAutoRate = FALSE;
14543+#endif // CONFIG_STA_SUPPORT //
14544+
14545+ Mcs_tmp = simple_strtol(arg, 0, 10);
14546+
14547+ if (Mcs_tmp <= 15 || Mcs_tmp == 32)
14548+ HtMcs = Mcs_tmp;
14549+ else
14550+ HtMcs = MCS_AUTO;
14551+
14552+#ifdef CONFIG_STA_SUPPORT
14553+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
14554+ {
14555+ pAd->StaCfg.DesiredTransmitSetting.field.MCS = HtMcs;
14556+ pAd->StaCfg.bAutoTxRateSwitch = (HtMcs == MCS_AUTO) ? TRUE:FALSE;
14557+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMcs_Proc::(HtMcs=%d, bAutoTxRateSwitch = %d)\n",
14558+ pAd->StaCfg.DesiredTransmitSetting.field.MCS, pAd->StaCfg.bAutoTxRateSwitch));
14559+
14560+ if ((pAd->CommonCfg.PhyMode < PHY_11ABGN_MIXED) ||
14561+ (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE < MODE_HTMIX))
14562+ {
14563+ if ((pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO) &&
14564+ (HtMcs >= 0 && HtMcs <= 3) &&
14565+ (pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode == FIXED_TXMODE_CCK))
14566+ {
14567+ RTMPSetDesiredRates(pAd, (LONG) (RateIdToMbps[HtMcs] * 1000000));
14568+ }
14569+ else if ((pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO) &&
14570+ (HtMcs >= 0 && HtMcs <= 7) &&
14571+ (pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode == FIXED_TXMODE_OFDM))
14572+ {
14573+ RTMPSetDesiredRates(pAd, (LONG) (RateIdToMbps[HtMcs+4] * 1000000));
14574+ }
14575+ else
14576+ bAutoRate = TRUE;
14577+
14578+ if (bAutoRate)
14579+ {
14580+ pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
14581+ RTMPSetDesiredRates(pAd, -1);
14582+ }
14583+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMcs_Proc::(FixedTxMode=%d)\n",pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode));
14584+ }
14585+ if (ADHOC_ON(pAd))
14586+ return TRUE;
14587+ }
14588+#endif // CONFIG_STA_SUPPORT //
14589+
14590+ SetCommonHT(pAd);
14591+
14592+ return TRUE;
14593+}
14594+
14595+INT Set_HtGi_Proc(
14596+ IN PRTMP_ADAPTER pAd,
14597+ IN PUCHAR arg)
14598+{
14599+ ULONG HtGi;
14600+
14601+ HtGi = simple_strtol(arg, 0, 10);
14602+
14603+ if ( HtGi == GI_400)
14604+ pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_400;
14605+ else if ( HtGi == GI_800 )
14606+ pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_800;
14607+ else
14608+ return FALSE; //Invalid argument
14609+
14610+ SetCommonHT(pAd);
14611+
14612+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtGi_Proc::(ShortGI=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.ShortGI));
14613+
14614+ return TRUE;
14615+}
14616+
14617+
14618+INT Set_HtTxBASize_Proc(
14619+ IN PRTMP_ADAPTER pAd,
14620+ IN PUCHAR arg)
14621+{
14622+ UCHAR Size;
14623+
14624+ Size = simple_strtol(arg, 0, 10);
14625+
14626+ if (Size <=0 || Size >=64)
14627+ {
14628+ Size = 8;
14629+ }
14630+ pAd->CommonCfg.TxBASize = Size-1;
14631+ DBGPRINT(RT_DEBUG_ERROR, ("Set_HtTxBASize ::(TxBASize= %d)\n", Size));
14632+
14633+ return TRUE;
14634+}
14635+
14636+
14637+INT Set_HtOpMode_Proc(
14638+ IN PRTMP_ADAPTER pAd,
14639+ IN PUCHAR arg)
14640+{
14641+
14642+ ULONG Value;
14643+
14644+ Value = simple_strtol(arg, 0, 10);
14645+
14646+ if (Value == HTMODE_GF)
14647+ pAd->CommonCfg.RegTransmitSetting.field.HTMODE = HTMODE_GF;
14648+ else if ( Value == HTMODE_MM )
14649+ pAd->CommonCfg.RegTransmitSetting.field.HTMODE = HTMODE_MM;
14650+ else
14651+ return FALSE; //Invalid argument
14652+
14653+ SetCommonHT(pAd);
14654+
14655+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtOpMode_Proc::(HtOpMode=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.HTMODE));
14656+
14657+ return TRUE;
14658+
14659+}
14660+
14661+INT Set_HtStbc_Proc(
14662+ IN PRTMP_ADAPTER pAd,
14663+ IN PUCHAR arg)
14664+{
14665+
14666+ ULONG Value;
14667+
14668+ Value = simple_strtol(arg, 0, 10);
14669+
14670+ if (Value == STBC_USE)
14671+ pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_USE;
14672+ else if ( Value == STBC_NONE )
14673+ pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_NONE;
14674+ else
14675+ return FALSE; //Invalid argument
14676+
14677+ SetCommonHT(pAd);
14678+
14679+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Stbc_Proc::(HtStbc=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.STBC));
14680+
14681+ return TRUE;
14682+}
14683+
14684+INT Set_HtHtc_Proc(
14685+ IN PRTMP_ADAPTER pAd,
14686+ IN PUCHAR arg)
14687+{
14688+
14689+ ULONG Value;
14690+
14691+ Value = simple_strtol(arg, 0, 10);
14692+ if (Value == 0)
14693+ pAd->HTCEnable = FALSE;
14694+ else if ( Value ==1 )
14695+ pAd->HTCEnable = TRUE;
14696+ else
14697+ return FALSE; //Invalid argument
14698+
14699+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtHtc_Proc::(HtHtc=%d)\n",pAd->HTCEnable));
14700+
14701+ return TRUE;
14702+}
14703+
14704+INT Set_HtExtcha_Proc(
14705+ IN PRTMP_ADAPTER pAd,
14706+ IN PUCHAR arg)
14707+{
14708+
14709+ ULONG Value;
14710+
14711+ Value = simple_strtol(arg, 0, 10);
14712+
14713+ if (Value == 0)
14714+ pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_BELOW;
14715+ else if ( Value ==1 )
14716+ pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE;
14717+ else
14718+ return FALSE; //Invalid argument
14719+
14720+ SetCommonHT(pAd);
14721+
14722+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtExtcha_Proc::(HtExtcha=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.EXTCHA));
14723+
14724+ return TRUE;
14725+}
14726+
14727+INT Set_HtMpduDensity_Proc(
14728+ IN PRTMP_ADAPTER pAd,
14729+ IN PUCHAR arg)
14730+{
14731+ ULONG Value;
14732+
14733+ Value = simple_strtol(arg, 0, 10);
14734+
14735+ if (Value <=7 && Value >= 0)
14736+ pAd->CommonCfg.BACapability.field.MpduDensity = Value;
14737+ else
14738+ pAd->CommonCfg.BACapability.field.MpduDensity = 4;
14739+
14740+ SetCommonHT(pAd);
14741+
14742+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMpduDensity_Proc::(HtMpduDensity=%d)\n",pAd->CommonCfg.BACapability.field.MpduDensity));
14743+
14744+ return TRUE;
14745+}
14746+
14747+INT Set_HtBaWinSize_Proc(
14748+ IN PRTMP_ADAPTER pAd,
14749+ IN PUCHAR arg)
14750+{
14751+ ULONG Value;
14752+
14753+ Value = simple_strtol(arg, 0, 10);
14754+
14755+
14756+ if (Value >=1 && Value <= 64)
14757+ {
14758+ pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = Value;
14759+ pAd->CommonCfg.BACapability.field.RxBAWinLimit = Value;
14760+ }
14761+ else
14762+ {
14763+ pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = 64;
14764+ pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64;
14765+ }
14766+
14767+ SetCommonHT(pAd);
14768+
14769+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtBaWinSize_Proc::(HtBaWinSize=%d)\n",pAd->CommonCfg.BACapability.field.RxBAWinLimit));
14770+
14771+ return TRUE;
14772+}
14773+
14774+INT Set_HtRdg_Proc(
14775+ IN PRTMP_ADAPTER pAd,
14776+ IN PUCHAR arg)
14777+{
14778+ ULONG Value;
14779+
14780+ Value = simple_strtol(arg, 0, 10);
14781+
14782+ if (Value == 0)
14783+ pAd->CommonCfg.bRdg = FALSE;
14784+ else if ( Value ==1 )
14785+ {
14786+ pAd->HTCEnable = TRUE;
14787+ pAd->CommonCfg.bRdg = TRUE;
14788+ }
14789+ else
14790+ return FALSE; //Invalid argument
14791+
14792+ SetCommonHT(pAd);
14793+
14794+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtRdg_Proc::(HtRdg=%d)\n",pAd->CommonCfg.bRdg));
14795+
14796+ return TRUE;
14797+}
14798+
14799+INT Set_HtLinkAdapt_Proc(
14800+ IN PRTMP_ADAPTER pAd,
14801+ IN PUCHAR arg)
14802+{
14803+ ULONG Value;
14804+
14805+ Value = simple_strtol(arg, 0, 10);
14806+ if (Value == 0)
14807+ pAd->bLinkAdapt = FALSE;
14808+ else if ( Value ==1 )
14809+ {
14810+ pAd->HTCEnable = TRUE;
14811+ pAd->bLinkAdapt = TRUE;
14812+ }
14813+ else
14814+ return FALSE; //Invalid argument
14815+
14816+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtLinkAdapt_Proc::(HtLinkAdapt=%d)\n",pAd->bLinkAdapt));
14817+
14818+ return TRUE;
14819+}
14820+
14821+INT Set_HtAmsdu_Proc(
14822+ IN PRTMP_ADAPTER pAd,
14823+ IN PUCHAR arg)
14824+{
14825+ ULONG Value;
14826+
14827+ Value = simple_strtol(arg, 0, 10);
14828+ if (Value == 0)
14829+ pAd->CommonCfg.BACapability.field.AmsduEnable = FALSE;
14830+ else if ( Value == 1 )
14831+ pAd->CommonCfg.BACapability.field.AmsduEnable = TRUE;
14832+ else
14833+ return FALSE; //Invalid argument
14834+
14835+ SetCommonHT(pAd);
14836+
14837+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtAmsdu_Proc::(HtAmsdu=%d)\n",pAd->CommonCfg.BACapability.field.AmsduEnable));
14838+
14839+ return TRUE;
14840+}
14841+
14842+INT Set_HtAutoBa_Proc(
14843+ IN PRTMP_ADAPTER pAd,
14844+ IN PUCHAR arg)
14845+{
14846+ ULONG Value;
14847+
14848+ Value = simple_strtol(arg, 0, 10);
14849+ if (Value == 0)
14850+ {
14851+ pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
14852+ pAd->CommonCfg.BACapability.field.Policy = BA_NOTUSE;
14853+ }
14854+ else if (Value == 1)
14855+ {
14856+ pAd->CommonCfg.BACapability.field.AutoBA = TRUE;
14857+ pAd->CommonCfg.BACapability.field.Policy = IMMED_BA;
14858+ }
14859+ else
14860+ return FALSE; //Invalid argument
14861+
14862+ pAd->CommonCfg.REGBACapability.field.AutoBA = pAd->CommonCfg.BACapability.field.AutoBA;
14863+ pAd->CommonCfg.REGBACapability.field.Policy = pAd->CommonCfg.BACapability.field.Policy;
14864+ SetCommonHT(pAd);
14865+
14866+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtAutoBa_Proc::(HtAutoBa=%d)\n",pAd->CommonCfg.BACapability.field.AutoBA));
14867+
14868+ return TRUE;
14869+
14870+}
14871+
14872+INT Set_HtProtect_Proc(
14873+ IN PRTMP_ADAPTER pAd,
14874+ IN PUCHAR arg)
14875+{
14876+ ULONG Value;
14877+
14878+ Value = simple_strtol(arg, 0, 10);
14879+ if (Value == 0)
14880+ pAd->CommonCfg.bHTProtect = FALSE;
14881+ else if (Value == 1)
14882+ pAd->CommonCfg.bHTProtect = TRUE;
14883+ else
14884+ return FALSE; //Invalid argument
14885+
14886+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtProtect_Proc::(HtProtect=%d)\n",pAd->CommonCfg.bHTProtect));
14887+
14888+ return TRUE;
14889+}
14890+
14891+INT Set_SendPSMPAction_Proc(
14892+ IN PRTMP_ADAPTER pAd,
14893+ IN PUCHAR arg)
14894+{
14895+ UCHAR mac[6], mode;
14896+ char *token, sepValue[] = ":", DASH = '-';
14897+ INT i;
14898+ MAC_TABLE_ENTRY *pEntry;
14899+
14900+ //printk("\n%s\n", arg);
14901+/*
14902+ The BARecTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d,
14903+ =>The six 2 digit hex-decimal number previous are the Mac address,
14904+ =>The seventh decimal number is the mode value.
14905+*/
14906+ if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and mode value in decimal format.
14907+ return FALSE;
14908+
14909+ token = strchr(arg, DASH);
14910+ if ((token != NULL) && (strlen(token)>1))
14911+ {
14912+ mode = simple_strtol((token+1), 0, 10);
14913+ if (mode > MMPS_ENABLE)
14914+ return FALSE;
14915+
14916+ *token = '\0';
14917+ for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
14918+ {
14919+ if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
14920+ return FALSE;
14921+ AtoH(token, (PUCHAR)(&mac[i]), 1);
14922+ }
14923+ if(i != 6)
14924+ return FALSE;
14925+
14926+ printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", mac[0], mac[1],
14927+ mac[2], mac[3], mac[4], mac[5], mode);
14928+
14929+ pEntry = MacTableLookup(pAd, mac);
14930+
14931+ if (pEntry) {
14932+ printk("\nSendPSMPAction MIPS mode = %d\n", mode);
14933+ SendPSMPAction(pAd, pEntry->Aid, mode);
14934+ }
14935+
14936+ return TRUE;
14937+ }
14938+
14939+ return FALSE;
14940+
14941+
14942+}
14943+
14944+INT Set_HtMIMOPSmode_Proc(
14945+ IN PRTMP_ADAPTER pAd,
14946+ IN PUCHAR arg)
14947+{
14948+ ULONG Value;
14949+
14950+ Value = simple_strtol(arg, 0, 10);
14951+
14952+ if (Value <=3 && Value >= 0)
14953+ pAd->CommonCfg.BACapability.field.MMPSmode = Value;
14954+ else
14955+ pAd->CommonCfg.BACapability.field.MMPSmode = 3;
14956+
14957+ SetCommonHT(pAd);
14958+
14959+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMIMOPSmode_Proc::(MIMOPS mode=%d)\n",pAd->CommonCfg.BACapability.field.MMPSmode));
14960+
14961+ return TRUE;
14962+}
14963+
14964+
14965+INT Set_ForceShortGI_Proc(
14966+ IN PRTMP_ADAPTER pAd,
14967+ IN PUCHAR arg)
14968+{
14969+ ULONG Value;
14970+
14971+ Value = simple_strtol(arg, 0, 10);
14972+ if (Value == 0)
14973+ pAd->WIFItestbed.bShortGI = FALSE;
14974+ else if (Value == 1)
14975+ pAd->WIFItestbed.bShortGI = TRUE;
14976+ else
14977+ return FALSE; //Invalid argument
14978+
14979+ SetCommonHT(pAd);
14980+
14981+ DBGPRINT(RT_DEBUG_TRACE, ("Set_ForceShortGI_Proc::(ForceShortGI=%d)\n", pAd->WIFItestbed.bShortGI));
14982+
14983+ return TRUE;
14984+}
14985+
14986+
14987+
14988+INT Set_ForceGF_Proc(
14989+ IN PRTMP_ADAPTER pAd,
14990+ IN PUCHAR arg)
14991+{
14992+ ULONG Value;
14993+
14994+ Value = simple_strtol(arg, 0, 10);
14995+ if (Value == 0)
14996+ pAd->WIFItestbed.bGreenField = FALSE;
14997+ else if (Value == 1)
14998+ pAd->WIFItestbed.bGreenField = TRUE;
14999+ else
15000+ return FALSE; //Invalid argument
15001+
15002+ SetCommonHT(pAd);
15003+
15004+ DBGPRINT(RT_DEBUG_TRACE, ("Set_ForceGF_Proc::(ForceGF=%d)\n", pAd->WIFItestbed.bGreenField));
15005+
15006+ return TRUE;
15007+}
15008+
15009+INT Set_HtMimoPs_Proc(
15010+ IN PRTMP_ADAPTER pAd,
15011+ IN PUCHAR arg)
15012+{
15013+ ULONG Value;
15014+
15015+ Value = simple_strtol(arg, 0, 10);
15016+ if (Value == 0)
15017+ pAd->CommonCfg.bMIMOPSEnable = FALSE;
15018+ else if (Value == 1)
15019+ pAd->CommonCfg.bMIMOPSEnable = TRUE;
15020+ else
15021+ return FALSE; //Invalid argument
15022+
15023+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMimoPs_Proc::(HtMimoPs=%d)\n",pAd->CommonCfg.bMIMOPSEnable));
15024+
15025+ return TRUE;
15026+}
15027+#endif // DOT11_N_SUPPORT //
15028+
15029+
15030+#ifdef DOT11_N_SUPPORT
15031+INT SetCommonHT(
15032+ IN PRTMP_ADAPTER pAd)
15033+{
15034+ OID_SET_HT_PHYMODE SetHT;
15035+
15036+ if (pAd->CommonCfg.PhyMode < PHY_11ABGN_MIXED)
15037+ return FALSE;
15038+
15039+ SetHT.PhyMode = pAd->CommonCfg.PhyMode;
15040+ SetHT.TransmitNo = ((UCHAR)pAd->Antenna.field.TxPath);
15041+ SetHT.HtMode = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.HTMODE;
15042+ SetHT.ExtOffset = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.EXTCHA;
15043+ SetHT.MCS = MCS_AUTO;
15044+ SetHT.BW = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.BW;
15045+ SetHT.STBC = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.STBC;
15046+ SetHT.SHORTGI = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.ShortGI;
15047+
15048+ RTMPSetHT(pAd, &SetHT);
15049+
15050+ return TRUE;
15051+}
15052+#endif // DOT11_N_SUPPORT //
15053+
15054+INT Set_FixedTxMode_Proc(
15055+ IN PRTMP_ADAPTER pAd,
15056+ IN PUCHAR arg)
15057+{
15058+ UCHAR fix_tx_mode = FIXED_TXMODE_HT;
15059+
15060+ if (strcmp(arg, "OFDM") == 0 || strcmp(arg, "ofdm") == 0)
15061+ {
15062+ fix_tx_mode = FIXED_TXMODE_OFDM;
15063+ }
15064+ else if (strcmp(arg, "CCK") == 0 || strcmp(arg, "cck") == 0)
15065+ {
15066+ fix_tx_mode = FIXED_TXMODE_CCK;
15067+ }
15068+
15069+#ifdef CONFIG_STA_SUPPORT
15070+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
15071+ pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode = fix_tx_mode;
15072+#endif // CONFIG_STA_SUPPORT //
15073+
15074+ DBGPRINT(RT_DEBUG_TRACE, ("Set_FixedTxMode_Proc::(FixedTxMode=%d)\n", fix_tx_mode));
15075+
15076+ return TRUE;
15077+}
15078+
15079+#ifdef CONFIG_APSTA_MIXED_SUPPORT
15080+INT Set_OpMode_Proc(
15081+ IN PRTMP_ADAPTER pAd,
15082+ IN PUCHAR arg)
15083+{
15084+ ULONG Value;
15085+
15086+ Value = simple_strtol(arg, 0, 10);
15087+
15088+#ifdef RT2870
15089+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
15090+#endif // RT2870 //
15091+ {
15092+ DBGPRINT(RT_DEBUG_ERROR, ("Can not switch operate mode on interface up !! \n"));
15093+ return FALSE;
15094+ }
15095+
15096+ if (Value == 0)
15097+ pAd->OpMode = OPMODE_STA;
15098+ else if (Value == 1)
15099+ pAd->OpMode = OPMODE_AP;
15100+ else
15101+ return FALSE; //Invalid argument
15102+
15103+ DBGPRINT(RT_DEBUG_TRACE, ("Set_OpMode_Proc::(OpMode=%s)\n", pAd->OpMode == 1 ? "AP Mode" : "STA Mode"));
15104+
15105+ return TRUE;
15106+}
15107+#endif // CONFIG_APSTA_MIXED_SUPPORT //
15108+
15109+
15110+/////////////////////////////////////////////////////////////////////////
15111+PCHAR RTMPGetRalinkAuthModeStr(
15112+ IN NDIS_802_11_AUTHENTICATION_MODE authMode)
15113+{
15114+ switch(authMode)
15115+ {
15116+ case Ndis802_11AuthModeOpen:
15117+ return "OPEN";
15118+ default:
15119+ case Ndis802_11AuthModeWPAPSK:
15120+ return "WPAPSK";
15121+ case Ndis802_11AuthModeShared:
15122+ return "SHARED";
15123+ case Ndis802_11AuthModeWPA:
15124+ return "WPA";
15125+ case Ndis802_11AuthModeWPA2:
15126+ return "WPA2";
15127+ case Ndis802_11AuthModeWPA2PSK:
15128+ return "WPA2PSK";
15129+ case Ndis802_11AuthModeWPA1PSKWPA2PSK:
15130+ return "WPAPSKWPA2PSK";
15131+ case Ndis802_11AuthModeWPA1WPA2:
15132+ return "WPA1WPA2";
15133+ }
15134+}
15135+
15136+PCHAR RTMPGetRalinkEncryModeStr(
15137+ IN USHORT encryMode)
15138+{
15139+ switch(encryMode)
15140+ {
15141+ default:
15142+ case Ndis802_11WEPDisabled:
15143+ return "NONE";
15144+ case Ndis802_11WEPEnabled:
15145+ return "WEP";
15146+ case Ndis802_11Encryption2Enabled:
15147+ return "TKIP";
15148+ case Ndis802_11Encryption3Enabled:
15149+ return "AES";
15150+ case Ndis802_11Encryption4Enabled:
15151+ return "TKIPAES";
15152+ }
15153+}
15154+
15155+INT RTMPShowCfgValue(
15156+ IN PRTMP_ADAPTER pAd,
15157+ IN PUCHAR pName,
15158+ IN PUCHAR pBuf)
15159+{
15160+ INT Status = 0;
15161+
15162+ for (PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC = RTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC; PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name; PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC++)
15163+ {
15164+ if (!strcmp(pName, PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name))
15165+ {
15166+ if(PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->show_proc(pAd, pBuf))
15167+ Status = -EINVAL;
15168+ break; //Exit for loop.
15169+ }
15170+ }
15171+
15172+ if(PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name == NULL)
15173+ {
15174+ sprintf(pBuf, "\n");
15175+ for (PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC = RTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC; PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name; PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC++)
15176+ sprintf(pBuf, "%s%s\n", pBuf, PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name);
15177+ }
15178+
15179+ return Status;
15180+}
15181+
15182+INT Show_SSID_Proc(
15183+ IN PRTMP_ADAPTER pAd,
15184+ OUT PUCHAR pBuf)
15185+{
15186+
15187+#ifdef CONFIG_STA_SUPPORT
15188+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
15189+ sprintf(pBuf, "\t%s", pAd->CommonCfg.Ssid);
15190+#endif // CONFIG_STA_SUPPORT //
15191+ return 0;
15192+}
15193+
15194+INT Show_WirelessMode_Proc(
15195+ IN PRTMP_ADAPTER pAd,
15196+ OUT PUCHAR pBuf)
15197+{
15198+ switch(pAd->CommonCfg.PhyMode)
15199+ {
15200+ case PHY_11BG_MIXED:
15201+ sprintf(pBuf, "\t11B/G");
15202+ break;
15203+ case PHY_11B:
15204+ sprintf(pBuf, "\t11B");
15205+ break;
15206+ case PHY_11A:
15207+ sprintf(pBuf, "\t11A");
15208+ break;
15209+ case PHY_11ABG_MIXED:
15210+ sprintf(pBuf, "\t11A/B/G");
15211+ break;
15212+ case PHY_11G:
15213+ sprintf(pBuf, "\t11G");
15214+ break;
15215+#ifdef DOT11_N_SUPPORT
15216+ case PHY_11ABGN_MIXED:
15217+ sprintf(pBuf, "\t11A/B/G/N");
15218+ break;
15219+ case PHY_11N_2_4G:
15220+ sprintf(pBuf, "\t11N only with 2.4G");
15221+ break;
15222+ case PHY_11GN_MIXED:
15223+ sprintf(pBuf, "\t11G/N");
15224+ break;
15225+ case PHY_11AN_MIXED:
15226+ sprintf(pBuf, "\t11A/N");
15227+ break;
15228+ case PHY_11BGN_MIXED:
15229+ sprintf(pBuf, "\t11B/G/N");
15230+ break;
15231+ case PHY_11AGN_MIXED:
15232+ sprintf(pBuf, "\t11A/G/N");
15233+ break;
15234+ case PHY_11N_5G:
15235+ sprintf(pBuf, "\t11N only with 5G");
15236+ break;
15237+#endif // DOT11_N_SUPPORT //
15238+ default:
15239+ sprintf(pBuf, "\tUnknow Value(%d)", pAd->CommonCfg.PhyMode);
15240+ break;
15241+ }
15242+ return 0;
15243+}
15244+
15245+
15246+INT Show_TxBurst_Proc(
15247+ IN PRTMP_ADAPTER pAd,
15248+ OUT PUCHAR pBuf)
15249+{
15250+ sprintf(pBuf, "\t%s", pAd->CommonCfg.bEnableTxBurst ? "TRUE":"FALSE");
15251+ return 0;
15252+}
15253+
15254+INT Show_TxPreamble_Proc(
15255+ IN PRTMP_ADAPTER pAd,
15256+ OUT PUCHAR pBuf)
15257+{
15258+ switch(pAd->CommonCfg.TxPreamble)
15259+ {
15260+ case Rt802_11PreambleShort:
15261+ sprintf(pBuf, "\tShort");
15262+ break;
15263+ case Rt802_11PreambleLong:
15264+ sprintf(pBuf, "\tLong");
15265+ break;
15266+ case Rt802_11PreambleAuto:
15267+ sprintf(pBuf, "\tAuto");
15268+ break;
15269+ default:
15270+ sprintf(pBuf, "\tUnknow Value(%lu)", pAd->CommonCfg.TxPreamble);
15271+ break;
15272+ }
15273+
15274+ return 0;
15275+}
15276+
15277+INT Show_TxPower_Proc(
15278+ IN PRTMP_ADAPTER pAd,
15279+ OUT PUCHAR pBuf)
15280+{
15281+ sprintf(pBuf, "\t%lu", pAd->CommonCfg.TxPowerPercentage);
15282+ return 0;
15283+}
15284+
15285+INT Show_Channel_Proc(
15286+ IN PRTMP_ADAPTER pAd,
15287+ OUT PUCHAR pBuf)
15288+{
15289+ sprintf(pBuf, "\t%d", pAd->CommonCfg.Channel);
15290+ return 0;
15291+}
15292+
15293+INT Show_BGProtection_Proc(
15294+ IN PRTMP_ADAPTER pAd,
15295+ OUT PUCHAR pBuf)
15296+{
15297+ switch(pAd->CommonCfg.UseBGProtection)
15298+ {
15299+ case 1: //Always On
15300+ sprintf(pBuf, "\tON");
15301+ break;
15302+ case 2: //Always OFF
15303+ sprintf(pBuf, "\tOFF");
15304+ break;
15305+ case 0: //AUTO
15306+ sprintf(pBuf, "\tAuto");
15307+ break;
15308+ default:
15309+ sprintf(pBuf, "\tUnknow Value(%lu)", pAd->CommonCfg.UseBGProtection);
15310+ break;
15311+ }
15312+ return 0;
15313+}
15314+
15315+INT Show_RTSThreshold_Proc(
15316+ IN PRTMP_ADAPTER pAd,
15317+ OUT PUCHAR pBuf)
15318+{
15319+ sprintf(pBuf, "\t%u", pAd->CommonCfg.RtsThreshold);
15320+ return 0;
15321+}
15322+
15323+INT Show_FragThreshold_Proc(
15324+ IN PRTMP_ADAPTER pAd,
15325+ OUT PUCHAR pBuf)
15326+{
15327+ sprintf(pBuf, "\t%u", pAd->CommonCfg.FragmentThreshold);
15328+ return 0;
15329+}
15330+
15331+#ifdef DOT11_N_SUPPORT
15332+INT Show_HtBw_Proc(
15333+ IN PRTMP_ADAPTER pAd,
15334+ OUT PUCHAR pBuf)
15335+{
15336+ if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
15337+ {
15338+ sprintf(pBuf, "\t40 MHz");
15339+ }
15340+ else
15341+ {
15342+ sprintf(pBuf, "\t20 MHz");
15343+ }
15344+ return 0;
15345+}
15346+
15347+INT Show_HtMcs_Proc(
15348+ IN PRTMP_ADAPTER pAd,
15349+ OUT PUCHAR pBuf)
15350+{
15351+
15352+#ifdef CONFIG_STA_SUPPORT
15353+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
15354+ sprintf(pBuf, "\t%u", pAd->StaCfg.DesiredTransmitSetting.field.MCS);
15355+#endif // CONFIG_STA_SUPPORT //
15356+ return 0;
15357+}
15358+
15359+INT Show_HtGi_Proc(
15360+ IN PRTMP_ADAPTER pAd,
15361+ OUT PUCHAR pBuf)
15362+{
15363+ switch(pAd->CommonCfg.RegTransmitSetting.field.ShortGI)
15364+ {
15365+ case GI_400:
15366+ sprintf(pBuf, "\tGI_400");
15367+ break;
15368+ case GI_800:
15369+ sprintf(pBuf, "\tGI_800");
15370+ break;
15371+ default:
15372+ sprintf(pBuf, "\tUnknow Value(%u)", pAd->CommonCfg.RegTransmitSetting.field.ShortGI);
15373+ break;
15374+ }
15375+ return 0;
15376+}
15377+
15378+INT Show_HtOpMode_Proc(
15379+ IN PRTMP_ADAPTER pAd,
15380+ OUT PUCHAR pBuf)
15381+{
15382+ switch(pAd->CommonCfg.RegTransmitSetting.field.HTMODE)
15383+ {
15384+ case HTMODE_GF:
15385+ sprintf(pBuf, "\tGF");
15386+ break;
15387+ case HTMODE_MM:
15388+ sprintf(pBuf, "\tMM");
15389+ break;
15390+ default:
15391+ sprintf(pBuf, "\tUnknow Value(%u)", pAd->CommonCfg.RegTransmitSetting.field.HTMODE);
15392+ break;
15393+ }
15394+ return 0;
15395+}
15396+
15397+INT Show_HtExtcha_Proc(
15398+ IN PRTMP_ADAPTER pAd,
15399+ OUT PUCHAR pBuf)
15400+{
15401+ switch(pAd->CommonCfg.RegTransmitSetting.field.EXTCHA)
15402+ {
15403+ case EXTCHA_BELOW:
15404+ sprintf(pBuf, "\tBelow");
15405+ break;
15406+ case EXTCHA_ABOVE:
15407+ sprintf(pBuf, "\tAbove");
15408+ break;
15409+ default:
15410+ sprintf(pBuf, "\tUnknow Value(%u)", pAd->CommonCfg.RegTransmitSetting.field.EXTCHA);
15411+ break;
15412+ }
15413+ return 0;
15414+}
15415+
15416+
15417+INT Show_HtMpduDensity_Proc(
15418+ IN PRTMP_ADAPTER pAd,
15419+ OUT PUCHAR pBuf)
15420+{
15421+ sprintf(pBuf, "\t%u", pAd->CommonCfg.BACapability.field.MpduDensity);
15422+ return 0;
15423+}
15424+
15425+INT Show_HtBaWinSize_Proc(
15426+ IN PRTMP_ADAPTER pAd,
15427+ OUT PUCHAR pBuf)
15428+{
15429+ sprintf(pBuf, "\t%u", pAd->CommonCfg.BACapability.field.RxBAWinLimit);
15430+ return 0;
15431+}
15432+
15433+INT Show_HtRdg_Proc(
15434+ IN PRTMP_ADAPTER pAd,
15435+ OUT PUCHAR pBuf)
15436+{
15437+ sprintf(pBuf, "\t%s", pAd->CommonCfg.bRdg ? "TRUE":"FALSE");
15438+ return 0;
15439+}
15440+
15441+INT Show_HtAmsdu_Proc(
15442+ IN PRTMP_ADAPTER pAd,
15443+ OUT PUCHAR pBuf)
15444+{
15445+ sprintf(pBuf, "\t%s", pAd->CommonCfg.BACapability.field.AmsduEnable ? "TRUE":"FALSE");
15446+ return 0;
15447+}
15448+
15449+INT Show_HtAutoBa_Proc(
15450+ IN PRTMP_ADAPTER pAd,
15451+ OUT PUCHAR pBuf)
15452+{
15453+ sprintf(pBuf, "\t%s", pAd->CommonCfg.BACapability.field.AutoBA ? "TRUE":"FALSE");
15454+ return 0;
15455+}
15456+#endif // DOT11_N_SUPPORT //
15457+
15458+INT Show_CountryRegion_Proc(
15459+ IN PRTMP_ADAPTER pAd,
15460+ OUT PUCHAR pBuf)
15461+{
15462+ sprintf(pBuf, "\t%d", pAd->CommonCfg.CountryRegion);
15463+ return 0;
15464+}
15465+
15466+INT Show_CountryRegionABand_Proc(
15467+ IN PRTMP_ADAPTER pAd,
15468+ OUT PUCHAR pBuf)
15469+{
15470+ sprintf(pBuf, "\t%d", pAd->CommonCfg.CountryRegionForABand);
15471+ return 0;
15472+}
15473+
15474+INT Show_CountryCode_Proc(
15475+ IN PRTMP_ADAPTER pAd,
15476+ OUT PUCHAR pBuf)
15477+{
15478+ sprintf(pBuf, "\t%s", pAd->CommonCfg.CountryCode);
15479+ return 0;
15480+}
15481+
15482+#ifdef AGGREGATION_SUPPORT
15483+INT Show_PktAggregate_Proc(
15484+ IN PRTMP_ADAPTER pAd,
15485+ OUT PUCHAR pBuf)
15486+{
15487+ sprintf(pBuf, "\t%s", pAd->CommonCfg.bAggregationCapable ? "TRUE":"FALSE");
15488+ return 0;
15489+}
15490+#endif // AGGREGATION_SUPPORT //
15491+
15492+#ifdef WMM_SUPPORT
15493+INT Show_WmmCapable_Proc(
15494+ IN PRTMP_ADAPTER pAd,
15495+ OUT PUCHAR pBuf)
15496+{
15497+
15498+#ifdef CONFIG_STA_SUPPORT
15499+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
15500+ sprintf(pBuf, "\t%s", pAd->CommonCfg.bWmmCapable ? "TRUE":"FALSE");
15501+#endif // CONFIG_STA_SUPPORT //
15502+
15503+ return 0;
15504+}
15505+#endif // WMM_SUPPORT //
15506+
15507+INT Show_IEEE80211H_Proc(
15508+ IN PRTMP_ADAPTER pAd,
15509+ OUT PUCHAR pBuf)
15510+{
15511+ sprintf(pBuf, "\t%s", pAd->CommonCfg.bIEEE80211H ? "TRUE":"FALSE");
15512+ return 0;
15513+}
15514+
15515+#ifdef CONFIG_STA_SUPPORT
15516+INT Show_NetworkType_Proc(
15517+ IN PRTMP_ADAPTER pAd,
15518+ OUT PUCHAR pBuf)
15519+{
15520+ switch(pAd->StaCfg.BssType)
15521+ {
15522+ case BSS_ADHOC:
15523+ sprintf(pBuf, "\tAdhoc");
15524+ break;
15525+ case BSS_INFRA:
15526+ sprintf(pBuf, "\tInfra");
15527+ break;
15528+ case BSS_ANY:
15529+ sprintf(pBuf, "\tAny");
15530+ break;
15531+ case BSS_MONITOR:
15532+ sprintf(pBuf, "\tMonitor");
15533+ break;
15534+ default:
15535+ sprintf(pBuf, "\tUnknow Value(%d)", pAd->StaCfg.BssType);
15536+ break;
15537+ }
15538+ return 0;
15539+}
15540+#endif // CONFIG_STA_SUPPORT //
15541+
15542+INT Show_AuthMode_Proc(
15543+ IN PRTMP_ADAPTER pAd,
15544+ OUT PUCHAR pBuf)
15545+{
15546+ NDIS_802_11_AUTHENTICATION_MODE AuthMode = Ndis802_11AuthModeOpen;
15547+
15548+#ifdef CONFIG_STA_SUPPORT
15549+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
15550+ AuthMode = pAd->StaCfg.AuthMode;
15551+#endif // CONFIG_STA_SUPPORT //
15552+
15553+ if ((AuthMode >= Ndis802_11AuthModeOpen) &&
15554+ (AuthMode <= Ndis802_11AuthModeWPA1PSKWPA2PSK))
15555+ sprintf(pBuf, "\t%s", RTMPGetRalinkAuthModeStr(AuthMode));
15556+ else
15557+ sprintf(pBuf, "\tUnknow Value(%d)", AuthMode);
15558+
15559+ return 0;
15560+}
15561+
15562+INT Show_EncrypType_Proc(
15563+ IN PRTMP_ADAPTER pAd,
15564+ OUT PUCHAR pBuf)
15565+{
15566+ NDIS_802_11_WEP_STATUS WepStatus = Ndis802_11WEPDisabled;
15567+
15568+#ifdef CONFIG_STA_SUPPORT
15569+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
15570+ WepStatus = pAd->StaCfg.WepStatus;
15571+#endif // CONFIG_STA_SUPPORT //
15572+
15573+ if ((WepStatus >= Ndis802_11WEPEnabled) &&
15574+ (WepStatus <= Ndis802_11Encryption4KeyAbsent))
15575+ sprintf(pBuf, "\t%s", RTMPGetRalinkEncryModeStr(WepStatus));
15576+ else
15577+ sprintf(pBuf, "\tUnknow Value(%d)", WepStatus);
15578+
15579+ return 0;
15580+}
15581+
15582+INT Show_DefaultKeyID_Proc(
15583+ IN PRTMP_ADAPTER pAd,
15584+ OUT PUCHAR pBuf)
15585+{
15586+ UCHAR DefaultKeyId = 0;
15587+
15588+#ifdef CONFIG_STA_SUPPORT
15589+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
15590+ DefaultKeyId = pAd->StaCfg.DefaultKeyId;
15591+#endif // CONFIG_STA_SUPPORT //
15592+
15593+ sprintf(pBuf, "\t%d", DefaultKeyId);
15594+
15595+ return 0;
15596+}
15597+
15598+INT Show_WepKey_Proc(
15599+ IN PRTMP_ADAPTER pAd,
15600+ IN INT KeyIdx,
15601+ OUT PUCHAR pBuf)
15602+{
15603+ UCHAR Key[16] = {0}, KeyLength = 0;
15604+ INT index = BSS0;
15605+
15606+ KeyLength = pAd->SharedKey[index][KeyIdx].KeyLen;
15607+ NdisMoveMemory(Key, pAd->SharedKey[index][KeyIdx].Key, KeyLength);
15608+
15609+ //check key string is ASCII or not
15610+ if (RTMPCheckStrPrintAble(Key, KeyLength))
15611+ sprintf(pBuf, "\t%s", Key);
15612+ else
15613+ {
15614+ int idx;
15615+ sprintf(pBuf, "\t");
15616+ for (idx = 0; idx < KeyLength; idx++)
15617+ sprintf(pBuf+strlen(pBuf), "%02X", Key[idx]);
15618+ }
15619+ return 0;
15620+}
15621+
15622+INT Show_Key1_Proc(
15623+ IN PRTMP_ADAPTER pAd,
15624+ OUT PUCHAR pBuf)
15625+{
15626+ Show_WepKey_Proc(pAd, 0, pBuf);
15627+ return 0;
15628+}
15629+
15630+INT Show_Key2_Proc(
15631+ IN PRTMP_ADAPTER pAd,
15632+ OUT PUCHAR pBuf)
15633+{
15634+ Show_WepKey_Proc(pAd, 1, pBuf);
15635+ return 0;
15636+}
15637+
15638+INT Show_Key3_Proc(
15639+ IN PRTMP_ADAPTER pAd,
15640+ OUT PUCHAR pBuf)
15641+{
15642+ Show_WepKey_Proc(pAd, 2, pBuf);
15643+ return 0;
15644+}
15645+
15646+INT Show_Key4_Proc(
15647+ IN PRTMP_ADAPTER pAd,
15648+ OUT PUCHAR pBuf)
15649+{
15650+ Show_WepKey_Proc(pAd, 3, pBuf);
15651+ return 0;
15652+}
15653+
15654+INT Show_WPAPSK_Proc(
15655+ IN PRTMP_ADAPTER pAd,
15656+ OUT PUCHAR pBuf)
15657+{
15658+ INT idx;
15659+ UCHAR PMK[32] = {0};
15660+
15661+
15662+#ifdef CONFIG_STA_SUPPORT
15663+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
15664+ NdisMoveMemory(PMK, pAd->StaCfg.PMK, 32);
15665+#endif // CONFIG_STA_SUPPORT //
15666+
15667+ sprintf(pBuf, "\tPMK = ");
15668+ for (idx = 0; idx < 32; idx++)
15669+ sprintf(pBuf+strlen(pBuf), "%02X", PMK[idx]);
15670+
15671+ return 0;
15672+}
15673+
15674--- /dev/null
15675+++ b/drivers/staging/rt3070/common/cmm_sanity.c
15676@@ -0,0 +1,1669 @@
15677+/*
15678+ *************************************************************************
15679+ * Ralink Tech Inc.
15680+ * 5F., No.36, Taiyuan St., Jhubei City,
15681+ * Hsinchu County 302,
15682+ * Taiwan, R.O.C.
15683+ *
15684+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
15685+ *
15686+ * This program is free software; you can redistribute it and/or modify *
15687+ * it under the terms of the GNU General Public License as published by *
15688+ * the Free Software Foundation; either version 2 of the License, or *
15689+ * (at your option) any later version. *
15690+ * *
15691+ * This program is distributed in the hope that it will be useful, *
15692+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15693+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15694+ * GNU General Public License for more details. *
15695+ * *
15696+ * You should have received a copy of the GNU General Public License *
15697+ * along with this program; if not, write to the *
15698+ * Free Software Foundation, Inc., *
15699+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
15700+ * *
15701+ *************************************************************************
15702+
15703+ Module Name:
15704+ sanity.c
15705+
15706+ Abstract:
15707+
15708+ Revision History:
15709+ Who When What
15710+ -------- ---------- ----------------------------------------------
15711+ John Chang 2004-09-01 add WMM support
15712+*/
15713+#include "../rt_config.h"
15714+
15715+
15716+extern UCHAR CISCO_OUI[];
15717+
15718+extern UCHAR WPA_OUI[];
15719+extern UCHAR RSN_OUI[];
15720+extern UCHAR WME_INFO_ELEM[];
15721+extern UCHAR WME_PARM_ELEM[];
15722+extern UCHAR Ccx2QosInfo[];
15723+extern UCHAR RALINK_OUI[];
15724+extern UCHAR BROADCOM_OUI[];
15725+extern UCHAR WPS_OUI[];
15726+
15727+/*
15728+ ==========================================================================
15729+ Description:
15730+ MLME message sanity check
15731+ Return:
15732+ TRUE if all parameters are OK, FALSE otherwise
15733+
15734+ IRQL = DISPATCH_LEVEL
15735+
15736+ ==========================================================================
15737+ */
15738+BOOLEAN MlmeAddBAReqSanity(
15739+ IN PRTMP_ADAPTER pAd,
15740+ IN VOID *Msg,
15741+ IN ULONG MsgLen,
15742+ OUT PUCHAR pAddr2)
15743+{
15744+ PMLME_ADDBA_REQ_STRUCT pInfo;
15745+
15746+ pInfo = (MLME_ADDBA_REQ_STRUCT *)Msg;
15747+
15748+ if ((MsgLen != sizeof(MLME_ADDBA_REQ_STRUCT)))
15749+ {
15750+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - message lenght not correct.\n"));
15751+ return FALSE;
15752+ }
15753+
15754+ if ((pInfo->Wcid >= MAX_LEN_OF_MAC_TABLE))
15755+ {
15756+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - The peer Mac is not associated yet.\n"));
15757+ return FALSE;
15758+ }
15759+
15760+ /*
15761+ if ((pInfo->BaBufSize > MAX_RX_REORDERBUF) || (pInfo->BaBufSize < 2))
15762+ {
15763+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - Rx Reordering buffer too big or too small\n"));
15764+ return FALSE;
15765+ }
15766+ */
15767+
15768+ if ((pInfo->pAddr[0]&0x01) == 0x01)
15769+ {
15770+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - broadcast address not support BA\n"));
15771+ return FALSE;
15772+ }
15773+
15774+ return TRUE;
15775+}
15776+
15777+/*
15778+ ==========================================================================
15779+ Description:
15780+ MLME message sanity check
15781+ Return:
15782+ TRUE if all parameters are OK, FALSE otherwise
15783+
15784+ IRQL = DISPATCH_LEVEL
15785+
15786+ ==========================================================================
15787+ */
15788+BOOLEAN MlmeDelBAReqSanity(
15789+ IN PRTMP_ADAPTER pAd,
15790+ IN VOID *Msg,
15791+ IN ULONG MsgLen)
15792+{
15793+ MLME_DELBA_REQ_STRUCT *pInfo;
15794+ pInfo = (MLME_DELBA_REQ_STRUCT *)Msg;
15795+
15796+ if ((MsgLen != sizeof(MLME_DELBA_REQ_STRUCT)))
15797+ {
15798+ DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - message lenght not correct.\n"));
15799+ return FALSE;
15800+ }
15801+
15802+ if ((pInfo->Wcid >= MAX_LEN_OF_MAC_TABLE))
15803+ {
15804+ DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - The peer Mac is not associated yet.\n"));
15805+ return FALSE;
15806+ }
15807+
15808+ if ((pInfo->TID & 0xf0))
15809+ {
15810+ DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - The peer TID is incorrect.\n"));
15811+ return FALSE;
15812+ }
15813+
15814+ if (NdisEqualMemory(pAd->MacTab.Content[pInfo->Wcid].Addr, pInfo->Addr, MAC_ADDR_LEN) == 0)
15815+ {
15816+ DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - the peer addr dosen't exist.\n"));
15817+ return FALSE;
15818+ }
15819+
15820+ return TRUE;
15821+}
15822+
15823+BOOLEAN PeerAddBAReqActionSanity(
15824+ IN PRTMP_ADAPTER pAd,
15825+ IN VOID *pMsg,
15826+ IN ULONG MsgLen,
15827+ OUT PUCHAR pAddr2)
15828+{
15829+ PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
15830+ PFRAME_ADDBA_REQ pAddFrame;
15831+ pAddFrame = (PFRAME_ADDBA_REQ)(pMsg);
15832+ if (MsgLen < (sizeof(FRAME_ADDBA_REQ)))
15833+ {
15834+ DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request frame length size = %ld incorrect\n", MsgLen));
15835+ return FALSE;
15836+ }
15837+ // we support immediate BA.
15838+ *(USHORT *)(&pAddFrame->BaParm) = cpu2le16(*(USHORT *)(&pAddFrame->BaParm));
15839+ pAddFrame->TimeOutValue = cpu2le16(pAddFrame->TimeOutValue);
15840+ pAddFrame->BaStartSeq.word = cpu2le16(pAddFrame->BaStartSeq.word);
15841+
15842+ if (pAddFrame->BaParm.BAPolicy != IMMED_BA)
15843+ {
15844+ DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request Ba Policy[%d] not support\n", pAddFrame->BaParm.BAPolicy));
15845+ DBGPRINT(RT_DEBUG_ERROR,("ADDBA Request. tid=%x, Bufsize=%x, AMSDUSupported=%x \n", pAddFrame->BaParm.TID, pAddFrame->BaParm.BufSize, pAddFrame->BaParm.AMSDUSupported));
15846+ return FALSE;
15847+ }
15848+
15849+ // we support immediate BA.
15850+ if (pAddFrame->BaParm.TID &0xfff0)
15851+ {
15852+ DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request incorrect TID = %d\n", pAddFrame->BaParm.TID));
15853+ return FALSE;
15854+ }
15855+ COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
15856+ return TRUE;
15857+}
15858+
15859+BOOLEAN PeerAddBARspActionSanity(
15860+ IN PRTMP_ADAPTER pAd,
15861+ IN VOID *pMsg,
15862+ IN ULONG MsgLen)
15863+{
15864+ //PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
15865+ PFRAME_ADDBA_RSP pAddFrame;
15866+
15867+ pAddFrame = (PFRAME_ADDBA_RSP)(pMsg);
15868+ if (MsgLen < (sizeof(FRAME_ADDBA_RSP)))
15869+ {
15870+ DBGPRINT(RT_DEBUG_ERROR,("PeerAddBARspActionSanity: ADDBA Response frame length size = %ld incorrect\n", MsgLen));
15871+ return FALSE;
15872+ }
15873+ // we support immediate BA.
15874+ *(USHORT *)(&pAddFrame->BaParm) = cpu2le16(*(USHORT *)(&pAddFrame->BaParm));
15875+ pAddFrame->StatusCode = cpu2le16(pAddFrame->StatusCode);
15876+ pAddFrame->TimeOutValue = cpu2le16(pAddFrame->TimeOutValue);
15877+
15878+ if (pAddFrame->BaParm.BAPolicy != IMMED_BA)
15879+ {
15880+ DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Response Ba Policy[%d] not support\n", pAddFrame->BaParm.BAPolicy));
15881+ return FALSE;
15882+ }
15883+
15884+ // we support immediate BA.
15885+ if (pAddFrame->BaParm.TID &0xfff0)
15886+ {
15887+ DBGPRINT(RT_DEBUG_ERROR,("PeerAddBARspActionSanity: ADDBA Response incorrect TID = %d\n", pAddFrame->BaParm.TID));
15888+ return FALSE;
15889+ }
15890+ return TRUE;
15891+
15892+}
15893+
15894+BOOLEAN PeerDelBAActionSanity(
15895+ IN PRTMP_ADAPTER pAd,
15896+ IN UCHAR Wcid,
15897+ IN VOID *pMsg,
15898+ IN ULONG MsgLen )
15899+{
15900+ //PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
15901+ PFRAME_DELBA_REQ pDelFrame;
15902+ if (MsgLen != (sizeof(FRAME_DELBA_REQ)))
15903+ return FALSE;
15904+
15905+ if (Wcid >= MAX_LEN_OF_MAC_TABLE)
15906+ return FALSE;
15907+
15908+ pDelFrame = (PFRAME_DELBA_REQ)(pMsg);
15909+
15910+ *(USHORT *)(&pDelFrame->DelbaParm) = cpu2le16(*(USHORT *)(&pDelFrame->DelbaParm));
15911+ pDelFrame->ReasonCode = cpu2le16(pDelFrame->ReasonCode);
15912+
15913+ if (pDelFrame->DelbaParm.TID &0xfff0)
15914+ return FALSE;
15915+
15916+ return TRUE;
15917+}
15918+
15919+/*
15920+ ==========================================================================
15921+ Description:
15922+ MLME message sanity check
15923+ Return:
15924+ TRUE if all parameters are OK, FALSE otherwise
15925+
15926+ IRQL = DISPATCH_LEVEL
15927+
15928+ ==========================================================================
15929+ */
15930+BOOLEAN PeerBeaconAndProbeRspSanity(
15931+ IN PRTMP_ADAPTER pAd,
15932+ IN VOID *Msg,
15933+ IN ULONG MsgLen,
15934+ IN UCHAR MsgChannel,
15935+ OUT PUCHAR pAddr2,
15936+ OUT PUCHAR pBssid,
15937+ OUT CHAR Ssid[],
15938+ OUT UCHAR *pSsidLen,
15939+ OUT UCHAR *pBssType,
15940+ OUT USHORT *pBeaconPeriod,
15941+ OUT UCHAR *pChannel,
15942+ OUT UCHAR *pNewChannel,
15943+ OUT LARGE_INTEGER *pTimestamp,
15944+ OUT CF_PARM *pCfParm,
15945+ OUT USHORT *pAtimWin,
15946+ OUT USHORT *pCapabilityInfo,
15947+ OUT UCHAR *pErp,
15948+ OUT UCHAR *pDtimCount,
15949+ OUT UCHAR *pDtimPeriod,
15950+ OUT UCHAR *pBcastFlag,
15951+ OUT UCHAR *pMessageToMe,
15952+ OUT UCHAR SupRate[],
15953+ OUT UCHAR *pSupRateLen,
15954+ OUT UCHAR ExtRate[],
15955+ OUT UCHAR *pExtRateLen,
15956+ OUT UCHAR *pCkipFlag,
15957+ OUT UCHAR *pAironetCellPowerLimit,
15958+ OUT PEDCA_PARM pEdcaParm,
15959+ OUT PQBSS_LOAD_PARM pQbssLoad,
15960+ OUT PQOS_CAPABILITY_PARM pQosCapability,
15961+ OUT ULONG *pRalinkIe,
15962+ OUT UCHAR *pHtCapabilityLen,
15963+#ifdef CONFIG_STA_SUPPORT
15964+ OUT UCHAR *pPreNHtCapabilityLen,
15965+#endif // CONFIG_STA_SUPPORT //
15966+ OUT HT_CAPABILITY_IE *pHtCapability,
15967+ OUT UCHAR *AddHtInfoLen,
15968+ OUT ADD_HT_INFO_IE *AddHtInfo,
15969+ OUT UCHAR *NewExtChannelOffset, // Ht extension channel offset(above or below)
15970+ OUT USHORT *LengthVIE,
15971+ OUT PNDIS_802_11_VARIABLE_IEs pVIE)
15972+{
15973+ CHAR *Ptr;
15974+#ifdef CONFIG_STA_SUPPORT
15975+ CHAR TimLen;
15976+#endif // CONFIG_STA_SUPPORT //
15977+ PFRAME_802_11 pFrame;
15978+ PEID_STRUCT pEid;
15979+ UCHAR SubType;
15980+ UCHAR Sanity;
15981+ //UCHAR ECWMin, ECWMax;
15982+ //MAC_CSR9_STRUC Csr9;
15983+ ULONG Length = 0;
15984+
15985+ // For some 11a AP which didn't have DS_IE, we use two conditions to decide the channel
15986+ // 1. If the AP is 11n enabled, then check the control channel.
15987+ // 2. If the AP didn't have any info about channel, use the channel we received this frame as the channel. (May inaccuracy!!)
15988+ UCHAR CtrlChannel = 0;
15989+
15990+ // Add for 3 necessary EID field check
15991+ Sanity = 0;
15992+
15993+ *pAtimWin = 0;
15994+ *pErp = 0;
15995+ *pDtimCount = 0;
15996+ *pDtimPeriod = 0;
15997+ *pBcastFlag = 0;
15998+ *pMessageToMe = 0;
15999+ *pExtRateLen = 0;
16000+ *pCkipFlag = 0; // Default of CkipFlag is 0
16001+ *pAironetCellPowerLimit = 0xFF; // Default of AironetCellPowerLimit is 0xFF
16002+ *LengthVIE = 0; // Set the length of VIE to init value 0
16003+ *pHtCapabilityLen = 0; // Set the length of VIE to init value 0
16004+#ifdef CONFIG_STA_SUPPORT
16005+ if (pAd->OpMode == OPMODE_STA)
16006+ *pPreNHtCapabilityLen = 0; // Set the length of VIE to init value 0
16007+#endif // CONFIG_STA_SUPPORT //
16008+ *AddHtInfoLen = 0; // Set the length of VIE to init value 0
16009+ *pRalinkIe = 0;
16010+ *pNewChannel = 0;
16011+ *NewExtChannelOffset = 0xff; //Default 0xff means no such IE
16012+ pCfParm->bValid = FALSE; // default: no IE_CF found
16013+ pQbssLoad->bValid = FALSE; // default: no IE_QBSS_LOAD found
16014+ pEdcaParm->bValid = FALSE; // default: no IE_EDCA_PARAMETER found
16015+ pQosCapability->bValid = FALSE; // default: no IE_QOS_CAPABILITY found
16016+
16017+ pFrame = (PFRAME_802_11)Msg;
16018+
16019+ // get subtype from header
16020+ SubType = (UCHAR)pFrame->Hdr.FC.SubType;
16021+
16022+ // get Addr2 and BSSID from header
16023+ COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
16024+ COPY_MAC_ADDR(pBssid, pFrame->Hdr.Addr3);
16025+
16026+// hex_dump("Beacon", Msg, MsgLen);
16027+
16028+ Ptr = pFrame->Octet;
16029+ Length += LENGTH_802_11;
16030+
16031+ // get timestamp from payload and advance the pointer
16032+ NdisMoveMemory(pTimestamp, Ptr, TIMESTAMP_LEN);
16033+
16034+ pTimestamp->u.LowPart = cpu2le32(pTimestamp->u.LowPart);
16035+ pTimestamp->u.HighPart = cpu2le32(pTimestamp->u.HighPart);
16036+
16037+ Ptr += TIMESTAMP_LEN;
16038+ Length += TIMESTAMP_LEN;
16039+
16040+ // get beacon interval from payload and advance the pointer
16041+ NdisMoveMemory(pBeaconPeriod, Ptr, 2);
16042+ Ptr += 2;
16043+ Length += 2;
16044+
16045+ // get capability info from payload and advance the pointer
16046+ NdisMoveMemory(pCapabilityInfo, Ptr, 2);
16047+ Ptr += 2;
16048+ Length += 2;
16049+
16050+ if (CAP_IS_ESS_ON(*pCapabilityInfo))
16051+ *pBssType = BSS_INFRA;
16052+ else
16053+ *pBssType = BSS_ADHOC;
16054+
16055+ pEid = (PEID_STRUCT) Ptr;
16056+
16057+ // get variable fields from payload and advance the pointer
16058+ while ((Length + 2 + pEid->Len) <= MsgLen)
16059+ {
16060+ //
16061+ // Secure copy VIE to VarIE[MAX_VIE_LEN] didn't overflow.
16062+ //
16063+ if ((*LengthVIE + pEid->Len + 2) >= MAX_VIE_LEN)
16064+ {
16065+ DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - Variable IEs out of resource [len(=%d) > MAX_VIE_LEN(=%d)]\n",
16066+ (*LengthVIE + pEid->Len + 2), MAX_VIE_LEN));
16067+ break;
16068+ }
16069+
16070+ switch(pEid->Eid)
16071+ {
16072+ case IE_SSID:
16073+ // Already has one SSID EID in this beacon, ignore the second one
16074+ if (Sanity & 0x1)
16075+ break;
16076+ if(pEid->Len <= MAX_LEN_OF_SSID)
16077+ {
16078+ NdisMoveMemory(Ssid, pEid->Octet, pEid->Len);
16079+ *pSsidLen = pEid->Len;
16080+ Sanity |= 0x1;
16081+ }
16082+ else
16083+ {
16084+ DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_SSID (len=%d)\n",pEid->Len));
16085+ return FALSE;
16086+ }
16087+ break;
16088+
16089+ case IE_SUPP_RATES:
16090+ if(pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES)
16091+ {
16092+ Sanity |= 0x2;
16093+ NdisMoveMemory(SupRate, pEid->Octet, pEid->Len);
16094+ *pSupRateLen = pEid->Len;
16095+
16096+ // TODO: 2004-09-14 not a good design here, cause it exclude extra rates
16097+ // from ScanTab. We should report as is. And filter out unsupported
16098+ // rates in MlmeAux.
16099+ // Check against the supported rates
16100+ // RTMPCheckRates(pAd, SupRate, pSupRateLen);
16101+ }
16102+ else
16103+ {
16104+ DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_SUPP_RATES (len=%d)\n",pEid->Len));
16105+ return FALSE;
16106+ }
16107+ break;
16108+
16109+ case IE_HT_CAP:
16110+ if (pEid->Len >= SIZE_HT_CAP_IE) //Note: allow extension.!!
16111+ {
16112+ NdisMoveMemory(pHtCapability, pEid->Octet, sizeof(HT_CAPABILITY_IE));
16113+ *pHtCapabilityLen = SIZE_HT_CAP_IE; // Nnow we only support 26 bytes.
16114+
16115+ *(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo));
16116+ *(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
16117+
16118+#ifdef CONFIG_STA_SUPPORT
16119+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
16120+ {
16121+ *pPreNHtCapabilityLen = 0; // Nnow we only support 26 bytes.
16122+
16123+ Ptr = (PUCHAR) pVIE;
16124+ NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
16125+ *LengthVIE += (pEid->Len + 2);
16126+ }
16127+#endif // CONFIG_STA_SUPPORT //
16128+ }
16129+ else
16130+ {
16131+ DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - wrong IE_HT_CAP. pEid->Len = %d\n", pEid->Len));
16132+ }
16133+
16134+ break;
16135+ case IE_ADD_HT:
16136+ if (pEid->Len >= sizeof(ADD_HT_INFO_IE))
16137+ {
16138+ // This IE allows extension, but we can ignore extra bytes beyond our knowledge , so only
16139+ // copy first sizeof(ADD_HT_INFO_IE)
16140+ NdisMoveMemory(AddHtInfo, pEid->Octet, sizeof(ADD_HT_INFO_IE));
16141+ *AddHtInfoLen = SIZE_ADD_HT_INFO_IE;
16142+
16143+ CtrlChannel = AddHtInfo->ControlChan;
16144+
16145+ *(USHORT *)(&AddHtInfo->AddHtInfo2) = cpu2le16(*(USHORT *)(&AddHtInfo->AddHtInfo2));
16146+ *(USHORT *)(&AddHtInfo->AddHtInfo3) = cpu2le16(*(USHORT *)(&AddHtInfo->AddHtInfo3));
16147+
16148+#ifdef CONFIG_STA_SUPPORT
16149+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
16150+ {
16151+ Ptr = (PUCHAR) pVIE;
16152+ NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
16153+ *LengthVIE += (pEid->Len + 2);
16154+ }
16155+#endif // CONFIG_STA_SUPPORT //
16156+ }
16157+ else
16158+ {
16159+ DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - wrong IE_ADD_HT. \n"));
16160+ }
16161+
16162+ break;
16163+ case IE_SECONDARY_CH_OFFSET:
16164+ if (pEid->Len == 1)
16165+ {
16166+ *NewExtChannelOffset = pEid->Octet[0];
16167+ }
16168+ else
16169+ {
16170+ DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n"));
16171+ }
16172+
16173+ break;
16174+ case IE_FH_PARM:
16175+ DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity(IE_FH_PARM) \n"));
16176+ break;
16177+
16178+ case IE_DS_PARM:
16179+ if(pEid->Len == 1)
16180+ {
16181+ *pChannel = *pEid->Octet;
16182+#ifdef CONFIG_STA_SUPPORT
16183+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
16184+ {
16185+ if (ChannelSanity(pAd, *pChannel) == 0)
16186+ {
16187+
16188+ return FALSE;
16189+ }
16190+ }
16191+#endif // CONFIG_STA_SUPPORT //
16192+ Sanity |= 0x4;
16193+ }
16194+ else
16195+ {
16196+ DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_DS_PARM (len=%d)\n",pEid->Len));
16197+ return FALSE;
16198+ }
16199+ break;
16200+
16201+ case IE_CF_PARM:
16202+ if(pEid->Len == 6)
16203+ {
16204+ pCfParm->bValid = TRUE;
16205+ pCfParm->CfpCount = pEid->Octet[0];
16206+ pCfParm->CfpPeriod = pEid->Octet[1];
16207+ pCfParm->CfpMaxDuration = pEid->Octet[2] + 256 * pEid->Octet[3];
16208+ pCfParm->CfpDurRemaining = pEid->Octet[4] + 256 * pEid->Octet[5];
16209+ }
16210+ else
16211+ {
16212+ DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_CF_PARM\n"));
16213+ return FALSE;
16214+ }
16215+ break;
16216+
16217+ case IE_IBSS_PARM:
16218+ if(pEid->Len == 2)
16219+ {
16220+ NdisMoveMemory(pAtimWin, pEid->Octet, pEid->Len);
16221+ }
16222+ else
16223+ {
16224+ DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_IBSS_PARM\n"));
16225+ return FALSE;
16226+ }
16227+ break;
16228+
16229+#ifdef CONFIG_STA_SUPPORT
16230+ case IE_TIM:
16231+ if(INFRA_ON(pAd) && SubType == SUBTYPE_BEACON)
16232+ {
16233+ GetTimBit((PUCHAR)pEid, pAd->StaActive.Aid, &TimLen, pBcastFlag, pDtimCount, pDtimPeriod, pMessageToMe);
16234+ }
16235+ break;
16236+#endif // CONFIG_STA_SUPPORT //
16237+ case IE_CHANNEL_SWITCH_ANNOUNCEMENT:
16238+ if(pEid->Len == 3)
16239+ {
16240+ *pNewChannel = pEid->Octet[1]; //extract new channel number
16241+ }
16242+ break;
16243+
16244+ // New for WPA
16245+ // CCX v2 has the same IE, we need to parse that too
16246+ // Wifi WMM use the same IE vale, need to parse that too
16247+ // case IE_WPA:
16248+ case IE_VENDOR_SPECIFIC:
16249+ // Check Broadcom/Atheros 802.11n OUI version, for HT Capability IE.
16250+ // This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan.
16251+ /*if (NdisEqualMemory(pEid->Octet, BROADCOM_OUI, 3) && (pEid->Len >= 4))
16252+ {
16253+ if ((pEid->Octet[3] == OUI_BROADCOM_HT) && (pEid->Len >= 30))
16254+ {
16255+ {
16256+ NdisMoveMemory(pHtCapability, &pEid->Octet[4], sizeof(HT_CAPABILITY_IE));
16257+ *pHtCapabilityLen = SIZE_HT_CAP_IE; // Nnow we only support 26 bytes.
16258+ }
16259+ }
16260+ if ((pEid->Octet[3] == OUI_BROADCOM_HT) && (pEid->Len >= 26))
16261+ {
16262+ {
16263+ NdisMoveMemory(AddHtInfo, &pEid->Octet[4], sizeof(ADD_HT_INFO_IE));
16264+ *AddHtInfoLen = SIZE_ADD_HT_INFO_IE; // Nnow we only support 26 bytes.
16265+ }
16266+ }
16267+ }
16268+ */
16269+ // Check the OUI version, filter out non-standard usage
16270+ if (NdisEqualMemory(pEid->Octet, RALINK_OUI, 3) && (pEid->Len == 7))
16271+ {
16272+ //*pRalinkIe = pEid->Octet[3];
16273+ if (pEid->Octet[3] != 0)
16274+ *pRalinkIe = pEid->Octet[3];
16275+ else
16276+ *pRalinkIe = 0xf0000000; // Set to non-zero value (can't set bit0-2) to represent this is Ralink Chip. So at linkup, we will set ralinkchip flag.
16277+ }
16278+#ifdef CONFIG_STA_SUPPORT
16279+#ifdef DOT11_N_SUPPORT
16280+ // This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan.
16281+
16282+ // Other vendors had production before IE_HT_CAP value is assigned. To backward support those old-firmware AP,
16283+ // Check broadcom-defiend pre-802.11nD1.0 OUI for HT related IE, including HT Capatilities IE and HT Information IE
16284+ else if ((*pHtCapabilityLen == 0) && NdisEqualMemory(pEid->Octet, PRE_N_HT_OUI, 3) && (pEid->Len >= 4) && (pAd->OpMode == OPMODE_STA))
16285+ {
16286+ if ((pEid->Octet[3] == OUI_PREN_HT_CAP) && (pEid->Len >= 30) && (*pHtCapabilityLen == 0))
16287+ {
16288+ NdisMoveMemory(pHtCapability, &pEid->Octet[4], sizeof(HT_CAPABILITY_IE));
16289+ *pPreNHtCapabilityLen = SIZE_HT_CAP_IE;
16290+ }
16291+
16292+ if ((pEid->Octet[3] == OUI_PREN_ADD_HT) && (pEid->Len >= 26))
16293+ {
16294+ NdisMoveMemory(AddHtInfo, &pEid->Octet[4], sizeof(ADD_HT_INFO_IE));
16295+ *AddHtInfoLen = SIZE_ADD_HT_INFO_IE;
16296+ }
16297+ }
16298+#endif // DOT11_N_SUPPORT //
16299+#endif // CONFIG_STA_SUPPORT //
16300+ else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
16301+ {
16302+ // Copy to pVIE which will report to microsoft bssid list.
16303+ Ptr = (PUCHAR) pVIE;
16304+ NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
16305+ *LengthVIE += (pEid->Len + 2);
16306+ }
16307+ else if (NdisEqualMemory(pEid->Octet, WME_PARM_ELEM, 6) && (pEid->Len == 24))
16308+ {
16309+ PUCHAR ptr;
16310+ int i;
16311+
16312+ // parsing EDCA parameters
16313+ pEdcaParm->bValid = TRUE;
16314+ pEdcaParm->bQAck = FALSE; // pEid->Octet[0] & 0x10;
16315+ pEdcaParm->bQueueRequest = FALSE; // pEid->Octet[0] & 0x20;
16316+ pEdcaParm->bTxopRequest = FALSE; // pEid->Octet[0] & 0x40;
16317+ pEdcaParm->EdcaUpdateCount = pEid->Octet[6] & 0x0f;
16318+ pEdcaParm->bAPSDCapable = (pEid->Octet[6] & 0x80) ? 1 : 0;
16319+ ptr = &pEid->Octet[8];
16320+ for (i=0; i<4; i++)
16321+ {
16322+ UCHAR aci = (*ptr & 0x60) >> 5; // b5~6 is AC INDEX
16323+ pEdcaParm->bACM[aci] = (((*ptr) & 0x10) == 0x10); // b5 is ACM
16324+ pEdcaParm->Aifsn[aci] = (*ptr) & 0x0f; // b0~3 is AIFSN
16325+ pEdcaParm->Cwmin[aci] = *(ptr+1) & 0x0f; // b0~4 is Cwmin
16326+ pEdcaParm->Cwmax[aci] = *(ptr+1) >> 4; // b5~8 is Cwmax
16327+ pEdcaParm->Txop[aci] = *(ptr+2) + 256 * (*(ptr+3)); // in unit of 32-us
16328+ ptr += 4; // point to next AC
16329+ }
16330+ }
16331+ else if (NdisEqualMemory(pEid->Octet, WME_INFO_ELEM, 6) && (pEid->Len == 7))
16332+ {
16333+ // parsing EDCA parameters
16334+ pEdcaParm->bValid = TRUE;
16335+ pEdcaParm->bQAck = FALSE; // pEid->Octet[0] & 0x10;
16336+ pEdcaParm->bQueueRequest = FALSE; // pEid->Octet[0] & 0x20;
16337+ pEdcaParm->bTxopRequest = FALSE; // pEid->Octet[0] & 0x40;
16338+ pEdcaParm->EdcaUpdateCount = pEid->Octet[6] & 0x0f;
16339+ pEdcaParm->bAPSDCapable = (pEid->Octet[6] & 0x80) ? 1 : 0;
16340+
16341+ // use default EDCA parameter
16342+ pEdcaParm->bACM[QID_AC_BE] = 0;
16343+ pEdcaParm->Aifsn[QID_AC_BE] = 3;
16344+ pEdcaParm->Cwmin[QID_AC_BE] = CW_MIN_IN_BITS;
16345+ pEdcaParm->Cwmax[QID_AC_BE] = CW_MAX_IN_BITS;
16346+ pEdcaParm->Txop[QID_AC_BE] = 0;
16347+
16348+ pEdcaParm->bACM[QID_AC_BK] = 0;
16349+ pEdcaParm->Aifsn[QID_AC_BK] = 7;
16350+ pEdcaParm->Cwmin[QID_AC_BK] = CW_MIN_IN_BITS;
16351+ pEdcaParm->Cwmax[QID_AC_BK] = CW_MAX_IN_BITS;
16352+ pEdcaParm->Txop[QID_AC_BK] = 0;
16353+
16354+ pEdcaParm->bACM[QID_AC_VI] = 0;
16355+ pEdcaParm->Aifsn[QID_AC_VI] = 2;
16356+ pEdcaParm->Cwmin[QID_AC_VI] = CW_MIN_IN_BITS-1;
16357+ pEdcaParm->Cwmax[QID_AC_VI] = CW_MAX_IN_BITS;
16358+ pEdcaParm->Txop[QID_AC_VI] = 96; // AC_VI: 96*32us ~= 3ms
16359+
16360+ pEdcaParm->bACM[QID_AC_VO] = 0;
16361+ pEdcaParm->Aifsn[QID_AC_VO] = 2;
16362+ pEdcaParm->Cwmin[QID_AC_VO] = CW_MIN_IN_BITS-2;
16363+ pEdcaParm->Cwmax[QID_AC_VO] = CW_MAX_IN_BITS-1;
16364+ pEdcaParm->Txop[QID_AC_VO] = 48; // AC_VO: 48*32us ~= 1.5ms
16365+ }
16366+#ifdef CONFIG_STA_SUPPORT
16367+#endif // CONFIG_STA_SUPPORT //
16368+ else
16369+ {
16370+ }
16371+
16372+ break;
16373+
16374+ case IE_EXT_SUPP_RATES:
16375+ if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES)
16376+ {
16377+ NdisMoveMemory(ExtRate, pEid->Octet, pEid->Len);
16378+ *pExtRateLen = pEid->Len;
16379+
16380+ // TODO: 2004-09-14 not a good design here, cause it exclude extra rates
16381+ // from ScanTab. We should report as is. And filter out unsupported
16382+ // rates in MlmeAux.
16383+ // Check against the supported rates
16384+ // RTMPCheckRates(pAd, ExtRate, pExtRateLen);
16385+ }
16386+ break;
16387+
16388+ case IE_ERP:
16389+ if (pEid->Len == 1)
16390+ {
16391+ *pErp = (UCHAR)pEid->Octet[0];
16392+ }
16393+ break;
16394+
16395+ case IE_AIRONET_CKIP:
16396+ // 0. Check Aironet IE length, it must be larger or equal to 28
16397+ // Cisco AP350 used length as 28
16398+ // Cisco AP12XX used length as 30
16399+ if (pEid->Len < (CKIP_NEGOTIATION_LENGTH - 2))
16400+ break;
16401+
16402+ // 1. Copy CKIP flag byte to buffer for process
16403+ *pCkipFlag = *(pEid->Octet + 8);
16404+ break;
16405+
16406+ case IE_AP_TX_POWER:
16407+ // AP Control of Client Transmit Power
16408+ //0. Check Aironet IE length, it must be 6
16409+ if (pEid->Len != 0x06)
16410+ break;
16411+
16412+ // Get cell power limit in dBm
16413+ if (NdisEqualMemory(pEid->Octet, CISCO_OUI, 3) == 1)
16414+ *pAironetCellPowerLimit = *(pEid->Octet + 4);
16415+ break;
16416+
16417+ // WPA2 & 802.11i RSN
16418+ case IE_RSN:
16419+ // There is no OUI for version anymore, check the group cipher OUI before copying
16420+ if (RTMPEqualMemory(pEid->Octet + 2, RSN_OUI, 3))
16421+ {
16422+ // Copy to pVIE which will report to microsoft bssid list.
16423+ Ptr = (PUCHAR) pVIE;
16424+ NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
16425+ *LengthVIE += (pEid->Len + 2);
16426+ }
16427+ break;
16428+#ifdef CONFIG_STA_SUPPORT
16429+#ifdef EXT_BUILD_CHANNEL_LIST
16430+ case IE_COUNTRY:
16431+ Ptr = (PUCHAR) pVIE;
16432+ NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
16433+ *LengthVIE += (pEid->Len + 2);
16434+ break;
16435+#endif // EXT_BUILD_CHANNEL_LIST //
16436+#endif // CONFIG_STA_SUPPORT //
16437+ default:
16438+ break;
16439+ }
16440+
16441+ Length = Length + 2 + pEid->Len; // Eid[1] + Len[1]+ content[Len]
16442+ pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
16443+ }
16444+
16445+ // For some 11a AP. it did not have the channel EID, patch here
16446+#ifdef CONFIG_STA_SUPPORT
16447+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
16448+ {
16449+ UCHAR LatchRfChannel = MsgChannel;
16450+ if ((pAd->LatchRfRegs.Channel > 14) && ((Sanity & 0x4) == 0))
16451+ {
16452+ if (CtrlChannel != 0)
16453+ *pChannel = CtrlChannel;
16454+ else
16455+ *pChannel = LatchRfChannel;
16456+ Sanity |= 0x4;
16457+ }
16458+ }
16459+#endif // CONFIG_STA_SUPPORT //
16460+
16461+ if (Sanity != 0x7)
16462+ {
16463+ DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - missing field, Sanity=0x%02x\n", Sanity));
16464+ return FALSE;
16465+ }
16466+ else
16467+ {
16468+ return TRUE;
16469+ }
16470+
16471+}
16472+
16473+#ifdef DOT11N_DRAFT3
16474+/*
16475+ ==========================================================================
16476+ Description:
16477+ MLME message sanity check for some IE addressed in 802.11n d3.03.
16478+ Return:
16479+ TRUE if all parameters are OK, FALSE otherwise
16480+
16481+ IRQL = DISPATCH_LEVEL
16482+
16483+ ==========================================================================
16484+ */
16485+BOOLEAN PeerBeaconAndProbeRspSanity2(
16486+ IN PRTMP_ADAPTER pAd,
16487+ IN VOID *Msg,
16488+ IN ULONG MsgLen,
16489+ OUT UCHAR *RegClass)
16490+{
16491+ CHAR *Ptr;
16492+ PFRAME_802_11 pFrame;
16493+ PEID_STRUCT pEid;
16494+ ULONG Length = 0;
16495+
16496+ pFrame = (PFRAME_802_11)Msg;
16497+
16498+ *RegClass = 0;
16499+ Ptr = pFrame->Octet;
16500+ Length += LENGTH_802_11;
16501+
16502+ // get timestamp from payload and advance the pointer
16503+ Ptr += TIMESTAMP_LEN;
16504+ Length += TIMESTAMP_LEN;
16505+
16506+ // get beacon interval from payload and advance the pointer
16507+ Ptr += 2;
16508+ Length += 2;
16509+
16510+ // get capability info from payload and advance the pointer
16511+ Ptr += 2;
16512+ Length += 2;
16513+
16514+ pEid = (PEID_STRUCT) Ptr;
16515+
16516+ // get variable fields from payload and advance the pointer
16517+ while ((Length + 2 + pEid->Len) <= MsgLen)
16518+ {
16519+ switch(pEid->Eid)
16520+ {
16521+ case IE_SUPP_REG_CLASS:
16522+ if(pEid->Len > 0)
16523+ {
16524+ *RegClass = *pEid->Octet;
16525+ }
16526+ else
16527+ {
16528+ DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_SSID (len=%d)\n",pEid->Len));
16529+ return FALSE;
16530+ }
16531+ break;
16532+ }
16533+
16534+ Length = Length + 2 + pEid->Len; // Eid[1] + Len[1]+ content[Len]
16535+ pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
16536+ }
16537+
16538+ return TRUE;
16539+
16540+}
16541+#endif // DOT11N_DRAFT3 //
16542+
16543+/*
16544+ ==========================================================================
16545+ Description:
16546+ MLME message sanity check
16547+ Return:
16548+ TRUE if all parameters are OK, FALSE otherwise
16549+ ==========================================================================
16550+ */
16551+BOOLEAN MlmeScanReqSanity(
16552+ IN PRTMP_ADAPTER pAd,
16553+ IN VOID *Msg,
16554+ IN ULONG MsgLen,
16555+ OUT UCHAR *pBssType,
16556+ OUT CHAR Ssid[],
16557+ OUT UCHAR *pSsidLen,
16558+ OUT UCHAR *pScanType)
16559+{
16560+ MLME_SCAN_REQ_STRUCT *Info;
16561+
16562+ Info = (MLME_SCAN_REQ_STRUCT *)(Msg);
16563+ *pBssType = Info->BssType;
16564+ *pSsidLen = Info->SsidLen;
16565+ NdisMoveMemory(Ssid, Info->Ssid, *pSsidLen);
16566+ *pScanType = Info->ScanType;
16567+
16568+ if ((*pBssType == BSS_INFRA || *pBssType == BSS_ADHOC || *pBssType == BSS_ANY)
16569+ && (*pScanType == SCAN_ACTIVE || *pScanType == SCAN_PASSIVE
16570+#ifdef CONFIG_STA_SUPPORT
16571+ || *pScanType == SCAN_CISCO_PASSIVE || *pScanType == SCAN_CISCO_ACTIVE
16572+ || *pScanType == SCAN_CISCO_CHANNEL_LOAD || *pScanType == SCAN_CISCO_NOISE
16573+#endif // CONFIG_STA_SUPPORT //
16574+ ))
16575+ {
16576+ return TRUE;
16577+ }
16578+ else
16579+ {
16580+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqSanity fail - wrong BssType or ScanType\n"));
16581+ return FALSE;
16582+ }
16583+}
16584+
16585+// IRQL = DISPATCH_LEVEL
16586+UCHAR ChannelSanity(
16587+ IN PRTMP_ADAPTER pAd,
16588+ IN UCHAR channel)
16589+{
16590+ int i;
16591+
16592+ for (i = 0; i < pAd->ChannelListNum; i ++)
16593+ {
16594+ if (channel == pAd->ChannelList[i].Channel)
16595+ return 1;
16596+ }
16597+ return 0;
16598+}
16599+
16600+/*
16601+ ==========================================================================
16602+ Description:
16603+ MLME message sanity check
16604+ Return:
16605+ TRUE if all parameters are OK, FALSE otherwise
16606+
16607+ IRQL = DISPATCH_LEVEL
16608+
16609+ ==========================================================================
16610+ */
16611+BOOLEAN PeerDeauthSanity(
16612+ IN PRTMP_ADAPTER pAd,
16613+ IN VOID *Msg,
16614+ IN ULONG MsgLen,
16615+ OUT PUCHAR pAddr2,
16616+ OUT USHORT *pReason)
16617+{
16618+ PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
16619+
16620+ COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
16621+ NdisMoveMemory(pReason, &pFrame->Octet[0], 2);
16622+
16623+ return TRUE;
16624+}
16625+
16626+/*
16627+ ==========================================================================
16628+ Description:
16629+ MLME message sanity check
16630+ Return:
16631+ TRUE if all parameters are OK, FALSE otherwise
16632+
16633+ IRQL = DISPATCH_LEVEL
16634+
16635+ ==========================================================================
16636+ */
16637+BOOLEAN PeerAuthSanity(
16638+ IN PRTMP_ADAPTER pAd,
16639+ IN VOID *Msg,
16640+ IN ULONG MsgLen,
16641+ OUT PUCHAR pAddr,
16642+ OUT USHORT *pAlg,
16643+ OUT USHORT *pSeq,
16644+ OUT USHORT *pStatus,
16645+ CHAR *pChlgText)
16646+{
16647+ PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
16648+
16649+ COPY_MAC_ADDR(pAddr, pFrame->Hdr.Addr2);
16650+ NdisMoveMemory(pAlg, &pFrame->Octet[0], 2);
16651+ NdisMoveMemory(pSeq, &pFrame->Octet[2], 2);
16652+ NdisMoveMemory(pStatus, &pFrame->Octet[4], 2);
16653+
16654+ if ((*pAlg == Ndis802_11AuthModeOpen)
16655+#ifdef LEAP_SUPPORT
16656+ || (*pAlg == CISCO_AuthModeLEAP)
16657+#endif // LEAP_SUPPORT //
16658+ )
16659+ {
16660+ if (*pSeq == 1 || *pSeq == 2)
16661+ {
16662+ return TRUE;
16663+ }
16664+ else
16665+ {
16666+ DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong Seg#\n"));
16667+ return FALSE;
16668+ }
16669+ }
16670+ else if (*pAlg == Ndis802_11AuthModeShared)
16671+ {
16672+ if (*pSeq == 1 || *pSeq == 4)
16673+ {
16674+ return TRUE;
16675+ }
16676+ else if (*pSeq == 2 || *pSeq == 3)
16677+ {
16678+ NdisMoveMemory(pChlgText, &pFrame->Octet[8], CIPHER_TEXT_LEN);
16679+ return TRUE;
16680+ }
16681+ else
16682+ {
16683+ DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong Seg#\n"));
16684+ return FALSE;
16685+ }
16686+ }
16687+ else
16688+ {
16689+ DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong algorithm\n"));
16690+ return FALSE;
16691+ }
16692+}
16693+
16694+/*
16695+ ==========================================================================
16696+ Description:
16697+ MLME message sanity check
16698+ Return:
16699+ TRUE if all parameters are OK, FALSE otherwise
16700+ ==========================================================================
16701+ */
16702+BOOLEAN MlmeAuthReqSanity(
16703+ IN PRTMP_ADAPTER pAd,
16704+ IN VOID *Msg,
16705+ IN ULONG MsgLen,
16706+ OUT PUCHAR pAddr,
16707+ OUT ULONG *pTimeout,
16708+ OUT USHORT *pAlg)
16709+{
16710+ MLME_AUTH_REQ_STRUCT *pInfo;
16711+
16712+ pInfo = (MLME_AUTH_REQ_STRUCT *)Msg;
16713+ COPY_MAC_ADDR(pAddr, pInfo->Addr);
16714+ *pTimeout = pInfo->Timeout;
16715+ *pAlg = pInfo->Alg;
16716+
16717+ if (((*pAlg == Ndis802_11AuthModeShared) ||(*pAlg == Ndis802_11AuthModeOpen)
16718+#ifdef LEAP_SUPPORT
16719+ || (*pAlg == CISCO_AuthModeLEAP)
16720+#endif // LEAP_SUPPORT //
16721+ ) &&
16722+ ((*pAddr & 0x01) == 0))
16723+ {
16724+ return TRUE;
16725+ }
16726+ else
16727+ {
16728+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeAuthReqSanity fail - wrong algorithm\n"));
16729+ return FALSE;
16730+ }
16731+}
16732+
16733+/*
16734+ ==========================================================================
16735+ Description:
16736+ MLME message sanity check
16737+ Return:
16738+ TRUE if all parameters are OK, FALSE otherwise
16739+
16740+ IRQL = DISPATCH_LEVEL
16741+
16742+ ==========================================================================
16743+ */
16744+BOOLEAN MlmeAssocReqSanity(
16745+ IN PRTMP_ADAPTER pAd,
16746+ IN VOID *Msg,
16747+ IN ULONG MsgLen,
16748+ OUT PUCHAR pApAddr,
16749+ OUT USHORT *pCapabilityInfo,
16750+ OUT ULONG *pTimeout,
16751+ OUT USHORT *pListenIntv)
16752+{
16753+ MLME_ASSOC_REQ_STRUCT *pInfo;
16754+
16755+ pInfo = (MLME_ASSOC_REQ_STRUCT *)Msg;
16756+ *pTimeout = pInfo->Timeout; // timeout
16757+ COPY_MAC_ADDR(pApAddr, pInfo->Addr); // AP address
16758+ *pCapabilityInfo = pInfo->CapabilityInfo; // capability info
16759+ *pListenIntv = pInfo->ListenIntv;
16760+
16761+ return TRUE;
16762+}
16763+
16764+/*
16765+ ==========================================================================
16766+ Description:
16767+ MLME message sanity check
16768+ Return:
16769+ TRUE if all parameters are OK, FALSE otherwise
16770+
16771+ IRQL = DISPATCH_LEVEL
16772+
16773+ ==========================================================================
16774+ */
16775+BOOLEAN PeerDisassocSanity(
16776+ IN PRTMP_ADAPTER pAd,
16777+ IN VOID *Msg,
16778+ IN ULONG MsgLen,
16779+ OUT PUCHAR pAddr2,
16780+ OUT USHORT *pReason)
16781+{
16782+ PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
16783+
16784+ COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
16785+ NdisMoveMemory(pReason, &pFrame->Octet[0], 2);
16786+
16787+ return TRUE;
16788+}
16789+
16790+/*
16791+ ========================================================================
16792+ Routine Description:
16793+ Sanity check NetworkType (11b, 11g or 11a)
16794+
16795+ Arguments:
16796+ pBss - Pointer to BSS table.
16797+
16798+ Return Value:
16799+ Ndis802_11DS .......(11b)
16800+ Ndis802_11OFDM24....(11g)
16801+ Ndis802_11OFDM5.....(11a)
16802+
16803+ IRQL = DISPATCH_LEVEL
16804+
16805+ ========================================================================
16806+*/
16807+NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity(
16808+ IN PBSS_ENTRY pBss)
16809+{
16810+ NDIS_802_11_NETWORK_TYPE NetWorkType;
16811+ UCHAR rate, i;
16812+
16813+ NetWorkType = Ndis802_11DS;
16814+
16815+ if (pBss->Channel <= 14)
16816+ {
16817+ //
16818+ // First check support Rate.
16819+ //
16820+ for (i = 0; i < pBss->SupRateLen; i++)
16821+ {
16822+ rate = pBss->SupRate[i] & 0x7f; // Mask out basic rate set bit
16823+ if ((rate == 2) || (rate == 4) || (rate == 11) || (rate == 22))
16824+ {
16825+ continue;
16826+ }
16827+ else
16828+ {
16829+ //
16830+ // Otherwise (even rate > 108) means Ndis802_11OFDM24
16831+ //
16832+ NetWorkType = Ndis802_11OFDM24;
16833+ break;
16834+ }
16835+ }
16836+
16837+ //
16838+ // Second check Extend Rate.
16839+ //
16840+ if (NetWorkType != Ndis802_11OFDM24)
16841+ {
16842+ for (i = 0; i < pBss->ExtRateLen; i++)
16843+ {
16844+ rate = pBss->SupRate[i] & 0x7f; // Mask out basic rate set bit
16845+ if ((rate == 2) || (rate == 4) || (rate == 11) || (rate == 22))
16846+ {
16847+ continue;
16848+ }
16849+ else
16850+ {
16851+ //
16852+ // Otherwise (even rate > 108) means Ndis802_11OFDM24
16853+ //
16854+ NetWorkType = Ndis802_11OFDM24;
16855+ break;
16856+ }
16857+ }
16858+ }
16859+ }
16860+ else
16861+ {
16862+ NetWorkType = Ndis802_11OFDM5;
16863+ }
16864+
16865+ if (pBss->HtCapabilityLen != 0)
16866+ {
16867+ if (NetWorkType == Ndis802_11OFDM5)
16868+ NetWorkType = Ndis802_11OFDM5_N;
16869+ else
16870+ NetWorkType = Ndis802_11OFDM24_N;
16871+ }
16872+
16873+ return NetWorkType;
16874+}
16875+
16876+/*
16877+ ==========================================================================
16878+ Description:
16879+ WPA message sanity check
16880+ Return:
16881+ TRUE if all parameters are OK, FALSE otherwise
16882+ ==========================================================================
16883+ */
16884+BOOLEAN PeerWpaMessageSanity(
16885+ IN PRTMP_ADAPTER pAd,
16886+ IN PEAPOL_PACKET pMsg,
16887+ IN ULONG MsgLen,
16888+ IN UCHAR MsgType,
16889+ IN MAC_TABLE_ENTRY *pEntry)
16890+{
16891+ UCHAR mic[LEN_KEY_DESC_MIC], digest[80], KEYDATA[MAX_LEN_OF_RSNIE];
16892+ BOOLEAN bReplayDiff = FALSE;
16893+ BOOLEAN bWPA2 = FALSE;
16894+ KEY_INFO EapolKeyInfo;
16895+ UCHAR GroupKeyIndex = 0;
16896+
16897+
16898+ NdisZeroMemory(mic, sizeof(mic));
16899+ NdisZeroMemory(digest, sizeof(digest));
16900+ NdisZeroMemory(KEYDATA, sizeof(KEYDATA));
16901+ NdisZeroMemory((PUCHAR)&EapolKeyInfo, sizeof(EapolKeyInfo));
16902+
16903+ NdisMoveMemory((PUCHAR)&EapolKeyInfo, (PUCHAR)&pMsg->KeyDesc.KeyInfo, sizeof(KEY_INFO));
16904+
16905+ *((USHORT *)&EapolKeyInfo) = cpu2le16(*((USHORT *)&EapolKeyInfo));
16906+
16907+ // Choose WPA2 or not
16908+ if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
16909+ bWPA2 = TRUE;
16910+
16911+ // 0. Check MsgType
16912+ if ((MsgType > EAPOL_GROUP_MSG_2) || (MsgType < EAPOL_PAIR_MSG_1))
16913+ {
16914+ DBGPRINT(RT_DEBUG_ERROR, ("The message type is invalid(%d)! \n", MsgType));
16915+ return FALSE;
16916+ }
16917+
16918+ // 1. Replay counter check
16919+ if (MsgType == EAPOL_PAIR_MSG_1 || MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1) // For supplicant
16920+ {
16921+ // First validate replay counter, only accept message with larger replay counter.
16922+ // Let equal pass, some AP start with all zero replay counter
16923+ UCHAR ZeroReplay[LEN_KEY_DESC_REPLAY];
16924+
16925+ NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY);
16926+ if ((RTMPCompareMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY) != 1) &&
16927+ (RTMPCompareMemory(pMsg->KeyDesc.ReplayCounter, ZeroReplay, LEN_KEY_DESC_REPLAY) != 0))
16928+ {
16929+ bReplayDiff = TRUE;
16930+ }
16931+ }
16932+ else if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2) // For authenticator
16933+ {
16934+ // check Replay Counter coresponds to MSG from authenticator, otherwise discard
16935+ if (!NdisEqualMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY))
16936+ {
16937+ bReplayDiff = TRUE;
16938+ }
16939+ }
16940+
16941+ // Replay Counter different condition
16942+ if (bReplayDiff)
16943+ {
16944+ // send wireless event - for replay counter different
16945+ if (pAd->CommonCfg.bWirelessEvent)
16946+ RTMPSendWirelessEvent(pAd, IW_REPLAY_COUNTER_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
16947+
16948+ if (MsgType < EAPOL_GROUP_MSG_1)
16949+ {
16950+ DBGPRINT(RT_DEBUG_ERROR, ("Replay Counter Different in pairwise msg %d of 4-way handshake!\n", MsgType));
16951+ }
16952+ else
16953+ {
16954+ DBGPRINT(RT_DEBUG_ERROR, ("Replay Counter Different in group msg %d of 2-way handshake!\n", (MsgType - EAPOL_PAIR_MSG_4)));
16955+ }
16956+
16957+ hex_dump("Receive replay counter ", pMsg->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
16958+ hex_dump("Current replay counter ", pEntry->R_Counter, LEN_KEY_DESC_REPLAY);
16959+ return FALSE;
16960+ }
16961+
16962+ // 2. Verify MIC except Pairwise Msg1
16963+ if (MsgType != EAPOL_PAIR_MSG_1)
16964+ {
16965+ UCHAR rcvd_mic[LEN_KEY_DESC_MIC];
16966+
16967+ // Record the received MIC for check later
16968+ NdisMoveMemory(rcvd_mic, pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
16969+ NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
16970+
16971+ if (pEntry->WepStatus == Ndis802_11Encryption2Enabled) // TKIP
16972+ {
16973+ hmac_md5(pEntry->PTK, LEN_EAP_MICK, (PUCHAR)pMsg, MsgLen, mic);
16974+ }
16975+ else if (pEntry->WepStatus == Ndis802_11Encryption3Enabled) // AES
16976+ {
16977+ HMAC_SHA1((PUCHAR)pMsg, MsgLen, pEntry->PTK, LEN_EAP_MICK, digest);
16978+ NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
16979+ }
16980+
16981+ if (!NdisEqualMemory(rcvd_mic, mic, LEN_KEY_DESC_MIC))
16982+ {
16983+ // send wireless event - for MIC different
16984+ if (pAd->CommonCfg.bWirelessEvent)
16985+ RTMPSendWirelessEvent(pAd, IW_MIC_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
16986+
16987+ if (MsgType < EAPOL_GROUP_MSG_1)
16988+ {
16989+ DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in pairwise msg %d of 4-way handshake!\n", MsgType));
16990+ }
16991+ else
16992+ {
16993+ DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in group msg %d of 2-way handshake!\n", (MsgType - EAPOL_PAIR_MSG_4)));
16994+ }
16995+
16996+ hex_dump("Received MIC", rcvd_mic, LEN_KEY_DESC_MIC);
16997+ hex_dump("Desired MIC", mic, LEN_KEY_DESC_MIC);
16998+
16999+ return FALSE;
17000+ }
17001+ }
17002+
17003+ // Extract the context of the Key Data field if it exist
17004+ // The field in pairwise_msg_2_WPA1(WPA2) & pairwise_msg_3_WPA1 is un-encrypted.
17005+ // The field in group_msg_1_WPA1(WPA2) & pairwise_msg_3_WPA2 is encrypted.
17006+ if (pMsg->KeyDesc.KeyDataLen[1] > 0)
17007+ {
17008+ // Decrypt this field
17009+ if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2) || (MsgType == EAPOL_GROUP_MSG_1))
17010+ {
17011+ if(pEntry->WepStatus == Ndis802_11Encryption3Enabled)
17012+ {
17013+ // AES
17014+ AES_GTK_KEY_UNWRAP(&pEntry->PTK[16], KEYDATA, pMsg->KeyDesc.KeyDataLen[1],pMsg->KeyDesc.KeyData);
17015+ }
17016+ else
17017+ {
17018+ INT i;
17019+ UCHAR Key[32];
17020+ // Decrypt TKIP GTK
17021+ // Construct 32 bytes RC4 Key
17022+ NdisMoveMemory(Key, pMsg->KeyDesc.KeyIv, 16);
17023+ NdisMoveMemory(&Key[16], &pEntry->PTK[16], 16);
17024+ ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key, 32);
17025+ //discard first 256 bytes
17026+ for(i = 0; i < 256; i++)
17027+ ARCFOUR_BYTE(&pAd->PrivateInfo.WEPCONTEXT);
17028+ // Decrypt GTK. Becareful, there is no ICV to check the result is correct or not
17029+ ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, KEYDATA, pMsg->KeyDesc.KeyData, pMsg->KeyDesc.KeyDataLen[1]);
17030+ }
17031+
17032+ if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))
17033+ GroupKeyIndex = EapolKeyInfo.KeyIndex;
17034+
17035+ }
17036+ else if ((MsgType == EAPOL_PAIR_MSG_2) || (MsgType == EAPOL_PAIR_MSG_3 && !bWPA2))
17037+ {
17038+ NdisMoveMemory(KEYDATA, pMsg->KeyDesc.KeyData, pMsg->KeyDesc.KeyDataLen[1]);
17039+ }
17040+ else
17041+ {
17042+
17043+ return TRUE;
17044+ }
17045+
17046+ // Parse Key Data field to
17047+ // 1. verify RSN IE for pairwise_msg_2_WPA1(WPA2) ,pairwise_msg_3_WPA1(WPA2)
17048+ // 2. verify KDE format for pairwise_msg_3_WPA2, group_msg_1_WPA2
17049+ // 3. update shared key for pairwise_msg_3_WPA2, group_msg_1_WPA1(WPA2)
17050+ if (!RTMPParseEapolKeyData(pAd, KEYDATA, pMsg->KeyDesc.KeyDataLen[1], GroupKeyIndex, MsgType, bWPA2, pEntry))
17051+ {
17052+ return FALSE;
17053+ }
17054+ }
17055+
17056+ return TRUE;
17057+
17058+}
17059+
17060+#ifdef CONFIG_STA_SUPPORT
17061+#ifdef QOS_DLS_SUPPORT
17062+BOOLEAN MlmeDlsReqSanity(
17063+ IN PRTMP_ADAPTER pAd,
17064+ IN VOID *Msg,
17065+ IN ULONG MsgLen,
17066+ OUT PRT_802_11_DLS *pDLS,
17067+ OUT PUSHORT pReason)
17068+{
17069+ MLME_DLS_REQ_STRUCT *pInfo;
17070+
17071+ pInfo = (MLME_DLS_REQ_STRUCT *)Msg;
17072+
17073+ *pDLS = pInfo->pDLS;
17074+ *pReason = pInfo->Reason;
17075+
17076+ return TRUE;
17077+}
17078+#endif // QOS_DLS_SUPPORT //
17079+#endif // CONFIG_STA_SUPPORT //
17080+
17081+#ifdef QOS_DLS_SUPPORT
17082+BOOLEAN PeerDlsReqSanity(
17083+ IN PRTMP_ADAPTER pAd,
17084+ IN VOID *Msg,
17085+ IN ULONG MsgLen,
17086+ OUT PUCHAR pDA,
17087+ OUT PUCHAR pSA,
17088+ OUT USHORT *pCapabilityInfo,
17089+ OUT USHORT *pDlsTimeout,
17090+ OUT UCHAR *pRatesLen,
17091+ OUT UCHAR Rates[],
17092+ OUT UCHAR *pHtCapabilityLen,
17093+ OUT HT_CAPABILITY_IE *pHtCapability)
17094+{
17095+ CHAR *Ptr;
17096+ PFRAME_802_11 Fr = (PFRAME_802_11)Msg;
17097+ PEID_STRUCT eid_ptr;
17098+
17099+ // to prevent caller from using garbage output value
17100+ *pCapabilityInfo = 0;
17101+ *pDlsTimeout = 0;
17102+ *pHtCapabilityLen = 0;
17103+
17104+ Ptr = Fr->Octet;
17105+
17106+ // offset to destination MAC address (Category and Action field)
17107+ Ptr += 2;
17108+
17109+ // get DA from payload and advance the pointer
17110+ NdisMoveMemory(pDA, Ptr, MAC_ADDR_LEN);
17111+ Ptr += MAC_ADDR_LEN;
17112+
17113+ // get SA from payload and advance the pointer
17114+ NdisMoveMemory(pSA, Ptr, MAC_ADDR_LEN);
17115+ Ptr += MAC_ADDR_LEN;
17116+
17117+ // get capability info from payload and advance the pointer
17118+ NdisMoveMemory(pCapabilityInfo, Ptr, 2);
17119+ Ptr += 2;
17120+
17121+ // get capability info from payload and advance the pointer
17122+ NdisMoveMemory(pDlsTimeout, Ptr, 2);
17123+ Ptr += 2;
17124+
17125+ // Category and Action field + DA + SA + capability + Timeout
17126+ eid_ptr = (PEID_STRUCT) &Fr->Octet[18];
17127+
17128+ while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((UCHAR*)Fr + MsgLen))
17129+ {
17130+ switch(eid_ptr->Eid)
17131+ {
17132+ case IE_SUPP_RATES:
17133+ if ((eid_ptr->Len <= MAX_LEN_OF_SUPPORTED_RATES) && (eid_ptr->Len > 0))
17134+ {
17135+ NdisMoveMemory(Rates, eid_ptr->Octet, eid_ptr->Len);
17136+ DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - IE_SUPP_RATES., Len=%d. Rates[0]=%x\n",eid_ptr->Len, Rates[0]));
17137+ DBGPRINT(RT_DEBUG_TRACE, ("Rates[1]=%x %x %x %x %x %x %x\n", Rates[1], Rates[2], Rates[3], Rates[4], Rates[5], Rates[6], Rates[7]));
17138+ *pRatesLen = eid_ptr->Len;
17139+ }
17140+ else
17141+ {
17142+ *pRatesLen = 8;
17143+ Rates[0] = 0x82;
17144+ Rates[1] = 0x84;
17145+ Rates[2] = 0x8b;
17146+ Rates[3] = 0x96;
17147+ Rates[4] = 0x12;
17148+ Rates[5] = 0x24;
17149+ Rates[6] = 0x48;
17150+ Rates[7] = 0x6c;
17151+ DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - wrong IE_SUPP_RATES., Len=%d\n",eid_ptr->Len));
17152+ }
17153+ break;
17154+
17155+ case IE_EXT_SUPP_RATES:
17156+ if (eid_ptr->Len + *pRatesLen <= MAX_LEN_OF_SUPPORTED_RATES)
17157+ {
17158+ NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, eid_ptr->Len);
17159+ *pRatesLen = (*pRatesLen) + eid_ptr->Len;
17160+ }
17161+ else
17162+ {
17163+ NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, MAX_LEN_OF_SUPPORTED_RATES - (*pRatesLen));
17164+ *pRatesLen = MAX_LEN_OF_SUPPORTED_RATES;
17165+ }
17166+ break;
17167+
17168+ case IE_HT_CAP:
17169+ if (eid_ptr->Len >= sizeof(HT_CAPABILITY_IE))
17170+ {
17171+ NdisMoveMemory(pHtCapability, eid_ptr->Octet, sizeof(HT_CAPABILITY_IE));
17172+
17173+ *(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo));
17174+ *(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
17175+ *pHtCapabilityLen = sizeof(HT_CAPABILITY_IE);
17176+
17177+ DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - IE_HT_CAP\n"));
17178+ }
17179+ else
17180+ {
17181+ DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - wrong IE_HT_CAP.eid_ptr->Len = %d\n", eid_ptr->Len));
17182+ }
17183+ break;
17184+
17185+ default:
17186+ break;
17187+ }
17188+
17189+ eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
17190+ }
17191+
17192+ return TRUE;
17193+}
17194+
17195+BOOLEAN PeerDlsRspSanity(
17196+ IN PRTMP_ADAPTER pAd,
17197+ IN VOID *Msg,
17198+ IN ULONG MsgLen,
17199+ OUT PUCHAR pDA,
17200+ OUT PUCHAR pSA,
17201+ OUT USHORT *pCapabilityInfo,
17202+ OUT USHORT *pStatus,
17203+ OUT UCHAR *pRatesLen,
17204+ OUT UCHAR Rates[],
17205+ OUT UCHAR *pHtCapabilityLen,
17206+ OUT HT_CAPABILITY_IE *pHtCapability)
17207+{
17208+ CHAR *Ptr;
17209+ PFRAME_802_11 Fr = (PFRAME_802_11)Msg;
17210+ PEID_STRUCT eid_ptr;
17211+
17212+ // to prevent caller from using garbage output value
17213+ *pStatus = 0;
17214+ *pCapabilityInfo = 0;
17215+ *pHtCapabilityLen = 0;
17216+
17217+ Ptr = Fr->Octet;
17218+
17219+ // offset to destination MAC address (Category and Action field)
17220+ Ptr += 2;
17221+
17222+ // get status code from payload and advance the pointer
17223+ NdisMoveMemory(pStatus, Ptr, 2);
17224+ Ptr += 2;
17225+
17226+ // get DA from payload and advance the pointer
17227+ NdisMoveMemory(pDA, Ptr, MAC_ADDR_LEN);
17228+ Ptr += MAC_ADDR_LEN;
17229+
17230+ // get SA from payload and advance the pointer
17231+ NdisMoveMemory(pSA, Ptr, MAC_ADDR_LEN);
17232+ Ptr += MAC_ADDR_LEN;
17233+
17234+ if (pStatus == 0)
17235+ {
17236+ // get capability info from payload and advance the pointer
17237+ NdisMoveMemory(pCapabilityInfo, Ptr, 2);
17238+ Ptr += 2;
17239+ }
17240+
17241+ // Category and Action field + status code + DA + SA + capability
17242+ eid_ptr = (PEID_STRUCT) &Fr->Octet[18];
17243+
17244+ while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((UCHAR*)Fr + MsgLen))
17245+ {
17246+ switch(eid_ptr->Eid)
17247+ {
17248+ case IE_SUPP_RATES:
17249+ if ((eid_ptr->Len <= MAX_LEN_OF_SUPPORTED_RATES) && (eid_ptr->Len > 0))
17250+ {
17251+ NdisMoveMemory(Rates, eid_ptr->Octet, eid_ptr->Len);
17252+ DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - IE_SUPP_RATES., Len=%d. Rates[0]=%x\n",eid_ptr->Len, Rates[0]));
17253+ DBGPRINT(RT_DEBUG_TRACE, ("Rates[1]=%x %x %x %x %x %x %x\n", Rates[1], Rates[2], Rates[3], Rates[4], Rates[5], Rates[6], Rates[7]));
17254+ *pRatesLen = eid_ptr->Len;
17255+ }
17256+ else
17257+ {
17258+ *pRatesLen = 8;
17259+ Rates[0] = 0x82;
17260+ Rates[1] = 0x84;
17261+ Rates[2] = 0x8b;
17262+ Rates[3] = 0x96;
17263+ Rates[4] = 0x12;
17264+ Rates[5] = 0x24;
17265+ Rates[6] = 0x48;
17266+ Rates[7] = 0x6c;
17267+ DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - wrong IE_SUPP_RATES., Len=%d\n",eid_ptr->Len));
17268+ }
17269+ break;
17270+
17271+ case IE_EXT_SUPP_RATES:
17272+ if (eid_ptr->Len + *pRatesLen <= MAX_LEN_OF_SUPPORTED_RATES)
17273+ {
17274+ NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, eid_ptr->Len);
17275+ *pRatesLen = (*pRatesLen) + eid_ptr->Len;
17276+ }
17277+ else
17278+ {
17279+ NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, MAX_LEN_OF_SUPPORTED_RATES - (*pRatesLen));
17280+ *pRatesLen = MAX_LEN_OF_SUPPORTED_RATES;
17281+ }
17282+ break;
17283+
17284+ case IE_HT_CAP:
17285+ if (eid_ptr->Len >= sizeof(HT_CAPABILITY_IE))
17286+ {
17287+ NdisMoveMemory(pHtCapability, eid_ptr->Octet, sizeof(HT_CAPABILITY_IE));
17288+
17289+ *(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo));
17290+ *(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
17291+ *pHtCapabilityLen = sizeof(HT_CAPABILITY_IE);
17292+
17293+ DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - IE_HT_CAP\n"));
17294+ }
17295+ else
17296+ {
17297+ DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - wrong IE_HT_CAP.eid_ptr->Len = %d\n", eid_ptr->Len));
17298+ }
17299+ break;
17300+
17301+ default:
17302+ break;
17303+ }
17304+
17305+ eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
17306+ }
17307+
17308+ return TRUE;
17309+}
17310+
17311+BOOLEAN PeerDlsTearDownSanity(
17312+ IN PRTMP_ADAPTER pAd,
17313+ IN VOID *Msg,
17314+ IN ULONG MsgLen,
17315+ OUT PUCHAR pDA,
17316+ OUT PUCHAR pSA,
17317+ OUT USHORT *pReason)
17318+{
17319+ CHAR *Ptr;
17320+ PFRAME_802_11 Fr = (PFRAME_802_11)Msg;
17321+
17322+ // to prevent caller from using garbage output value
17323+ *pReason = 0;
17324+
17325+ Ptr = Fr->Octet;
17326+
17327+ // offset to destination MAC address (Category and Action field)
17328+ Ptr += 2;
17329+
17330+ // get DA from payload and advance the pointer
17331+ NdisMoveMemory(pDA, Ptr, MAC_ADDR_LEN);
17332+ Ptr += MAC_ADDR_LEN;
17333+
17334+ // get SA from payload and advance the pointer
17335+ NdisMoveMemory(pSA, Ptr, MAC_ADDR_LEN);
17336+ Ptr += MAC_ADDR_LEN;
17337+
17338+ // get reason code from payload and advance the pointer
17339+ NdisMoveMemory(pReason, Ptr, 2);
17340+ Ptr += 2;
17341+
17342+ return TRUE;
17343+}
17344+#endif // QOS_DLS_SUPPORT //
17345+
17346--- /dev/null
17347+++ b/drivers/staging/rt3070/common/cmm_sync.c
17348@@ -0,0 +1,711 @@
17349+/*
17350+ *************************************************************************
17351+ * Ralink Tech Inc.
17352+ * 5F., No.36, Taiyuan St., Jhubei City,
17353+ * Hsinchu County 302,
17354+ * Taiwan, R.O.C.
17355+ *
17356+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
17357+ *
17358+ * This program is free software; you can redistribute it and/or modify *
17359+ * it under the terms of the GNU General Public License as published by *
17360+ * the Free Software Foundation; either version 2 of the License, or *
17361+ * (at your option) any later version. *
17362+ * *
17363+ * This program is distributed in the hope that it will be useful, *
17364+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17365+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17366+ * GNU General Public License for more details. *
17367+ * *
17368+ * You should have received a copy of the GNU General Public License *
17369+ * along with this program; if not, write to the *
17370+ * Free Software Foundation, Inc., *
17371+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
17372+ * *
17373+ *************************************************************************
17374+
17375+ Module Name:
17376+ sync.c
17377+
17378+ Abstract:
17379+
17380+ Revision History:
17381+ Who When What
17382+ -------- ---------- ----------------------------------------------
17383+ John Chang 2004-09-01 modified for rt2561/2661
17384+*/
17385+#include "../rt_config.h"
17386+
17387+// 2.4 Ghz channel plan index in the TxPower arrays.
17388+#define BG_BAND_REGION_0_START 0 // 1,2,3,4,5,6,7,8,9,10,11
17389+#define BG_BAND_REGION_0_SIZE 11
17390+#define BG_BAND_REGION_1_START 0 // 1,2,3,4,5,6,7,8,9,10,11,12,13
17391+#define BG_BAND_REGION_1_SIZE 13
17392+#define BG_BAND_REGION_2_START 9 // 10,11
17393+#define BG_BAND_REGION_2_SIZE 2
17394+#define BG_BAND_REGION_3_START 9 // 10,11,12,13
17395+#define BG_BAND_REGION_3_SIZE 4
17396+#define BG_BAND_REGION_4_START 13 // 14
17397+#define BG_BAND_REGION_4_SIZE 1
17398+#define BG_BAND_REGION_5_START 0 // 1,2,3,4,5,6,7,8,9,10,11,12,13,14
17399+#define BG_BAND_REGION_5_SIZE 14
17400+#define BG_BAND_REGION_6_START 2 // 3,4,5,6,7,8,9
17401+#define BG_BAND_REGION_6_SIZE 7
17402+#define BG_BAND_REGION_7_START 4 // 5,6,7,8,9,10,11,12,13
17403+#define BG_BAND_REGION_7_SIZE 9
17404+#define BG_BAND_REGION_31_START 0 // 1,2,3,4,5,6,7,8,9,10,11,12,13,14
17405+#define BG_BAND_REGION_31_SIZE 14
17406+
17407+// 5 Ghz channel plan index in the TxPower arrays.
17408+UCHAR A_BAND_REGION_0_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165};
17409+UCHAR A_BAND_REGION_1_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
17410+UCHAR A_BAND_REGION_2_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64};
17411+UCHAR A_BAND_REGION_3_CHANNEL_LIST[]={52, 56, 60, 64, 149, 153, 157, 161};
17412+UCHAR A_BAND_REGION_4_CHANNEL_LIST[]={149, 153, 157, 161, 165};
17413+UCHAR A_BAND_REGION_5_CHANNEL_LIST[]={149, 153, 157, 161};
17414+UCHAR A_BAND_REGION_6_CHANNEL_LIST[]={36, 40, 44, 48};
17415+UCHAR A_BAND_REGION_7_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165};
17416+UCHAR A_BAND_REGION_8_CHANNEL_LIST[]={52, 56, 60, 64};
17417+UCHAR A_BAND_REGION_9_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165};
17418+UCHAR A_BAND_REGION_10_CHANNEL_LIST[]={36, 40, 44, 48, 149, 153, 157, 161, 165};
17419+UCHAR A_BAND_REGION_11_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153, 157, 161};
17420+
17421+//BaSizeArray follows the 802.11n definition as MaxRxFactor. 2^(13+factor) bytes. When factor =0, it's about Ba buffer size =8.
17422+UCHAR BaSizeArray[4] = {8,16,32,64};
17423+
17424+/*
17425+ ==========================================================================
17426+ Description:
17427+ Update StaCfg->ChannelList[] according to 1) Country Region 2) RF IC type,
17428+ and 3) PHY-mode user selected.
17429+ The outcome is used by driver when doing site survey.
17430+
17431+ IRQL = PASSIVE_LEVEL
17432+ IRQL = DISPATCH_LEVEL
17433+
17434+ ==========================================================================
17435+ */
17436+VOID BuildChannelList(
17437+ IN PRTMP_ADAPTER pAd)
17438+{
17439+ UCHAR i, j, index=0, num=0;
17440+ PUCHAR pChannelList = NULL;
17441+
17442+ NdisZeroMemory(pAd->ChannelList, MAX_NUM_OF_CHANNELS * sizeof(CHANNEL_TX_POWER));
17443+
17444+ // if not 11a-only mode, channel list starts from 2.4Ghz band
17445+ if ((pAd->CommonCfg.PhyMode != PHY_11A)
17446+#ifdef DOT11_N_SUPPORT
17447+ && (pAd->CommonCfg.PhyMode != PHY_11AN_MIXED) && (pAd->CommonCfg.PhyMode != PHY_11N_5G)
17448+#endif // DOT11_N_SUPPORT //
17449+ )
17450+ {
17451+ switch (pAd->CommonCfg.CountryRegion & 0x7f)
17452+ {
17453+ case REGION_0_BG_BAND: // 1 -11
17454+ NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_0_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_0_SIZE);
17455+ index += BG_BAND_REGION_0_SIZE;
17456+ break;
17457+ case REGION_1_BG_BAND: // 1 - 13
17458+ NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_1_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_1_SIZE);
17459+ index += BG_BAND_REGION_1_SIZE;
17460+ break;
17461+ case REGION_2_BG_BAND: // 10 - 11
17462+ NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_2_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_2_SIZE);
17463+ index += BG_BAND_REGION_2_SIZE;
17464+ break;
17465+ case REGION_3_BG_BAND: // 10 - 13
17466+ NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_3_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_3_SIZE);
17467+ index += BG_BAND_REGION_3_SIZE;
17468+ break;
17469+ case REGION_4_BG_BAND: // 14
17470+ NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_4_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_4_SIZE);
17471+ index += BG_BAND_REGION_4_SIZE;
17472+ break;
17473+ case REGION_5_BG_BAND: // 1 - 14
17474+ NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_5_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_5_SIZE);
17475+ index += BG_BAND_REGION_5_SIZE;
17476+ break;
17477+ case REGION_6_BG_BAND: // 3 - 9
17478+ NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_6_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_6_SIZE);
17479+ index += BG_BAND_REGION_6_SIZE;
17480+ break;
17481+ case REGION_7_BG_BAND: // 5 - 13
17482+ NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_7_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_7_SIZE);
17483+ index += BG_BAND_REGION_7_SIZE;
17484+ break;
17485+ case REGION_31_BG_BAND: // 1 - 14
17486+ NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_31_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_31_SIZE);
17487+ index += BG_BAND_REGION_31_SIZE;
17488+ break;
17489+ default: // Error. should never happen
17490+ break;
17491+ }
17492+ for (i=0; i<index; i++)
17493+ pAd->ChannelList[i].MaxTxPwr = 20;
17494+ }
17495+
17496+ if ((pAd->CommonCfg.PhyMode == PHY_11A) || (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
17497+#ifdef DOT11_N_SUPPORT
17498+ || (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11AN_MIXED)
17499+ || (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)
17500+#endif // DOT11_N_SUPPORT //
17501+ )
17502+ {
17503+ switch (pAd->CommonCfg.CountryRegionForABand & 0x7f)
17504+ {
17505+ case REGION_0_A_BAND:
17506+ num = sizeof(A_BAND_REGION_0_CHANNEL_LIST)/sizeof(UCHAR);
17507+ pChannelList = A_BAND_REGION_0_CHANNEL_LIST;
17508+ break;
17509+ case REGION_1_A_BAND:
17510+ num = sizeof(A_BAND_REGION_1_CHANNEL_LIST)/sizeof(UCHAR);
17511+ pChannelList = A_BAND_REGION_1_CHANNEL_LIST;
17512+ break;
17513+ case REGION_2_A_BAND:
17514+ num = sizeof(A_BAND_REGION_2_CHANNEL_LIST)/sizeof(UCHAR);
17515+ pChannelList = A_BAND_REGION_2_CHANNEL_LIST;
17516+ break;
17517+ case REGION_3_A_BAND:
17518+ num = sizeof(A_BAND_REGION_3_CHANNEL_LIST)/sizeof(UCHAR);
17519+ pChannelList = A_BAND_REGION_3_CHANNEL_LIST;
17520+ break;
17521+ case REGION_4_A_BAND:
17522+ num = sizeof(A_BAND_REGION_4_CHANNEL_LIST)/sizeof(UCHAR);
17523+ pChannelList = A_BAND_REGION_4_CHANNEL_LIST;
17524+ break;
17525+ case REGION_5_A_BAND:
17526+ num = sizeof(A_BAND_REGION_5_CHANNEL_LIST)/sizeof(UCHAR);
17527+ pChannelList = A_BAND_REGION_5_CHANNEL_LIST;
17528+ break;
17529+ case REGION_6_A_BAND:
17530+ num = sizeof(A_BAND_REGION_6_CHANNEL_LIST)/sizeof(UCHAR);
17531+ pChannelList = A_BAND_REGION_6_CHANNEL_LIST;
17532+ break;
17533+ case REGION_7_A_BAND:
17534+ num = sizeof(A_BAND_REGION_7_CHANNEL_LIST)/sizeof(UCHAR);
17535+ pChannelList = A_BAND_REGION_7_CHANNEL_LIST;
17536+ break;
17537+ case REGION_8_A_BAND:
17538+ num = sizeof(A_BAND_REGION_8_CHANNEL_LIST)/sizeof(UCHAR);
17539+ pChannelList = A_BAND_REGION_8_CHANNEL_LIST;
17540+ break;
17541+ case REGION_9_A_BAND:
17542+ num = sizeof(A_BAND_REGION_9_CHANNEL_LIST)/sizeof(UCHAR);
17543+ pChannelList = A_BAND_REGION_9_CHANNEL_LIST;
17544+ break;
17545+
17546+ case REGION_10_A_BAND:
17547+ num = sizeof(A_BAND_REGION_10_CHANNEL_LIST)/sizeof(UCHAR);
17548+ pChannelList = A_BAND_REGION_10_CHANNEL_LIST;
17549+ break;
17550+
17551+ case REGION_11_A_BAND:
17552+ num = sizeof(A_BAND_REGION_11_CHANNEL_LIST)/sizeof(UCHAR);
17553+ pChannelList = A_BAND_REGION_11_CHANNEL_LIST;
17554+ break;
17555+
17556+ default: // Error. should never happen
17557+ DBGPRINT(RT_DEBUG_WARN,("countryregion=%d not support", pAd->CommonCfg.CountryRegionForABand));
17558+ break;
17559+ }
17560+
17561+ if (num != 0)
17562+ {
17563+ UCHAR RadarCh[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
17564+ for (i=0; i<num; i++)
17565+ {
17566+ for (j=0; j<MAX_NUM_OF_CHANNELS; j++)
17567+ {
17568+ if (pChannelList[i] == pAd->TxPower[j].Channel)
17569+ NdisMoveMemory(&pAd->ChannelList[index+i], &pAd->TxPower[j], sizeof(CHANNEL_TX_POWER));
17570+ }
17571+ for (j=0; j<15; j++)
17572+ {
17573+ if (pChannelList[i] == RadarCh[j])
17574+ pAd->ChannelList[index+i].DfsReq = TRUE;
17575+ }
17576+ pAd->ChannelList[index+i].MaxTxPwr = 20;
17577+ }
17578+ index += num;
17579+ }
17580+ }
17581+
17582+ pAd->ChannelListNum = index;
17583+ DBGPRINT(RT_DEBUG_TRACE,("country code=%d/%d, RFIC=%d, PHY mode=%d, support %d channels\n",
17584+ pAd->CommonCfg.CountryRegion, pAd->CommonCfg.CountryRegionForABand, pAd->RfIcType, pAd->CommonCfg.PhyMode, pAd->ChannelListNum));
17585+#ifdef DBG
17586+ for (i=0;i<pAd->ChannelListNum;i++)
17587+ {
17588+ DBGPRINT_RAW(RT_DEBUG_TRACE,("BuildChannel # %d :: Pwr0 = %d, Pwr1 =%d, \n ", pAd->ChannelList[i].Channel, pAd->ChannelList[i].Power, pAd->ChannelList[i].Power2));
17589+ }
17590+#endif
17591+}
17592+
17593+/*
17594+ ==========================================================================
17595+ Description:
17596+ This routine return the first channel number according to the country
17597+ code selection and RF IC selection (signal band or dual band). It is called
17598+ whenever driver need to start a site survey of all supported channels.
17599+ Return:
17600+ ch - the first channel number of current country code setting
17601+
17602+ IRQL = PASSIVE_LEVEL
17603+
17604+ ==========================================================================
17605+ */
17606+UCHAR FirstChannel(
17607+ IN PRTMP_ADAPTER pAd)
17608+{
17609+ return pAd->ChannelList[0].Channel;
17610+}
17611+
17612+/*
17613+ ==========================================================================
17614+ Description:
17615+ This routine returns the next channel number. This routine is called
17616+ during driver need to start a site survey of all supported channels.
17617+ Return:
17618+ next_channel - the next channel number valid in current country code setting.
17619+ Note:
17620+ return 0 if no more next channel
17621+ ==========================================================================
17622+ */
17623+UCHAR NextChannel(
17624+ IN PRTMP_ADAPTER pAd,
17625+ IN UCHAR channel)
17626+{
17627+ int i;
17628+ UCHAR next_channel = 0;
17629+
17630+ for (i = 0; i < (pAd->ChannelListNum - 1); i++)
17631+ if (channel == pAd->ChannelList[i].Channel)
17632+ {
17633+ next_channel = pAd->ChannelList[i+1].Channel;
17634+ break;
17635+ }
17636+ return next_channel;
17637+}
17638+
17639+/*
17640+ ==========================================================================
17641+ Description:
17642+ This routine is for Cisco Compatible Extensions 2.X
17643+ Spec31. AP Control of Client Transmit Power
17644+ Return:
17645+ None
17646+ Note:
17647+ Required by Aironet dBm(mW)
17648+ 0dBm(1mW), 1dBm(5mW), 13dBm(20mW), 15dBm(30mW),
17649+ 17dBm(50mw), 20dBm(100mW)
17650+
17651+ We supported
17652+ 3dBm(Lowest), 6dBm(10%), 9dBm(25%), 12dBm(50%),
17653+ 14dBm(75%), 15dBm(100%)
17654+
17655+ The client station's actual transmit power shall be within +/- 5dB of
17656+ the minimum value or next lower value.
17657+ ==========================================================================
17658+ */
17659+VOID ChangeToCellPowerLimit(
17660+ IN PRTMP_ADAPTER pAd,
17661+ IN UCHAR AironetCellPowerLimit)
17662+{
17663+ //valud 0xFF means that hasn't found power limit information
17664+ //from the AP's Beacon/Probe response.
17665+ if (AironetCellPowerLimit == 0xFF)
17666+ return;
17667+
17668+ if (AironetCellPowerLimit < 6) //Used Lowest Power Percentage.
17669+ pAd->CommonCfg.TxPowerPercentage = 6;
17670+ else if (AironetCellPowerLimit < 9)
17671+ pAd->CommonCfg.TxPowerPercentage = 10;
17672+ else if (AironetCellPowerLimit < 12)
17673+ pAd->CommonCfg.TxPowerPercentage = 25;
17674+ else if (AironetCellPowerLimit < 14)
17675+ pAd->CommonCfg.TxPowerPercentage = 50;
17676+ else if (AironetCellPowerLimit < 15)
17677+ pAd->CommonCfg.TxPowerPercentage = 75;
17678+ else
17679+ pAd->CommonCfg.TxPowerPercentage = 100; //else used maximum
17680+
17681+ if (pAd->CommonCfg.TxPowerPercentage > pAd->CommonCfg.TxPowerDefault)
17682+ pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
17683+
17684+}
17685+
17686+CHAR ConvertToRssi(
17687+ IN PRTMP_ADAPTER pAd,
17688+ IN CHAR Rssi,
17689+ IN UCHAR RssiNumber)
17690+{
17691+ UCHAR RssiOffset, LNAGain;
17692+
17693+ // Rssi equals to zero should be an invalid value
17694+ if (Rssi == 0)
17695+ return -99;
17696+
17697+ LNAGain = GET_LNA_GAIN(pAd);
17698+ if (pAd->LatchRfRegs.Channel > 14)
17699+ {
17700+ if (RssiNumber == 0)
17701+ RssiOffset = pAd->ARssiOffset0;
17702+ else if (RssiNumber == 1)
17703+ RssiOffset = pAd->ARssiOffset1;
17704+ else
17705+ RssiOffset = pAd->ARssiOffset2;
17706+ }
17707+ else
17708+ {
17709+ if (RssiNumber == 0)
17710+ RssiOffset = pAd->BGRssiOffset0;
17711+ else if (RssiNumber == 1)
17712+ RssiOffset = pAd->BGRssiOffset1;
17713+ else
17714+ RssiOffset = pAd->BGRssiOffset2;
17715+ }
17716+
17717+ return (-12 - RssiOffset - LNAGain - Rssi);
17718+}
17719+
17720+/*
17721+ ==========================================================================
17722+ Description:
17723+ Scan next channel
17724+ ==========================================================================
17725+ */
17726+VOID ScanNextChannel(
17727+ IN PRTMP_ADAPTER pAd)
17728+{
17729+ HEADER_802_11 Hdr80211;
17730+ PUCHAR pOutBuffer = NULL;
17731+ NDIS_STATUS NStatus;
17732+ ULONG FrameLen = 0;
17733+ UCHAR SsidLen = 0, ScanType = pAd->MlmeAux.ScanType, BBPValue = 0;
17734+#ifdef CONFIG_STA_SUPPORT
17735+ USHORT Status;
17736+ PHEADER_802_11 pHdr80211;
17737+#endif // CONFIG_STA_SUPPORT //
17738+ UINT ScanTimeIn5gChannel = SHORT_CHANNEL_TIME;
17739+
17740+#ifdef CONFIG_STA_SUPPORT
17741+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
17742+ {
17743+ if (MONITOR_ON(pAd))
17744+ return;
17745+ }
17746+#endif // CONFIG_STA_SUPPORT //
17747+
17748+#ifdef RALINK_ATE
17749+ // Nothing to do in ATE mode.
17750+ if (ATE_ON(pAd))
17751+ return;
17752+#endif // RALINK_ATE //
17753+
17754+ if (pAd->MlmeAux.Channel == 0)
17755+ {
17756+ if ((pAd->CommonCfg.BBPCurrentBW == BW_40)
17757+#ifdef CONFIG_STA_SUPPORT
17758+ && (INFRA_ON(pAd)
17759+ || (pAd->OpMode == OPMODE_AP))
17760+#endif // CONFIG_STA_SUPPORT //
17761+ )
17762+ {
17763+ AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
17764+ AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
17765+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
17766+ BBPValue &= (~0x18);
17767+ BBPValue |= 0x10;
17768+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
17769+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",pAd->CommonCfg.CentralChannel, pAd->ScanTab.BssNr));
17770+ }
17771+ else
17772+ {
17773+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
17774+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
17775+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to channel %d, Total BSS[%02d]\n",pAd->CommonCfg.Channel, pAd->ScanTab.BssNr));
17776+ }
17777+
17778+#ifdef CONFIG_STA_SUPPORT
17779+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
17780+ {
17781+ //
17782+ // To prevent data lost.
17783+ // Send an NULL data with turned PSM bit on to current associated AP before SCAN progress.
17784+ // Now, we need to send an NULL data with turned PSM bit off to AP, when scan progress done
17785+ //
17786+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (INFRA_ON(pAd)))
17787+ {
17788+ NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);
17789+ if (NStatus == NDIS_STATUS_SUCCESS)
17790+ {
17791+ pHdr80211 = (PHEADER_802_11) pOutBuffer;
17792+ MgtMacHeaderInit(pAd, pHdr80211, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
17793+ pHdr80211->Duration = 0;
17794+ pHdr80211->FC.Type = BTYPE_DATA;
17795+ pHdr80211->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
17796+
17797+ // Send using priority queue
17798+ MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
17799+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqAction -- Send PSM Data frame\n"));
17800+ MlmeFreeMemory(pAd, pOutBuffer);
17801+ RTMPusecDelay(5000);
17802+ }
17803+ }
17804+
17805+ pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
17806+ Status = MLME_SUCCESS;
17807+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
17808+ }
17809+#endif // CONFIG_STA_SUPPORT //
17810+
17811+
17812+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
17813+ }
17814+#ifdef RT2870
17815+#ifdef CONFIG_STA_SUPPORT
17816+ else if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) && (pAd->OpMode == OPMODE_STA))
17817+ {
17818+ pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
17819+ MlmeCntlConfirm(pAd, MT2_SCAN_CONF, MLME_FAIL_NO_RESOURCE);
17820+ }
17821+#endif // CONFIG_STA_SUPPORT //
17822+#endif // RT2870 //
17823+ else
17824+ {
17825+#ifdef CONFIG_STA_SUPPORT
17826+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
17827+ {
17828+ // BBP and RF are not accessible in PS mode, we has to wake them up first
17829+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
17830+ AsicForceWakeup(pAd, TRUE);
17831+
17832+ // leave PSM during scanning. otherwise we may lost ProbeRsp & BEACON
17833+ if (pAd->StaCfg.Psm == PWR_SAVE)
17834+ MlmeSetPsmBit(pAd, PWR_ACTIVE);
17835+ }
17836+#endif // CONFIG_STA_SUPPORT //
17837+
17838+ AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, TRUE);
17839+ AsicLockChannel(pAd, pAd->MlmeAux.Channel);
17840+
17841+#ifdef CONFIG_STA_SUPPORT
17842+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
17843+ {
17844+ if (pAd->MlmeAux.Channel > 14)
17845+ {
17846+ if ((pAd->CommonCfg.bIEEE80211H == 1) && RadarChannelCheck(pAd, pAd->MlmeAux.Channel))
17847+ {
17848+ ScanType = SCAN_PASSIVE;
17849+ ScanTimeIn5gChannel = MIN_CHANNEL_TIME;
17850+ }
17851+ }
17852+
17853+#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
17854+ // carrier detection
17855+ if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
17856+ {
17857+ ScanType = SCAN_PASSIVE;
17858+ ScanTimeIn5gChannel = MIN_CHANNEL_TIME;
17859+ }
17860+#endif // CARRIER_DETECTION_SUPPORT //
17861+ }
17862+
17863+#endif // CONFIG_STA_SUPPORT //
17864+
17865+ //Global country domain(ch1-11:active scan, ch12-14 passive scan)
17866+ if ((pAd->MlmeAux.Channel <= 14) && (pAd->MlmeAux.Channel >= 12) && ((pAd->CommonCfg.CountryRegion & 0x7f) == REGION_31_BG_BAND))
17867+ {
17868+ ScanType = SCAN_PASSIVE;
17869+ }
17870+
17871+ // We need to shorten active scan time in order for WZC connect issue
17872+ // Chnage the channel scan time for CISCO stuff based on its IAPP announcement
17873+ if (ScanType == FAST_SCAN_ACTIVE)
17874+ RTMPSetTimer(&pAd->MlmeAux.ScanTimer, FAST_ACTIVE_SCAN_TIME);
17875+#ifdef CONFIG_STA_SUPPORT
17876+ else if (((ScanType == SCAN_CISCO_ACTIVE) ||
17877+ (ScanType == SCAN_CISCO_PASSIVE) ||
17878+ (ScanType == SCAN_CISCO_CHANNEL_LOAD) ||
17879+ (ScanType == SCAN_CISCO_NOISE)) && (pAd->OpMode == OPMODE_STA))
17880+ {
17881+ if (pAd->StaCfg.CCXScanTime < 25)
17882+ RTMPSetTimer(&pAd->MlmeAux.ScanTimer, pAd->StaCfg.CCXScanTime * 2);
17883+ else
17884+ RTMPSetTimer(&pAd->MlmeAux.ScanTimer, pAd->StaCfg.CCXScanTime);
17885+ }
17886+#endif // CONFIG_STA_SUPPORT //
17887+ else // must be SCAN_PASSIVE or SCAN_ACTIVE
17888+ {
17889+ if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
17890+#ifdef DOT11_N_SUPPORT
17891+ || (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED)
17892+#endif // DOT11_N_SUPPORT //
17893+ )
17894+ {
17895+ if (pAd->MlmeAux.Channel > 14)
17896+ RTMPSetTimer(&pAd->MlmeAux.ScanTimer, ScanTimeIn5gChannel);
17897+ else
17898+ RTMPSetTimer(&pAd->MlmeAux.ScanTimer, MIN_CHANNEL_TIME);
17899+ }
17900+ else
17901+ RTMPSetTimer(&pAd->MlmeAux.ScanTimer, MAX_CHANNEL_TIME);
17902+ }
17903+
17904+ if ((ScanType == SCAN_ACTIVE) || (ScanType == FAST_SCAN_ACTIVE) ||
17905+ (ScanType == SCAN_CISCO_ACTIVE))
17906+ {
17907+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
17908+ if (NStatus != NDIS_STATUS_SUCCESS)
17909+ {
17910+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - ScanNextChannel() allocate memory fail\n"));
17911+#ifdef CONFIG_STA_SUPPORT
17912+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
17913+ {
17914+ pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
17915+ Status = MLME_FAIL_NO_RESOURCE;
17916+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
17917+ }
17918+#endif // CONFIG_STA_SUPPORT //
17919+
17920+ return;
17921+ }
17922+
17923+ // There is no need to send broadcast probe request if active scan is in effect.
17924+ if ((ScanType == SCAN_ACTIVE) || (ScanType == FAST_SCAN_ACTIVE)
17925+ )
17926+ SsidLen = pAd->MlmeAux.SsidLen;
17927+ else
17928+ SsidLen = 0;
17929+
17930+ MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
17931+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
17932+ sizeof(HEADER_802_11), &Hdr80211,
17933+ 1, &SsidIe,
17934+ 1, &SsidLen,
17935+ SsidLen, pAd->MlmeAux.Ssid,
17936+ 1, &SupRateIe,
17937+ 1, &pAd->CommonCfg.SupRateLen,
17938+ pAd->CommonCfg.SupRateLen, pAd->CommonCfg.SupRate,
17939+ END_OF_ARGS);
17940+
17941+ if (pAd->CommonCfg.ExtRateLen)
17942+ {
17943+ ULONG Tmp;
17944+ MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
17945+ 1, &ExtRateIe,
17946+ 1, &pAd->CommonCfg.ExtRateLen,
17947+ pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRate,
17948+ END_OF_ARGS);
17949+ FrameLen += Tmp;
17950+ }
17951+
17952+#ifdef DOT11_N_SUPPORT
17953+ if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
17954+ {
17955+ ULONG Tmp;
17956+ UCHAR HtLen;
17957+ UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
17958+#ifdef RT_BIG_ENDIAN
17959+ HT_CAPABILITY_IE HtCapabilityTmp;
17960+#endif
17961+ if (pAd->bBroadComHT == TRUE)
17962+ {
17963+ HtLen = pAd->MlmeAux.HtCapabilityLen + 4;
17964+#ifdef RT_BIG_ENDIAN
17965+ NdisMoveMemory(&HtCapabilityTmp, &pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
17966+ *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
17967+ *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
17968+
17969+ MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
17970+ 1, &WpaIe,
17971+ 1, &HtLen,
17972+ 4, &BROADCOM[0],
17973+ pAd->MlmeAux.HtCapabilityLen, &HtCapabilityTmp,
17974+ END_OF_ARGS);
17975+#else
17976+ MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
17977+ 1, &WpaIe,
17978+ 1, &HtLen,
17979+ 4, &BROADCOM[0],
17980+ pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability,
17981+ END_OF_ARGS);
17982+#endif // RT_BIG_ENDIAN //
17983+ }
17984+ else
17985+ {
17986+ HtLen = pAd->MlmeAux.HtCapabilityLen;
17987+#ifdef RT_BIG_ENDIAN
17988+ NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, SIZE_HT_CAP_IE);
17989+ *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
17990+ *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
17991+
17992+ MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
17993+ 1, &HtCapIe,
17994+ 1, &HtLen,
17995+ HtLen, &HtCapabilityTmp,
17996+ END_OF_ARGS);
17997+#else
17998+ MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
17999+ 1, &HtCapIe,
18000+ 1, &HtLen,
18001+ HtLen, &pAd->CommonCfg.HtCapability,
18002+ END_OF_ARGS);
18003+#endif // RT_BIG_ENDIAN //
18004+ }
18005+ FrameLen += Tmp;
18006+
18007+#ifdef DOT11N_DRAFT3
18008+ if (pAd->CommonCfg.BACapability.field.b2040CoexistScanSup == 1)
18009+ {
18010+ ULONG Tmp;
18011+ HtLen = 1;
18012+ MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
18013+ 1, &ExtHtCapIe,
18014+ 1, &HtLen,
18015+ 1, &pAd->CommonCfg.BSSCoexist2040.word,
18016+ END_OF_ARGS);
18017+
18018+ FrameLen += Tmp;
18019+ }
18020+#endif // DOT11N_DRAFT3 //
18021+ }
18022+#endif // DOT11_N_SUPPORT //
18023+
18024+
18025+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
18026+ MlmeFreeMemory(pAd, pOutBuffer);
18027+ }
18028+
18029+ // For SCAN_CISCO_PASSIVE, do nothing and silently wait for beacon or other probe reponse
18030+
18031+#ifdef CONFIG_STA_SUPPORT
18032+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
18033+ pAd->Mlme.SyncMachine.CurrState = SCAN_LISTEN;
18034+#endif // CONFIG_STA_SUPPORT //
18035+
18036+ }
18037+}
18038+
18039+VOID MgtProbReqMacHeaderInit(
18040+ IN PRTMP_ADAPTER pAd,
18041+ IN OUT PHEADER_802_11 pHdr80211,
18042+ IN UCHAR SubType,
18043+ IN UCHAR ToDs,
18044+ IN PUCHAR pDA,
18045+ IN PUCHAR pBssid)
18046+{
18047+ NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
18048+
18049+ pHdr80211->FC.Type = BTYPE_MGMT;
18050+ pHdr80211->FC.SubType = SubType;
18051+ if (SubType == SUBTYPE_ACK)
18052+ pHdr80211->FC.Type = BTYPE_CNTL;
18053+ pHdr80211->FC.ToDs = ToDs;
18054+ COPY_MAC_ADDR(pHdr80211->Addr1, pDA);
18055+ COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
18056+ COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
18057+}
18058+
18059+
18060--- /dev/null
18061+++ b/drivers/staging/rt3070/common/cmm_wpa.c
18062@@ -0,0 +1,1606 @@
18063+/*
18064+ *************************************************************************
18065+ * Ralink Tech Inc.
18066+ * 5F., No.36, Taiyuan St., Jhubei City,
18067+ * Hsinchu County 302,
18068+ * Taiwan, R.O.C.
18069+ *
18070+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
18071+ *
18072+ * This program is free software; you can redistribute it and/or modify *
18073+ * it under the terms of the GNU General Public License as published by *
18074+ * the Free Software Foundation; either version 2 of the License, or *
18075+ * (at your option) any later version. *
18076+ * *
18077+ * This program is distributed in the hope that it will be useful, *
18078+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18079+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18080+ * GNU General Public License for more details. *
18081+ * *
18082+ * You should have received a copy of the GNU General Public License *
18083+ * along with this program; if not, write to the *
18084+ * Free Software Foundation, Inc., *
18085+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18086+ * *
18087+ *************************************************************************
18088+
18089+ Module Name:
18090+ wpa.c
18091+
18092+ Abstract:
18093+
18094+ Revision History:
18095+ Who When What
18096+ -------- ---------- ----------------------------------------------
18097+ Jan Lee 03-07-22 Initial
18098+ Paul Lin 03-11-28 Modify for supplicant
18099+*/
18100+#include "../rt_config.h"
18101+// WPA OUI
18102+UCHAR OUI_WPA_NONE_AKM[4] = {0x00, 0x50, 0xF2, 0x00};
18103+UCHAR OUI_WPA_VERSION[4] = {0x00, 0x50, 0xF2, 0x01};
18104+UCHAR OUI_WPA_TKIP[4] = {0x00, 0x50, 0xF2, 0x02};
18105+UCHAR OUI_WPA_CCMP[4] = {0x00, 0x50, 0xF2, 0x04};
18106+UCHAR OUI_WPA_8021X_AKM[4] = {0x00, 0x50, 0xF2, 0x01};
18107+UCHAR OUI_WPA_PSK_AKM[4] = {0x00, 0x50, 0xF2, 0x02};
18108+// WPA2 OUI
18109+UCHAR OUI_WPA2_WEP40[4] = {0x00, 0x0F, 0xAC, 0x01};
18110+UCHAR OUI_WPA2_TKIP[4] = {0x00, 0x0F, 0xAC, 0x02};
18111+UCHAR OUI_WPA2_CCMP[4] = {0x00, 0x0F, 0xAC, 0x04};
18112+UCHAR OUI_WPA2_8021X_AKM[4] = {0x00, 0x0F, 0xAC, 0x01};
18113+UCHAR OUI_WPA2_PSK_AKM[4] = {0x00, 0x0F, 0xAC, 0x02};
18114+// MSA OUI
18115+UCHAR OUI_MSA_8021X_AKM[4] = {0x00, 0x0F, 0xAC, 0x05}; // Not yet final - IEEE 802.11s-D1.06
18116+UCHAR OUI_MSA_PSK_AKM[4] = {0x00, 0x0F, 0xAC, 0x06}; // Not yet final - IEEE 802.11s-D1.06
18117+
18118+/*
18119+ ========================================================================
18120+
18121+ Routine Description:
18122+ The pseudo-random function(PRF) that hashes various inputs to
18123+ derive a pseudo-random value. To add liveness to the pseudo-random
18124+ value, a nonce should be one of the inputs.
18125+
18126+ It is used to generate PTK, GTK or some specific random value.
18127+
18128+ Arguments:
18129+ UCHAR *key, - the key material for HMAC_SHA1 use
18130+ INT key_len - the length of key
18131+ UCHAR *prefix - a prefix label
18132+ INT prefix_len - the length of the label
18133+ UCHAR *data - a specific data with variable length
18134+ INT data_len - the length of a specific data
18135+ INT len - the output lenght
18136+
18137+ Return Value:
18138+ UCHAR *output - the calculated result
18139+
18140+ Note:
18141+ 802.11i-2004 Annex H.3
18142+
18143+ ========================================================================
18144+*/
18145+VOID PRF(
18146+ IN UCHAR *key,
18147+ IN INT key_len,
18148+ IN UCHAR *prefix,
18149+ IN INT prefix_len,
18150+ IN UCHAR *data,
18151+ IN INT data_len,
18152+ OUT UCHAR *output,
18153+ IN INT len)
18154+{
18155+ INT i;
18156+ UCHAR *input;
18157+ INT currentindex = 0;
18158+ INT total_len;
18159+
18160+ // Allocate memory for input
18161+ os_alloc_mem(NULL, (PUCHAR *)&input, 1024);
18162+
18163+ if (input == NULL)
18164+ {
18165+ DBGPRINT(RT_DEBUG_ERROR, ("!!!PRF: no memory!!!\n"));
18166+ return;
18167+ }
18168+
18169+ // Generate concatenation input
18170+ NdisMoveMemory(input, prefix, prefix_len);
18171+
18172+ // Concatenate a single octet containing 0
18173+ input[prefix_len] = 0;
18174+
18175+ // Concatenate specific data
18176+ NdisMoveMemory(&input[prefix_len + 1], data, data_len);
18177+ total_len = prefix_len + 1 + data_len;
18178+
18179+ // Concatenate a single octet containing 0
18180+ // This octet shall be update later
18181+ input[total_len] = 0;
18182+ total_len++;
18183+
18184+ // Iterate to calculate the result by hmac-sha-1
18185+ // Then concatenate to last result
18186+ for (i = 0; i < (len + 19) / 20; i++)
18187+ {
18188+ HMAC_SHA1(input, total_len, key, key_len, &output[currentindex]);
18189+ currentindex += 20;
18190+
18191+ // update the last octet
18192+ input[total_len - 1]++;
18193+ }
18194+ os_free_mem(NULL, input);
18195+}
18196+
18197+/*
18198+ ========================================================================
18199+
18200+ Routine Description:
18201+ It utilizes PRF-384 or PRF-512 to derive session-specific keys from a PMK.
18202+ It shall be called by 4-way handshake processing.
18203+
18204+ Arguments:
18205+ pAd - pointer to our pAdapter context
18206+ PMK - pointer to PMK
18207+ ANonce - pointer to ANonce
18208+ AA - pointer to Authenticator Address
18209+ SNonce - pointer to SNonce
18210+ SA - pointer to Supplicant Address
18211+ len - indicate the length of PTK (octet)
18212+
18213+ Return Value:
18214+ Output pointer to the PTK
18215+
18216+ Note:
18217+ Refer to IEEE 802.11i-2004 8.5.1.2
18218+
18219+ ========================================================================
18220+*/
18221+VOID WpaCountPTK(
18222+ IN PRTMP_ADAPTER pAd,
18223+ IN UCHAR *PMK,
18224+ IN UCHAR *ANonce,
18225+ IN UCHAR *AA,
18226+ IN UCHAR *SNonce,
18227+ IN UCHAR *SA,
18228+ OUT UCHAR *output,
18229+ IN UINT len)
18230+{
18231+ UCHAR concatenation[76];
18232+ UINT CurrPos = 0;
18233+ UCHAR temp[32];
18234+ UCHAR Prefix[] = {'P', 'a', 'i', 'r', 'w', 'i', 's', 'e', ' ', 'k', 'e', 'y', ' ',
18235+ 'e', 'x', 'p', 'a', 'n', 's', 'i', 'o', 'n'};
18236+
18237+ // initiate the concatenation input
18238+ NdisZeroMemory(temp, sizeof(temp));
18239+ NdisZeroMemory(concatenation, 76);
18240+
18241+ // Get smaller address
18242+ if (RTMPCompareMemory(SA, AA, 6) == 1)
18243+ NdisMoveMemory(concatenation, AA, 6);
18244+ else
18245+ NdisMoveMemory(concatenation, SA, 6);
18246+ CurrPos += 6;
18247+
18248+ // Get larger address
18249+ if (RTMPCompareMemory(SA, AA, 6) == 1)
18250+ NdisMoveMemory(&concatenation[CurrPos], SA, 6);
18251+ else
18252+ NdisMoveMemory(&concatenation[CurrPos], AA, 6);
18253+
18254+ // store the larger mac address for backward compatible of
18255+ // ralink proprietary STA-key issue
18256+ NdisMoveMemory(temp, &concatenation[CurrPos], MAC_ADDR_LEN);
18257+ CurrPos += 6;
18258+
18259+ // Get smaller Nonce
18260+ if (RTMPCompareMemory(ANonce, SNonce, 32) == 0)
18261+ NdisMoveMemory(&concatenation[CurrPos], temp, 32); // patch for ralink proprietary STA-key issue
18262+ else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
18263+ NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
18264+ else
18265+ NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
18266+ CurrPos += 32;
18267+
18268+ // Get larger Nonce
18269+ if (RTMPCompareMemory(ANonce, SNonce, 32) == 0)
18270+ NdisMoveMemory(&concatenation[CurrPos], temp, 32); // patch for ralink proprietary STA-key issue
18271+ else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
18272+ NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
18273+ else
18274+ NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
18275+ CurrPos += 32;
18276+
18277+ hex_dump("concatenation=", concatenation, 76);
18278+
18279+ // Use PRF to generate PTK
18280+ PRF(PMK, LEN_MASTER_KEY, Prefix, 22, concatenation, 76, output, len);
18281+
18282+}
18283+
18284+/*
18285+ ========================================================================
18286+
18287+ Routine Description:
18288+ Generate random number by software.
18289+
18290+ Arguments:
18291+ pAd - pointer to our pAdapter context
18292+ macAddr - pointer to local MAC address
18293+
18294+ Return Value:
18295+
18296+ Note:
18297+ 802.1ii-2004 Annex H.5
18298+
18299+ ========================================================================
18300+*/
18301+VOID GenRandom(
18302+ IN PRTMP_ADAPTER pAd,
18303+ IN UCHAR *macAddr,
18304+ OUT UCHAR *random)
18305+{
18306+ INT i, curr;
18307+ UCHAR local[80], KeyCounter[32];
18308+ UCHAR result[80];
18309+ ULONG CurrentTime;
18310+ UCHAR prefix[] = {'I', 'n', 'i', 't', ' ', 'C', 'o', 'u', 'n', 't', 'e', 'r'};
18311+
18312+ // Zero the related information
18313+ NdisZeroMemory(result, 80);
18314+ NdisZeroMemory(local, 80);
18315+ NdisZeroMemory(KeyCounter, 32);
18316+
18317+ for (i = 0; i < 32; i++)
18318+ {
18319+ // copy the local MAC address
18320+ COPY_MAC_ADDR(local, macAddr);
18321+ curr = MAC_ADDR_LEN;
18322+
18323+ // concatenate the current time
18324+ NdisGetSystemUpTime(&CurrentTime);
18325+ NdisMoveMemory(&local[curr], &CurrentTime, sizeof(CurrentTime));
18326+ curr += sizeof(CurrentTime);
18327+
18328+ // concatenate the last result
18329+ NdisMoveMemory(&local[curr], result, 32);
18330+ curr += 32;
18331+
18332+ // concatenate a variable
18333+ NdisMoveMemory(&local[curr], &i, 2);
18334+ curr += 2;
18335+
18336+ // calculate the result
18337+ PRF(KeyCounter, 32, prefix,12, local, curr, result, 32);
18338+ }
18339+
18340+ NdisMoveMemory(random, result, 32);
18341+}
18342+
18343+/*
18344+ ========================================================================
18345+
18346+ Routine Description:
18347+ Build cipher suite in RSN-IE.
18348+ It only shall be called by RTMPMakeRSNIE.
18349+
18350+ Arguments:
18351+ pAd - pointer to our pAdapter context
18352+ ElementID - indicate the WPA1 or WPA2
18353+ WepStatus - indicate the encryption type
18354+ bMixCipher - a boolean to indicate the pairwise cipher and group
18355+ cipher are the same or not
18356+
18357+ Return Value:
18358+
18359+ Note:
18360+
18361+ ========================================================================
18362+*/
18363+static VOID RTMPInsertRsnIeCipher(
18364+ IN PRTMP_ADAPTER pAd,
18365+ IN UCHAR ElementID,
18366+ IN UINT WepStatus,
18367+ IN BOOLEAN bMixCipher,
18368+ IN UCHAR FlexibleCipher,
18369+ OUT PUCHAR pRsnIe,
18370+ OUT UCHAR *rsn_len)
18371+{
18372+ UCHAR PairwiseCnt;
18373+
18374+ *rsn_len = 0;
18375+
18376+ // decide WPA2 or WPA1
18377+ if (ElementID == Wpa2Ie)
18378+ {
18379+ RSNIE2 *pRsnie_cipher = (RSNIE2*)pRsnIe;
18380+
18381+ // Assign the verson as 1
18382+ pRsnie_cipher->version = 1;
18383+
18384+ switch (WepStatus)
18385+ {
18386+ // TKIP mode
18387+ case Ndis802_11Encryption2Enabled:
18388+ NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
18389+ pRsnie_cipher->ucount = 1;
18390+ NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_TKIP, 4);
18391+ *rsn_len = sizeof(RSNIE2);
18392+ break;
18393+
18394+ // AES mode
18395+ case Ndis802_11Encryption3Enabled:
18396+ if (bMixCipher)
18397+ NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
18398+ else
18399+ NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_CCMP, 4);
18400+ pRsnie_cipher->ucount = 1;
18401+ NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_CCMP, 4);
18402+ *rsn_len = sizeof(RSNIE2);
18403+ break;
18404+
18405+ // TKIP-AES mix mode
18406+ case Ndis802_11Encryption4Enabled:
18407+ NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
18408+
18409+ PairwiseCnt = 1;
18410+ // Insert WPA2 TKIP as the first pairwise cipher
18411+ if (MIX_CIPHER_WPA2_TKIP_ON(FlexibleCipher))
18412+ {
18413+ NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_TKIP, 4);
18414+ // Insert WPA2 AES as the secondary pairwise cipher
18415+ if (MIX_CIPHER_WPA2_AES_ON(FlexibleCipher))
18416+ {
18417+ NdisMoveMemory(pRsnie_cipher->ucast[0].oui + 4, OUI_WPA2_CCMP, 4);
18418+ PairwiseCnt = 2;
18419+ }
18420+ }
18421+ else
18422+ {
18423+ // Insert WPA2 AES as the first pairwise cipher
18424+ NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_CCMP, 4);
18425+ }
18426+
18427+ pRsnie_cipher->ucount = PairwiseCnt;
18428+ *rsn_len = sizeof(RSNIE2) + (4 * (PairwiseCnt - 1));
18429+ break;
18430+ }
18431+
18432+ // swap for big-endian platform
18433+ pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
18434+ pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
18435+ }
18436+ else
18437+ {
18438+ RSNIE *pRsnie_cipher = (RSNIE*)pRsnIe;
18439+
18440+ // Assign OUI and version
18441+ NdisMoveMemory(pRsnie_cipher->oui, OUI_WPA_VERSION, 4);
18442+ pRsnie_cipher->version = 1;
18443+
18444+ switch (WepStatus)
18445+ {
18446+ // TKIP mode
18447+ case Ndis802_11Encryption2Enabled:
18448+ NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
18449+ pRsnie_cipher->ucount = 1;
18450+ NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_TKIP, 4);
18451+ *rsn_len = sizeof(RSNIE);
18452+ break;
18453+
18454+ // AES mode
18455+ case Ndis802_11Encryption3Enabled:
18456+ if (bMixCipher)
18457+ NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
18458+ else
18459+ NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_CCMP, 4);
18460+ pRsnie_cipher->ucount = 1;
18461+ NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_CCMP, 4);
18462+ *rsn_len = sizeof(RSNIE);
18463+ break;
18464+
18465+ // TKIP-AES mix mode
18466+ case Ndis802_11Encryption4Enabled:
18467+ NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
18468+
18469+ PairwiseCnt = 1;
18470+ // Insert WPA TKIP as the first pairwise cipher
18471+ if (MIX_CIPHER_WPA_TKIP_ON(FlexibleCipher))
18472+ {
18473+ NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_TKIP, 4);
18474+ // Insert WPA AES as the secondary pairwise cipher
18475+ if (MIX_CIPHER_WPA_AES_ON(FlexibleCipher))
18476+ {
18477+ NdisMoveMemory(pRsnie_cipher->ucast[0].oui + 4, OUI_WPA_CCMP, 4);
18478+ PairwiseCnt = 2;
18479+ }
18480+ }
18481+ else
18482+ {
18483+ // Insert WPA AES as the first pairwise cipher
18484+ NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_CCMP, 4);
18485+ }
18486+
18487+ pRsnie_cipher->ucount = PairwiseCnt;
18488+ *rsn_len = sizeof(RSNIE) + (4 * (PairwiseCnt - 1));
18489+ break;
18490+ }
18491+
18492+ // swap for big-endian platform
18493+ pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
18494+ pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
18495+ }
18496+
18497+}
18498+
18499+/*
18500+ ========================================================================
18501+
18502+ Routine Description:
18503+ Build AKM suite in RSN-IE.
18504+ It only shall be called by RTMPMakeRSNIE.
18505+
18506+ Arguments:
18507+ pAd - pointer to our pAdapter context
18508+ ElementID - indicate the WPA1 or WPA2
18509+ AuthMode - indicate the authentication mode
18510+ apidx - indicate the interface index
18511+
18512+ Return Value:
18513+
18514+ Note:
18515+
18516+ ========================================================================
18517+*/
18518+static VOID RTMPInsertRsnIeAKM(
18519+ IN PRTMP_ADAPTER pAd,
18520+ IN UCHAR ElementID,
18521+ IN UINT AuthMode,
18522+ IN UCHAR apidx,
18523+ OUT PUCHAR pRsnIe,
18524+ OUT UCHAR *rsn_len)
18525+{
18526+ RSNIE_AUTH *pRsnie_auth;
18527+
18528+ pRsnie_auth = (RSNIE_AUTH*)(pRsnIe + (*rsn_len));
18529+
18530+ // decide WPA2 or WPA1
18531+ if (ElementID == Wpa2Ie)
18532+ {
18533+ switch (AuthMode)
18534+ {
18535+ case Ndis802_11AuthModeWPA2:
18536+ case Ndis802_11AuthModeWPA1WPA2:
18537+ pRsnie_auth->acount = 1;
18538+ NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA2_8021X_AKM, 4);
18539+ break;
18540+
18541+ case Ndis802_11AuthModeWPA2PSK:
18542+ case Ndis802_11AuthModeWPA1PSKWPA2PSK:
18543+ pRsnie_auth->acount = 1;
18544+ NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA2_PSK_AKM, 4);
18545+ break;
18546+ }
18547+ }
18548+ else
18549+ {
18550+ switch (AuthMode)
18551+ {
18552+ case Ndis802_11AuthModeWPA:
18553+ case Ndis802_11AuthModeWPA1WPA2:
18554+ pRsnie_auth->acount = 1;
18555+ NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_8021X_AKM, 4);
18556+ break;
18557+
18558+ case Ndis802_11AuthModeWPAPSK:
18559+ case Ndis802_11AuthModeWPA1PSKWPA2PSK:
18560+ pRsnie_auth->acount = 1;
18561+ NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_PSK_AKM, 4);
18562+ break;
18563+
18564+ case Ndis802_11AuthModeWPANone:
18565+ pRsnie_auth->acount = 1;
18566+ NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_NONE_AKM, 4);
18567+ break;
18568+ }
18569+ }
18570+
18571+ pRsnie_auth->acount = cpu2le16(pRsnie_auth->acount);
18572+
18573+ (*rsn_len) += sizeof(RSNIE_AUTH); // update current RSNIE length
18574+
18575+}
18576+
18577+/*
18578+ ========================================================================
18579+
18580+ Routine Description:
18581+ Build capability in RSN-IE.
18582+ It only shall be called by RTMPMakeRSNIE.
18583+
18584+ Arguments:
18585+ pAd - pointer to our pAdapter context
18586+ ElementID - indicate the WPA1 or WPA2
18587+ apidx - indicate the interface index
18588+
18589+ Return Value:
18590+
18591+ Note:
18592+
18593+ ========================================================================
18594+*/
18595+static VOID RTMPInsertRsnIeCap(
18596+ IN PRTMP_ADAPTER pAd,
18597+ IN UCHAR ElementID,
18598+ IN UCHAR apidx,
18599+ OUT PUCHAR pRsnIe,
18600+ OUT UCHAR *rsn_len)
18601+{
18602+ RSN_CAPABILITIES *pRSN_Cap;
18603+
18604+ // it could be ignored in WPA1 mode
18605+ if (ElementID == WpaIe)
18606+ return;
18607+
18608+ pRSN_Cap = (RSN_CAPABILITIES*)(pRsnIe + (*rsn_len));
18609+
18610+
18611+ pRSN_Cap->word = cpu2le16(pRSN_Cap->word);
18612+
18613+ (*rsn_len) += sizeof(RSN_CAPABILITIES); // update current RSNIE length
18614+
18615+}
18616+
18617+
18618+/*
18619+ ========================================================================
18620+
18621+ Routine Description:
18622+ Build RSN IE context. It is not included element-ID and length.
18623+
18624+ Arguments:
18625+ pAd - pointer to our pAdapter context
18626+ AuthMode - indicate the authentication mode
18627+ WepStatus - indicate the encryption type
18628+ apidx - indicate the interface index
18629+
18630+ Return Value:
18631+
18632+ Note:
18633+
18634+ ========================================================================
18635+*/
18636+VOID RTMPMakeRSNIE(
18637+ IN PRTMP_ADAPTER pAd,
18638+ IN UINT AuthMode,
18639+ IN UINT WepStatus,
18640+ IN UCHAR apidx)
18641+{
18642+ PUCHAR pRsnIe = NULL; // primary RSNIE
18643+ UCHAR *rsnielen_cur_p = 0; // the length of the primary RSNIE
18644+ UCHAR *rsnielen_ex_cur_p = 0; // the length of the secondary RSNIE
18645+ UCHAR PrimaryRsnie;
18646+ BOOLEAN bMixCipher = FALSE; // indicate the pairwise and group cipher are different
18647+ UCHAR p_offset;
18648+ WPA_MIX_PAIR_CIPHER FlexibleCipher = MIX_CIPHER_NOTUSE; // it provide the more flexible cipher combination in WPA-WPA2 and TKIPAES mode
18649+
18650+ rsnielen_cur_p = NULL;
18651+ rsnielen_ex_cur_p = NULL;
18652+
18653+ {
18654+#ifdef CONFIG_STA_SUPPORT
18655+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
18656+ {
18657+#ifdef WPA_SUPPLICANT_SUPPORT
18658+ if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
18659+ {
18660+ if (AuthMode < Ndis802_11AuthModeWPA)
18661+ return;
18662+ }
18663+ else
18664+#endif // WPA_SUPPLICANT_SUPPORT //
18665+ {
18666+ // Support WPAPSK or WPA2PSK in STA-Infra mode
18667+ // Support WPANone in STA-Adhoc mode
18668+ if ((AuthMode != Ndis802_11AuthModeWPAPSK) &&
18669+ (AuthMode != Ndis802_11AuthModeWPA2PSK) &&
18670+ (AuthMode != Ndis802_11AuthModeWPANone)
18671+ )
18672+ return;
18673+ }
18674+
18675+ DBGPRINT(RT_DEBUG_TRACE,("==> RTMPMakeRSNIE(STA)\n"));
18676+
18677+ // Zero RSNIE context
18678+ pAd->StaCfg.RSNIE_Len = 0;
18679+ NdisZeroMemory(pAd->StaCfg.RSN_IE, MAX_LEN_OF_RSNIE);
18680+
18681+ // Pointer to RSNIE
18682+ rsnielen_cur_p = &pAd->StaCfg.RSNIE_Len;
18683+ pRsnIe = pAd->StaCfg.RSN_IE;
18684+
18685+ bMixCipher = pAd->StaCfg.bMixCipher;
18686+ }
18687+#endif // CONFIG_STA_SUPPORT //
18688+ }
18689+
18690+ // indicate primary RSNIE as WPA or WPA2
18691+ if ((AuthMode == Ndis802_11AuthModeWPA) ||
18692+ (AuthMode == Ndis802_11AuthModeWPAPSK) ||
18693+ (AuthMode == Ndis802_11AuthModeWPANone) ||
18694+ (AuthMode == Ndis802_11AuthModeWPA1WPA2) ||
18695+ (AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK))
18696+ PrimaryRsnie = WpaIe;
18697+ else
18698+ PrimaryRsnie = Wpa2Ie;
18699+
18700+ {
18701+ // Build the primary RSNIE
18702+ // 1. insert cipher suite
18703+ RTMPInsertRsnIeCipher(pAd, PrimaryRsnie, WepStatus, bMixCipher, FlexibleCipher, pRsnIe, &p_offset);
18704+
18705+ // 2. insert AKM
18706+ RTMPInsertRsnIeAKM(pAd, PrimaryRsnie, AuthMode, apidx, pRsnIe, &p_offset);
18707+
18708+ // 3. insert capability
18709+ RTMPInsertRsnIeCap(pAd, PrimaryRsnie, apidx, pRsnIe, &p_offset);
18710+ }
18711+
18712+ // 4. update the RSNIE length
18713+ *rsnielen_cur_p = p_offset;
18714+
18715+ hex_dump("The primary RSNIE", pRsnIe, (*rsnielen_cur_p));
18716+
18717+
18718+}
18719+
18720+/*
18721+ ==========================================================================
18722+ Description:
18723+ Check whether the received frame is EAP frame.
18724+
18725+ Arguments:
18726+ pAd - pointer to our pAdapter context
18727+ pEntry - pointer to active entry
18728+ pData - the received frame
18729+ DataByteCount - the received frame's length
18730+ FromWhichBSSID - indicate the interface index
18731+
18732+ Return:
18733+ TRUE - This frame is EAP frame
18734+ FALSE - otherwise
18735+ ==========================================================================
18736+*/
18737+BOOLEAN RTMPCheckWPAframe(
18738+ IN PRTMP_ADAPTER pAd,
18739+ IN PMAC_TABLE_ENTRY pEntry,
18740+ IN PUCHAR pData,
18741+ IN ULONG DataByteCount,
18742+ IN UCHAR FromWhichBSSID)
18743+{
18744+ ULONG Body_len;
18745+ BOOLEAN Cancelled;
18746+
18747+
18748+ if(DataByteCount < (LENGTH_802_1_H + LENGTH_EAPOL_H))
18749+ return FALSE;
18750+
18751+
18752+ // Skip LLC header
18753+ if (NdisEqualMemory(SNAP_802_1H, pData, 6) ||
18754+ // Cisco 1200 AP may send packet with SNAP_BRIDGE_TUNNEL
18755+ NdisEqualMemory(SNAP_BRIDGE_TUNNEL, pData, 6))
18756+ {
18757+ pData += 6;
18758+ }
18759+ // Skip 2-bytes EAPoL type
18760+ if (NdisEqualMemory(EAPOL, pData, 2))
18761+ {
18762+ pData += 2;
18763+ }
18764+ else
18765+ return FALSE;
18766+
18767+ switch (*(pData+1))
18768+ {
18769+ case EAPPacket:
18770+ Body_len = (*(pData+2)<<8) | (*(pData+3));
18771+ DBGPRINT(RT_DEBUG_TRACE, ("Receive EAP-Packet frame, TYPE = 0, Length = %ld\n", Body_len));
18772+ break;
18773+ case EAPOLStart:
18774+ DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL-Start frame, TYPE = 1 \n"));
18775+ if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE)
18776+ {
18777+ DBGPRINT(RT_DEBUG_TRACE, ("Cancel the EnqueueEapolStartTimerRunning \n"));
18778+ RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled);
18779+ pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
18780+ }
18781+ break;
18782+ case EAPOLLogoff:
18783+ DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOLLogoff frame, TYPE = 2 \n"));
18784+ break;
18785+ case EAPOLKey:
18786+ Body_len = (*(pData+2)<<8) | (*(pData+3));
18787+ DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL-Key frame, TYPE = 3, Length = %ld\n", Body_len));
18788+ break;
18789+ case EAPOLASFAlert:
18790+ DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOLASFAlert frame, TYPE = 4 \n"));
18791+ break;
18792+ default:
18793+ return FALSE;
18794+
18795+ }
18796+ return TRUE;
18797+}
18798+
18799+
18800+/*
18801+ ==========================================================================
18802+ Description:
18803+ ENCRYPT AES GTK before sending in EAPOL frame.
18804+ AES GTK length = 128 bit, so fix blocks for aes-key-wrap as 2 in this function.
18805+ This function references to RFC 3394 for aes key wrap algorithm.
18806+ Return:
18807+ ==========================================================================
18808+*/
18809+VOID AES_GTK_KEY_WRAP(
18810+ IN UCHAR *key,
18811+ IN UCHAR *plaintext,
18812+ IN UCHAR p_len,
18813+ OUT UCHAR *ciphertext)
18814+{
18815+ UCHAR A[8], BIN[16], BOUT[16];
18816+ UCHAR R[512];
18817+ INT num_blocks = p_len/8; // unit:64bits
18818+ INT i, j;
18819+ aes_context aesctx;
18820+ UCHAR xor;
18821+
18822+ rtmp_aes_set_key(&aesctx, key, 128);
18823+
18824+ // Init IA
18825+ for (i = 0; i < 8; i++)
18826+ A[i] = 0xa6;
18827+
18828+ //Input plaintext
18829+ for (i = 0; i < num_blocks; i++)
18830+ {
18831+ for (j = 0 ; j < 8; j++)
18832+ R[8 * (i + 1) + j] = plaintext[8 * i + j];
18833+ }
18834+
18835+ // Key Mix
18836+ for (j = 0; j < 6; j++)
18837+ {
18838+ for(i = 1; i <= num_blocks; i++)
18839+ {
18840+ //phase 1
18841+ NdisMoveMemory(BIN, A, 8);
18842+ NdisMoveMemory(&BIN[8], &R[8 * i], 8);
18843+ rtmp_aes_encrypt(&aesctx, BIN, BOUT);
18844+
18845+ NdisMoveMemory(A, &BOUT[0], 8);
18846+ xor = num_blocks * j + i;
18847+ A[7] = BOUT[7] ^ xor;
18848+ NdisMoveMemory(&R[8 * i], &BOUT[8], 8);
18849+ }
18850+ }
18851+
18852+ // Output ciphertext
18853+ NdisMoveMemory(ciphertext, A, 8);
18854+
18855+ for (i = 1; i <= num_blocks; i++)
18856+ {
18857+ for (j = 0 ; j < 8; j++)
18858+ ciphertext[8 * i + j] = R[8 * i + j];
18859+ }
18860+}
18861+
18862+
18863+/*
18864+ ========================================================================
18865+
18866+ Routine Description:
18867+ Misc function to decrypt AES body
18868+
18869+ Arguments:
18870+
18871+ Return Value:
18872+
18873+ Note:
18874+ This function references to RFC 3394 for aes key unwrap algorithm.
18875+
18876+ ========================================================================
18877+*/
18878+VOID AES_GTK_KEY_UNWRAP(
18879+ IN UCHAR *key,
18880+ OUT UCHAR *plaintext,
18881+ IN UCHAR c_len,
18882+ IN UCHAR *ciphertext)
18883+
18884+{
18885+ UCHAR A[8], BIN[16], BOUT[16];
18886+ UCHAR xor;
18887+ INT i, j;
18888+ aes_context aesctx;
18889+ UCHAR *R;
18890+ INT num_blocks = c_len/8; // unit:64bits
18891+
18892+
18893+ os_alloc_mem(NULL, (PUCHAR *)&R, 512);
18894+
18895+ if (R == NULL)
18896+ {
18897+ DBGPRINT(RT_DEBUG_ERROR, ("!!!AES_GTK_KEY_UNWRAP: no memory!!!\n"));
18898+ return;
18899+ } /* End of if */
18900+
18901+ // Initialize
18902+ NdisMoveMemory(A, ciphertext, 8);
18903+ //Input plaintext
18904+ for(i = 0; i < (c_len-8); i++)
18905+ {
18906+ R[ i] = ciphertext[i + 8];
18907+ }
18908+
18909+ rtmp_aes_set_key(&aesctx, key, 128);
18910+
18911+ for(j = 5; j >= 0; j--)
18912+ {
18913+ for(i = (num_blocks-1); i > 0; i--)
18914+ {
18915+ xor = (num_blocks -1 )* j + i;
18916+ NdisMoveMemory(BIN, A, 8);
18917+ BIN[7] = A[7] ^ xor;
18918+ NdisMoveMemory(&BIN[8], &R[(i-1)*8], 8);
18919+ rtmp_aes_decrypt(&aesctx, BIN, BOUT);
18920+ NdisMoveMemory(A, &BOUT[0], 8);
18921+ NdisMoveMemory(&R[(i-1)*8], &BOUT[8], 8);
18922+ }
18923+ }
18924+
18925+ // OUTPUT
18926+ for(i = 0; i < c_len; i++)
18927+ {
18928+ plaintext[i] = R[i];
18929+ }
18930+
18931+
18932+ os_free_mem(NULL, R);
18933+}
18934+
18935+/*
18936+ ==========================================================================
18937+ Description:
18938+ Report the EAP message type
18939+
18940+ Arguments:
18941+ msg - EAPOL_PAIR_MSG_1
18942+ EAPOL_PAIR_MSG_2
18943+ EAPOL_PAIR_MSG_3
18944+ EAPOL_PAIR_MSG_4
18945+ EAPOL_GROUP_MSG_1
18946+ EAPOL_GROUP_MSG_2
18947+
18948+ Return:
18949+ message type string
18950+
18951+ ==========================================================================
18952+*/
18953+CHAR *GetEapolMsgType(CHAR msg)
18954+{
18955+ if(msg == EAPOL_PAIR_MSG_1)
18956+ return "Pairwise Message 1";
18957+ else if(msg == EAPOL_PAIR_MSG_2)
18958+ return "Pairwise Message 2";
18959+ else if(msg == EAPOL_PAIR_MSG_3)
18960+ return "Pairwise Message 3";
18961+ else if(msg == EAPOL_PAIR_MSG_4)
18962+ return "Pairwise Message 4";
18963+ else if(msg == EAPOL_GROUP_MSG_1)
18964+ return "Group Message 1";
18965+ else if(msg == EAPOL_GROUP_MSG_2)
18966+ return "Group Message 2";
18967+ else
18968+ return "Invalid Message";
18969+}
18970+
18971+
18972+/*
18973+ ========================================================================
18974+
18975+ Routine Description:
18976+ Check Sanity RSN IE of EAPoL message
18977+
18978+ Arguments:
18979+
18980+ Return Value:
18981+
18982+
18983+ ========================================================================
18984+*/
18985+BOOLEAN RTMPCheckRSNIE(
18986+ IN PRTMP_ADAPTER pAd,
18987+ IN PUCHAR pData,
18988+ IN UCHAR DataLen,
18989+ IN MAC_TABLE_ENTRY *pEntry,
18990+ OUT UCHAR *Offset)
18991+{
18992+ PUCHAR pVIE;
18993+ UCHAR len;
18994+ PEID_STRUCT pEid;
18995+ BOOLEAN result = FALSE;
18996+
18997+ pVIE = pData;
18998+ len = DataLen;
18999+ *Offset = 0;
19000+
19001+ while (len > sizeof(RSNIE2))
19002+ {
19003+ pEid = (PEID_STRUCT) pVIE;
19004+ // WPA RSN IE
19005+ if ((pEid->Eid == IE_WPA) && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)))
19006+ {
19007+ if ((pEntry->AuthMode == Ndis802_11AuthModeWPA || pEntry->AuthMode == Ndis802_11AuthModeWPAPSK) &&
19008+ (NdisEqualMemory(pVIE, pEntry->RSN_IE, pEntry->RSNIE_Len)) &&
19009+ (pEntry->RSNIE_Len == (pEid->Len + 2)))
19010+ {
19011+ result = TRUE;
19012+ }
19013+
19014+ *Offset += (pEid->Len + 2);
19015+ }
19016+ // WPA2 RSN IE
19017+ else if ((pEid->Eid == IE_RSN) && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3)))
19018+ {
19019+ if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2 || pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) &&
19020+ (NdisEqualMemory(pVIE, pEntry->RSN_IE, pEntry->RSNIE_Len)) &&
19021+ (pEntry->RSNIE_Len == (pEid->Len + 2))/* ToDo-AlbertY for mesh*/)
19022+ {
19023+ result = TRUE;
19024+ }
19025+
19026+ *Offset += (pEid->Len + 2);
19027+ }
19028+ else
19029+ {
19030+ break;
19031+ }
19032+
19033+ pVIE += (pEid->Len + 2);
19034+ len -= (pEid->Len + 2);
19035+ }
19036+
19037+
19038+ return result;
19039+
19040+}
19041+
19042+
19043+/*
19044+ ========================================================================
19045+
19046+ Routine Description:
19047+ Parse KEYDATA field. KEYDATA[] May contain 2 RSN IE and optionally GTK.
19048+ GTK is encaptulated in KDE format at p.83 802.11i D10
19049+
19050+ Arguments:
19051+
19052+ Return Value:
19053+
19054+ Note:
19055+ 802.11i D10
19056+
19057+ ========================================================================
19058+*/
19059+BOOLEAN RTMPParseEapolKeyData(
19060+ IN PRTMP_ADAPTER pAd,
19061+ IN PUCHAR pKeyData,
19062+ IN UCHAR KeyDataLen,
19063+ IN UCHAR GroupKeyIndex,
19064+ IN UCHAR MsgType,
19065+ IN BOOLEAN bWPA2,
19066+ IN MAC_TABLE_ENTRY *pEntry)
19067+{
19068+ PKDE_ENCAP pKDE = NULL;
19069+ PUCHAR pMyKeyData = pKeyData;
19070+ UCHAR KeyDataLength = KeyDataLen;
19071+ UCHAR GTKLEN = 0;
19072+ UCHAR DefaultIdx = 0;
19073+ UCHAR skip_offset;
19074+
19075+ // Verify The RSN IE contained in pairewise_msg_2 && pairewise_msg_3 and skip it
19076+ if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_3)
19077+ {
19078+ // Check RSN IE whether it is WPA2/WPA2PSK
19079+ if (!RTMPCheckRSNIE(pAd, pKeyData, KeyDataLen, pEntry, &skip_offset))
19080+ {
19081+ // send wireless event - for RSN IE different
19082+ if (pAd->CommonCfg.bWirelessEvent)
19083+ RTMPSendWirelessEvent(pAd, IW_RSNIE_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
19084+
19085+ DBGPRINT(RT_DEBUG_ERROR, ("RSN_IE Different in msg %d of 4-way handshake!\n", MsgType));
19086+ hex_dump("Receive RSN_IE ", pKeyData, KeyDataLen);
19087+ hex_dump("Desired RSN_IE ", pEntry->RSN_IE, pEntry->RSNIE_Len);
19088+
19089+ return FALSE;
19090+ }
19091+ else
19092+ {
19093+ if (bWPA2 && MsgType == EAPOL_PAIR_MSG_3)
19094+ {
19095+ // skip RSN IE
19096+ pMyKeyData += skip_offset;
19097+ KeyDataLength -= skip_offset;
19098+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPParseEapolKeyData ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", skip_offset));
19099+ }
19100+ else
19101+ return TRUE;
19102+ }
19103+ }
19104+
19105+ DBGPRINT(RT_DEBUG_TRACE,("RTMPParseEapolKeyData ==> KeyDataLength %d without RSN_IE \n", KeyDataLength));
19106+
19107+ // Parse EKD format in pairwise_msg_3_WPA2 && group_msg_1_WPA2
19108+ if (bWPA2 && (MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1))
19109+ {
19110+ if (KeyDataLength >= 8) // KDE format exclude GTK length
19111+ {
19112+ pKDE = (PKDE_ENCAP) pMyKeyData;
19113+
19114+
19115+ DefaultIdx = pKDE->GTKEncap.Kid;
19116+
19117+ // Sanity check - KED length
19118+ if (KeyDataLength < (pKDE->Len + 2))
19119+ {
19120+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The len from KDE is too short \n"));
19121+ return FALSE;
19122+ }
19123+
19124+ // Get GTK length - refer to IEEE 802.11i-2004 p.82
19125+ GTKLEN = pKDE->Len -6;
19126+ if (GTKLEN < LEN_AES_KEY)
19127+ {
19128+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key length is too short (%d) \n", GTKLEN));
19129+ return FALSE;
19130+ }
19131+
19132+ }
19133+ else
19134+ {
19135+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: KDE format length is too short \n"));
19136+ return FALSE;
19137+ }
19138+
19139+ DBGPRINT(RT_DEBUG_TRACE, ("GTK in KDE format ,DefaultKeyID=%d, KeyLen=%d \n", DefaultIdx, GTKLEN));
19140+ // skip it
19141+ pMyKeyData += 8;
19142+ KeyDataLength -= 8;
19143+
19144+ }
19145+ else if (!bWPA2 && MsgType == EAPOL_GROUP_MSG_1)
19146+ {
19147+ DefaultIdx = GroupKeyIndex;
19148+ DBGPRINT(RT_DEBUG_TRACE, ("GTK DefaultKeyID=%d \n", DefaultIdx));
19149+ }
19150+
19151+ // Sanity check - shared key index must be 1 ~ 3
19152+ if (DefaultIdx < 1 || DefaultIdx > 3)
19153+ {
19154+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key index(%d) is invalid in %s %s \n", DefaultIdx, ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType)));
19155+ return FALSE;
19156+ }
19157+
19158+
19159+#ifdef CONFIG_STA_SUPPORT
19160+ // Todo
19161+#endif // CONFIG_STA_SUPPORT //
19162+
19163+ return TRUE;
19164+
19165+}
19166+
19167+
19168+/*
19169+ ========================================================================
19170+
19171+ Routine Description:
19172+ Construct EAPoL message for WPA handshaking
19173+ Its format is below,
19174+
19175+ +--------------------+
19176+ | Protocol Version | 1 octet
19177+ +--------------------+
19178+ | Protocol Type | 1 octet
19179+ +--------------------+
19180+ | Body Length | 2 octets
19181+ +--------------------+
19182+ | Descriptor Type | 1 octet
19183+ +--------------------+
19184+ | Key Information | 2 octets
19185+ +--------------------+
19186+ | Key Length | 1 octet
19187+ +--------------------+
19188+ | Key Repaly Counter | 8 octets
19189+ +--------------------+
19190+ | Key Nonce | 32 octets
19191+ +--------------------+
19192+ | Key IV | 16 octets
19193+ +--------------------+
19194+ | Key RSC | 8 octets
19195+ +--------------------+
19196+ | Key ID or Reserved | 8 octets
19197+ +--------------------+
19198+ | Key MIC | 16 octets
19199+ +--------------------+
19200+ | Key Data Length | 2 octets
19201+ +--------------------+
19202+ | Key Data | n octets
19203+ +--------------------+
19204+
19205+
19206+ Arguments:
19207+ pAd Pointer to our adapter
19208+
19209+ Return Value:
19210+ None
19211+
19212+ Note:
19213+
19214+ ========================================================================
19215+*/
19216+VOID ConstructEapolMsg(
19217+ IN PRTMP_ADAPTER pAd,
19218+ IN UCHAR AuthMode,
19219+ IN UCHAR WepStatus,
19220+ IN UCHAR GroupKeyWepStatus,
19221+ IN UCHAR MsgType,
19222+ IN UCHAR DefaultKeyIdx,
19223+ IN UCHAR *ReplayCounter,
19224+ IN UCHAR *KeyNonce,
19225+ IN UCHAR *TxRSC,
19226+ IN UCHAR *PTK,
19227+ IN UCHAR *GTK,
19228+ IN UCHAR *RSNIE,
19229+ IN UCHAR RSNIE_Len,
19230+ OUT PEAPOL_PACKET pMsg)
19231+{
19232+ BOOLEAN bWPA2 = FALSE;
19233+
19234+ // Choose WPA2 or not
19235+ if ((AuthMode == Ndis802_11AuthModeWPA2) || (AuthMode == Ndis802_11AuthModeWPA2PSK))
19236+ bWPA2 = TRUE;
19237+
19238+ // Init Packet and Fill header
19239+ pMsg->ProVer = EAPOL_VER;
19240+ pMsg->ProType = EAPOLKey;
19241+
19242+ // Default 95 bytes, the EAPoL-Key descriptor exclude Key-data field
19243+ pMsg->Body_Len[1] = LEN_EAPOL_KEY_MSG;
19244+
19245+ // Fill in EAPoL descriptor
19246+ if (bWPA2)
19247+ pMsg->KeyDesc.Type = WPA2_KEY_DESC;
19248+ else
19249+ pMsg->KeyDesc.Type = WPA1_KEY_DESC;
19250+
19251+ // Fill in Key information, refer to IEEE Std 802.11i-2004 page 78
19252+ // When either the pairwise or the group cipher is AES, the DESC_TYPE_AES(2) shall be used.
19253+ pMsg->KeyDesc.KeyInfo.KeyDescVer =
19254+ (((WepStatus == Ndis802_11Encryption3Enabled) || (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
19255+
19256+ // Specify Key Type as Group(0) or Pairwise(1)
19257+ if (MsgType >= EAPOL_GROUP_MSG_1)
19258+ pMsg->KeyDesc.KeyInfo.KeyType = GROUPKEY;
19259+ else
19260+ pMsg->KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
19261+
19262+ // Specify Key Index, only group_msg1_WPA1
19263+ if (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1))
19264+ pMsg->KeyDesc.KeyInfo.KeyIndex = DefaultKeyIdx;
19265+
19266+ if (MsgType == EAPOL_PAIR_MSG_3)
19267+ pMsg->KeyDesc.KeyInfo.Install = 1;
19268+
19269+ if ((MsgType == EAPOL_PAIR_MSG_1) || (MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1))
19270+ pMsg->KeyDesc.KeyInfo.KeyAck = 1;
19271+
19272+ if (MsgType != EAPOL_PAIR_MSG_1)
19273+ pMsg->KeyDesc.KeyInfo.KeyMic = 1;
19274+
19275+ if ((bWPA2 && (MsgType >= EAPOL_PAIR_MSG_3)) || (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1)))
19276+ {
19277+ pMsg->KeyDesc.KeyInfo.Secure = 1;
19278+ }
19279+
19280+ if (bWPA2 && ((MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1)))
19281+ {
19282+ pMsg->KeyDesc.KeyInfo.EKD_DL = 1;
19283+ }
19284+
19285+ // key Information element has done.
19286+ *(USHORT *)(&pMsg->KeyDesc.KeyInfo) = cpu2le16(*(USHORT *)(&pMsg->KeyDesc.KeyInfo));
19287+
19288+ // Fill in Key Length
19289+ {
19290+ if (MsgType >= EAPOL_GROUP_MSG_1)
19291+ {
19292+ // the length of group key cipher
19293+ pMsg->KeyDesc.KeyLength[1] = ((GroupKeyWepStatus == Ndis802_11Encryption2Enabled) ? TKIP_GTK_LENGTH : LEN_AES_KEY);
19294+ }
19295+ else
19296+ {
19297+ // the length of pairwise key cipher
19298+ pMsg->KeyDesc.KeyLength[1] = ((WepStatus == Ndis802_11Encryption2Enabled) ? LEN_TKIP_KEY : LEN_AES_KEY);
19299+ }
19300+ }
19301+
19302+ // Fill in replay counter
19303+ NdisMoveMemory(pMsg->KeyDesc.ReplayCounter, ReplayCounter, LEN_KEY_DESC_REPLAY);
19304+
19305+ // Fill Key Nonce field
19306+ // ANonce : pairwise_msg1 & pairwise_msg3
19307+ // SNonce : pairwise_msg2
19308+ // GNonce : group_msg1_wpa1
19309+ if ((MsgType <= EAPOL_PAIR_MSG_3) || ((!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))))
19310+ NdisMoveMemory(pMsg->KeyDesc.KeyNonce, KeyNonce, LEN_KEY_DESC_NONCE);
19311+
19312+ // Fill key IV - WPA2 as 0, WPA1 as random
19313+ if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))
19314+ {
19315+ // Suggest IV be random number plus some number,
19316+ NdisMoveMemory(pMsg->KeyDesc.KeyIv, &KeyNonce[16], LEN_KEY_DESC_IV);
19317+ pMsg->KeyDesc.KeyIv[15] += 2;
19318+ }
19319+
19320+ // Fill Key RSC field
19321+ // It contains the RSC for the GTK being installed.
19322+ if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2) || (MsgType == EAPOL_GROUP_MSG_1))
19323+ {
19324+ NdisMoveMemory(pMsg->KeyDesc.KeyRsc, TxRSC, 6);
19325+ }
19326+
19327+ // Clear Key MIC field for MIC calculation later
19328+ NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
19329+
19330+ ConstructEapolKeyData(pAd,
19331+ AuthMode,
19332+ WepStatus,
19333+ GroupKeyWepStatus,
19334+ MsgType,
19335+ DefaultKeyIdx,
19336+ bWPA2,
19337+ PTK,
19338+ GTK,
19339+ RSNIE,
19340+ RSNIE_Len,
19341+ pMsg);
19342+
19343+ // Calculate MIC and fill in KeyMic Field except Pairwise Msg 1.
19344+ if (MsgType != EAPOL_PAIR_MSG_1)
19345+ {
19346+ CalculateMIC(pAd, WepStatus, PTK, pMsg);
19347+ }
19348+
19349+ DBGPRINT(RT_DEBUG_TRACE, ("===> ConstructEapolMsg for %s %s\n", ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType)));
19350+ DBGPRINT(RT_DEBUG_TRACE, (" Body length = %d \n", pMsg->Body_Len[1]));
19351+ DBGPRINT(RT_DEBUG_TRACE, (" Key length = %d \n", pMsg->KeyDesc.KeyLength[1]));
19352+
19353+
19354+}
19355+
19356+/*
19357+ ========================================================================
19358+
19359+ Routine Description:
19360+ Construct the Key Data field of EAPoL message
19361+
19362+ Arguments:
19363+ pAd Pointer to our adapter
19364+ Elem Message body
19365+
19366+ Return Value:
19367+ None
19368+
19369+ Note:
19370+
19371+ ========================================================================
19372+*/
19373+VOID ConstructEapolKeyData(
19374+ IN PRTMP_ADAPTER pAd,
19375+ IN UCHAR AuthMode,
19376+ IN UCHAR WepStatus,
19377+ IN UCHAR GroupKeyWepStatus,
19378+ IN UCHAR MsgType,
19379+ IN UCHAR DefaultKeyIdx,
19380+ IN BOOLEAN bWPA2Capable,
19381+ IN UCHAR *PTK,
19382+ IN UCHAR *GTK,
19383+ IN UCHAR *RSNIE,
19384+ IN UCHAR RSNIE_LEN,
19385+ OUT PEAPOL_PACKET pMsg)
19386+{
19387+ UCHAR *mpool, *Key_Data, *Rc4GTK;
19388+ UCHAR ekey[(LEN_KEY_DESC_IV+LEN_EAP_EK)];
19389+ UCHAR data_offset;
19390+
19391+
19392+ if (MsgType == EAPOL_PAIR_MSG_1 || MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2)
19393+ return;
19394+
19395+ // allocate memory pool
19396+ os_alloc_mem(pAd, (PUCHAR *)&mpool, 1500);
19397+
19398+ if (mpool == NULL)
19399+ return;
19400+
19401+ /* Rc4GTK Len = 512 */
19402+ Rc4GTK = (UCHAR *) ROUND_UP(mpool, 4);
19403+ /* Key_Data Len = 512 */
19404+ Key_Data = (UCHAR *) ROUND_UP(Rc4GTK + 512, 4);
19405+
19406+ NdisZeroMemory(Key_Data, 512);
19407+ pMsg->KeyDesc.KeyDataLen[1] = 0;
19408+ data_offset = 0;
19409+
19410+ // Encapsulate RSNIE in pairwise_msg2 & pairwise_msg3
19411+ if (RSNIE_LEN && ((MsgType == EAPOL_PAIR_MSG_2) || (MsgType == EAPOL_PAIR_MSG_3)))
19412+ {
19413+ if (bWPA2Capable)
19414+ Key_Data[data_offset + 0] = IE_WPA2;
19415+ else
19416+ Key_Data[data_offset + 0] = IE_WPA;
19417+
19418+ Key_Data[data_offset + 1] = RSNIE_LEN;
19419+ NdisMoveMemory(&Key_Data[data_offset + 2], RSNIE, RSNIE_LEN);
19420+ data_offset += (2 + RSNIE_LEN);
19421+ }
19422+
19423+ // Encapsulate KDE format in pairwise_msg3_WPA2 & group_msg1_WPA2
19424+ if (bWPA2Capable && ((MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1)))
19425+ {
19426+ // Key Data Encapsulation (KDE) format - 802.11i-2004 Figure-43w and Table-20h
19427+ Key_Data[data_offset + 0] = 0xDD;
19428+
19429+ if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)
19430+ {
19431+ Key_Data[data_offset + 1] = 0x16;// 4+2+16(OUI+DataType+DataField)
19432+ }
19433+ else
19434+ {
19435+ Key_Data[data_offset + 1] = 0x26;// 4+2+32(OUI+DataType+DataField)
19436+ }
19437+
19438+ Key_Data[data_offset + 2] = 0x00;
19439+ Key_Data[data_offset + 3] = 0x0F;
19440+ Key_Data[data_offset + 4] = 0xAC;
19441+ Key_Data[data_offset + 5] = 0x01;
19442+
19443+ // GTK KDE format - 802.11i-2004 Figure-43x
19444+ Key_Data[data_offset + 6] = (DefaultKeyIdx & 0x03);
19445+ Key_Data[data_offset + 7] = 0x00; // Reserved Byte
19446+
19447+ data_offset += 8;
19448+ }
19449+
19450+
19451+ // Encapsulate GTK and encrypt the key-data field with KEK.
19452+ // Only for pairwise_msg3_WPA2 and group_msg1
19453+ if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2Capable) || (MsgType == EAPOL_GROUP_MSG_1))
19454+ {
19455+ // Fill in GTK
19456+ if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)
19457+ {
19458+ NdisMoveMemory(&Key_Data[data_offset], GTK, LEN_AES_KEY);
19459+ data_offset += LEN_AES_KEY;
19460+ }
19461+ else
19462+ {
19463+ NdisMoveMemory(&Key_Data[data_offset], GTK, TKIP_GTK_LENGTH);
19464+ data_offset += TKIP_GTK_LENGTH;
19465+ }
19466+
19467+ // Still dont know why, but if not append will occur "GTK not include in MSG3"
19468+ // Patch for compatibility between zero config and funk
19469+ if (MsgType == EAPOL_PAIR_MSG_3 && bWPA2Capable)
19470+ {
19471+ if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)
19472+ {
19473+ Key_Data[data_offset + 0] = 0xDD;
19474+ Key_Data[data_offset + 1] = 0;
19475+ data_offset += 2;
19476+ }
19477+ else
19478+ {
19479+ Key_Data[data_offset + 0] = 0xDD;
19480+ Key_Data[data_offset + 1] = 0;
19481+ Key_Data[data_offset + 2] = 0;
19482+ Key_Data[data_offset + 3] = 0;
19483+ Key_Data[data_offset + 4] = 0;
19484+ Key_Data[data_offset + 5] = 0;
19485+ data_offset += 6;
19486+ }
19487+ }
19488+
19489+ // Encrypt the data material in key data field
19490+ if (WepStatus == Ndis802_11Encryption3Enabled)
19491+ {
19492+ AES_GTK_KEY_WRAP(&PTK[16], Key_Data, data_offset, Rc4GTK);
19493+ // AES wrap function will grow 8 bytes in length
19494+ data_offset += 8;
19495+ }
19496+ else
19497+ {
19498+ // PREPARE Encrypted "Key DATA" field. (Encrypt GTK with RC4, usinf PTK[16]->[31] as Key, IV-field as IV)
19499+ // put TxTsc in Key RSC field
19500+ pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32; //Init crc32.
19501+
19502+ // ekey is the contanetion of IV-field, and PTK[16]->PTK[31]
19503+ NdisMoveMemory(ekey, pMsg->KeyDesc.KeyIv, LEN_KEY_DESC_IV);
19504+ NdisMoveMemory(&ekey[LEN_KEY_DESC_IV], &PTK[16], LEN_EAP_EK);
19505+ ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, ekey, sizeof(ekey)); //INIT SBOX, KEYLEN+3(IV)
19506+ pAd->PrivateInfo.FCSCRC32 = RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, Key_Data, data_offset);
19507+ WPAARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, Rc4GTK, Key_Data, data_offset);
19508+ }
19509+
19510+ NdisMoveMemory(pMsg->KeyDesc.KeyData, Rc4GTK, data_offset);
19511+ }
19512+ else
19513+ {
19514+ NdisMoveMemory(pMsg->KeyDesc.KeyData, Key_Data, data_offset);
19515+ }
19516+
19517+ // set key data length field and total length
19518+ pMsg->KeyDesc.KeyDataLen[1] = data_offset;
19519+ pMsg->Body_Len[1] += data_offset;
19520+
19521+ os_free_mem(pAd, mpool);
19522+
19523+}
19524+
19525+/*
19526+ ========================================================================
19527+
19528+ Routine Description:
19529+ Calcaulate MIC. It is used during 4-ways handsharking.
19530+
19531+ Arguments:
19532+ pAd - pointer to our pAdapter context
19533+ PeerWepStatus - indicate the encryption type
19534+
19535+ Return Value:
19536+
19537+ Note:
19538+
19539+ ========================================================================
19540+*/
19541+VOID CalculateMIC(
19542+ IN PRTMP_ADAPTER pAd,
19543+ IN UCHAR PeerWepStatus,
19544+ IN UCHAR *PTK,
19545+ OUT PEAPOL_PACKET pMsg)
19546+{
19547+ UCHAR *OutBuffer;
19548+ ULONG FrameLen = 0;
19549+ UCHAR mic[LEN_KEY_DESC_MIC];
19550+ UCHAR digest[80];
19551+
19552+ // allocate memory for MIC calculation
19553+ os_alloc_mem(pAd, (PUCHAR *)&OutBuffer, 512);
19554+
19555+ if (OutBuffer == NULL)
19556+ {
19557+ DBGPRINT(RT_DEBUG_ERROR, ("!!!CalculateMIC: no memory!!!\n"));
19558+ return;
19559+ }
19560+
19561+ // make a frame for calculating MIC.
19562+ MakeOutgoingFrame(OutBuffer, &FrameLen,
19563+ pMsg->Body_Len[1] + 4, pMsg,
19564+ END_OF_ARGS);
19565+
19566+ NdisZeroMemory(mic, sizeof(mic));
19567+
19568+ // Calculate MIC
19569+ if (PeerWepStatus == Ndis802_11Encryption3Enabled)
19570+ {
19571+ HMAC_SHA1(OutBuffer, FrameLen, PTK, LEN_EAP_MICK, digest);
19572+ NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
19573+ }
19574+ else
19575+ {
19576+ hmac_md5(PTK, LEN_EAP_MICK, OutBuffer, FrameLen, mic);
19577+ }
19578+
19579+ // store the calculated MIC
19580+ NdisMoveMemory(pMsg->KeyDesc.KeyMic, mic, LEN_KEY_DESC_MIC);
19581+
19582+ os_free_mem(pAd, OutBuffer);
19583+}
19584+
19585+/*
19586+ ========================================================================
19587+
19588+ Routine Description:
19589+ Some received frames can't decrypt by Asic, so decrypt them by software.
19590+
19591+ Arguments:
19592+ pAd - pointer to our pAdapter context
19593+ PeerWepStatus - indicate the encryption type
19594+
19595+ Return Value:
19596+ NDIS_STATUS_SUCCESS - decryption successful
19597+ NDIS_STATUS_FAILURE - decryption failure
19598+
19599+ ========================================================================
19600+*/
19601+NDIS_STATUS RTMPSoftDecryptBroadCastData(
19602+ IN PRTMP_ADAPTER pAd,
19603+ IN RX_BLK *pRxBlk,
19604+ IN NDIS_802_11_ENCRYPTION_STATUS GroupCipher,
19605+ IN PCIPHER_KEY pShard_key)
19606+{
19607+ PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
19608+
19609+
19610+
19611+ // handle WEP decryption
19612+ if (GroupCipher == Ndis802_11Encryption1Enabled)
19613+ {
19614+ if (RTMPSoftDecryptWEP(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, pShard_key))
19615+ {
19616+
19617+ //Minus IV[4] & ICV[4]
19618+ pRxWI->MPDUtotalByteCount -= 8;
19619+ }
19620+ else
19621+ {
19622+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR : Software decrypt WEP data fails.\n"));
19623+ // give up this frame
19624+ return NDIS_STATUS_FAILURE;
19625+ }
19626+ }
19627+ // handle TKIP decryption
19628+ else if (GroupCipher == Ndis802_11Encryption2Enabled)
19629+ {
19630+ if (RTMPSoftDecryptTKIP(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, 0, pShard_key))
19631+ {
19632+
19633+ //Minus 8 bytes MIC, 8 bytes IV/EIV, 4 bytes ICV
19634+ pRxWI->MPDUtotalByteCount -= 20;
19635+ }
19636+ else
19637+ {
19638+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR : RTMPSoftDecryptTKIP Failed\n"));
19639+ // give up this frame
19640+ return NDIS_STATUS_FAILURE;
19641+ }
19642+ }
19643+ // handle AES decryption
19644+ else if (GroupCipher == Ndis802_11Encryption3Enabled)
19645+ {
19646+ if (RTMPSoftDecryptAES(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount , pShard_key))
19647+ {
19648+
19649+ //8 bytes MIC, 8 bytes IV/EIV (CCMP Header)
19650+ pRxWI->MPDUtotalByteCount -= 16;
19651+ }
19652+ else
19653+ {
19654+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR : RTMPSoftDecryptAES Failed\n"));
19655+ // give up this frame
19656+ return NDIS_STATUS_FAILURE;
19657+ }
19658+ }
19659+ else
19660+ {
19661+ // give up this frame
19662+ return NDIS_STATUS_FAILURE;
19663+ }
19664+
19665+ return NDIS_STATUS_SUCCESS;
19666+
19667+}
19668+
19669--- /dev/null
19670+++ b/drivers/staging/rt3070/common/dfs.c
19671@@ -0,0 +1,441 @@
19672+/*
19673+ *************************************************************************
19674+ * Ralink Tech Inc.
19675+ * 5F., No.36, Taiyuan St., Jhubei City,
19676+ * Hsinchu County 302,
19677+ * Taiwan, R.O.C.
19678+ *
19679+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
19680+ *
19681+ * This program is free software; you can redistribute it and/or modify *
19682+ * it under the terms of the GNU General Public License as published by *
19683+ * the Free Software Foundation; either version 2 of the License, or *
19684+ * (at your option) any later version. *
19685+ * *
19686+ * This program is distributed in the hope that it will be useful, *
19687+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
19688+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19689+ * GNU General Public License for more details. *
19690+ * *
19691+ * You should have received a copy of the GNU General Public License *
19692+ * along with this program; if not, write to the *
19693+ * Free Software Foundation, Inc., *
19694+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19695+ * *
19696+ *************************************************************************
19697+
19698+ Module Name:
19699+ ap_dfs.c
19700+
19701+ Abstract:
19702+ Support DFS function.
19703+
19704+ Revision History:
19705+ Who When What
19706+ -------- ---------- ----------------------------------------------
19707+ Fonchi 03-12-2007 created
19708+*/
19709+
19710+#include "../rt_config.h"
19711+
19712+typedef struct _RADAR_DURATION_TABLE
19713+{
19714+ ULONG RDDurRegion;
19715+ ULONG RadarSignalDuration;
19716+ ULONG Tolerance;
19717+} RADAR_DURATION_TABLE, *PRADAR_DURATION_TABLE;
19718+
19719+
19720+static UCHAR RdIdleTimeTable[MAX_RD_REGION][4] =
19721+{
19722+ {9, 250, 250, 250}, // CE
19723+ {4, 250, 250, 250}, // FCC
19724+ {4, 250, 250, 250}, // JAP
19725+ {15, 250, 250, 250}, // JAP_W53
19726+ {4, 250, 250, 250} // JAP_W56
19727+};
19728+
19729+/*
19730+ ========================================================================
19731+
19732+ Routine Description:
19733+ Bbp Radar detection routine
19734+
19735+ Arguments:
19736+ pAd Pointer to our adapter
19737+
19738+ Return Value:
19739+
19740+ ========================================================================
19741+*/
19742+VOID BbpRadarDetectionStart(
19743+ IN PRTMP_ADAPTER pAd)
19744+{
19745+ UINT8 RadarPeriod;
19746+
19747+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 114, 0x02);
19748+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 121, 0x20);
19749+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 122, 0x00);
19750+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 123, 0x08/*0x80*/);
19751+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 124, 0x28);
19752+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 125, 0xff);
19753+
19754+ RadarPeriod = ((UINT)RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + (UINT)pAd->CommonCfg.RadarDetect.DfsSessionTime) < 250 ?
19755+ (RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + pAd->CommonCfg.RadarDetect.DfsSessionTime) : 250;
19756+
19757+ RTMP_IO_WRITE8(pAd, 0x7020, 0x1d);
19758+ RTMP_IO_WRITE8(pAd, 0x7021, 0x40);
19759+
19760+ RadarDetectionStart(pAd, 0, RadarPeriod);
19761+ return;
19762+}
19763+
19764+/*
19765+ ========================================================================
19766+
19767+ Routine Description:
19768+ Bbp Radar detection routine
19769+
19770+ Arguments:
19771+ pAd Pointer to our adapter
19772+
19773+ Return Value:
19774+
19775+ ========================================================================
19776+*/
19777+VOID BbpRadarDetectionStop(
19778+ IN PRTMP_ADAPTER pAd)
19779+{
19780+ RTMP_IO_WRITE8(pAd, 0x7020, 0x1d);
19781+ RTMP_IO_WRITE8(pAd, 0x7021, 0x60);
19782+
19783+ RadarDetectionStop(pAd);
19784+ return;
19785+}
19786+
19787+/*
19788+ ========================================================================
19789+
19790+ Routine Description:
19791+ Radar detection routine
19792+
19793+ Arguments:
19794+ pAd Pointer to our adapter
19795+
19796+ Return Value:
19797+
19798+ ========================================================================
19799+*/
19800+VOID RadarDetectionStart(
19801+ IN PRTMP_ADAPTER pAd,
19802+ IN BOOLEAN CTSProtect,
19803+ IN UINT8 CTSPeriod)
19804+{
19805+ UINT8 DfsActiveTime = (pAd->CommonCfg.RadarDetect.DfsSessionTime & 0x1f);
19806+ UINT8 CtsProtect = (CTSProtect == 1) ? 0x02 : 0x01; // CTS protect.
19807+
19808+ if (CTSProtect != 0)
19809+ {
19810+ switch(pAd->CommonCfg.RadarDetect.RDDurRegion)
19811+ {
19812+ case FCC:
19813+ case JAP_W56:
19814+ CtsProtect = 0x03;
19815+ break;
19816+
19817+ case CE:
19818+ case JAP_W53:
19819+ default:
19820+ CtsProtect = 0x02;
19821+ break;
19822+ }
19823+ }
19824+ else
19825+ CtsProtect = 0x01;
19826+
19827+
19828+ // send start-RD with CTS protection command to MCU
19829+ // highbyte [7] reserve
19830+ // highbyte [6:5] 0x: stop Carrier/Radar detection
19831+ // highbyte [10]: Start Carrier/Radar detection without CTS protection, 11: Start Carrier/Radar detection with CTS protection
19832+ // highbyte [4:0] Radar/carrier detection duration. In 1ms.
19833+
19834+ // lowbyte [7:0] Radar/carrier detection period, in 1ms.
19835+ AsicSendCommandToMcu(pAd, 0x60, 0xff, CTSPeriod, DfsActiveTime | (CtsProtect << 5));
19836+ //AsicSendCommandToMcu(pAd, 0x63, 0xff, 10, 0);
19837+
19838+ return;
19839+}
19840+
19841+/*
19842+ ========================================================================
19843+
19844+ Routine Description:
19845+ Radar detection routine
19846+
19847+ Arguments:
19848+ pAd Pointer to our adapter
19849+
19850+ Return Value:
19851+ TRUE Found radar signal
19852+ FALSE Not found radar signal
19853+
19854+ ========================================================================
19855+*/
19856+VOID RadarDetectionStop(
19857+ IN PRTMP_ADAPTER pAd)
19858+{
19859+ DBGPRINT(RT_DEBUG_TRACE,("RadarDetectionStop.\n"));
19860+ AsicSendCommandToMcu(pAd, 0x60, 0xff, 0x00, 0x00); // send start-RD with CTS protection command to MCU
19861+
19862+ return;
19863+}
19864+
19865+/*
19866+ ========================================================================
19867+
19868+ Routine Description:
19869+ Radar channel check routine
19870+
19871+ Arguments:
19872+ pAd Pointer to our adapter
19873+
19874+ Return Value:
19875+ TRUE need to do radar detect
19876+ FALSE need not to do radar detect
19877+
19878+ ========================================================================
19879+*/
19880+BOOLEAN RadarChannelCheck(
19881+ IN PRTMP_ADAPTER pAd,
19882+ IN UCHAR Ch)
19883+{
19884+#if 1
19885+ INT i;
19886+ BOOLEAN result = FALSE;
19887+
19888+ for (i=0; i<pAd->ChannelListNum; i++)
19889+ {
19890+ if (Ch == pAd->ChannelList[i].Channel)
19891+ {
19892+ result = pAd->ChannelList[i].DfsReq;
19893+ break;
19894+ }
19895+ }
19896+
19897+ return result;
19898+#else
19899+ INT i;
19900+ UCHAR Channel[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
19901+
19902+ for (i=0; i<15; i++)
19903+ {
19904+ if (Ch == Channel[i])
19905+ {
19906+ break;
19907+ }
19908+ }
19909+
19910+ if (i != 15)
19911+ return TRUE;
19912+ else
19913+ return FALSE;
19914+#endif
19915+}
19916+
19917+ULONG JapRadarType(
19918+ IN PRTMP_ADAPTER pAd)
19919+{
19920+ ULONG i;
19921+ const UCHAR Channel[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
19922+
19923+ if (pAd->CommonCfg.RadarDetect.RDDurRegion != JAP)
19924+ {
19925+ return pAd->CommonCfg.RadarDetect.RDDurRegion;
19926+ }
19927+
19928+ for (i=0; i<15; i++)
19929+ {
19930+ if (pAd->CommonCfg.Channel == Channel[i])
19931+ {
19932+ break;
19933+ }
19934+ }
19935+
19936+ if (i < 4)
19937+ return JAP_W53;
19938+ else if (i < 15)
19939+ return JAP_W56;
19940+ else
19941+ return JAP; // W52
19942+
19943+}
19944+
19945+ULONG RTMPBbpReadRadarDuration(
19946+ IN PRTMP_ADAPTER pAd)
19947+{
19948+ UINT8 byteValue = 0;
19949+ ULONG result;
19950+
19951+ BBP_IO_READ8_BY_REG_ID(pAd, BBP_R115, &byteValue);
19952+
19953+ result = 0;
19954+ switch (byteValue)
19955+ {
19956+ case 1: // radar signal detected by pulse mode.
19957+ case 2: // radar signal detected by width mode.
19958+ result = RTMPReadRadarDuration(pAd);
19959+ break;
19960+
19961+ case 0: // No radar signal.
19962+ default:
19963+
19964+ result = 0;
19965+ break;
19966+ }
19967+
19968+ return result;
19969+}
19970+
19971+ULONG RTMPReadRadarDuration(
19972+ IN PRTMP_ADAPTER pAd)
19973+{
19974+ ULONG result = 0;
19975+
19976+#ifdef DFS_SUPPORT
19977+ UINT8 duration1 = 0, duration2 = 0, duration3 = 0;
19978+
19979+ BBP_IO_READ8_BY_REG_ID(pAd, BBP_R116, &duration1);
19980+ BBP_IO_READ8_BY_REG_ID(pAd, BBP_R117, &duration2);
19981+ BBP_IO_READ8_BY_REG_ID(pAd, BBP_R118, &duration3);
19982+ result = (duration1 << 16) + (duration2 << 8) + duration3;
19983+#endif // DFS_SUPPORT //
19984+
19985+ return result;
19986+
19987+}
19988+
19989+VOID RTMPCleanRadarDuration(
19990+ IN PRTMP_ADAPTER pAd)
19991+{
19992+ return;
19993+}
19994+
19995+/*
19996+ ========================================================================
19997+ Routine Description:
19998+ Radar wave detection. The API should be invoke each second.
19999+
20000+ Arguments:
20001+ pAd - Adapter pointer
20002+
20003+ Return Value:
20004+ None
20005+
20006+ ========================================================================
20007+*/
20008+VOID ApRadarDetectPeriodic(
20009+ IN PRTMP_ADAPTER pAd)
20010+{
20011+ INT i;
20012+
20013+ pAd->CommonCfg.RadarDetect.InServiceMonitorCount++;
20014+
20015+ for (i=0; i<pAd->ChannelListNum; i++)
20016+ {
20017+ if (pAd->ChannelList[i].RemainingTimeForUse > 0)
20018+ {
20019+ pAd->ChannelList[i].RemainingTimeForUse --;
20020+ if ((pAd->Mlme.PeriodicRound%5) == 0)
20021+ {
20022+ DBGPRINT(RT_DEBUG_TRACE, ("RadarDetectPeriodic - ch=%d, RemainingTimeForUse=%d\n", pAd->ChannelList[i].Channel, pAd->ChannelList[i].RemainingTimeForUse));
20023+ }
20024+ }
20025+ }
20026+
20027+ //radar detect
20028+ if ((pAd->CommonCfg.Channel > 14)
20029+ && (pAd->CommonCfg.bIEEE80211H == 1)
20030+ && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
20031+ {
20032+ RadarDetectPeriodic(pAd);
20033+ }
20034+
20035+ return;
20036+}
20037+
20038+// Periodic Radar detection, switch channel will occur in RTMPHandleTBTTInterrupt()
20039+// Before switch channel, driver needs doing channel switch announcement.
20040+VOID RadarDetectPeriodic(
20041+ IN PRTMP_ADAPTER pAd)
20042+{
20043+ // need to check channel availability, after switch channel
20044+ if (pAd->CommonCfg.RadarDetect.RDMode != RD_SILENCE_MODE)
20045+ return;
20046+
20047+ // channel availability check time is 60sec, use 65 for assurance
20048+ if (pAd->CommonCfg.RadarDetect.RDCount++ > pAd->CommonCfg.RadarDetect.ChMovingTime)
20049+ {
20050+ DBGPRINT(RT_DEBUG_TRACE, ("Not found radar signal, start send beacon and radar detection in service monitor\n\n"));
20051+ BbpRadarDetectionStop(pAd);
20052+ AsicEnableBssSync(pAd);
20053+ pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
20054+
20055+
20056+ return;
20057+ }
20058+
20059+ return;
20060+}
20061+
20062+
20063+/*
20064+ ==========================================================================
20065+ Description:
20066+ change channel moving time for DFS testing.
20067+
20068+ Arguments:
20069+ pAdapter Pointer to our adapter
20070+ wrq Pointer to the ioctl argument
20071+
20072+ Return Value:
20073+ None
20074+
20075+ Note:
20076+ Usage:
20077+ 1.) iwpriv ra0 set ChMovTime=[value]
20078+ ==========================================================================
20079+*/
20080+INT Set_ChMovingTime_Proc(
20081+ IN PRTMP_ADAPTER pAd,
20082+ IN PUCHAR arg)
20083+{
20084+ UINT8 Value;
20085+
20086+ Value = simple_strtol(arg, 0, 10);
20087+
20088+ pAd->CommonCfg.RadarDetect.ChMovingTime = Value;
20089+
20090+ DBGPRINT(RT_DEBUG_TRACE, ("%s:: %d\n", __FUNCTION__,
20091+ pAd->CommonCfg.RadarDetect.ChMovingTime));
20092+
20093+ return TRUE;
20094+}
20095+
20096+INT Set_LongPulseRadarTh_Proc(
20097+ IN PRTMP_ADAPTER pAd,
20098+ IN PUCHAR arg)
20099+{
20100+ UINT8 Value;
20101+
20102+ Value = simple_strtol(arg, 0, 10) > 10 ? 10 : simple_strtol(arg, 0, 10);
20103+
20104+ pAd->CommonCfg.RadarDetect.LongPulseRadarTh = Value;
20105+
20106+ DBGPRINT(RT_DEBUG_TRACE, ("%s:: %d\n", __FUNCTION__,
20107+ pAd->CommonCfg.RadarDetect.LongPulseRadarTh));
20108+
20109+ return TRUE;
20110+}
20111+
20112+
20113--- /dev/null
20114+++ b/drivers/staging/rt3070/common/eeprom.c
20115@@ -0,0 +1,1498 @@
20116+/*
20117+ *************************************************************************
20118+ * Ralink Tech Inc.
20119+ * 5F., No.36, Taiyuan St., Jhubei City,
20120+ * Hsinchu County 302,
20121+ * Taiwan, R.O.C.
20122+ *
20123+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
20124+ *
20125+ * This program is free software; you can redistribute it and/or modify *
20126+ * it under the terms of the GNU General Public License as published by *
20127+ * the Free Software Foundation; either version 2 of the License, or *
20128+ * (at your option) any later version. *
20129+ * *
20130+ * This program is distributed in the hope that it will be useful, *
20131+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
20132+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
20133+ * GNU General Public License for more details. *
20134+ * *
20135+ * You should have received a copy of the GNU General Public License *
20136+ * along with this program; if not, write to the *
20137+ * Free Software Foundation, Inc., *
20138+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
20139+ * *
20140+ *************************************************************************
20141+
20142+ Module Name:
20143+ eeprom.c
20144+
20145+ Abstract:
20146+
20147+ Revision History:
20148+ Who When What
20149+ -------- ---------- ----------------------------------------------
20150+ Name Date Modification logs
20151+*/
20152+#include "../rt_config.h"
20153+
20154+// IRQL = PASSIVE_LEVEL
20155+VOID RaiseClock(
20156+ IN PRTMP_ADAPTER pAd,
20157+ IN UINT32 *x)
20158+{
20159+ *x = *x | EESK;
20160+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
20161+ RTMPusecDelay(1); // Max frequency = 1MHz in Spec. definition
20162+}
20163+
20164+// IRQL = PASSIVE_LEVEL
20165+VOID LowerClock(
20166+ IN PRTMP_ADAPTER pAd,
20167+ IN UINT32 *x)
20168+{
20169+ *x = *x & ~EESK;
20170+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
20171+ RTMPusecDelay(1);
20172+}
20173+
20174+// IRQL = PASSIVE_LEVEL
20175+USHORT ShiftInBits(
20176+ IN PRTMP_ADAPTER pAd)
20177+{
20178+ UINT32 x,i;
20179+ USHORT data=0;
20180+
20181+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
20182+
20183+ x &= ~( EEDO | EEDI);
20184+
20185+ for(i=0; i<16; i++)
20186+ {
20187+ data = data << 1;
20188+ RaiseClock(pAd, &x);
20189+
20190+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
20191+ LowerClock(pAd, &x); //prevent read failed
20192+
20193+ x &= ~(EEDI);
20194+ if(x & EEDO)
20195+ data |= 1;
20196+ }
20197+
20198+ return data;
20199+}
20200+
20201+// IRQL = PASSIVE_LEVEL
20202+VOID ShiftOutBits(
20203+ IN PRTMP_ADAPTER pAd,
20204+ IN USHORT data,
20205+ IN USHORT count)
20206+{
20207+ UINT32 x,mask;
20208+
20209+ mask = 0x01 << (count - 1);
20210+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
20211+
20212+ x &= ~(EEDO | EEDI);
20213+
20214+ do
20215+ {
20216+ x &= ~EEDI;
20217+ if(data & mask) x |= EEDI;
20218+
20219+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
20220+
20221+ RaiseClock(pAd, &x);
20222+ LowerClock(pAd, &x);
20223+
20224+ mask = mask >> 1;
20225+ } while(mask);
20226+
20227+ x &= ~EEDI;
20228+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
20229+}
20230+
20231+// IRQL = PASSIVE_LEVEL
20232+VOID EEpromCleanup(
20233+ IN PRTMP_ADAPTER pAd)
20234+{
20235+ UINT32 x;
20236+
20237+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
20238+
20239+ x &= ~(EECS | EEDI);
20240+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
20241+
20242+ RaiseClock(pAd, &x);
20243+ LowerClock(pAd, &x);
20244+}
20245+
20246+VOID EWEN(
20247+ IN PRTMP_ADAPTER pAd)
20248+{
20249+ UINT32 x;
20250+
20251+ // reset bits and set EECS
20252+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
20253+ x &= ~(EEDI | EEDO | EESK);
20254+ x |= EECS;
20255+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
20256+
20257+ // kick a pulse
20258+ RaiseClock(pAd, &x);
20259+ LowerClock(pAd, &x);
20260+
20261+ // output the read_opcode and six pulse in that order
20262+ ShiftOutBits(pAd, EEPROM_EWEN_OPCODE, 5);
20263+ ShiftOutBits(pAd, 0, 6);
20264+
20265+ EEpromCleanup(pAd);
20266+}
20267+
20268+VOID EWDS(
20269+ IN PRTMP_ADAPTER pAd)
20270+{
20271+ UINT32 x;
20272+
20273+ // reset bits and set EECS
20274+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
20275+ x &= ~(EEDI | EEDO | EESK);
20276+ x |= EECS;
20277+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
20278+
20279+ // kick a pulse
20280+ RaiseClock(pAd, &x);
20281+ LowerClock(pAd, &x);
20282+
20283+ // output the read_opcode and six pulse in that order
20284+ ShiftOutBits(pAd, EEPROM_EWDS_OPCODE, 5);
20285+ ShiftOutBits(pAd, 0, 6);
20286+
20287+ EEpromCleanup(pAd);
20288+}
20289+
20290+// IRQL = PASSIVE_LEVEL
20291+USHORT RTMP_EEPROM_READ16(
20292+ IN PRTMP_ADAPTER pAd,
20293+ IN USHORT Offset)
20294+{
20295+ UINT32 x;
20296+ USHORT data;
20297+
20298+ if (pAd->NicConfig2.field.AntDiversity)
20299+ {
20300+ pAd->EepromAccess = TRUE;
20301+ }
20302+//2008/09/11:KH add to support efuse<--
20303+//2008/09/11:KH add to support efuse-->
20304+{
20305+ Offset /= 2;
20306+ // reset bits and set EECS
20307+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
20308+ x &= ~(EEDI | EEDO | EESK);
20309+ x |= EECS;
20310+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
20311+
20312+ // patch can not access e-Fuse issue
20313+ if (!IS_RT3090(pAd))
20314+ {
20315+ // kick a pulse
20316+ RaiseClock(pAd, &x);
20317+ LowerClock(pAd, &x);
20318+ }
20319+
20320+ // output the read_opcode and register number in that order
20321+ ShiftOutBits(pAd, EEPROM_READ_OPCODE, 3);
20322+ ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
20323+
20324+ // Now read the data (16 bits) in from the selected EEPROM word
20325+ data = ShiftInBits(pAd);
20326+
20327+ EEpromCleanup(pAd);
20328+
20329+ // Antenna and EEPROM access are both using EESK pin,
20330+ // Therefor we should avoid accessing EESK at the same time
20331+ // Then restore antenna after EEPROM access
20332+ if ((pAd->NicConfig2.field.AntDiversity) || (pAd->RfIcType == RFIC_3020))
20333+ {
20334+ pAd->EepromAccess = FALSE;
20335+ AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
20336+ }
20337+}
20338+ return data;
20339+} //ReadEEprom
20340+
20341+VOID RTMP_EEPROM_WRITE16(
20342+ IN PRTMP_ADAPTER pAd,
20343+ IN USHORT Offset,
20344+ IN USHORT Data)
20345+{
20346+ UINT32 x;
20347+
20348+ if (pAd->NicConfig2.field.AntDiversity)
20349+ {
20350+ pAd->EepromAccess = TRUE;
20351+ }
20352+ //2008/09/11:KH add to support efuse<--
20353+//2008/09/11:KH add to support efuse-->
20354+ {
20355+ Offset /= 2;
20356+
20357+ EWEN(pAd);
20358+
20359+ // reset bits and set EECS
20360+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
20361+ x &= ~(EEDI | EEDO | EESK);
20362+ x |= EECS;
20363+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
20364+
20365+ // patch can not access e-Fuse issue
20366+ if (!IS_RT3090(pAd))
20367+ {
20368+ // kick a pulse
20369+ RaiseClock(pAd, &x);
20370+ LowerClock(pAd, &x);
20371+ }
20372+
20373+ // output the read_opcode ,register number and data in that order
20374+ ShiftOutBits(pAd, EEPROM_WRITE_OPCODE, 3);
20375+ ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
20376+ ShiftOutBits(pAd, Data, 16); // 16-bit access
20377+
20378+ // read DO status
20379+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
20380+
20381+ EEpromCleanup(pAd);
20382+
20383+ RTMPusecDelay(10000); //delay for twp(MAX)=10ms
20384+
20385+ EWDS(pAd);
20386+
20387+ EEpromCleanup(pAd);
20388+
20389+ // Antenna and EEPROM access are both using EESK pin,
20390+ // Therefor we should avoid accessing EESK at the same time
20391+ // Then restore antenna after EEPROM access
20392+ if ((pAd->NicConfig2.field.AntDiversity) || (pAd->RfIcType == RFIC_3020))
20393+ {
20394+ pAd->EepromAccess = FALSE;
20395+ AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
20396+ }
20397+}
20398+}
20399+
20400+//2008/09/11:KH add to support efuse<--
20401+#ifdef RT30xx
20402+/*
20403+ ========================================================================
20404+
20405+ Routine Description:
20406+
20407+ Arguments:
20408+
20409+ Return Value:
20410+
20411+ IRQL =
20412+
20413+ Note:
20414+
20415+ ========================================================================
20416+*/
20417+UCHAR eFuseReadRegisters(
20418+ IN PRTMP_ADAPTER pAd,
20419+ IN USHORT Offset,
20420+ IN USHORT Length,
20421+ OUT USHORT* pData)
20422+{
20423+ EFUSE_CTRL_STRUC eFuseCtrlStruc;
20424+ int i;
20425+ USHORT efuseDataOffset;
20426+ UINT32 data;
20427+
20428+ RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
20429+
20430+ //Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
20431+ //Use the eeprom logical address and covert to address to block number
20432+ eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
20433+
20434+ //Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 0.
20435+ eFuseCtrlStruc.field.EFSROM_MODE = 0;
20436+
20437+ //Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
20438+ eFuseCtrlStruc.field.EFSROM_KICK = 1;
20439+
20440+ NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
20441+ RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
20442+
20443+ //Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
20444+ i = 0;
20445+ while(i < 100)
20446+ {
20447+ //rtmp.HwMemoryReadDword(EFUSE_CTRL, (DWORD *) &eFuseCtrlStruc, 4);
20448+ RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
20449+ if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
20450+ {
20451+ break;
20452+ }
20453+ RTMPusecDelay(2);
20454+ i++;
20455+ }
20456+
20457+ //if EFSROM_AOUT is not found in physical address, write 0xffff
20458+ if (eFuseCtrlStruc.field.EFSROM_AOUT == 0x3f)
20459+ {
20460+ for(i=0; i<Length/2; i++)
20461+ *(pData+2*i) = 0xffff;
20462+ }
20463+ else
20464+ {
20465+ //Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x590-0x59C)
20466+ efuseDataOffset = EFUSE_DATA3 - (Offset & 0xC) ;
20467+ //data hold 4 bytes data.
20468+ //In RTMP_IO_READ32 will automatically execute 32-bytes swapping
20469+ RTMP_IO_READ32(pAd, efuseDataOffset, &data);
20470+ //Decide the upper 2 bytes or the bottom 2 bytes.
20471+ // Little-endian S | S Big-endian
20472+ // addr 3 2 1 0 | 0 1 2 3
20473+ // Ori-V D C B A | A B C D
20474+ //After swapping
20475+ // D C B A | D C B A
20476+ //Return 2-bytes
20477+ //The return byte statrs from S. Therefore, the little-endian will return BA, the Big-endian will return DC.
20478+ //For returning the bottom 2 bytes, the Big-endian should shift right 2-bytes.
20479+#ifdef RT_BIG_ENDIAN
20480+ data = data << (8*((Offset & 0x3)^0x2));
20481+#else
20482+ data = data >> (8*(Offset & 0x3));
20483+#endif
20484+
20485+ NdisMoveMemory(pData, &data, Length);
20486+ }
20487+
20488+ return (UCHAR) eFuseCtrlStruc.field.EFSROM_AOUT;
20489+
20490+}
20491+
20492+/*
20493+ ========================================================================
20494+
20495+ Routine Description:
20496+
20497+ Arguments:
20498+
20499+ Return Value:
20500+
20501+ IRQL =
20502+
20503+ Note:
20504+
20505+ ========================================================================
20506+*/
20507+VOID eFusePhysicalReadRegisters(
20508+ IN PRTMP_ADAPTER pAd,
20509+ IN USHORT Offset,
20510+ IN USHORT Length,
20511+ OUT USHORT* pData)
20512+{
20513+ EFUSE_CTRL_STRUC eFuseCtrlStruc;
20514+ int i;
20515+ USHORT efuseDataOffset;
20516+ UINT32 data;
20517+
20518+ RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
20519+
20520+ //Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
20521+ eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
20522+
20523+ //Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
20524+ //Read in physical view
20525+ eFuseCtrlStruc.field.EFSROM_MODE = 1;
20526+
20527+ //Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
20528+ eFuseCtrlStruc.field.EFSROM_KICK = 1;
20529+
20530+ NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
20531+ RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
20532+
20533+ //Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
20534+ i = 0;
20535+ while(i < 100)
20536+ {
20537+ RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
20538+ if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
20539+ break;
20540+ RTMPusecDelay(2);
20541+ i++;
20542+ }
20543+
20544+ //Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
20545+ //Because the size of each EFUSE_DATA is 4 Bytes, the size of address of each is 2 bits.
20546+ //The previous 2 bits is the EFUSE_DATA number, the last 2 bits is used to decide which bytes
20547+ //Decide which EFUSE_DATA to read
20548+ //590:F E D C
20549+ //594:B A 9 8
20550+ //598:7 6 5 4
20551+ //59C:3 2 1 0
20552+ efuseDataOffset = EFUSE_DATA3 - (Offset & 0xC) ;
20553+
20554+ RTMP_IO_READ32(pAd, efuseDataOffset, &data);
20555+
20556+#ifdef RT_BIG_ENDIAN
20557+ data = data << (8*((Offset & 0x3)^0x2));
20558+#else
20559+ data = data >> (8*(Offset & 0x3));
20560+#endif
20561+
20562+ NdisMoveMemory(pData, &data, Length);
20563+
20564+}
20565+
20566+/*
20567+ ========================================================================
20568+
20569+ Routine Description:
20570+
20571+ Arguments:
20572+
20573+ Return Value:
20574+
20575+ IRQL =
20576+
20577+ Note:
20578+
20579+ ========================================================================
20580+*/
20581+VOID eFuseReadPhysical(
20582+ IN PRTMP_ADAPTER pAd,
20583+ IN PUSHORT lpInBuffer,
20584+ IN ULONG nInBufferSize,
20585+ OUT PUSHORT lpOutBuffer,
20586+ IN ULONG nOutBufferSize
20587+)
20588+{
20589+ USHORT* pInBuf = (USHORT*)lpInBuffer;
20590+ USHORT* pOutBuf = (USHORT*)lpOutBuffer;
20591+
20592+ USHORT Offset = pInBuf[0]; //addr
20593+ USHORT Length = pInBuf[1]; //length
20594+ int i;
20595+
20596+ for(i=0; i<Length; i+=2)
20597+ {
20598+ eFusePhysicalReadRegisters(pAd,Offset+i, 2, &pOutBuf[i/2]);
20599+ }
20600+}
20601+
20602+/*
20603+ ========================================================================
20604+
20605+ Routine Description:
20606+
20607+ Arguments:
20608+
20609+ Return Value:
20610+
20611+ IRQL =
20612+
20613+ Note:
20614+
20615+ ========================================================================
20616+*/
20617+NTSTATUS eFuseRead(
20618+ IN PRTMP_ADAPTER pAd,
20619+ IN USHORT Offset,
20620+ OUT PUCHAR pData,
20621+ IN USHORT Length)
20622+{
20623+ USHORT* pOutBuf = (USHORT*)pData;
20624+ NTSTATUS Status = STATUS_SUCCESS;
20625+ UCHAR EFSROM_AOUT;
20626+ int i;
20627+
20628+ for(i=0; i<Length; i+=2)
20629+ {
20630+ EFSROM_AOUT = eFuseReadRegisters(pAd, Offset+i, 2, &pOutBuf[i/2]);
20631+ }
20632+ return Status;
20633+}
20634+
20635+/*
20636+ ========================================================================
20637+
20638+ Routine Description:
20639+
20640+ Arguments:
20641+
20642+ Return Value:
20643+
20644+ IRQL =
20645+
20646+ Note:
20647+
20648+ ========================================================================
20649+*/
20650+VOID eFusePhysicalWriteRegisters(
20651+ IN PRTMP_ADAPTER pAd,
20652+ IN USHORT Offset,
20653+ IN USHORT Length,
20654+ OUT USHORT* pData)
20655+{
20656+ EFUSE_CTRL_STRUC eFuseCtrlStruc;
20657+ int i;
20658+ USHORT efuseDataOffset;
20659+ UINT32 data, eFuseDataBuffer[4];
20660+
20661+ //Step0. Write 16-byte of data to EFUSE_DATA0-3 (0x590-0x59C), where EFUSE_DATA0 is the LSB DW, EFUSE_DATA3 is the MSB DW.
20662+
20663+ /////////////////////////////////////////////////////////////////
20664+ //read current values of 16-byte block
20665+ RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
20666+
20667+ //Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
20668+ eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
20669+
20670+ //Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
20671+ eFuseCtrlStruc.field.EFSROM_MODE = 1;
20672+
20673+ //Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
20674+ eFuseCtrlStruc.field.EFSROM_KICK = 1;
20675+
20676+ NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
20677+ RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
20678+
20679+ //Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
20680+ i = 0;
20681+ while(i < 100)
20682+ {
20683+ RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
20684+
20685+ if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
20686+ break;
20687+ RTMPusecDelay(2);
20688+ i++;
20689+ }
20690+
20691+ //Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
20692+ efuseDataOffset = EFUSE_DATA3;
20693+ for(i=0; i< 4; i++)
20694+ {
20695+ RTMP_IO_READ32(pAd, efuseDataOffset, (PUINT32) &eFuseDataBuffer[i]);
20696+ efuseDataOffset -= 4;
20697+ }
20698+
20699+ //Update the value, the offset is multiple of 2, length is 2
20700+ efuseDataOffset = (Offset & 0xc) >> 2;
20701+ data = pData[0] & 0xffff;
20702+ //The offset should be 0x***10 or 0x***00
20703+ if((Offset % 4) != 0)
20704+ {
20705+ eFuseDataBuffer[efuseDataOffset] = (eFuseDataBuffer[efuseDataOffset] & 0xffff) | (data << 16);
20706+ }
20707+ else
20708+ {
20709+ eFuseDataBuffer[efuseDataOffset] = (eFuseDataBuffer[efuseDataOffset] & 0xffff0000) | data;
20710+ }
20711+
20712+ efuseDataOffset = EFUSE_DATA3;
20713+ for(i=0; i< 4; i++)
20714+ {
20715+ RTMP_IO_WRITE32(pAd, efuseDataOffset, eFuseDataBuffer[i]);
20716+ efuseDataOffset -= 4;
20717+ }
20718+ /////////////////////////////////////////////////////////////////
20719+
20720+ //Step1. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
20721+ eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
20722+
20723+ //Step2. Write EFSROM_MODE (0x580, bit7:bit6) to 3.
20724+ eFuseCtrlStruc.field.EFSROM_MODE = 3;
20725+
20726+ //Step3. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical write procedure.
20727+ eFuseCtrlStruc.field.EFSROM_KICK = 1;
20728+
20729+ NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
20730+ RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
20731+
20732