aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2009-02-25 19:14:55 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2009-04-03 17:54:24 -0400
commite642f09951f7cbb69983781b07bb9cd881546ac4 (patch)
treec783967792f17f0abfab38c9a893fb9565b8bae2
parent21a6a6e9f81fb26fbcecbb1304018d34dcd1794f (diff)
Staging: add rt3070 wireless driver
This is the Ralink RT3070 driver from the company that does horrible things like reading a config file from /etc. However, the driver that is currently under development from the wireless development community is not working at all yet, so distros and users are using this version instead (quite common hardware on a lot of netbook machines). So here is this driver, for now, until the wireless developers get a "clean" version into the main tree, or until this version is cleaned up sufficiently to move out of the staging tree. Ported to the Linux build system, fixed lots of build issues, forward ported to the current kernel version, and other minor cleanups were all done by me. Cc: Linux wireless <linux-wireless@vger.kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/staging/Kconfig2
-rw-r--r--drivers/staging/Makefile1
-rw-r--r--drivers/staging/rt3070/2870_main_dev.c1627
-rw-r--r--drivers/staging/rt3070/Kconfig6
-rw-r--r--drivers/staging/rt3070/Makefile47
-rw-r--r--drivers/staging/rt3070/action.h68
-rw-r--r--drivers/staging/rt3070/aironet.h210
-rw-r--r--drivers/staging/rt3070/ap.h557
-rw-r--r--drivers/staging/rt3070/chlist.h1253
-rw-r--r--drivers/staging/rt3070/common/2870_rtmp_init.c1762
-rw-r--r--drivers/staging/rt3070/common/action.c1038
-rw-r--r--drivers/staging/rt3070/common/ba_action.c1810
-rw-r--r--drivers/staging/rt3070/common/cmm_data.c2827
-rw-r--r--drivers/staging/rt3070/common/cmm_data_2870.c980
-rw-r--r--drivers/staging/rt3070/common/cmm_info.c3395
-rw-r--r--drivers/staging/rt3070/common/cmm_sanity.c1669
-rw-r--r--drivers/staging/rt3070/common/cmm_sync.c711
-rw-r--r--drivers/staging/rt3070/common/cmm_wpa.c1606
-rw-r--r--drivers/staging/rt3070/common/dfs.c441
-rw-r--r--drivers/staging/rt3070/common/eeprom.c1498
-rw-r--r--drivers/staging/rt3070/common/md5.c1427
-rw-r--r--drivers/staging/rt3070/common/mlme.c9136
-rw-r--r--drivers/staging/rt3070/common/netif_block.c136
-rw-r--r--drivers/staging/rt3070/common/rtmp_init.c4197
-rw-r--r--drivers/staging/rt3070/common/rtmp_tkip.c1613
-rw-r--r--drivers/staging/rt3070/common/rtmp_wep.c508
-rw-r--r--drivers/staging/rt3070/common/rtusb_bulk.c1382
-rw-r--r--drivers/staging/rt3070/common/rtusb_data.c218
-rw-r--r--drivers/staging/rt3070/common/rtusb_io.c1908
-rw-r--r--drivers/staging/rt3070/common/spectrum.c1876
-rw-r--r--drivers/staging/rt3070/dfs.h100
-rw-r--r--drivers/staging/rt3070/firmware.h558
-rw-r--r--drivers/staging/rt3070/leap.h215
-rw-r--r--drivers/staging/rt3070/link_list.h134
-rw-r--r--drivers/staging/rt3070/md4.h42
-rw-r--r--drivers/staging/rt3070/md5.h107
-rw-r--r--drivers/staging/rt3070/mlme.h1468
-rw-r--r--drivers/staging/rt3070/netif_block.h58
-rw-r--r--drivers/staging/rt3070/oid.h1142
-rw-r--r--drivers/staging/rt3070/rt2870.h756
-rw-r--r--drivers/staging/rt3070/rt28xx.h2725
-rw-r--r--drivers/staging/rt3070/rt_ate.c6506
-rw-r--r--drivers/staging/rt3070/rt_ate.h294
-rw-r--r--drivers/staging/rt3070/rt_config.h121
-rw-r--r--drivers/staging/rt3070/rt_linux.c1063
-rw-r--r--drivers/staging/rt3070/rt_linux.h887
-rw-r--r--drivers/staging/rt3070/rt_main_dev.c1800
-rw-r--r--drivers/staging/rt3070/rt_profile.c2041
-rw-r--r--drivers/staging/rt3070/rtmp.h7728
-rw-r--r--drivers/staging/rt3070/rtmp_ckipmic.h113
-rw-r--r--drivers/staging/rt3070/rtmp_def.h1559
-rw-r--r--drivers/staging/rt3070/rtmp_type.h95
-rw-r--r--drivers/staging/rt3070/spectrum.h322
-rw-r--r--drivers/staging/rt3070/spectrum_def.h95
-rw-r--r--drivers/staging/rt3070/sta/aironet.c1312
-rw-r--r--drivers/staging/rt3070/sta/assoc.c2060
-rw-r--r--drivers/staging/rt3070/sta/auth.c475
-rw-r--r--drivers/staging/rt3070/sta/auth_rsp.c167
-rw-r--r--drivers/staging/rt3070/sta/connect.c2857
-rw-r--r--drivers/staging/rt3070/sta/dls.c2170
-rw-r--r--drivers/staging/rt3070/sta/rtmp_data.c2637
-rw-r--r--drivers/staging/rt3070/sta/sanity.c420
-rw-r--r--drivers/staging/rt3070/sta/sync.c1755
-rw-r--r--drivers/staging/rt3070/sta/wpa.c2099
-rw-r--r--drivers/staging/rt3070/sta_ioctl.c7203
-rw-r--r--drivers/staging/rt3070/wpa.h356
66 files changed, 97349 insertions, 0 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index c378078a40ef..073c154bdeb1 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -73,6 +73,8 @@ source "drivers/staging/rt2860/Kconfig"
73 73
74source "drivers/staging/rt2870/Kconfig" 74source "drivers/staging/rt2870/Kconfig"
75 75
76source "drivers/staging/rt3070/Kconfig"
77
76source "drivers/staging/comedi/Kconfig" 78source "drivers/staging/comedi/Kconfig"
77 79
78source "drivers/staging/asus_oled/Kconfig" 80source "drivers/staging/asus_oled/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 5e252a66fbe1..b69703e72c0c 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_AGNX) += agnx/
19obj-$(CONFIG_OTUS) += otus/ 19obj-$(CONFIG_OTUS) += otus/
20obj-$(CONFIG_RT2860) += rt2860/ 20obj-$(CONFIG_RT2860) += rt2860/
21obj-$(CONFIG_RT2870) += rt2870/ 21obj-$(CONFIG_RT2870) += rt2870/
22obj-$(CONFIG_RT3070) += rt3070/
22obj-$(CONFIG_COMEDI) += comedi/ 23obj-$(CONFIG_COMEDI) += comedi/
23obj-$(CONFIG_ASUS_OLED) += asus_oled/ 24obj-$(CONFIG_ASUS_OLED) += asus_oled/
24obj-$(CONFIG_PANEL) += panel/ 25obj-$(CONFIG_PANEL) += panel/
diff --git a/drivers/staging/rt3070/2870_main_dev.c b/drivers/staging/rt3070/2870_main_dev.c
new file mode 100644
index 000000000000..401ddb012131
--- /dev/null
+++ b/drivers/staging/rt3070/2870_main_dev.c
@@ -0,0 +1,1627 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 rtmp_main.c
29
30 Abstract:
31 main initialization routines
32
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36 Name Date Modification logs
37 Jan Lee 01-10-2005 modified
38 Sample Jun/01/07 Merge RT2870 and RT2860 drivers.
39*/
40
41#include "rt_config.h"
42
43
44// Following information will be show when you run 'modinfo'
45// *** If you have a solution for the bug in current version of driver, please mail to me.
46// Otherwise post to forum in ralinktech's web site(www.ralinktech.com) and let all users help you. ***
47MODULE_AUTHOR("Paul Lin <paul_lin@ralinktech.com>");
48MODULE_DESCRIPTION("RT2870 Wireless Lan Linux Driver");
49#ifdef CONFIG_STA_SUPPORT
50MODULE_LICENSE("GPL");
51#ifdef MODULE_VERSION
52MODULE_VERSION(STA_DRIVER_VERSION);
53#endif
54#endif // CONFIG_STA_SUPPORT //
55
56#ifdef MULTIPLE_CARD_SUPPORT
57// record whether the card in the card list is used in the card file
58extern UINT8 MC_CardUsed[];
59#endif // MULTIPLE_CARD_SUPPORT //
60
61/* Kernel thread and vars, which handles packets that are completed. Only
62 * packets that have a "complete" function are sent here. This way, the
63 * completion is run out of kernel context, and doesn't block the rest of
64 * the stack. */
65//static int mlme_kill = 0; // Mlme kernel thread
66//static int RTUSBCmd_kill = 0; // Command kernel thread
67//static int TimerFunc_kill = 0; // TimerQ kernel thread
68
69//static wait_queue_head_t timerWaitQ;
70//static wait_queue_t waitQ;
71
72extern INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p,
73 IN UINT argc, OUT PRTMP_ADAPTER *ppAd);
74
75
76/* module table */
77struct usb_device_id rtusb_usb_id[] = RT2870_USB_DEVICES;
78INT const rtusb_usb_id_len = sizeof(rtusb_usb_id) / sizeof(struct usb_device_id);
79MODULE_DEVICE_TABLE(usb, rtusb_usb_id);
80
81#ifndef PF_NOFREEZE
82#define PF_NOFREEZE 0
83#endif
84
85
86#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
87
88/**************************************************************************/
89/**************************************************************************/
90//tested for kernel 2.4 series
91/**************************************************************************/
92/**************************************************************************/
93static void *rtusb_probe(struct usb_device *dev, UINT interface,
94 const struct usb_device_id *id_table);
95static void rtusb_disconnect(struct usb_device *dev, void *ptr);
96
97struct usb_driver rtusb_driver = {
98 name:"rt2870",
99 probe:rtusb_probe,
100 disconnect:rtusb_disconnect,
101 id_table:rtusb_usb_id,
102 };
103
104#else
105
106#ifdef CONFIG_PM
107static int rt2870_suspend(struct usb_interface *intf, pm_message_t state);
108static int rt2870_resume(struct usb_interface *intf);
109#endif // CONFIG_PM //
110
111/**************************************************************************/
112/**************************************************************************/
113//tested for kernel 2.6series
114/**************************************************************************/
115/**************************************************************************/
116static int rtusb_probe (struct usb_interface *intf,
117 const struct usb_device_id *id);
118static void rtusb_disconnect(struct usb_interface *intf);
119
120struct usb_driver rtusb_driver = {
121#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
122 .owner = THIS_MODULE,
123#endif
124 .name="rt2870",
125 .probe=rtusb_probe,
126 .disconnect=rtusb_disconnect,
127 .id_table=rtusb_usb_id,
128
129#ifdef CONFIG_PM
130 suspend: rt2870_suspend,
131 resume: rt2870_resume,
132#endif
133 };
134
135#ifdef CONFIG_PM
136
137VOID RT2860RejectPendingPackets(
138 IN PRTMP_ADAPTER pAd)
139{
140 // clear PS packets
141 // clear TxSw packets
142}
143
144static int rt2870_suspend(
145 struct usb_interface *intf,
146 pm_message_t state)
147{
148 struct net_device *net_dev;
149 PRTMP_ADAPTER pAd = usb_get_intfdata(intf);
150
151
152 DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_suspend()\n"));
153 net_dev = pAd->net_dev;
154 netif_device_detach(net_dev);
155
156 pAd->PM_FlgSuspend = 1;
157 if (netif_running(net_dev)) {
158 RTUSBCancelPendingBulkInIRP(pAd);
159 RTUSBCancelPendingBulkOutIRP(pAd);
160 }
161 DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_suspend()\n"));
162 return 0;
163}
164
165static int rt2870_resume(
166 struct usb_interface *intf)
167{
168 struct net_device *net_dev;
169 PRTMP_ADAPTER pAd = usb_get_intfdata(intf);
170
171
172 DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_resume()\n"));
173
174 pAd->PM_FlgSuspend = 0;
175 net_dev = pAd->net_dev;
176 netif_device_attach(net_dev);
177 netif_start_queue(net_dev);
178 netif_carrier_on(net_dev);
179 netif_wake_queue(net_dev);
180
181 DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_resume()\n"));
182 return 0;
183}
184#endif // CONFIG_PM //
185#endif // LINUX_VERSION_CODE //
186
187
188// Init driver module
189INT __init rtusb_init(void)
190{
191 printk("rtusb init --->\n");
192 return usb_register(&rtusb_driver);
193}
194
195// Deinit driver module
196VOID __exit rtusb_exit(void)
197{
198 usb_deregister(&rtusb_driver);
199 printk("<--- rtusb exit\n");
200}
201
202module_init(rtusb_init);
203module_exit(rtusb_exit);
204
205
206
207
208/*--------------------------------------------------------------------- */
209/* function declarations */
210/*--------------------------------------------------------------------- */
211
212/*
213========================================================================
214Routine Description:
215 MLME kernel thread.
216
217Arguments:
218 *Context the pAd, driver control block pointer
219
220Return Value:
221 0 close the thread
222
223Note:
224========================================================================
225*/
226INT MlmeThread(
227 IN void *Context)
228{
229 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)Context;
230 POS_COOKIE pObj;
231 int status;
232
233 pObj = (POS_COOKIE)pAd->OS_Cookie;
234
235 rtmp_os_thread_init("rt2870MlmeThread", (PVOID)&(pAd->mlmeComplete));
236
237 while (pAd->mlme_kill == 0)
238 {
239 /* lock the device pointers */
240 //down(&(pAd->mlme_semaphore));
241 status = down_interruptible(&(pAd->mlme_semaphore));
242
243 /* lock the device pointers , need to check if required*/
244 //down(&(pAd->usbdev_semaphore));
245
246 if (!pAd->PM_FlgSuspend)
247 MlmeHandler(pAd);
248
249 /* unlock the device pointers */
250 //up(&(pAd->usbdev_semaphore));
251 if (status != 0)
252 {
253 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
254 break;
255 }
256 }
257
258 /* notify the exit routine that we're actually exiting now
259 *
260 * complete()/wait_for_completion() is similar to up()/down(),
261 * except that complete() is safe in the case where the structure
262 * is getting deleted in a parallel mode of execution (i.e. just
263 * after the down() -- that's necessary for the thread-shutdown
264 * case.
265 *
266 * complete_and_exit() goes even further than this -- it is safe in
267 * the case that the thread of the caller is going away (not just
268 * the structure) -- this is necessary for the module-remove case.
269 * This is important in preemption kernels, which transfer the flow
270 * of execution immediately upon a complete().
271 */
272 DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__FUNCTION__));
273
274 pObj->MLMEThr_pid = NULL;
275
276 complete_and_exit (&pAd->mlmeComplete, 0);
277 return 0;
278
279}
280
281
282/*
283========================================================================
284Routine Description:
285 USB command kernel thread.
286
287Arguments:
288 *Context the pAd, driver control block pointer
289
290Return Value:
291 0 close the thread
292
293Note:
294========================================================================
295*/
296INT RTUSBCmdThread(
297 IN void * Context)
298{
299 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)Context;
300 POS_COOKIE pObj;
301 int status;
302
303 pObj = (POS_COOKIE)pAd->OS_Cookie;
304
305 rtmp_os_thread_init("rt2870CmdThread", (PVOID)&(pAd->CmdQComplete));
306
307 NdisAcquireSpinLock(&pAd->CmdQLock);
308 pAd->CmdQ.CmdQState = RT2870_THREAD_RUNNING;
309 NdisReleaseSpinLock(&pAd->CmdQLock);
310
311 while (pAd->CmdQ.CmdQState == RT2870_THREAD_RUNNING)
312 {
313 /* lock the device pointers */
314 //down(&(pAd->RTUSBCmd_semaphore));
315 status = down_interruptible(&(pAd->RTUSBCmd_semaphore));
316
317 if (pAd->CmdQ.CmdQState == RT2870_THREAD_STOPED)
318 break;
319
320 if (status != 0)
321 {
322 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
323 break;
324 }
325 /* lock the device pointers , need to check if required*/
326 //down(&(pAd->usbdev_semaphore));
327
328 if (!pAd->PM_FlgSuspend)
329 CMDHandler(pAd);
330
331 /* unlock the device pointers */
332 //up(&(pAd->usbdev_semaphore));
333 }
334
335 if (!pAd->PM_FlgSuspend)
336 { // Clear the CmdQElements.
337 CmdQElmt *pCmdQElmt = NULL;
338
339 NdisAcquireSpinLock(&pAd->CmdQLock);
340 pAd->CmdQ.CmdQState = RT2870_THREAD_STOPED;
341 while(pAd->CmdQ.size)
342 {
343 RTUSBDequeueCmd(&pAd->CmdQ, &pCmdQElmt);
344 if (pCmdQElmt)
345 {
346 if (pCmdQElmt->CmdFromNdis == TRUE)
347 {
348 if (pCmdQElmt->buffer != NULL)
349 NdisFreeMemory(pCmdQElmt->buffer, pCmdQElmt->bufferlength, 0);
350
351 NdisFreeMemory(pCmdQElmt, sizeof(CmdQElmt), 0);
352 }
353 else
354 {
355 if ((pCmdQElmt->buffer != NULL) && (pCmdQElmt->bufferlength != 0))
356 NdisFreeMemory(pCmdQElmt->buffer, pCmdQElmt->bufferlength, 0);
357 {
358 NdisFreeMemory(pCmdQElmt, sizeof(CmdQElmt), 0);
359 }
360 }
361 }
362 }
363
364 NdisReleaseSpinLock(&pAd->CmdQLock);
365 }
366 /* notify the exit routine that we're actually exiting now
367 *
368 * complete()/wait_for_completion() is similar to up()/down(),
369 * except that complete() is safe in the case where the structure
370 * is getting deleted in a parallel mode of execution (i.e. just
371 * after the down() -- that's necessary for the thread-shutdown
372 * case.
373 *
374 * complete_and_exit() goes even further than this -- it is safe in
375 * the case that the thread of the caller is going away (not just
376 * the structure) -- this is necessary for the module-remove case.
377 * This is important in preemption kernels, which transfer the flow
378 * of execution immediately upon a complete().
379 */
380 DBGPRINT(RT_DEBUG_TRACE,( "<---RTUSBCmdThread\n"));
381
382 pObj->RTUSBCmdThr_pid = NULL;
383
384 complete_and_exit (&pAd->CmdQComplete, 0);
385 return 0;
386
387}
388
389
390static void RT2870_TimerQ_Handle(RTMP_ADAPTER *pAd)
391{
392 int status;
393 RALINK_TIMER_STRUCT *pTimer;
394 RT2870_TIMER_ENTRY *pEntry;
395 unsigned long irqFlag;
396
397 while(!pAd->TimerFunc_kill)
398 {
399// printk("waiting for event!\n");
400 pTimer = NULL;
401
402 status = down_interruptible(&(pAd->RTUSBTimer_semaphore));
403
404 if (pAd->TimerQ.status == RT2870_THREAD_STOPED)
405 break;
406
407 // event happened.
408 while(pAd->TimerQ.pQHead)
409 {
410 RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlag);
411 pEntry = pAd->TimerQ.pQHead;
412 if (pEntry)
413 {
414 pTimer = pEntry->pRaTimer;
415
416 // update pQHead
417 pAd->TimerQ.pQHead = pEntry->pNext;
418 if (pEntry == pAd->TimerQ.pQTail)
419 pAd->TimerQ.pQTail = NULL;
420
421 // return this queue entry to timerQFreeList.
422 pEntry->pNext = pAd->TimerQ.pQPollFreeList;
423 pAd->TimerQ.pQPollFreeList = pEntry;
424 }
425 RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlag);
426
427 if (pTimer)
428 {
429 if (pTimer->handle != NULL)
430 if (!pAd->PM_FlgSuspend)
431 pTimer->handle(NULL, (PVOID) pTimer->cookie, NULL, pTimer);
432 if ((pTimer->Repeat) && (pTimer->State == FALSE))
433 RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue);
434 }
435 }
436
437 if (status != 0)
438 {
439 pAd->TimerQ.status = RT2870_THREAD_STOPED;
440 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
441 break;
442 }
443 }
444}
445
446
447INT TimerQThread(
448 IN OUT PVOID Context)
449{
450 PRTMP_ADAPTER pAd;
451 POS_COOKIE pObj;
452
453 pAd = (PRTMP_ADAPTER)Context;
454 pObj = (POS_COOKIE) pAd->OS_Cookie;
455
456 rtmp_os_thread_init("rt2870TimerQHandle", (PVOID)&(pAd->TimerQComplete));
457
458 RT2870_TimerQ_Handle(pAd);
459
460 /* notify the exit routine that we're actually exiting now
461 *
462 * complete()/wait_for_completion() is similar to up()/down(),
463 * except that complete() is safe in the case where the structure
464 * is getting deleted in a parallel mode of execution (i.e. just
465 * after the down() -- that's necessary for the thread-shutdown
466 * case.
467 *
468 * complete_and_exit() goes even further than this -- it is safe in
469 * the case that the thread of the caller is going away (not just
470 * the structure) -- this is necessary for the module-remove case.
471 * This is important in preemption kernels, which transfer the flow
472 * of execution immediately upon a complete().
473 */
474 DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__FUNCTION__));
475
476 pObj->TimerQThr_pid = NULL;
477
478 complete_and_exit(&pAd->TimerQComplete, 0);
479 return 0;
480
481}
482
483
484RT2870_TIMER_ENTRY *RT2870_TimerQ_Insert(
485 IN RTMP_ADAPTER *pAd,
486 IN RALINK_TIMER_STRUCT *pTimer)
487{
488 RT2870_TIMER_ENTRY *pQNode = NULL, *pQTail;
489 unsigned long irqFlags;
490
491
492 RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
493 if (pAd->TimerQ.status & RT2870_THREAD_CAN_DO_INSERT)
494 {
495 if(pAd->TimerQ.pQPollFreeList)
496 {
497 pQNode = pAd->TimerQ.pQPollFreeList;
498 pAd->TimerQ.pQPollFreeList = pQNode->pNext;
499
500 pQNode->pRaTimer = pTimer;
501 pQNode->pNext = NULL;
502
503 pQTail = pAd->TimerQ.pQTail;
504 if (pAd->TimerQ.pQTail != NULL)
505 pQTail->pNext = pQNode;
506 pAd->TimerQ.pQTail = pQNode;
507 if (pAd->TimerQ.pQHead == NULL)
508 pAd->TimerQ.pQHead = pQNode;
509 }
510 RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
511
512 if (pQNode)
513 up(&pAd->RTUSBTimer_semaphore);
514 //wake_up(&timerWaitQ);
515 }
516 else
517 {
518 RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
519 }
520 return pQNode;
521}
522
523
524BOOLEAN RT2870_TimerQ_Remove(
525 IN RTMP_ADAPTER *pAd,
526 IN RALINK_TIMER_STRUCT *pTimer)
527{
528 RT2870_TIMER_ENTRY *pNode, *pPrev = NULL;
529 unsigned long irqFlags;
530
531 RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
532 if (pAd->TimerQ.status >= RT2870_THREAD_INITED)
533 {
534 pNode = pAd->TimerQ.pQHead;
535 while (pNode)
536 {
537 if (pNode->pRaTimer == pTimer)
538 break;
539 pPrev = pNode;
540 pNode = pNode->pNext;
541 }
542
543 // Now move it to freeList queue.
544 if (pNode)
545 {
546 if (pNode == pAd->TimerQ.pQHead)
547 pAd->TimerQ.pQHead = pNode->pNext;
548 if (pNode == pAd->TimerQ.pQTail)
549 pAd->TimerQ.pQTail = pPrev;
550 if (pPrev != NULL)
551 pPrev->pNext = pNode->pNext;
552
553 // return this queue entry to timerQFreeList.
554 pNode->pNext = pAd->TimerQ.pQPollFreeList;
555 pAd->TimerQ.pQPollFreeList = pNode;
556 }
557 }
558 RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
559
560 return TRUE;
561}
562
563
564void RT2870_TimerQ_Exit(RTMP_ADAPTER *pAd)
565{
566 RT2870_TIMER_ENTRY *pTimerQ;
567 unsigned long irqFlags;
568
569 RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
570 while (pAd->TimerQ.pQHead)
571 {
572 pTimerQ = pAd->TimerQ.pQHead;
573 pAd->TimerQ.pQHead = pTimerQ->pNext;
574 // remove the timeQ
575 }
576 pAd->TimerQ.pQPollFreeList = NULL;
577 os_free_mem(pAd, pAd->TimerQ.pTimerQPoll);
578 pAd->TimerQ.pQTail = NULL;
579 pAd->TimerQ.pQHead = NULL;
580 pAd->TimerQ.status = RT2870_THREAD_STOPED;
581 RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
582
583}
584
585
586void RT2870_TimerQ_Init(RTMP_ADAPTER *pAd)
587{
588 int i;
589 RT2870_TIMER_ENTRY *pQNode, *pEntry;
590 unsigned long irqFlags;
591
592 NdisAllocateSpinLock(&pAd->TimerQLock);
593
594 RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
595 NdisZeroMemory(&pAd->TimerQ, sizeof(pAd->TimerQ));
596 //InterlockedExchange(&pAd->TimerQ.count, 0);
597
598 /* Initialise the wait q head */
599 //init_waitqueue_head(&timerWaitQ);
600
601 os_alloc_mem(pAd, &pAd->TimerQ.pTimerQPoll, sizeof(RT2870_TIMER_ENTRY) * TIMER_QUEUE_SIZE_MAX);
602 if (pAd->TimerQ.pTimerQPoll)
603 {
604 pEntry = NULL;
605 pQNode = (RT2870_TIMER_ENTRY *)pAd->TimerQ.pTimerQPoll;
606 for (i = 0 ;i <TIMER_QUEUE_SIZE_MAX; i++)
607 {
608 pQNode->pNext = pEntry;
609 pEntry = pQNode;
610 pQNode++;
611 }
612 pAd->TimerQ.pQPollFreeList = pEntry;
613 pAd->TimerQ.pQHead = NULL;
614 pAd->TimerQ.pQTail = NULL;
615 pAd->TimerQ.status = RT2870_THREAD_INITED;
616 }
617 RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
618}
619
620
621VOID RT2870_WatchDog(IN RTMP_ADAPTER *pAd)
622{
623 PHT_TX_CONTEXT pHTTXContext;
624 int idx;
625 ULONG irqFlags;
626 PURB pUrb;
627 BOOLEAN needDumpSeq = FALSE;
628 UINT32 MACValue;
629
630
631 idx = 0;
632 RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
633 if ((MACValue & 0xff) !=0 )
634 {
635 DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 0 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue));
636 RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40012);
637 while((MACValue &0xff) != 0 && (idx++ < 10))
638 {
639 RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
640 NdisMSleep(1);
641 }
642 RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006);
643 }
644
645//PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
646#ifdef CONFIG_STA_SUPPORT
647 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
648 {
649 idx = 0;
650 if ((MACValue & 0xff00) !=0 )
651 {
652 DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 1 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue));
653 RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf4000a);
654 while((MACValue &0xff00) != 0 && (idx++ < 10))
655 {
656 RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
657 NdisMSleep(1);
658 }
659 RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006);
660 }
661 }
662#endif // CONFIG_STA_SUPPORT //
663
664 if (pAd->watchDogRxOverFlowCnt >= 2)
665 {
666 DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Rx Bulk-In hanged! Cancel the pending Rx bulks request!\n"));
667 if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
668 fRTMP_ADAPTER_BULKIN_RESET |
669 fRTMP_ADAPTER_HALT_IN_PROGRESS |
670 fRTMP_ADAPTER_NIC_NOT_EXIST))))
671 {
672 DBGPRINT(RT_DEBUG_TRACE, ("Call CMDTHREAD_RESET_BULK_IN to cancel the pending Rx Bulk!\n"));
673 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
674 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0);
675 needDumpSeq = TRUE;
676 }
677 pAd->watchDogRxOverFlowCnt = 0;
678 }
679
680
681 for (idx = 0; idx < NUM_OF_TX_RING; idx++)
682 {
683 pUrb = NULL;
684
685 RTMP_IRQ_LOCK(&pAd->BulkOutLock[idx], irqFlags);
686 if ((pAd->BulkOutPending[idx] == TRUE) && pAd->watchDogTxPendingCnt)
687 {
688 pAd->watchDogTxPendingCnt[idx]++;
689
690 if ((pAd->watchDogTxPendingCnt[idx] > 2) &&
691 (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_BULKOUT_RESET)))
692 )
693 {
694 // FIXME: Following code just support single bulk out. If you wanna support multiple bulk out. Modify it!
695 pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[idx]);
696 if (pHTTXContext->IRPPending)
697 { // Check TxContext.
698 pUrb = pHTTXContext->pUrb;
699 }
700 else if (idx == MGMTPIPEIDX)
701 {
702 PTX_CONTEXT pMLMEContext, pNULLContext, pPsPollContext;
703
704 //Check MgmtContext.
705 pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa);
706 pPsPollContext = (PTX_CONTEXT)(&pAd->PsPollContext);
707 pNULLContext = (PTX_CONTEXT)(&pAd->NullContext);
708
709 if (pMLMEContext->IRPPending)
710 {
711 ASSERT(pMLMEContext->IRPPending);
712 pUrb = pMLMEContext->pUrb;
713 }
714 else if (pNULLContext->IRPPending)
715 {
716 ASSERT(pNULLContext->IRPPending);
717 pUrb = pNULLContext->pUrb;
718 }
719 else if (pPsPollContext->IRPPending)
720 {
721 ASSERT(pPsPollContext->IRPPending);
722 pUrb = pPsPollContext->pUrb;
723 }
724 }
725
726 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
727
728 DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Tx Bulk-Out hanged! Cancel the pending Tx bulks request of idx(%d)!\n", idx));
729 if (pUrb)
730 {
731 DBGPRINT(RT_DEBUG_TRACE, ("Unlink the pending URB!\n"));
732 // unlink it now
733 RTUSB_UNLINK_URB(pUrb);
734 // Sleep 200 microseconds to give cancellation time to work
735 RTMPusecDelay(200);
736 needDumpSeq = TRUE;
737 }
738 else
739 {
740 DBGPRINT(RT_DEBUG_ERROR, ("Unkonw bulkOut URB maybe hanged!!!!!!!!!!!!\n"));
741 }
742 }
743 else
744 {
745 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
746 }
747 }
748 else
749 {
750 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
751 }
752 }
753
754#ifdef DOT11_N_SUPPORT
755 // For Sigma debug, dump the ba_reordering sequence.
756 if((needDumpSeq == TRUE) && (pAd->CommonCfg.bDisableReordering == 0))
757 {
758 USHORT Idx;
759 PBA_REC_ENTRY pBAEntry = NULL;
760 UCHAR count = 0;
761 struct reordering_mpdu *mpdu_blk;
762
763 Idx = pAd->MacTab.Content[BSSID_WCID].BARecWcidArray[0];
764
765 pBAEntry = &pAd->BATable.BARecEntry[Idx];
766 if((pBAEntry->list.qlen > 0) && (pBAEntry->list.next != NULL))
767 {
768 DBGPRINT(RT_DEBUG_TRACE, ("NICUpdateRawCounters():The Queueing pkt in reordering buffer:\n"));
769 NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
770 mpdu_blk = pBAEntry->list.next;
771 while (mpdu_blk)
772 {
773 DBGPRINT(RT_DEBUG_TRACE, ("\t%d:Seq-%d, bAMSDU-%d!\n", count, mpdu_blk->Sequence, mpdu_blk->bAMSDU));
774 mpdu_blk = mpdu_blk->next;
775 count++;
776 }
777
778 DBGPRINT(RT_DEBUG_TRACE, ("\npBAEntry->LastIndSeq=%d!\n", pBAEntry->LastIndSeq));
779 NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
780 }
781 }
782#endif // DOT11_N_SUPPORT //
783}
784
785/*
786========================================================================
787Routine Description:
788 Release allocated resources.
789
790Arguments:
791 *dev Point to the PCI or USB device
792 pAd driver control block pointer
793
794Return Value:
795 None
796
797Note:
798========================================================================
799*/
800static void _rtusb_disconnect(struct usb_device *dev, PRTMP_ADAPTER pAd)
801{
802 struct net_device *net_dev = NULL;
803
804
805 DBGPRINT(RT_DEBUG_ERROR, ("rtusb_disconnect: unregister usbnet usb-%s-%s\n",
806 dev->bus->bus_name, dev->devpath));
807 if (!pAd)
808 {
809#ifdef MULTIPLE_CARD_SUPPORT
810 if ((pAd->MC_RowID >= 0) && (pAd->MC_RowID <= MAX_NUM_OF_MULTIPLE_CARD))
811 MC_CardUsed[pAd->MC_RowID] = 0; // not clear MAC address
812#endif // MULTIPLE_CARD_SUPPORT //
813
814#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
815 while(MOD_IN_USE > 0)
816 {
817 MOD_DEC_USE_COUNT;
818 }
819#else
820 usb_put_dev(dev);
821#endif // LINUX_VERSION_CODE //
822
823 printk("rtusb_disconnect: pAd == NULL!\n");
824 return;
825 }
826 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
827
828
829
830 // for debug, wait to show some messages to /proc system
831 udelay(1);
832
833
834
835
836 net_dev = pAd->net_dev;
837 if (pAd->net_dev != NULL)
838 {
839 printk("rtusb_disconnect: unregister_netdev(), dev->name=%s!\n", net_dev->name);
840 unregister_netdev (pAd->net_dev);
841 }
842 udelay(1);
843#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
844#else
845 flush_scheduled_work();
846#endif // LINUX_VERSION_CODE //
847 udelay(1);
848
849 // free net_device memory
850#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
851 kfree(net_dev);
852#else
853 free_netdev(net_dev);
854#endif // LINUX_VERSION_CODE //
855
856 // free adapter memory
857 RTMPFreeAdapter(pAd);
858
859 // release a use of the usb device structure
860#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
861 while(MOD_IN_USE > 0)
862 {
863 MOD_DEC_USE_COUNT;
864 }
865#else
866 usb_put_dev(dev);
867#endif // LINUX_VERSION_CODE //
868 udelay(1);
869
870 DBGPRINT(RT_DEBUG_ERROR, (" RTUSB disconnect successfully\n"));
871}
872
873
874/*
875========================================================================
876Routine Description:
877 Probe RT28XX chipset.
878
879Arguments:
880 *dev Point to the PCI or USB device
881 interface
882 *id_table Point to the PCI or USB device ID
883
884Return Value:
885 None
886
887Note:
888========================================================================
889*/
890#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
891static void *rtusb_probe(struct usb_device *dev, UINT interface,
892 const struct usb_device_id *id)
893{
894 PRTMP_ADAPTER pAd;
895 rt28xx_probe((void *)dev, (void *)id, interface, &pAd);
896 return (void *)pAd;
897}
898
899//Disconnect function is called within exit routine
900static void rtusb_disconnect(struct usb_device *dev, void *ptr)
901{
902 _rtusb_disconnect(dev, ((PRTMP_ADAPTER)ptr));
903}
904
905#else /* kernel 2.6 series */
906static int rtusb_probe (struct usb_interface *intf,
907 const struct usb_device_id *id)
908{
909 PRTMP_ADAPTER pAd;
910 return (int)rt28xx_probe((void *)intf, (void *)id, 0, &pAd);
911}
912
913
914static void rtusb_disconnect(struct usb_interface *intf)
915{
916 struct usb_device *dev = interface_to_usbdev(intf);
917 PRTMP_ADAPTER pAd;
918
919
920 pAd = usb_get_intfdata(intf);
921 usb_set_intfdata(intf, NULL);
922
923 _rtusb_disconnect(dev, pAd);
924}
925#endif // LINUX_VERSION_CODE //
926
927
928/*
929========================================================================
930Routine Description:
931 Close kernel threads.
932
933Arguments:
934 *pAd the raxx interface data pointer
935
936Return Value:
937 NONE
938
939Note:
940========================================================================
941*/
942VOID RT28xxThreadTerminate(
943 IN RTMP_ADAPTER *pAd)
944{
945 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
946 INT ret;
947
948
949 // Sleep 50 milliseconds so pending io might finish normally
950 RTMPusecDelay(50000);
951
952 // We want to wait until all pending receives and sends to the
953 // device object. We cancel any
954 // irps. Wait until sends and receives have stopped.
955 RTUSBCancelPendingIRPs(pAd);
956
957 // Terminate Threads
958 if (pObj->MLMEThr_pid)
959 {
960 printk("Terminate the MLMEThr_pid=%d!\n", pid_nr(pObj->MLMEThr_pid));
961 mb();
962 pAd->mlme_kill = 1;
963 //RT28XX_MLME_HANDLER(pAd);
964 mb();
965 ret = kill_pid(pObj->MLMEThr_pid, SIGTERM, 1);
966 if (ret)
967 {
968 printk (KERN_WARNING "%s: unable to Mlme thread, pid=%d, ret=%d!\n",
969 pAd->net_dev->name, pid_nr(pObj->MLMEThr_pid), ret);
970 }
971 else
972 {
973 //wait_for_completion (&pAd->notify);
974 wait_for_completion (&pAd->mlmeComplete);
975 pObj->MLMEThr_pid = NULL;
976 }
977 }
978
979 if (pObj->RTUSBCmdThr_pid >= 0)
980 {
981 printk("Terminate the RTUSBCmdThr_pid=%d!\n", pid_nr(pObj->RTUSBCmdThr_pid));
982 mb();
983 NdisAcquireSpinLock(&pAd->CmdQLock);
984 pAd->CmdQ.CmdQState = RT2870_THREAD_STOPED;
985 NdisReleaseSpinLock(&pAd->CmdQLock);
986 mb();
987 //RTUSBCMDUp(pAd);
988 ret = kill_pid(pObj->RTUSBCmdThr_pid, SIGTERM, 1);
989 if (ret)
990 {
991 printk(KERN_WARNING "%s: unable to RTUSBCmd thread, pid=%d, ret=%d!\n",
992 pAd->net_dev->name, pid_nr(pObj->RTUSBCmdThr_pid), ret);
993 }
994 else
995 {
996 //wait_for_completion (&pAd->notify);
997 wait_for_completion (&pAd->CmdQComplete);
998 pObj->RTUSBCmdThr_pid = NULL;
999 }
1000 }
1001 if (pObj->TimerQThr_pid >= 0)
1002 {
1003 POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
1004
1005 printk("Terminate the TimerQThr_pid=%d!\n", pid_nr(pObj->TimerQThr_pid));
1006 mb();
1007 pAd->TimerFunc_kill = 1;
1008 mb();
1009 ret = kill_pid(pObj->TimerQThr_pid, SIGTERM, 1);
1010 if (ret)
1011 {
1012 printk(KERN_WARNING "%s: unable to stop TimerQThread, pid=%d, ret=%d!\n",
1013 pAd->net_dev->name, pid_nr(pObj->TimerQThr_pid), ret);
1014 }
1015 else
1016 {
1017 printk("wait_for_completion TimerQThr\n");
1018 wait_for_completion(&pAd->TimerQComplete);
1019 pObj->TimerQThr_pid = NULL;
1020 }
1021 }
1022 // Kill tasklets
1023 pAd->mlme_kill = 0;
1024 pAd->CmdQ.CmdQState = RT2870_THREAD_UNKNOWN;
1025 pAd->TimerFunc_kill = 0;
1026}
1027
1028
1029void kill_thread_task(IN PRTMP_ADAPTER pAd)
1030{
1031 POS_COOKIE pObj;
1032
1033 pObj = (POS_COOKIE) pAd->OS_Cookie;
1034
1035 tasklet_kill(&pObj->rx_done_task);
1036 tasklet_kill(&pObj->mgmt_dma_done_task);
1037 tasklet_kill(&pObj->ac0_dma_done_task);
1038 tasklet_kill(&pObj->ac1_dma_done_task);
1039 tasklet_kill(&pObj->ac2_dma_done_task);
1040 tasklet_kill(&pObj->ac3_dma_done_task);
1041 tasklet_kill(&pObj->hcca_dma_done_task);
1042 tasklet_kill(&pObj->tbtt_task);
1043
1044}
1045
1046
1047/*
1048========================================================================
1049Routine Description:
1050 Check the chipset vendor/product ID.
1051
1052Arguments:
1053 _dev_p Point to the PCI or USB device
1054
1055Return Value:
1056 TRUE Check ok
1057 FALSE Check fail
1058
1059Note:
1060========================================================================
1061*/
1062BOOLEAN RT28XXChipsetCheck(
1063 IN void *_dev_p)
1064{
1065#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
1066 struct usb_device *dev_p = (struct usb_device *)_dev_p;
1067#else
1068 struct usb_interface *intf = (struct usb_interface *)_dev_p;
1069 struct usb_device *dev_p = interface_to_usbdev(intf);
1070#endif // LINUX_VERSION_CODE //
1071 UINT32 i;
1072
1073
1074 for(i=0; i<rtusb_usb_id_len; i++)
1075 {
1076 if (dev_p->descriptor.idVendor == rtusb_usb_id[i].idVendor &&
1077 dev_p->descriptor.idProduct == rtusb_usb_id[i].idProduct)
1078 {
1079 printk("rt2870: idVendor = 0x%x, idProduct = 0x%x\n",
1080 dev_p->descriptor.idVendor, dev_p->descriptor.idProduct);
1081 break;
1082 }
1083 }
1084
1085 if (i == rtusb_usb_id_len)
1086 {
1087 printk("rt2870: Error! Device Descriptor not matching!\n");
1088 return FALSE;
1089 }
1090
1091 return TRUE;
1092}
1093
1094
1095/*
1096========================================================================
1097Routine Description:
1098 Init net device structure.
1099
1100Arguments:
1101 _dev_p Point to the PCI or USB device
1102 *net_dev Point to the net device
1103 *pAd the raxx interface data pointer
1104
1105Return Value:
1106 TRUE Init ok
1107 FALSE Init fail
1108
1109Note:
1110========================================================================
1111*/
1112BOOLEAN RT28XXNetDevInit(
1113 IN void *_dev_p,
1114 IN struct net_device *net_dev,
1115 IN RTMP_ADAPTER *pAd)
1116{
1117#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
1118 struct usb_device *dev_p = (struct usb_device *)_dev_p;
1119#else
1120 struct usb_interface *intf = (struct usb_interface *)_dev_p;
1121 struct usb_device *dev_p = interface_to_usbdev(intf);
1122#endif // LINUX_VERSION_CODE //
1123
1124
1125#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
1126 pAd->config = dev_p->config;
1127#else
1128 pAd->config = &dev_p->config->desc;
1129#endif // LINUX_VERSION_CODE //
1130 return TRUE;
1131}
1132
1133
1134/*
1135========================================================================
1136Routine Description:
1137 Init net device structure.
1138
1139Arguments:
1140 _dev_p Point to the PCI or USB device
1141 *pAd the raxx interface data pointer
1142
1143Return Value:
1144 TRUE Config ok
1145 FALSE Config fail
1146
1147Note:
1148========================================================================
1149*/
1150#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
1151BOOLEAN RT28XXProbePostConfig(
1152 IN void *_dev_p,
1153 IN RTMP_ADAPTER *pAd,
1154 IN INT32 interface)
1155{
1156 struct usb_device *dev_p = (struct usb_device *)_dev_p;
1157 struct usb_interface *intf;
1158 struct usb_interface_descriptor *iface_desc;
1159 struct usb_endpoint_descriptor *endpoint;
1160 ULONG BulkOutIdx;
1161 UINT32 i;
1162
1163
1164 /* get the active interface descriptor */
1165 intf = &dev_p->actconfig->interface[interface];
1166 iface_desc = &intf->altsetting[0];
1167
1168 /* get # of enpoints */
1169 pAd->NumberOfPipes = iface_desc->bNumEndpoints;
1170 DBGPRINT(RT_DEBUG_TRACE, ("NumEndpoints=%d\n", iface_desc->bNumEndpoints));
1171
1172 /* Configure Pipes */
1173 endpoint = &iface_desc->endpoint[0];
1174 BulkOutIdx = 0;
1175
1176 for(i=0; i<pAd->NumberOfPipes; i++)
1177 {
1178 if ((endpoint[i].bmAttributes == USB_ENDPOINT_XFER_BULK) &&
1179 ((endpoint[i].bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN))
1180 {
1181 pAd->BulkInEpAddr = endpoint[i].bEndpointAddress;
1182 pAd->BulkInMaxPacketSize = endpoint[i].wMaxPacketSize;
1183
1184 DBGPRINT_RAW(RT_DEBUG_TRACE,
1185 ("BULK IN MaximumPacketSize = %d\n", pAd->BulkInMaxPacketSize));
1186 DBGPRINT_RAW(RT_DEBUG_TRACE,
1187 ("EP address = 0x%2x \n", endpoint[i].bEndpointAddress));
1188 }
1189 else if ((endpoint[i].bmAttributes == USB_ENDPOINT_XFER_BULK) &&
1190 ((endpoint[i].bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT))
1191 {
1192 // There are 6 bulk out EP. EP6 highest priority.
1193 // EP1-4 is EDCA. EP5 is HCCA.
1194 pAd->BulkOutEpAddr[BulkOutIdx++] = endpoint[i].bEndpointAddress;
1195 pAd->BulkOutMaxPacketSize = endpoint[i].wMaxPacketSize;
1196
1197 DBGPRINT_RAW(RT_DEBUG_TRACE,
1198 ("BULK OUT MaximumPacketSize = %d\n", pAd->BulkOutMaxPacketSize));
1199 DBGPRINT_RAW(RT_DEBUG_TRACE,
1200 ("EP address = 0x%2x \n", endpoint[i].bEndpointAddress));
1201 }
1202 }
1203
1204 if (!(pAd->BulkInEpAddr && pAd->BulkOutEpAddr[0]))
1205 {
1206 printk("Could not find both bulk-in and bulk-out endpoints\n");
1207 return FALSE;
1208 }
1209
1210 return TRUE;
1211}
1212
1213#else
1214BOOLEAN RT28XXProbePostConfig(
1215 IN void *_dev_p,
1216 IN RTMP_ADAPTER *pAd,
1217 IN INT32 interface)
1218{
1219 struct usb_interface *intf = (struct usb_interface *)_dev_p;
1220 struct usb_host_interface *iface_desc;
1221 ULONG BulkOutIdx;
1222 UINT32 i;
1223
1224
1225 /* get the active interface descriptor */
1226 iface_desc = intf->cur_altsetting;
1227
1228 /* get # of enpoints */
1229 pAd->NumberOfPipes = iface_desc->desc.bNumEndpoints;
1230 DBGPRINT(RT_DEBUG_TRACE,
1231 ("NumEndpoints=%d\n", iface_desc->desc.bNumEndpoints));
1232
1233 /* Configure Pipes */
1234 BulkOutIdx = 0;
1235
1236 for(i=0; i<pAd->NumberOfPipes; i++)
1237 {
1238 if ((iface_desc->endpoint[i].desc.bmAttributes ==
1239 USB_ENDPOINT_XFER_BULK) &&
1240 ((iface_desc->endpoint[i].desc.bEndpointAddress &
1241 USB_ENDPOINT_DIR_MASK) == USB_DIR_IN))
1242 {
1243 pAd->BulkInEpAddr = iface_desc->endpoint[i].desc.bEndpointAddress;
1244 pAd->BulkInMaxPacketSize = iface_desc->endpoint[i].desc.wMaxPacketSize;
1245
1246 DBGPRINT_RAW(RT_DEBUG_TRACE,
1247 ("BULK IN MaximumPacketSize = %d\n", pAd->BulkInMaxPacketSize));
1248 DBGPRINT_RAW(RT_DEBUG_TRACE,
1249 ("EP address = 0x%2x\n", iface_desc->endpoint[i].desc.bEndpointAddress));
1250 }
1251 else if ((iface_desc->endpoint[i].desc.bmAttributes ==
1252 USB_ENDPOINT_XFER_BULK) &&
1253 ((iface_desc->endpoint[i].desc.bEndpointAddress &
1254 USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT))
1255 {
1256 // there are 6 bulk out EP. EP6 highest priority.
1257 // EP1-4 is EDCA. EP5 is HCCA.
1258 pAd->BulkOutEpAddr[BulkOutIdx++] = iface_desc->endpoint[i].desc.bEndpointAddress;
1259 pAd->BulkOutMaxPacketSize = iface_desc->endpoint[i].desc.wMaxPacketSize;
1260
1261 DBGPRINT_RAW(RT_DEBUG_TRACE,
1262 ("BULK OUT MaximumPacketSize = %d\n", pAd->BulkOutMaxPacketSize));
1263 DBGPRINT_RAW(RT_DEBUG_TRACE,
1264 ("EP address = 0x%2x \n", iface_desc->endpoint[i].desc.bEndpointAddress));
1265 }
1266 }
1267
1268 if (!(pAd->BulkInEpAddr && pAd->BulkOutEpAddr[0]))
1269 {
1270 printk("%s: Could not find both bulk-in and bulk-out endpoints\n", __FUNCTION__);
1271 return FALSE;
1272 }
1273
1274 return TRUE;
1275}
1276#endif // LINUX_VERSION_CODE //
1277
1278
1279/*
1280========================================================================
1281Routine Description:
1282 Disable DMA.
1283
1284Arguments:
1285 *pAd the raxx interface data pointer
1286
1287Return Value:
1288 None
1289
1290Note:
1291========================================================================
1292*/
1293VOID RT28XXDMADisable(
1294 IN RTMP_ADAPTER *pAd)
1295{
1296 // no use
1297}
1298
1299
1300
1301/*
1302========================================================================
1303Routine Description:
1304 Enable DMA.
1305
1306Arguments:
1307 *pAd the raxx interface data pointer
1308
1309Return Value:
1310 None
1311
1312Note:
1313========================================================================
1314*/
1315VOID RT28XXDMAEnable(
1316 IN RTMP_ADAPTER *pAd)
1317{
1318 WPDMA_GLO_CFG_STRUC GloCfg;
1319 USB_DMA_CFG_STRUC UsbCfg;
1320 int i = 0;
1321
1322
1323 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
1324 do
1325 {
1326 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
1327 if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
1328 break;
1329
1330 DBGPRINT(RT_DEBUG_TRACE, ("==> DMABusy\n"));
1331 RTMPusecDelay(1000);
1332 i++;
1333 }while ( i <200);
1334
1335
1336 RTMPusecDelay(50);
1337 GloCfg.field.EnTXWriteBackDDONE = 1;
1338 GloCfg.field.EnableRxDMA = 1;
1339 GloCfg.field.EnableTxDMA = 1;
1340 DBGPRINT(RT_DEBUG_TRACE, ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word));
1341 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
1342
1343 UsbCfg.word = 0;
1344 UsbCfg.field.phyclear = 0;
1345 /* usb version is 1.1,do not use bulk in aggregation */
1346 if (pAd->BulkInMaxPacketSize == 512)
1347 UsbCfg.field.RxBulkAggEn = 1;
1348 /* for last packet, PBF might use more than limited, so minus 2 to prevent from error */
1349 UsbCfg.field.RxBulkAggLmt = (MAX_RXBULK_SIZE /1024)-3;
1350 UsbCfg.field.RxBulkAggTOut = 0x80; /* 2006-10-18 */
1351 UsbCfg.field.RxBulkEn = 1;
1352 UsbCfg.field.TxBulkEn = 1;
1353
1354 RTUSBWriteMACRegister(pAd, USB_DMA_CFG, UsbCfg.word);
1355
1356}
1357
1358/*
1359========================================================================
1360Routine Description:
1361 Write Beacon buffer to Asic.
1362
1363Arguments:
1364 *pAd the raxx interface data pointer
1365
1366Return Value:
1367 None
1368
1369Note:
1370========================================================================
1371*/
1372VOID RT28xx_UpdateBeaconToAsic(
1373 IN RTMP_ADAPTER *pAd,
1374 IN INT apidx,
1375 IN ULONG FrameLen,
1376 IN ULONG UpdatePos)
1377{
1378 PUCHAR pBeaconFrame = NULL;
1379 UCHAR *ptr;
1380 UINT i, padding;
1381 BEACON_SYNC_STRUCT *pBeaconSync = pAd->CommonCfg.pBeaconSync;
1382 UINT32 longValue;
1383// USHORT shortValue;
1384 BOOLEAN bBcnReq = FALSE;
1385 UCHAR bcn_idx = 0;
1386
1387
1388 if (pBeaconFrame == NULL)
1389 {
1390 DBGPRINT(RT_DEBUG_ERROR,("pBeaconFrame is NULL!\n"));
1391 return;
1392 }
1393
1394 if (pBeaconSync == NULL)
1395 {
1396 DBGPRINT(RT_DEBUG_ERROR,("pBeaconSync is NULL!\n"));
1397 return;
1398 }
1399
1400 //if ((pAd->WdsTab.Mode == WDS_BRIDGE_MODE) ||
1401 // ((pAd->ApCfg.MBSSID[apidx].MSSIDDev == NULL) || !(pAd->ApCfg.MBSSID[apidx].MSSIDDev->flags & IFF_UP))
1402 // )
1403 if (bBcnReq == FALSE)
1404 {
1405 /* when the ra interface is down, do not send its beacon frame */
1406 /* clear all zero */
1407 for(i=0; i<TXWI_SIZE; i+=4) {
1408 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, 0x00);
1409 }
1410 pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
1411 NdisZeroMemory(pBeaconSync->BeaconTxWI[bcn_idx], TXWI_SIZE);
1412 }
1413 else
1414 {
1415 ptr = (PUCHAR)&pAd->BeaconTxWI;
1416#ifdef RT_BIG_ENDIAN
1417 RTMPWIEndianChange(ptr, TYPE_TXWI);
1418#endif
1419 if (NdisEqualMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE) == FALSE)
1420 { // If BeaconTxWI changed, we need to rewrite the TxWI for the Beacon frames.
1421 pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
1422 NdisMoveMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE);
1423 }
1424
1425 if ((pBeaconSync->BeaconBitMap & (1 << bcn_idx)) != (1 << bcn_idx))
1426 {
1427 for (i=0; i<TXWI_SIZE; i+=4) // 16-byte TXWI field
1428 {
1429 longValue = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
1430 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, longValue);
1431 ptr += 4;
1432 }
1433 }
1434
1435 ptr = pBeaconSync->BeaconBuf[bcn_idx];
1436 padding = (FrameLen & 0x01);
1437 NdisZeroMemory((PUCHAR)(pBeaconFrame + FrameLen), padding);
1438 FrameLen += padding;
1439 for (i = 0 ; i < FrameLen /*HW_BEACON_OFFSET*/; i += 2)
1440 {
1441 if (NdisEqualMemory(ptr, pBeaconFrame, 2) == FALSE)
1442 {
1443 NdisMoveMemory(ptr, pBeaconFrame, 2);
1444 //shortValue = *ptr + (*(ptr+1)<<8);
1445 //RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, shortValue);
1446 RTUSBMultiWrite(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, ptr, 2);
1447 }
1448 ptr +=2;
1449 pBeaconFrame += 2;
1450 }
1451
1452 pBeaconSync->BeaconBitMap |= (1 << bcn_idx);
1453
1454 // For AP interface, set the DtimBitOn so that we can send Bcast/Mcast frame out after this beacon frame.
1455 }
1456
1457}
1458
1459
1460VOID RT2870_BssBeaconStop(
1461 IN RTMP_ADAPTER *pAd)
1462{
1463 BEACON_SYNC_STRUCT *pBeaconSync;
1464 int i, offset;
1465 BOOLEAN Cancelled = TRUE;
1466
1467 pBeaconSync = pAd->CommonCfg.pBeaconSync;
1468 if (pBeaconSync && pBeaconSync->EnableBeacon)
1469 {
1470 INT NumOfBcn;
1471
1472
1473#ifdef CONFIG_STA_SUPPORT
1474 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1475 {
1476 NumOfBcn = MAX_MESH_NUM;
1477 }
1478#endif // CONFIG_STA_SUPPORT //
1479
1480 RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
1481
1482 for(i=0; i<NumOfBcn; i++)
1483 {
1484 NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
1485 NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
1486
1487 for (offset=0; offset<HW_BEACON_OFFSET; offset+=4)
1488 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[i] + offset, 0x00);
1489
1490 pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
1491 pBeaconSync->TimIELocationInBeacon[i] = 0;
1492 }
1493 pBeaconSync->BeaconBitMap = 0;
1494 pBeaconSync->DtimBitOn = 0;
1495 }
1496}
1497
1498
1499VOID RT2870_BssBeaconStart(
1500 IN RTMP_ADAPTER *pAd)
1501{
1502 int apidx;
1503 BEACON_SYNC_STRUCT *pBeaconSync;
1504// LARGE_INTEGER tsfTime, deltaTime;
1505
1506 pBeaconSync = pAd->CommonCfg.pBeaconSync;
1507 if (pBeaconSync && pBeaconSync->EnableBeacon)
1508 {
1509 INT NumOfBcn;
1510
1511
1512#ifdef CONFIG_STA_SUPPORT
1513 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1514 {
1515 NumOfBcn = MAX_MESH_NUM;
1516 }
1517#endif // CONFIG_STA_SUPPORT //
1518
1519 for(apidx=0; apidx<NumOfBcn; apidx++)
1520 {
1521 UCHAR CapabilityInfoLocationInBeacon = 0;
1522 UCHAR TimIELocationInBeacon = 0;
1523
1524#ifdef CONFIG_STA_SUPPORT
1525#endif // CONFIG_STA_SUPPORT //
1526
1527 NdisZeroMemory(pBeaconSync->BeaconBuf[apidx], HW_BEACON_OFFSET);
1528 pBeaconSync->CapabilityInfoLocationInBeacon[apidx] = CapabilityInfoLocationInBeacon;
1529 pBeaconSync->TimIELocationInBeacon[apidx] = TimIELocationInBeacon;
1530 NdisZeroMemory(pBeaconSync->BeaconTxWI[apidx], TXWI_SIZE);
1531 }
1532 pBeaconSync->BeaconBitMap = 0;
1533 pBeaconSync->DtimBitOn = 0;
1534 pAd->CommonCfg.BeaconUpdateTimer.Repeat = TRUE;
1535
1536 pAd->CommonCfg.BeaconAdjust = 0;
1537 pAd->CommonCfg.BeaconFactor = 0xffffffff / (pAd->CommonCfg.BeaconPeriod << 10);
1538 pAd->CommonCfg.BeaconRemain = (0xffffffff % (pAd->CommonCfg.BeaconPeriod << 10)) + 1;
1539 printk("RT2870_BssBeaconStart:BeaconFactor=%d, BeaconRemain=%d!\n", pAd->CommonCfg.BeaconFactor, pAd->CommonCfg.BeaconRemain);
1540 RTMPSetTimer(&pAd->CommonCfg.BeaconUpdateTimer, pAd->CommonCfg.BeaconPeriod);
1541
1542 }
1543}
1544
1545
1546VOID RT2870_BssBeaconInit(
1547 IN RTMP_ADAPTER *pAd)
1548{
1549 BEACON_SYNC_STRUCT *pBeaconSync;
1550 int i;
1551
1552 NdisAllocMemory(pAd->CommonCfg.pBeaconSync, sizeof(BEACON_SYNC_STRUCT), MEM_ALLOC_FLAG);
1553 if (pAd->CommonCfg.pBeaconSync)
1554 {
1555 pBeaconSync = pAd->CommonCfg.pBeaconSync;
1556 NdisZeroMemory(pBeaconSync, sizeof(BEACON_SYNC_STRUCT));
1557 for(i=0; i < HW_BEACON_MAX_COUNT; i++)
1558 {
1559 NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
1560 pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
1561 pBeaconSync->TimIELocationInBeacon[i] = 0;
1562 NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
1563 }
1564 pBeaconSync->BeaconBitMap = 0;
1565
1566 //RTMPInitTimer(pAd, &pAd->CommonCfg.BeaconUpdateTimer, GET_TIMER_FUNCTION(BeaconUpdateExec), pAd, TRUE);
1567 pBeaconSync->EnableBeacon = TRUE;
1568 }
1569}
1570
1571
1572VOID RT2870_BssBeaconExit(
1573 IN RTMP_ADAPTER *pAd)
1574{
1575 BEACON_SYNC_STRUCT *pBeaconSync;
1576 BOOLEAN Cancelled = TRUE;
1577 int i;
1578
1579 if (pAd->CommonCfg.pBeaconSync)
1580 {
1581 pBeaconSync = pAd->CommonCfg.pBeaconSync;
1582 pBeaconSync->EnableBeacon = FALSE;
1583 RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
1584 pBeaconSync->BeaconBitMap = 0;
1585
1586 for(i=0; i<HW_BEACON_MAX_COUNT; i++)
1587 {
1588 NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
1589 pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
1590 pBeaconSync->TimIELocationInBeacon[i] = 0;
1591 NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
1592 }
1593
1594 NdisFreeMemory(pAd->CommonCfg.pBeaconSync, HW_BEACON_OFFSET * HW_BEACON_MAX_COUNT, 0);
1595 pAd->CommonCfg.pBeaconSync = NULL;
1596 }
1597}
1598
1599VOID BeaconUpdateExec(
1600 IN PVOID SystemSpecific1,
1601 IN PVOID FunctionContext,
1602 IN PVOID SystemSpecific2,
1603 IN PVOID SystemSpecific3)
1604{
1605 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)FunctionContext;
1606 LARGE_INTEGER tsfTime_a;//, tsfTime_b, deltaTime_exp, deltaTime_ab;
1607 UINT32 delta, remain, remain_low, remain_high;
1608// BOOLEAN positive;
1609
1610 ReSyncBeaconTime(pAd);
1611
1612
1613
1614 RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &tsfTime_a.u.LowPart);
1615 RTMP_IO_READ32(pAd, TSF_TIMER_DW1, &tsfTime_a.u.HighPart);
1616
1617
1618 //positive=getDeltaTime(tsfTime_a, expectedTime, &deltaTime_exp);
1619 remain_high = pAd->CommonCfg.BeaconRemain * tsfTime_a.u.HighPart;
1620 remain_low = tsfTime_a.u.LowPart % (pAd->CommonCfg.BeaconPeriod << 10);
1621 remain = (remain_high + remain_low)%(pAd->CommonCfg.BeaconPeriod << 10);
1622 delta = (pAd->CommonCfg.BeaconPeriod << 10) - remain;
1623
1624 pAd->CommonCfg.BeaconUpdateTimer.TimerValue = (delta >> 10) + 10;
1625
1626}
1627
diff --git a/drivers/staging/rt3070/Kconfig b/drivers/staging/rt3070/Kconfig
new file mode 100644
index 000000000000..b37fb5d13a4f
--- /dev/null
+++ b/drivers/staging/rt3070/Kconfig
@@ -0,0 +1,6 @@
1config RT3070
2 tristate "Ralink 3070 wireless support"
3 depends on USB && X86 && WLAN_80211
4 ---help---
5 This is an experimental driver for the Ralink 3070 wireless chip.
6
diff --git a/drivers/staging/rt3070/Makefile b/drivers/staging/rt3070/Makefile
new file mode 100644
index 000000000000..55980c929254
--- /dev/null
+++ b/drivers/staging/rt3070/Makefile
@@ -0,0 +1,47 @@
1obj-$(CONFIG_RT3070) += rt3070sta.o
2
3# TODO: all of these should be removed
4EXTRA_CFLAGS += -DLINUX -DAGGREGATION_SUPPORT -DPIGGYBACK_SUPPORT -DWMM_SUPPORT
5EXTRA_CFLAGS += -DRT2870 -DRT30xx -DRT3070
6EXTRA_CFLAGS += -DCONFIG_STA_SUPPORT
7EXTRA_CFLAGS += -DDBG
8EXTRA_CFLAGS += -DDOT11_N_SUPPORT
9EXTRA_CFLAGS += -DWPA_SUPPLICANT_SUPPORT
10EXTRA_CFLAGS += -DNATIVE_WPA_SUPPLICANT_SUPPORT
11
12rt3070sta-objs := \
13 common/md5.o \
14 common/mlme.o \
15 common/rtmp_wep.o \
16 common/action.o \
17 common/cmm_data.o \
18 common/rtmp_init.o \
19 common/rtmp_tkip.o \
20 common/cmm_sync.o \
21 common/eeprom.o \
22 common/cmm_sanity.o \
23 common/cmm_info.o \
24 common/cmm_wpa.o \
25 common/dfs.o \
26 common/spectrum.o \
27 sta/assoc.o \
28 sta/aironet.o \
29 sta/auth.o \
30 sta/auth_rsp.o \
31 sta/sync.o \
32 sta/sanity.o \
33 sta/rtmp_data.o \
34 sta/connect.o \
35 sta/wpa.o \
36 rt_linux.o \
37 rt_profile.o \
38 rt_main_dev.o \
39 sta_ioctl.o \
40 common/ba_action.o \
41 2870_main_dev.o \
42 common/2870_rtmp_init.o \
43 common/rtusb_io.o \
44 common/rtusb_bulk.o \
45 common/rtusb_data.o \
46 common/cmm_data_2870.o
47
diff --git a/drivers/staging/rt3070/action.h b/drivers/staging/rt3070/action.h
new file mode 100644
index 000000000000..ce3877dce81b
--- /dev/null
+++ b/drivers/staging/rt3070/action.h
@@ -0,0 +1,68 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 aironet.h
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Name Date Modification logs
36 Paul Lin 04-06-15 Initial
37*/
38
39#ifndef __ACTION_H__
40#define __ACTION_H__
41
42typedef struct PACKED __HT_INFO_OCTET
43{
44#ifdef RT_BIG_ENDIAN
45 UCHAR Reserved:5;
46 UCHAR STA_Channel_Width:1;
47 UCHAR Forty_MHz_Intolerant:1;
48 UCHAR Request:1;
49#else
50 UCHAR Request:1;
51 UCHAR Forty_MHz_Intolerant:1;
52 UCHAR STA_Channel_Width:1;
53 UCHAR Reserved:5;
54#endif
55} HT_INFORMATION_OCTET;
56
57
58typedef struct PACKED __FRAME_HT_INFO
59{
60 HEADER_802_11 Hdr;
61 UCHAR Category;
62 UCHAR Action;
63 HT_INFORMATION_OCTET HT_Info;
64} FRAME_HT_INFO, *PFRAME_HT_INFO;
65
66#endif /* __ACTION_H__ */
67
68
diff --git a/drivers/staging/rt3070/aironet.h b/drivers/staging/rt3070/aironet.h
new file mode 100644
index 000000000000..1e07b19b8cdc
--- /dev/null
+++ b/drivers/staging/rt3070/aironet.h
@@ -0,0 +1,210 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 aironet.h
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Name Date Modification logs
36 Paul Lin 04-06-15 Initial
37*/
38
39#ifndef __AIRONET_H__
40#define __AIRONET_H__
41
42// Measurement Type definition
43#define MSRN_TYPE_UNUSED 0
44#define MSRN_TYPE_CHANNEL_LOAD_REQ 1
45#define MSRN_TYPE_NOISE_HIST_REQ 2
46#define MSRN_TYPE_BEACON_REQ 3
47#define MSRN_TYPE_FRAME_REQ 4
48
49// Scan Mode in Beacon Request
50#define MSRN_SCAN_MODE_PASSIVE 0
51#define MSRN_SCAN_MODE_ACTIVE 1
52#define MSRN_SCAN_MODE_BEACON_TABLE 2
53
54// PHY type definition for Aironet beacon report, CCX 2 table 36-9
55#define PHY_FH 1
56#define PHY_DSS 2
57#define PHY_UNUSED 3
58#define PHY_OFDM 4
59#define PHY_HR_DSS 5
60#define PHY_ERP 6
61
62// RPI table in dBm
63#define RPI_0 0 // Power <= -87
64#define RPI_1 1 // -87 < Power <= -82
65#define RPI_2 2 // -82 < Power <= -77
66#define RPI_3 3 // -77 < Power <= -72
67#define RPI_4 4 // -72 < Power <= -67
68#define RPI_5 5 // -67 < Power <= -62
69#define RPI_6 6 // -62 < Power <= -57
70#define RPI_7 7 // -57 < Power
71
72// Cisco Aironet IAPP definetions
73#define AIRONET_IAPP_TYPE 0x32
74#define AIRONET_IAPP_SUBTYPE_REQUEST 0x01
75#define AIRONET_IAPP_SUBTYPE_REPORT 0x81
76
77// Measurement Request detail format
78typedef struct _MEASUREMENT_REQUEST {
79 UCHAR Channel;
80 UCHAR ScanMode; // Use only in beacon request, other requests did not use this field
81 USHORT Duration;
82} MEASUREMENT_REQUEST, *PMEASUREMENT_REQUEST;
83
84// Beacon Measurement Report
85// All these field might change to UCHAR, because we didn't do anything to these report.
86// We copy all these beacons and report to CCX 2 AP.
87typedef struct _BEACON_REPORT {
88 UCHAR Channel;
89 UCHAR Spare;
90 USHORT Duration;
91 UCHAR PhyType; // Definiation is listed above table 36-9
92 UCHAR RxPower;
93 UCHAR BSSID[6];
94 UCHAR ParentTSF[4];
95 UCHAR TargetTSF[8];
96 USHORT BeaconInterval;
97 USHORT CapabilityInfo;
98} BEACON_REPORT, *PBEACON_REPORT;
99
100// Frame Measurement Report (Optional)
101typedef struct _FRAME_REPORT {
102 UCHAR Channel;
103 UCHAR Spare;
104 USHORT Duration;
105 UCHAR TA;
106 UCHAR BSSID[6];
107 UCHAR RSSI;
108 UCHAR Count;
109} FRAME_REPORT, *PFRAME_REPORT;
110
111#pragma pack(1)
112// Channel Load Report
113typedef struct _CHANNEL_LOAD_REPORT {
114 UCHAR Channel;
115 UCHAR Spare;
116 USHORT Duration;
117 UCHAR CCABusy;
118} CHANNEL_LOAD_REPORT, *PCHANNEL_LOAD_REPORT;
119#pragma pack()
120
121// Nosie Histogram Report
122typedef struct _NOISE_HIST_REPORT {
123 UCHAR Channel;
124 UCHAR Spare;
125 USHORT Duration;
126 UCHAR Density[8];
127} NOISE_HIST_REPORT, *PNOISE_HIST_REPORT;
128
129// Radio Management Capability element
130typedef struct _RADIO_MANAGEMENT_CAPABILITY {
131 UCHAR Eid; // TODO: Why the Eid is 1 byte, not normal 2 bytes???
132 UCHAR Length;
133 UCHAR AironetOui[3]; // AIronet OUI (00 40 96)
134 UCHAR Type; // Type / Version
135 USHORT Status; // swap16 required
136} RADIO_MANAGEMENT_CAPABILITY, *PRADIO_MANAGEMENT_CAPABILITY;
137
138// Measurement Mode Bit definition
139typedef struct _MEASUREMENT_MODE {
140 UCHAR Rsvd:4;
141 UCHAR Report:1;
142 UCHAR NotUsed:1;
143 UCHAR Enable:1;
144 UCHAR Parallel:1;
145} MEASUREMENT_MODE, *PMEASUREMENT_MODE;
146
147// Measurement Request element, This is little endian mode
148typedef struct _MEASUREMENT_REQUEST_ELEMENT {
149 USHORT Eid;
150 USHORT Length; // swap16 required
151 USHORT Token; // non-zero unique token
152 UCHAR Mode; // Measurement Mode
153 UCHAR Type; // Measurement type
154} MEASUREMENT_REQUEST_ELEMENT, *PMEASUREMENT_REQUEST_ELEMENT;
155
156// Measurement Report element, This is little endian mode
157typedef struct _MEASUREMENT_REPORT_ELEMENT {
158 USHORT Eid;
159 USHORT Length; // swap16 required
160 USHORT Token; // non-zero unique token
161 UCHAR Mode; // Measurement Mode
162 UCHAR Type; // Measurement type
163} MEASUREMENT_REPORT_ELEMENT, *PMEASUREMENT_REPORT_ELEMENT;
164
165// Cisco Aironet IAPP Frame Header, Network byte order used
166typedef struct _AIRONET_IAPP_HEADER {
167 UCHAR CiscoSnapHeader[8]; // 8 bytes Cisco snap header
168 USHORT Length; // IAPP ID & length, remember to swap16 in LE system
169 UCHAR Type; // IAPP type
170 UCHAR SubType; // IAPP subtype
171 UCHAR DA[6]; // Destination MAC address
172 UCHAR SA[6]; // Source MAC address
173 USHORT Token; // Dialog token, no need to swap16 since it is for yoken usage only
174} AIRONET_IAPP_HEADER, *PAIRONET_IAPP_HEADER;
175
176// Radio Measurement Request frame
177typedef struct _AIRONET_RM_REQUEST_FRAME {
178 AIRONET_IAPP_HEADER IAPP; // Common header
179 UCHAR Delay; // Activation Delay
180 UCHAR Offset; // Measurement offset
181} AIRONET_RM_REQUEST_FRAME, *PAIRONET_RM_REQUEST_FRAME;
182
183// Radio Measurement Report frame
184typedef struct _AIRONET_RM_REPORT_FRAME {
185 AIRONET_IAPP_HEADER IAPP; // Common header
186} AIRONET_RM_REPORT_FRAME, *PAIRONET_RM_REPORT_FRAME;
187
188// Saved element request actions which will saved in StaCfg.
189typedef struct _RM_REQUEST_ACTION {
190 MEASUREMENT_REQUEST_ELEMENT ReqElem; // Saved request element
191 MEASUREMENT_REQUEST Measurement; // Saved measurement within the request element
192} RM_REQUEST_ACTION, *PRM_REQUEST_ACTION;
193
194// CCX administration control
195typedef union _CCX_CONTROL {
196 struct {
197 UINT32 Enable:1; // Enable CCX2
198 UINT32 LeapEnable:1; // Enable LEAP at CCX2
199 UINT32 RMEnable:1; // Radio Measurement Enable
200 UINT32 DCRMEnable:1; // Non serving channel Radio Measurement enable
201 UINT32 QOSEnable:1; // Enable QOS for CCX 2.0 support
202 UINT32 FastRoamEnable:1; // Enable fast roaming
203 UINT32 Rsvd:2; // Not used
204 UINT32 dBmToRoam:8; // the condition to roam when receiving Rssi less than this value. It's negative value.
205 UINT32 TuLimit:16; // Limit for different channel scan
206 } field;
207 UINT32 word;
208} CCX_CONTROL, *PCCX_CONTROL;
209
210#endif // __AIRONET_H__
diff --git a/drivers/staging/rt3070/ap.h b/drivers/staging/rt3070/ap.h
new file mode 100644
index 000000000000..f5ba042e52ba
--- /dev/null
+++ b/drivers/staging/rt3070/ap.h
@@ -0,0 +1,557 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 ap.h
29
30 Abstract:
31 Miniport generic portion header file
32
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36 Paul Lin 08-01-2002 created
37 James Tan 09-06-2002 modified (Revise NTCRegTable)
38 John Chang 12-22-2004 modified for RT2561/2661. merge with STA driver
39*/
40#ifndef __AP_H__
41#define __AP_H__
42
43
44
45// ========================= AP RTMP.h ================================
46
47
48
49// =============================================================
50// Function Prototypes
51// =============================================================
52
53// ap_data.c
54
55BOOLEAN APBridgeToWirelessSta(
56 IN PRTMP_ADAPTER pAd,
57 IN PUCHAR pHeader,
58 IN UINT HdrLen,
59 IN PUCHAR pData,
60 IN UINT DataLen,
61 IN ULONG fromwdsidx);
62
63BOOLEAN APHandleRxDoneInterrupt(
64 IN PRTMP_ADAPTER pAd);
65
66VOID APSendPackets(
67 IN NDIS_HANDLE MiniportAdapterContext,
68 IN PPNDIS_PACKET ppPacketArray,
69 IN UINT NumberOfPackets);
70
71NDIS_STATUS APSendPacket(
72 IN PRTMP_ADAPTER pAd,
73 IN PNDIS_PACKET pPacket);
74
75
76NDIS_STATUS APHardTransmit(
77 IN PRTMP_ADAPTER pAd,
78 IN TX_BLK *pTxBlk,
79 IN UCHAR QueIdx);
80
81VOID APRxEAPOLFrameIndicate(
82 IN PRTMP_ADAPTER pAd,
83 IN MAC_TABLE_ENTRY *pEntry,
84 IN RX_BLK *pRxBlk,
85 IN UCHAR FromWhichBSSID);
86
87NDIS_STATUS APCheckRxError(
88 IN PRTMP_ADAPTER pAd,
89 IN PRT28XX_RXD_STRUC pRxD,
90 IN UCHAR Wcid);
91
92BOOLEAN APCheckClass2Class3Error(
93 IN PRTMP_ADAPTER pAd,
94 IN ULONG Wcid,
95 IN PHEADER_802_11 pHeader);
96
97VOID APHandleRxPsPoll(
98 IN PRTMP_ADAPTER pAd,
99 IN PUCHAR pAddr,
100 IN USHORT Aid,
101 IN BOOLEAN isActive);
102
103VOID RTMPDescriptorEndianChange(
104 IN PUCHAR pData,
105 IN ULONG DescriptorType);
106
107VOID RTMPFrameEndianChange(
108 IN PRTMP_ADAPTER pAd,
109 IN PUCHAR pData,
110 IN ULONG Dir,
111 IN BOOLEAN FromRxDoneInt);
112
113// ap_assoc.c
114
115VOID APAssocStateMachineInit(
116 IN PRTMP_ADAPTER pAd,
117 IN STATE_MACHINE *S,
118 OUT STATE_MACHINE_FUNC Trans[]);
119
120VOID APPeerAssocReqAction(
121 IN PRTMP_ADAPTER pAd,
122 IN MLME_QUEUE_ELEM *Elem);
123
124VOID APPeerReassocReqAction(
125 IN PRTMP_ADAPTER pAd,
126 IN MLME_QUEUE_ELEM *Elem);
127
128VOID APPeerDisassocReqAction(
129 IN PRTMP_ADAPTER pAd,
130 IN MLME_QUEUE_ELEM *Elem);
131
132VOID MbssKickOutStas(
133 IN PRTMP_ADAPTER pAd,
134 IN INT apidx,
135 IN USHORT Reason);
136
137VOID APMlmeKickOutSta(
138 IN PRTMP_ADAPTER pAd,
139 IN PUCHAR pStaAddr,
140 IN UCHAR Wcid,
141 IN USHORT Reason);
142
143VOID APMlmeDisassocReqAction(
144 IN PRTMP_ADAPTER pAd,
145 IN MLME_QUEUE_ELEM *Elem);
146
147VOID APCls3errAction(
148 IN PRTMP_ADAPTER pAd,
149 IN ULONG Wcid,
150 IN PHEADER_802_11 pHeader);
151
152
153USHORT APBuildAssociation(
154 IN PRTMP_ADAPTER pAd,
155 IN MAC_TABLE_ENTRY *pEntry,
156 IN USHORT CapabilityInfo,
157 IN UCHAR MaxSupportedRateIn500Kbps,
158 IN UCHAR *RSN,
159 IN UCHAR *pRSNLen,
160 IN BOOLEAN bWmmCapable,
161 IN ULONG RalinkIe,
162#ifdef DOT11N_DRAFT3
163 IN EXT_CAP_INFO_ELEMENT ExtCapInfo,
164#endif // DOT11N_DRAFT3 //
165 IN HT_CAPABILITY_IE *pHtCapability,
166 IN UCHAR HtCapabilityLen,
167 OUT USHORT *pAid);
168
169/*
170VOID RTMPAddClientSec(
171 IN PRTMP_ADAPTER pAd,
172 IN UCHAR BssIdx,
173 IN UCHAR KeyIdx,
174 IN UCHAR CipherAlg,
175 IN PUCHAR pKey,
176 IN PUCHAR pTxMic,
177 IN PUCHAR pRxMic,
178 IN MAC_TABLE_ENTRY *pEntry);
179*/
180
181// ap_auth.c
182
183void APAuthStateMachineInit(
184 IN PRTMP_ADAPTER pAd,
185 IN STATE_MACHINE *Sm,
186 OUT STATE_MACHINE_FUNC Trans[]);
187
188VOID APMlmeDeauthReqAction(
189 IN PRTMP_ADAPTER pAd,
190 IN MLME_QUEUE_ELEM *Elem);
191
192VOID APCls2errAction(
193 IN PRTMP_ADAPTER pAd,
194 IN ULONG Wcid,
195 IN PHEADER_802_11 pHeader);
196
197// ap_authrsp.c
198
199VOID APAuthRspStateMachineInit(
200 IN PRTMP_ADAPTER pAd,
201 IN PSTATE_MACHINE Sm,
202 IN STATE_MACHINE_FUNC Trans[]);
203
204VOID APPeerAuthAtAuthRspIdleAction(
205 IN PRTMP_ADAPTER pAd,
206 IN MLME_QUEUE_ELEM *Elem);
207
208VOID APPeerDeauthReqAction(
209 IN PRTMP_ADAPTER pAd,
210 IN MLME_QUEUE_ELEM *Elem);
211
212VOID APPeerAuthSimpleRspGenAndSend(
213 IN PRTMP_ADAPTER pAd,
214 IN PHEADER_802_11 pHdr80211,
215 IN USHORT Alg,
216 IN USHORT Seq,
217 IN USHORT StatusCode);
218
219// ap_connect.c
220
221BOOLEAN BeaconTransmitRequired(
222 IN PRTMP_ADAPTER pAd,
223 IN INT apidx);
224
225VOID APMakeBssBeacon(
226 IN PRTMP_ADAPTER pAd,
227 IN INT apidx);
228
229VOID APUpdateBeaconFrame(
230 IN PRTMP_ADAPTER pAd,
231 IN INT apidx);
232
233VOID APMakeAllBssBeacon(
234 IN PRTMP_ADAPTER pAd);
235
236VOID APUpdateAllBeaconFrame(
237 IN PRTMP_ADAPTER pAd);
238
239
240// ap_sync.c
241
242VOID APSyncStateMachineInit(
243 IN PRTMP_ADAPTER pAd,
244 IN STATE_MACHINE *Sm,
245 OUT STATE_MACHINE_FUNC Trans[]);
246
247VOID APScanTimeout(
248 IN PVOID SystemSpecific1,
249 IN PVOID FunctionContext,
250 IN PVOID SystemSpecific2,
251 IN PVOID SystemSpecific3);
252
253VOID APInvalidStateWhenScan(
254 IN PRTMP_ADAPTER pAd,
255 IN MLME_QUEUE_ELEM *Elem);
256
257VOID APScanTimeoutAction(
258 IN PRTMP_ADAPTER pAd,
259 IN MLME_QUEUE_ELEM *Elem);
260
261VOID APPeerProbeReqAction(
262 IN PRTMP_ADAPTER pAd,
263 IN MLME_QUEUE_ELEM *Elem);
264
265VOID APPeerBeaconAction(
266 IN PRTMP_ADAPTER pAd,
267 IN MLME_QUEUE_ELEM *Elem);
268
269VOID APMlmeScanReqAction(
270 IN PRTMP_ADAPTER pAd,
271 IN MLME_QUEUE_ELEM *Elem);
272
273VOID APPeerBeaconAtScanAction(
274 IN PRTMP_ADAPTER pAd,
275 IN MLME_QUEUE_ELEM *Elem);
276
277VOID APScanCnclAction(
278 IN PRTMP_ADAPTER pAd,
279 IN MLME_QUEUE_ELEM *Elem);
280
281VOID ApSiteSurvey(
282 IN PRTMP_ADAPTER pAd);
283
284VOID SupportRate(
285 IN PUCHAR SupRate,
286 IN UCHAR SupRateLen,
287 IN PUCHAR ExtRate,
288 IN UCHAR ExtRateLen,
289 OUT PUCHAR *Rates,
290 OUT PUCHAR RatesLen,
291 OUT PUCHAR pMaxSupportRate);
292
293
294BOOLEAN ApScanRunning(
295 IN PRTMP_ADAPTER pAd);
296
297#ifdef DOT11N_DRAFT3
298VOID APOverlappingBSSScan(
299 IN RTMP_ADAPTER *pAd);
300#endif // DOT11N_DRAFT3 //
301
302// ap_wpa.c
303
304VOID APWpaStateMachineInit(
305 IN PRTMP_ADAPTER pAd,
306 IN STATE_MACHINE *Sm,
307 OUT STATE_MACHINE_FUNC Trans[]);
308
309// ap_mlme.c
310
311VOID APMlmePeriodicExec(
312 IN PRTMP_ADAPTER pAd);
313
314VOID APMlmeSelectTxRateTable(
315 IN PRTMP_ADAPTER pAd,
316 IN PMAC_TABLE_ENTRY pEntry,
317 IN PUCHAR *ppTable,
318 IN PUCHAR pTableSize,
319 IN PUCHAR pInitTxRateIdx);
320
321VOID APMlmeSetTxRate(
322 IN PRTMP_ADAPTER pAd,
323 IN PMAC_TABLE_ENTRY pEntry,
324 IN PRTMP_TX_RATE_SWITCH pTxRate);
325
326VOID APMlmeDynamicTxRateSwitching(
327 IN PRTMP_ADAPTER pAd);
328
329VOID APQuickResponeForRateUpExec(
330 IN PVOID SystemSpecific1,
331 IN PVOID FunctionContext,
332 IN PVOID SystemSpecific2,
333 IN PVOID SystemSpecific3);
334
335BOOLEAN APMsgTypeSubst(
336 IN PRTMP_ADAPTER pAd,
337 IN PFRAME_802_11 pFrame,
338 OUT INT *Machine,
339 OUT INT *MsgType);
340
341VOID APQuickResponeForRateUpExec(
342 IN PVOID SystemSpecific1,
343 IN PVOID FunctionContext,
344 IN PVOID SystemSpecific2,
345 IN PVOID SystemSpecific3);
346
347#ifdef RT2870
348VOID BeaconUpdateExec(
349 IN PVOID SystemSpecific1,
350 IN PVOID FunctionContext,
351 IN PVOID SystemSpecific2,
352 IN PVOID SystemSpecific3);
353#endif // RT2870 //
354
355VOID RTMPSetPiggyBack(
356 IN PRTMP_ADAPTER pAd,
357 IN BOOLEAN bPiggyBack);
358
359VOID APAsicEvaluateRxAnt(
360 IN PRTMP_ADAPTER pAd);
361
362VOID APAsicRxAntEvalTimeout(
363 IN PRTMP_ADAPTER pAd);
364
365// ap.c
366
367VOID APSwitchChannel(
368 IN PRTMP_ADAPTER pAd,
369 IN INT Channel);
370
371NDIS_STATUS APInitialize(
372 IN PRTMP_ADAPTER pAd);
373
374VOID APShutdown(
375 IN PRTMP_ADAPTER pAd);
376
377VOID APStartUp(
378 IN PRTMP_ADAPTER pAd);
379
380VOID APStop(
381 IN PRTMP_ADAPTER pAd);
382
383VOID APCleanupPsQueue(
384 IN PRTMP_ADAPTER pAd,
385 IN PQUEUE_HEADER pQueue);
386
387VOID MacTableReset(
388 IN PRTMP_ADAPTER pAd);
389
390MAC_TABLE_ENTRY *MacTableInsertEntry(
391 IN PRTMP_ADAPTER pAd,
392 IN PUCHAR pAddr,
393 IN UCHAR apidx,
394 IN BOOLEAN CleanAll);
395
396BOOLEAN MacTableDeleteEntry(
397 IN PRTMP_ADAPTER pAd,
398 IN USHORT wcid,
399 IN PUCHAR pAddr);
400
401MAC_TABLE_ENTRY *MacTableLookup(
402 IN PRTMP_ADAPTER pAd,
403 IN PUCHAR pAddr);
404
405VOID MacTableMaintenance(
406 IN PRTMP_ADAPTER pAd);
407
408UINT32 MacTableAssocStaNumGet(
409 IN PRTMP_ADAPTER pAd);
410
411MAC_TABLE_ENTRY *APSsPsInquiry(
412 IN PRTMP_ADAPTER pAd,
413 IN PUCHAR pAddr,
414 OUT SST *Sst,
415 OUT USHORT *Aid,
416 OUT UCHAR *PsMode,
417 OUT UCHAR *Rate);
418
419BOOLEAN APPsIndicate(
420 IN PRTMP_ADAPTER pAd,
421 IN PUCHAR pAddr,
422 IN ULONG Wcid,
423 IN UCHAR Psm);
424
425VOID ApLogEvent(
426 IN PRTMP_ADAPTER pAd,
427 IN PUCHAR pAddr,
428 IN USHORT Event);
429
430#ifdef DOT11_N_SUPPORT
431VOID APUpdateOperationMode(
432 IN PRTMP_ADAPTER pAd);
433#endif // DOT11_N_SUPPORT //
434
435VOID APUpdateCapabilityAndErpIe(
436 IN PRTMP_ADAPTER pAd);
437
438BOOLEAN ApCheckAccessControlList(
439 IN PRTMP_ADAPTER pAd,
440 IN PUCHAR pAddr,
441 IN UCHAR Apidx);
442
443VOID ApUpdateAccessControlList(
444 IN PRTMP_ADAPTER pAd,
445 IN UCHAR Apidx);
446
447VOID ApEnqueueNullFrame(
448 IN PRTMP_ADAPTER pAd,
449 IN PUCHAR pAddr,
450 IN UCHAR TxRate,
451 IN UCHAR PID,
452 IN UCHAR apidx,
453 IN BOOLEAN bQosNull,
454 IN BOOLEAN bEOSP,
455 IN UCHAR OldUP);
456
457VOID ApSendFrame(
458 IN PRTMP_ADAPTER pAd,
459 IN PVOID pBuffer,
460 IN ULONG Length,
461 IN UCHAR TxRate,
462 IN UCHAR PID);
463
464VOID ApEnqueueAckFrame(
465 IN PRTMP_ADAPTER pAd,
466 IN PUCHAR pAddr,
467 IN UCHAR TxRate,
468 IN UCHAR apidx);
469
470UCHAR APAutoSelectChannel(
471 IN PRTMP_ADAPTER pAd,
472 IN BOOLEAN Optimal);
473
474// ap_sanity.c
475
476
477BOOLEAN PeerAssocReqCmmSanity(
478 IN PRTMP_ADAPTER pAd,
479 IN BOOLEAN isRessoc,
480 IN VOID *Msg,
481 IN ULONG MsgLen,
482 OUT PUCHAR pAddr2,
483 OUT USHORT *pCapabilityInfo,
484 OUT USHORT *pListenInterval,
485 OUT PUCHAR pApAddr,
486 OUT UCHAR *pSsidLen,
487 OUT char *Ssid,
488 OUT UCHAR *pRatesLen,
489 OUT UCHAR Rates[],
490 OUT UCHAR *RSN,
491 OUT UCHAR *pRSNLen,
492 OUT BOOLEAN *pbWmmCapable,
493 OUT ULONG *pRalinkIe,
494#ifdef DOT11N_DRAFT3
495 OUT EXT_CAP_INFO_ELEMENT *pExtCapInfo,
496#endif // DOT11N_DRAFT3 //
497 OUT UCHAR *pHtCapabilityLen,
498 OUT HT_CAPABILITY_IE *pHtCapability);
499
500
501BOOLEAN PeerDisassocReqSanity(
502 IN PRTMP_ADAPTER pAd,
503 IN VOID *Msg,
504 IN ULONG MsgLen,
505 OUT PUCHAR pAddr2,
506 OUT USHORT *Reason);
507
508BOOLEAN PeerDeauthReqSanity(
509 IN PRTMP_ADAPTER pAd,
510 IN VOID *Msg,
511 IN ULONG MsgLen,
512 OUT PUCHAR pAddr2,
513 OUT USHORT *Reason);
514
515BOOLEAN APPeerAuthSanity(
516 IN PRTMP_ADAPTER pAd,
517 IN VOID *Msg,
518 IN ULONG MsgLen,
519 OUT PUCHAR pAddr1,
520 OUT PUCHAR pAddr2,
521 OUT USHORT *Alg,
522 OUT USHORT *Seq,
523 OUT USHORT *Status,
524 CHAR *ChlgText);
525
526BOOLEAN APPeerProbeReqSanity(
527 IN PRTMP_ADAPTER pAd,
528 IN VOID *Msg,
529 IN ULONG MsgLen,
530 OUT PUCHAR pAddr2,
531 OUT CHAR Ssid[],
532 OUT UCHAR *SsidLen);
533
534BOOLEAN APPeerBeaconAndProbeRspSanity(
535 IN PRTMP_ADAPTER pAd,
536 IN VOID *Msg,
537 IN ULONG MsgLen,
538 OUT PUCHAR pAddr2,
539 OUT PUCHAR pBssid,
540 OUT CHAR Ssid[],
541 OUT UCHAR *SsidLen,
542 OUT UCHAR *BssType,
543 OUT USHORT *BeaconPeriod,
544 OUT UCHAR *Channel,
545 OUT LARGE_INTEGER *Timestamp,
546 OUT USHORT *CapabilityInfo,
547 OUT UCHAR Rate[],
548 OUT UCHAR *RateLen,
549 OUT BOOLEAN *ExtendedRateIeExist,
550 OUT UCHAR *Erp);
551
552
553// ================== end of AP RTMP.h ========================
554
555
556#endif // __AP_H__
557
diff --git a/drivers/staging/rt3070/chlist.h b/drivers/staging/rt3070/chlist.h
new file mode 100644
index 000000000000..7151e8668cb5
--- /dev/null
+++ b/drivers/staging/rt3070/chlist.h
@@ -0,0 +1,1253 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 chlist.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Fonchi Wu 2007-12-19 created
36*/
37
38#ifndef __CHLIST_H__
39#define __CHLIST_H__
40
41#include "rtmp_type.h"
42#include "rtmp_def.h"
43
44
45#define ODOR 0
46#define IDOR 1
47#define BOTH 2
48
49#define BAND_5G 0
50#define BAND_24G 1
51#define BAND_BOTH 2
52
53typedef struct _CH_DESP {
54 UCHAR FirstChannel;
55 UCHAR NumOfCh;
56 CHAR MaxTxPwr; // dBm
57 UCHAR Geography; // 0:out door, 1:in door, 2:both
58 BOOLEAN DfsReq; // Dfs require, 0: No, 1: yes.
59} CH_DESP, *PCH_DESP;
60
61typedef struct _CH_REGION {
62 UCHAR CountReg[3];
63 UCHAR DfsType; // 0: CE, 1: FCC, 2: JAP, 3:JAP_W53, JAP_W56
64 CH_DESP ChDesp[10];
65} CH_REGION, *PCH_REGION;
66
67static CH_REGION ChRegion[] =
68{
69 { // Antigua and Berbuda
70 "AG",
71 CE,
72 {
73 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
74 { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
75 { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
76 { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
77 { 0}, // end
78 }
79 },
80
81 { // Argentina
82 "AR",
83 CE,
84 {
85 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
86 { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
87 { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
88 { 0}, // end
89 }
90 },
91
92 { // Aruba
93 "AW",
94 CE,
95 {
96 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
97 { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
98 { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
99 { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
100 { 0}, // end
101 }
102 },
103
104 { // Australia
105 "AU",
106 CE,
107 {
108 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
109 { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
110 { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
111 { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165
112 { 0}, // end
113 }
114 },
115
116 { // Austria
117 "AT",
118 CE,
119 {
120 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
121 { 36, 4, 23, IDOR, TRUE}, // 5G, ch 36~48
122 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
123 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
124 { 0}, // end
125 }
126 },
127
128 { // Bahamas
129 "BS",
130 CE,
131 {
132 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
133 { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
134 { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
135 { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165
136 { 0}, // end
137 }
138 },
139
140 { // Barbados
141 "BB",
142 CE,
143 {
144 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
145 { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
146 { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
147 { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
148 { 0}, // end
149 }
150 },
151
152 { // Bermuda
153 "BM",
154 CE,
155 {
156 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
157 { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
158 { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
159 { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
160 { 0}, // end
161 }
162 },
163
164 { // Brazil
165 "BR",
166 CE,
167 {
168 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
169 { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
170 { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
171 { 100, 11, 24, BOTH, FALSE}, // 5G, ch 100~140
172 { 149, 5, 30, BOTH, FALSE}, // 5G, ch 100~140
173 { 0}, // end
174 }
175 },
176
177 { // Belgium
178 "BE",
179 CE,
180 {
181 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
182 { 36, 4, 18, IDOR, FALSE}, // 5G, ch 36~48
183 { 52, 4, 18, IDOR, FALSE}, // 5G, ch 52~64
184 { 0}, // end
185 }
186 },
187
188 { // Bulgaria
189 "BG",
190 CE,
191 {
192 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
193 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
194 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
195 { 100, 11, 30, ODOR, TRUE}, // 5G, ch 100~140
196 { 0}, // end
197 }
198 },
199
200 { // Canada
201 "CA",
202 CE,
203 {
204 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
205 { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
206 { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
207 { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165
208 { 0}, // end
209 }
210 },
211
212 { // Cayman IsLands
213 "KY",
214 CE,
215 {
216 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
217 { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
218 { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
219 { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
220 { 0}, // end
221 }
222 },
223
224 { // Chile
225 "CL",
226 CE,
227 {
228 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
229 { 36, 4, 20, BOTH, FALSE}, // 5G, ch 36~48
230 { 52, 4, 20, BOTH, FALSE}, // 5G, ch 52~64
231 { 149, 5, 20, BOTH, FALSE}, // 5G, ch 149~165
232 { 0}, // end
233 }
234 },
235
236 { // China
237 "CN",
238 CE,
239 {
240 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
241 { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161
242 { 0}, // end
243 }
244 },
245
246 { // Colombia
247 "CO",
248 CE,
249 {
250 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
251 { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48
252 { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
253 { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
254 { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165
255 { 0}, // end
256 }
257 },
258
259 { // Costa Rica
260 "CR",
261 CE,
262 {
263 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
264 { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48
265 { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
266 { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
267 { 0}, // end
268 }
269 },
270
271 { // Cyprus
272 "CY",
273 CE,
274 {
275 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
276 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
277 { 52, 4, 24, IDOR, TRUE}, // 5G, ch 52~64
278 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
279 { 0}, // end
280 }
281 },
282
283 { // Czech_Republic
284 "CZ",
285 CE,
286 {
287 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
288 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
289 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
290 { 0}, // end
291 }
292 },
293
294 { // Denmark
295 "DK",
296 CE,
297 {
298 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
299 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
300 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
301 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
302 { 0}, // end
303 }
304 },
305
306 { // Dominican Republic
307 "DO",
308 CE,
309 {
310 { 1, 0, 20, BOTH, FALSE}, // 2.4 G, ch 0
311 { 149, 4, 20, BOTH, FALSE}, // 5G, ch 149~161
312 { 0}, // end
313 }
314 },
315
316 { // Equador
317 "EC",
318 CE,
319 {
320 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
321 { 100, 11, 27, BOTH, FALSE}, // 5G, ch 100~140
322 { 0}, // end
323 }
324 },
325
326 { // El Salvador
327 "SV",
328 CE,
329 {
330 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
331 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
332 { 52, 4, 30, BOTH, TRUE}, // 5G, ch 52~64
333 { 149, 4, 36, BOTH, TRUE}, // 5G, ch 149~165
334 { 0}, // end
335 }
336 },
337
338 { // Finland
339 "FI",
340 CE,
341 {
342 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
343 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
344 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
345 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
346 { 0}, // end
347 }
348 },
349
350 { // France
351 "FR",
352 CE,
353 {
354 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
355 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
356 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
357 { 0}, // end
358 }
359 },
360
361 { // Germany
362 "DE",
363 CE,
364 {
365 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
366 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
367 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
368 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
369 { 0}, // end
370 }
371 },
372
373 { // Greece
374 "GR",
375 CE,
376 {
377 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
378 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
379 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
380 { 100, 11, 30, ODOR, TRUE}, // 5G, ch 100~140
381 { 0}, // end
382 }
383 },
384
385 { // Guam
386 "GU",
387 CE,
388 {
389 { 1, 11, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
390 { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48
391 { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
392 { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
393 { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165
394 { 0}, // end
395 }
396 },
397
398 { // Guatemala
399 "GT",
400 CE,
401 {
402 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
403 { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48
404 { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
405 { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
406 { 0}, // end
407 }
408 },
409
410 { // Haiti
411 "HT",
412 CE,
413 {
414 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
415 { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48
416 { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
417 { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
418 { 0}, // end
419 }
420 },
421
422 { // Honduras
423 "HN",
424 CE,
425 {
426 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
427 { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161
428 { 0}, // end
429 }
430 },
431
432 { // Hong Kong
433 "HK",
434 CE,
435 {
436 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
437 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
438 { 52, 4, 23, IDOR, FALSE}, // 5G, ch 52~64
439 { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
440 { 0}, // end
441 }
442 },
443
444 { // Hungary
445 "HU",
446 CE,
447 {
448 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
449 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
450 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
451 { 0}, // end
452 }
453 },
454
455 { // Iceland
456 "IS",
457 CE,
458 {
459 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
460 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
461 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
462 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
463 { 0}, // end
464 }
465 },
466
467 { // India
468 "IN",
469 CE,
470 {
471 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
472 { 149, 4, 24, IDOR, FALSE}, // 5G, ch 149~161
473 { 0}, // end
474 }
475 },
476
477 { // Indonesia
478 "ID",
479 CE,
480 {
481 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
482 { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161
483 { 0}, // end
484 }
485 },
486
487 { // Ireland
488 "IE",
489 CE,
490 {
491 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
492 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
493 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
494 { 100, 11, 30, ODOR, TRUE}, // 5G, ch 100~140
495 { 0}, // end
496 }
497 },
498
499 { // Israel
500 "IL",
501 CE,
502 {
503 { 1, 3, 20, IDOR, FALSE}, // 2.4 G, ch 1~3
504 { 4, 6, 20, BOTH, FALSE}, // 2.4 G, ch 4~9
505 { 10, 4, 20, IDOR, FALSE}, // 2.4 G, ch 10~13
506 { 0}, // end
507 }
508 },
509
510 { // Italy
511 "IT",
512 CE,
513 {
514 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
515 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
516 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
517 { 100, 11, 30, ODOR, TRUE}, // 5G, ch 100~140
518 { 0}, // end
519 }
520 },
521
522 { // Japan
523 "JP",
524 JAP,
525 {
526 { 1, 14, 20, BOTH, FALSE}, // 2.4 G, ch 1~14
527 { 34, 4, 23, IDOR, FALSE}, // 5G, ch 34~46
528 { 0}, // end
529 }
530 },
531
532 { // Jordan
533 "JO",
534 CE,
535 {
536 { 1, 13, 20, IDOR, FALSE}, // 2.4 G, ch 1~13
537 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
538 { 149, 4, 23, IDOR, FALSE}, // 5G, ch 149~161
539 { 0}, // end
540 }
541 },
542
543 { // Latvia
544 "LV",
545 CE,
546 {
547 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
548 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
549 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
550 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
551 { 0}, // end
552 }
553 },
554
555 { // Liechtenstein
556 "LI",
557 CE,
558 {
559 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
560 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
561 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
562 { 0}, // end
563 }
564 },
565
566 { // Lithuania
567 "LT",
568 CE,
569 {
570 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
571 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
572 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
573 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
574 { 0}, // end
575 }
576 },
577
578 { // Luxemburg
579 "LU",
580 CE,
581 {
582 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
583 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
584 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
585 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
586 { 0}, // end
587 }
588 },
589
590 { // Malaysia
591 "MY",
592 CE,
593 {
594 { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
595 { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
596 { 149, 5, 20, BOTH, FALSE}, // 5G, ch 149~165
597 { 0}, // end
598 }
599 },
600
601 { // Malta
602 "MT",
603 CE,
604 {
605 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
606 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
607 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
608 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
609 { 0}, // end
610 }
611 },
612
613 { // Marocco
614 "MA",
615 CE,
616 {
617 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
618 { 36, 4, 24, IDOR, FALSE}, // 5G, ch 36~48
619 { 0}, // end
620 }
621 },
622
623 { // Mexico
624 "MX",
625 CE,
626 {
627 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
628 { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
629 { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
630 { 149, 5, 30, IDOR, FALSE}, // 5G, ch 149~165
631 { 0}, // end
632 }
633 },
634
635 { // Netherlands
636 "NL",
637 CE,
638 {
639 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
640 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
641 { 52, 4, 24, IDOR, TRUE}, // 5G, ch 52~64
642 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
643 { 0}, // end
644 }
645 },
646
647 { // New Zealand
648 "NZ",
649 CE,
650 {
651 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
652 { 36, 4, 24, BOTH, FALSE}, // 5G, ch 36~48
653 { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
654 { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
655 { 0}, // end
656 }
657 },
658
659 { // Norway
660 "NO",
661 CE,
662 {
663 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
664 { 36, 4, 24, IDOR, FALSE}, // 5G, ch 36~48
665 { 52, 4, 24, IDOR, TRUE}, // 5G, ch 52~64
666 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 149~161
667 { 0}, // end
668 }
669 },
670
671 { // Peru
672 "PE",
673 CE,
674 {
675 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
676 { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161
677 { 0}, // end
678 }
679 },
680
681 { // Portugal
682 "PT",
683 CE,
684 {
685 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
686 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
687 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
688 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
689 { 0}, // end
690 }
691 },
692
693 { // Poland
694 "PL",
695 CE,
696 {
697 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
698 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
699 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
700 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
701 { 0}, // end
702 }
703 },
704
705 { // Romania
706 "RO",
707 CE,
708 {
709 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
710 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
711 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
712 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
713 { 0}, // end
714 }
715 },
716
717 { // Russia
718 "RU",
719 CE,
720 {
721 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
722 { 149, 4, 20, IDOR, FALSE}, // 5G, ch 149~161
723 { 0}, // end
724 }
725 },
726
727 { // Saudi Arabia
728 "SA",
729 CE,
730 {
731 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
732 { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
733 { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
734 { 149, 4, 23, BOTH, FALSE}, // 5G, ch 149~161
735 { 0}, // end
736 }
737 },
738
739 { // Serbia_and_Montenegro
740 "CS",
741 CE,
742 {
743 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
744 { 0}, // end
745 }
746 },
747
748 { // Singapore
749 "SG",
750 CE,
751 {
752 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
753 { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
754 { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
755 { 149, 4, 20, BOTH, FALSE}, // 5G, ch 149~161
756 { 0}, // end
757 }
758 },
759
760 { // Slovakia
761 "SK",
762 CE,
763 {
764 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
765 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
766 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
767 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
768 { 0}, // end
769 }
770 },
771
772 { // Slovenia
773 "SI",
774 CE,
775 {
776 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
777 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
778 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
779 { 0}, // end
780 }
781 },
782
783 { // South Africa
784 "ZA",
785 CE,
786 {
787 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
788 { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
789 { 52, 4, 23, IDOR, FALSE}, // 5G, ch 52~64
790 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
791 { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
792 { 0}, // end
793 }
794 },
795
796 { // South Korea
797 "KR",
798 CE,
799 {
800 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
801 { 36, 4, 20, BOTH, FALSE}, // 5G, ch 36~48
802 { 52, 4, 20, BOTH, FALSE}, // 5G, ch 52~64
803 { 100, 8, 20, BOTH, FALSE}, // 5G, ch 100~128
804 { 149, 4, 20, BOTH, FALSE}, // 5G, ch 149~161
805 { 0}, // end
806 }
807 },
808
809 { // Spain
810 "ES",
811 CE,
812 {
813 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
814 { 36, 4, 17, IDOR, FALSE}, // 5G, ch 36~48
815 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
816 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
817 { 0}, // end
818 }
819 },
820
821 { // Sweden
822 "SE",
823 CE,
824 {
825 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
826 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
827 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
828 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
829 { 0}, // end
830 }
831 },
832
833 { // Switzerland
834 "CH",
835 CE,
836 {
837 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
838 { 36, 4, 23, IDOR, TRUE}, // 5G, ch 36~48
839 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
840 { 0}, // end
841 }
842 },
843
844 { // Taiwan
845 "TW",
846 CE,
847 {
848 { 1, 11, 30, BOTH, FALSE}, // 2.4 G, ch 1~11
849 { 52, 4, 23, IDOR, FALSE}, // 5G, ch 52~64
850 { 0}, // end
851 }
852 },
853
854 { // Turkey
855 "TR",
856 CE,
857 {
858 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
859 { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
860 { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
861 { 0}, // end
862 }
863 },
864
865 { // UK
866 "GB",
867 CE,
868 {
869 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
870 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 52~64
871 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
872 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
873 { 0}, // end
874 }
875 },
876
877 { // Ukraine
878 "UA",
879 CE,
880 {
881 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
882 { 0}, // end
883 }
884 },
885
886 { // United_Arab_Emirates
887 "AE",
888 CE,
889 {
890 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
891 { 0}, // end
892 }
893 },
894
895 { // United_States
896 "US",
897 CE,
898 {
899 { 1, 11, 30, BOTH, FALSE}, // 2.4 G, ch 1~11
900 { 36, 4, 17, IDOR, FALSE}, // 5G, ch 52~64
901 { 52, 4, 24, BOTH, TRUE}, // 5G, ch 52~64
902 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
903 { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165
904 { 0}, // end
905 }
906 },
907
908 { // Venezuela
909 "VE",
910 CE,
911 {
912 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
913 { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161
914 { 0}, // end
915 }
916 },
917
918 { // Default
919 "",
920 CE,
921 {
922 { 1, 11, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
923 { 36, 4, 20, BOTH, FALSE}, // 5G, ch 52~64
924 { 52, 4, 20, BOTH, FALSE}, // 5G, ch 52~64
925 { 100, 11, 20, BOTH, FALSE}, // 5G, ch 100~140
926 { 149, 5, 20, BOTH, FALSE}, // 5G, ch 149~165
927 { 0}, // end
928 }
929 },
930};
931
932static inline PCH_REGION GetChRegion(
933 IN PUCHAR CntryCode)
934{
935 INT loop = 0;
936 PCH_REGION pChRegion = NULL;
937
938 while (strcmp(ChRegion[loop].CountReg, "") != 0)
939 {
940 if (strncmp(ChRegion[loop].CountReg, CntryCode, 2) == 0)
941 {
942 pChRegion = &ChRegion[loop];
943 break;
944 }
945 loop++;
946 }
947
948 if (pChRegion == NULL)
949 pChRegion = &ChRegion[loop];
950 return pChRegion;
951}
952
953static inline VOID ChBandCheck(
954 IN UCHAR PhyMode,
955 OUT PUCHAR pChType)
956{
957 switch(PhyMode)
958 {
959 case PHY_11A:
960#ifdef DOT11_N_SUPPORT
961 case PHY_11AN_MIXED:
962#endif // DOT11_N_SUPPORT //
963 *pChType = BAND_5G;
964 break;
965 case PHY_11ABG_MIXED:
966#ifdef DOT11_N_SUPPORT
967 case PHY_11AGN_MIXED:
968 case PHY_11ABGN_MIXED:
969#endif // DOT11_N_SUPPORT //
970 *pChType = BAND_BOTH;
971 break;
972
973 default:
974 *pChType = BAND_24G;
975 break;
976 }
977}
978
979static inline UCHAR FillChList(
980 IN PRTMP_ADAPTER pAd,
981 IN PCH_DESP pChDesp,
982 IN UCHAR Offset,
983 IN UCHAR increment)
984{
985 INT i, j, l;
986 UCHAR channel;
987
988 j = Offset;
989 for (i = 0; i < pChDesp->NumOfCh; i++)
990 {
991 channel = pChDesp->FirstChannel + i * increment;
992 for (l=0; l<MAX_NUM_OF_CHANNELS; l++)
993 {
994 if (channel == pAd->TxPower[l].Channel)
995 {
996 pAd->ChannelList[j].Power = pAd->TxPower[l].Power;
997 pAd->ChannelList[j].Power2 = pAd->TxPower[l].Power2;
998 break;
999 }
1000 }
1001 if (l == MAX_NUM_OF_CHANNELS)
1002 continue;
1003
1004 pAd->ChannelList[j].Channel = pChDesp->FirstChannel + i * increment;
1005 pAd->ChannelList[j].MaxTxPwr = pChDesp->MaxTxPwr;
1006 pAd->ChannelList[j].DfsReq = pChDesp->DfsReq;
1007 j++;
1008 }
1009 pAd->ChannelListNum = j;
1010
1011 return j;
1012}
1013
1014static inline VOID CreateChList(
1015 IN PRTMP_ADAPTER pAd,
1016 IN PCH_REGION pChRegion,
1017 IN UCHAR Geography)
1018{
1019 INT i;
1020 UCHAR offset = 0;
1021 PCH_DESP pChDesp;
1022 UCHAR ChType;
1023 UCHAR increment;
1024
1025 if (pChRegion == NULL)
1026 return;
1027
1028 ChBandCheck(pAd->CommonCfg.PhyMode, &ChType);
1029
1030 for (i=0; i<10; i++)
1031 {
1032 pChDesp = &pChRegion->ChDesp[i];
1033 if (pChDesp->FirstChannel == 0)
1034 break;
1035
1036 if (ChType == BAND_5G)
1037 {
1038 if (pChDesp->FirstChannel <= 14)
1039 continue;
1040 }
1041 else if (ChType == BAND_24G)
1042 {
1043 if (pChDesp->FirstChannel > 14)
1044 continue;
1045 }
1046
1047 if ((pChDesp->Geography == BOTH)
1048 || (pChDesp->Geography == Geography))
1049 {
1050 if (pChDesp->FirstChannel > 14)
1051 increment = 4;
1052 else
1053 increment = 1;
1054 offset = FillChList(pAd, pChDesp, offset, increment);
1055 }
1056 }
1057}
1058
1059static inline VOID BuildChannelListEx(
1060 IN PRTMP_ADAPTER pAd)
1061{
1062 PCH_REGION pChReg;
1063
1064 pChReg = GetChRegion(pAd->CommonCfg.CountryCode);
1065 CreateChList(pAd, pChReg, pAd->CommonCfg.Geography);
1066}
1067
1068static inline VOID BuildBeaconChList(
1069 IN PRTMP_ADAPTER pAd,
1070 OUT PUCHAR pBuf,
1071 OUT PULONG pBufLen)
1072{
1073 INT i;
1074 ULONG TmpLen;
1075 PCH_REGION pChRegion;
1076 PCH_DESP pChDesp;
1077 UCHAR ChType;
1078
1079 pChRegion = GetChRegion(pAd->CommonCfg.CountryCode);
1080
1081 if (pChRegion == NULL)
1082 return;
1083
1084 ChBandCheck(pAd->CommonCfg.PhyMode, &ChType);
1085 *pBufLen = 0;
1086
1087 for (i=0; i<10; i++)
1088 {
1089 pChDesp = &pChRegion->ChDesp[i];
1090 if (pChDesp->FirstChannel == 0)
1091 break;
1092
1093 if (ChType == BAND_5G)
1094 {
1095 if (pChDesp->FirstChannel <= 14)
1096 continue;
1097 }
1098 else if (ChType == BAND_24G)
1099 {
1100 if (pChDesp->FirstChannel > 14)
1101 continue;
1102 }
1103
1104 if ((pChDesp->Geography == BOTH)
1105 || (pChDesp->Geography == pAd->CommonCfg.Geography))
1106 {
1107 MakeOutgoingFrame(pBuf + *pBufLen, &TmpLen,
1108 1, &pChDesp->FirstChannel,
1109 1, &pChDesp->NumOfCh,
1110 1, &pChDesp->MaxTxPwr,
1111 END_OF_ARGS);
1112 *pBufLen += TmpLen;
1113 }
1114 }
1115}
1116
1117
1118#ifdef DOT11_N_SUPPORT
1119static inline BOOLEAN IsValidChannel(
1120 IN PRTMP_ADAPTER pAd,
1121 IN UCHAR channel)
1122
1123{
1124 INT i;
1125
1126 for (i = 0; i < pAd->ChannelListNum; i++)
1127 {
1128 if (pAd->ChannelList[i].Channel == channel)
1129 break;
1130 }
1131
1132 if (i == pAd->ChannelListNum)
1133 return FALSE;
1134 else
1135 return TRUE;
1136}
1137
1138
1139static inline UCHAR GetExtCh(
1140 IN UCHAR Channel,
1141 IN UCHAR Direction)
1142{
1143 CHAR ExtCh;
1144
1145 if (Direction == EXTCHA_ABOVE)
1146 ExtCh = Channel + 4;
1147 else
1148 ExtCh = (Channel - 4) > 0 ? (Channel - 4) : 0;
1149
1150 return ExtCh;
1151}
1152
1153
1154static inline VOID N_ChannelCheck(
1155 IN PRTMP_ADAPTER pAd)
1156{
1157 //UCHAR ChannelNum = pAd->ChannelListNum;
1158 UCHAR Channel = pAd->CommonCfg.Channel;
1159
1160 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40))
1161 {
1162 if (Channel > 14)
1163 {
1164 if ((Channel == 36) || (Channel == 44) || (Channel == 52) || (Channel == 60) || (Channel == 100) || (Channel == 108) ||
1165 (Channel == 116) || (Channel == 124) || (Channel == 132) || (Channel == 149) || (Channel == 157))
1166 {
1167 pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE;
1168 }
1169 else if ((Channel == 40) || (Channel == 48) || (Channel == 56) || (Channel == 64) || (Channel == 104) || (Channel == 112) ||
1170 (Channel == 120) || (Channel == 128) || (Channel == 136) || (Channel == 153) || (Channel == 161))
1171 {
1172 pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_BELOW;
1173 }
1174 else
1175 {
1176 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
1177 }
1178 }
1179 else
1180 {
1181 do
1182 {
1183 UCHAR ExtCh;
1184 UCHAR Dir = pAd->CommonCfg.RegTransmitSetting.field.EXTCHA;
1185 ExtCh = GetExtCh(Channel, Dir);
1186 if (IsValidChannel(pAd, ExtCh))
1187 break;
1188
1189 Dir = (Dir == EXTCHA_ABOVE) ? EXTCHA_BELOW : EXTCHA_ABOVE;
1190 ExtCh = GetExtCh(Channel, Dir);
1191 if (IsValidChannel(pAd, ExtCh))
1192 {
1193 pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = Dir;
1194 break;
1195 }
1196 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
1197 } while(FALSE);
1198
1199 if (Channel == 14)
1200 {
1201 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
1202 //pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_NONE; // We didn't set the ExtCh as NONE due to it'll set in RTMPSetHT()
1203 }
1204 }
1205 }
1206
1207
1208}
1209
1210
1211static inline VOID N_SetCenCh(
1212 IN PRTMP_ADAPTER pAd)
1213{
1214 if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
1215 {
1216 if (pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)
1217 {
1218 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2;
1219 }
1220 else
1221 {
1222 if (pAd->CommonCfg.Channel == 14)
1223 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 1;
1224 else
1225 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2;
1226 }
1227 }
1228 else
1229 {
1230 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
1231 }
1232}
1233#endif // DOT11_N_SUPPORT //
1234
1235
1236static inline UINT8 GetCuntryMaxTxPwr(
1237 IN PRTMP_ADAPTER pAd,
1238 IN UINT8 channel)
1239{
1240 int i;
1241 for (i = 0; i < pAd->ChannelListNum; i++)
1242 {
1243 if (pAd->ChannelList[i].Channel == channel)
1244 break;
1245 }
1246
1247 if (i == pAd->ChannelListNum)
1248 return 0xff;
1249 else
1250 return pAd->ChannelList[i].MaxTxPwr;
1251}
1252#endif // __CHLIST_H__
1253
diff --git a/drivers/staging/rt3070/common/2870_rtmp_init.c b/drivers/staging/rt3070/common/2870_rtmp_init.c
new file mode 100644
index 000000000000..fdf8dc176a67
--- /dev/null
+++ b/drivers/staging/rt3070/common/2870_rtmp_init.c
@@ -0,0 +1,1762 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 2870_rtmp_init.c
29
30 Abstract:
31 Miniport generic portion header file
32
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36 Paul Lin 2002-08-01 created
37 John Chang 2004-08-20 RT2561/2661 use scatter-gather scheme
38 Jan Lee 2006-09-15 RT2860. Change for 802.11n , EEPROM, Led, BA, HT.
39 Sample Lin 2007-05-31 Merge RT2860 and RT2870 drivers.
40*/
41
42#include "../rt_config.h"
43
44
45static void rx_done_tasklet(unsigned long data);
46static void rt2870_hcca_dma_done_tasklet(unsigned long data);
47static void rt2870_ac3_dma_done_tasklet(unsigned long data);
48static void rt2870_ac2_dma_done_tasklet(unsigned long data);
49static void rt2870_ac1_dma_done_tasklet(unsigned long data);
50static void rt2870_ac0_dma_done_tasklet(unsigned long data);
51static void rt2870_mgmt_dma_done_tasklet(unsigned long data);
52static void rt2870_null_frame_complete_tasklet(unsigned long data);
53static void rt2870_rts_frame_complete_tasklet(unsigned long data);
54static void rt2870_pspoll_frame_complete_tasklet(unsigned long data);
55static void rt2870_dataout_complete_tasklet(unsigned long data);
56
57
58/*
59========================================================================
60Routine Description:
61 Initialize receive data structures.
62
63Arguments:
64 pAd Pointer to our adapter
65
66Return Value:
67 NDIS_STATUS_SUCCESS
68 NDIS_STATUS_RESOURCES
69
70Note:
71 Initialize all receive releated private buffer, include those define
72 in RTMP_ADAPTER structure and all private data structures. The mahor
73 work is to allocate buffer for each packet and chain buffer to
74 NDIS packet descriptor.
75========================================================================
76*/
77NDIS_STATUS NICInitRecv(
78 IN PRTMP_ADAPTER pAd)
79{
80 UCHAR i;
81 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
82 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
83
84
85 DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitRecv\n"));
86 pObj = pObj;
87
88 //InterlockedExchange(&pAd->PendingRx, 0);
89 pAd->PendingRx = 0;
90 pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index
91 pAd->NextRxBulkInIndex = 0 ; //RX_RING_SIZE -1; // Rx Bulk pointer
92 pAd->NextRxBulkInPosition = 0;
93
94 for (i = 0; i < (RX_RING_SIZE); i++)
95 {
96 PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
97
98 //Allocate URB
99 pRxContext->pUrb = RTUSB_ALLOC_URB(0);
100 if (pRxContext->pUrb == NULL)
101 {
102 Status = NDIS_STATUS_RESOURCES;
103 goto out1;
104 }
105
106 // Allocate transfer buffer
107 pRxContext->TransferBuffer = RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE, &pRxContext->data_dma);
108 if (pRxContext->TransferBuffer == NULL)
109 {
110 Status = NDIS_STATUS_RESOURCES;
111 goto out1;
112 }
113
114 NdisZeroMemory(pRxContext->TransferBuffer, MAX_RXBULK_SIZE);
115
116 pRxContext->pAd = pAd;
117 pRxContext->pIrp = NULL;
118 pRxContext->InUse = FALSE;
119 pRxContext->IRPPending = FALSE;
120 pRxContext->Readable = FALSE;
121 //pRxContext->ReorderInUse = FALSE;
122 pRxContext->bRxHandling = FALSE;
123 pRxContext->BulkInOffset = 0;
124 }
125
126 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitRecv\n"));
127 return Status;
128
129out1:
130 for (i = 0; i < (RX_RING_SIZE); i++)
131 {
132 PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
133
134 if (NULL != pRxContext->TransferBuffer)
135 {
136 RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE,
137 pRxContext->TransferBuffer, pRxContext->data_dma);
138 pRxContext->TransferBuffer = NULL;
139 }
140
141 if (NULL != pRxContext->pUrb)
142 {
143 RTUSB_UNLINK_URB(pRxContext->pUrb);
144 RTUSB_FREE_URB(pRxContext->pUrb);
145 pRxContext->pUrb = NULL;
146 }
147 }
148
149 return Status;
150}
151
152
153/*
154========================================================================
155Routine Description:
156 Initialize transmit data structures.
157
158Arguments:
159 pAd Pointer to our adapter
160
161Return Value:
162 NDIS_STATUS_SUCCESS
163 NDIS_STATUS_RESOURCES
164
165Note:
166========================================================================
167*/
168NDIS_STATUS NICInitTransmit(
169 IN PRTMP_ADAPTER pAd)
170{
171#define LM_USB_ALLOC(pObj, Context, TB_Type, BufferSize, Status, msg1, err1, msg2, err2) \
172 Context->pUrb = RTUSB_ALLOC_URB(0); \
173 if (Context->pUrb == NULL) { \
174 DBGPRINT(RT_DEBUG_ERROR, msg1); \
175 Status = NDIS_STATUS_RESOURCES; \
176 goto err1; } \
177 \
178 Context->TransferBuffer = \
179 (TB_Type)RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, BufferSize, &Context->data_dma); \
180 if (Context->TransferBuffer == NULL) { \
181 DBGPRINT(RT_DEBUG_ERROR, msg2); \
182 Status = NDIS_STATUS_RESOURCES; \
183 goto err2; }
184
185#define LM_URB_FREE(pObj, Context, BufferSize) \
186 if (NULL != Context->pUrb) { \
187 RTUSB_UNLINK_URB(Context->pUrb); \
188 RTUSB_FREE_URB(Context->pUrb); \
189 Context->pUrb = NULL; } \
190 if (NULL != Context->TransferBuffer) { \
191 RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize, \
192 Context->TransferBuffer, \
193 Context->data_dma); \
194 Context->TransferBuffer = NULL; }
195
196 UCHAR i, acidx;
197 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
198 PTX_CONTEXT pNullContext = &(pAd->NullContext);
199 PTX_CONTEXT pPsPollContext = &(pAd->PsPollContext);
200 PTX_CONTEXT pRTSContext = &(pAd->RTSContext);
201 PTX_CONTEXT pMLMEContext = NULL;
202// PHT_TX_CONTEXT pHTTXContext = NULL;
203 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
204 PVOID RingBaseVa;
205// RTMP_TX_RING *pTxRing;
206 RTMP_MGMT_RING *pMgmtRing;
207
208 DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitTransmit\n"));
209 pObj = pObj;
210
211 // Init 4 set of Tx parameters
212 for(acidx = 0; acidx < NUM_OF_TX_RING; acidx++)
213 {
214 // Initialize all Transmit releated queues
215 InitializeQueueHeader(&pAd->TxSwQueue[acidx]);
216
217 // Next Local tx ring pointer waiting for buck out
218 pAd->NextBulkOutIndex[acidx] = acidx;
219 pAd->BulkOutPending[acidx] = FALSE; // Buck Out control flag
220 //pAd->DataBulkDoneIdx[acidx] = 0;
221 }
222
223 //pAd->NextMLMEIndex = 0;
224 //pAd->PushMgmtIndex = 0;
225 //pAd->PopMgmtIndex = 0;
226 //InterlockedExchange(&pAd->MgmtQueueSize, 0);
227 //InterlockedExchange(&pAd->TxCount, 0);
228
229 //pAd->PrioRingFirstIndex = 0;
230 //pAd->PrioRingTxCnt = 0;
231
232 do
233 {
234 //
235 // TX_RING_SIZE, 4 ACs
236 //
237#ifdef CONFIG_STA_SUPPORT
238 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
239 for(acidx=0; acidx<4; acidx++)
240#endif // CONFIG_STA_SUPPORT //
241 {
242#if 1 //def DOT11_N_SUPPORT
243 PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]);
244
245 NdisZeroMemory(pHTTXContext, sizeof(HT_TX_CONTEXT));
246 //Allocate URB
247 LM_USB_ALLOC(pObj, pHTTXContext, PHTTX_BUFFER, sizeof(HTTX_BUFFER), Status,
248 ("<-- ERROR in Alloc TX TxContext[%d] urb!! \n", acidx),
249 done,
250 ("<-- ERROR in Alloc TX TxContext[%d] HTTX_BUFFER !! \n", acidx),
251 out1);
252
253 NdisZeroMemory(pHTTXContext->TransferBuffer->Aggregation, 4);
254 pHTTXContext->pAd = pAd;
255 pHTTXContext->pIrp = NULL;
256 pHTTXContext->IRPPending = FALSE;
257 pHTTXContext->NextBulkOutPosition = 0;
258 pHTTXContext->ENextBulkOutPosition = 0;
259 pHTTXContext->CurWritePosition = 0;
260 pHTTXContext->CurWriteRealPos = 0;
261 pHTTXContext->BulkOutSize = 0;
262 pHTTXContext->BulkOutPipeId = acidx;
263 pHTTXContext->bRingEmpty = TRUE;
264 pHTTXContext->bCopySavePad = FALSE;
265#endif // DOT11_N_SUPPORT //
266 pAd->BulkOutPending[acidx] = FALSE;
267 }
268
269
270 //
271 // MGMT_RING_SIZE
272 //
273 // Allocate MGMT ring descriptor's memory
274 pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * sizeof(TX_CONTEXT);
275 RTMPAllocateMemory(&pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);
276 if (pAd->MgmtDescRing.AllocVa == NULL)
277 {
278 DBGPRINT_ERR(("Failed to allocate a big buffer for MgmtDescRing!\n"));
279 Status = NDIS_STATUS_RESOURCES;
280 goto out1;
281 }
282 NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);
283 RingBaseVa = pAd->MgmtDescRing.AllocVa;
284
285 // Initialize MGMT Ring and associated buffer memory
286 pMgmtRing = &pAd->MgmtRing;
287 for (i = 0; i < MGMT_RING_SIZE; i++)
288 {
289 // link the pre-allocated Mgmt buffer to MgmtRing.Cell
290 pMgmtRing->Cell[i].AllocSize = sizeof(TX_CONTEXT);
291 pMgmtRing->Cell[i].AllocVa = RingBaseVa;
292 pMgmtRing->Cell[i].pNdisPacket = NULL;
293 pMgmtRing->Cell[i].pNextNdisPacket = NULL;
294
295 //Allocate URB for MLMEContext
296 pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
297 pMLMEContext->pUrb = RTUSB_ALLOC_URB(0);
298 if (pMLMEContext->pUrb == NULL)
299 {
300 DBGPRINT(RT_DEBUG_ERROR, ("<-- ERROR in Alloc TX MLMEContext[%d] urb!! \n", i));
301 Status = NDIS_STATUS_RESOURCES;
302 goto out2;
303 }
304 pMLMEContext->pAd = pAd;
305 pMLMEContext->pIrp = NULL;
306 pMLMEContext->TransferBuffer = NULL;
307 pMLMEContext->InUse = FALSE;
308 pMLMEContext->IRPPending = FALSE;
309 pMLMEContext->bWaitingBulkOut = FALSE;
310 pMLMEContext->BulkOutSize = 0;
311 pMLMEContext->SelfIdx = i;
312
313 // Offset to next ring descriptor address
314 RingBaseVa = (PUCHAR) RingBaseVa + sizeof(TX_CONTEXT);
315 }
316 DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", i));
317
318 //pAd->MgmtRing.TxSwFreeIdx = (MGMT_RING_SIZE - 1);
319 pAd->MgmtRing.TxSwFreeIdx = MGMT_RING_SIZE;
320 pAd->MgmtRing.TxCpuIdx = 0;
321 pAd->MgmtRing.TxDmaIdx = 0;
322
323 //
324 // BEACON_RING_SIZE
325 //
326 for(i=0; i<BEACON_RING_SIZE; i++) // 2
327 {
328 PTX_CONTEXT pBeaconContext = &(pAd->BeaconContext[i]);
329
330
331 NdisZeroMemory(pBeaconContext, sizeof(TX_CONTEXT));
332
333 //Allocate URB
334 LM_USB_ALLOC(pObj, pBeaconContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
335 ("<-- ERROR in Alloc TX BeaconContext[%d] urb!! \n", i),
336 out2,
337 ("<-- ERROR in Alloc TX BeaconContext[%d] TX_BUFFER !! \n", i),
338 out3);
339
340 pBeaconContext->pAd = pAd;
341 pBeaconContext->pIrp = NULL;
342 pBeaconContext->InUse = FALSE;
343 pBeaconContext->IRPPending = FALSE;
344 }
345
346 //
347 // NullContext
348 //
349 NdisZeroMemory(pNullContext, sizeof(TX_CONTEXT));
350
351 //Allocate URB
352 LM_USB_ALLOC(pObj, pNullContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
353 ("<-- ERROR in Alloc TX NullContext urb!! \n"),
354 out3,
355 ("<-- ERROR in Alloc TX NullContext TX_BUFFER !! \n"),
356 out4);
357
358 pNullContext->pAd = pAd;
359 pNullContext->pIrp = NULL;
360 pNullContext->InUse = FALSE;
361 pNullContext->IRPPending = FALSE;
362
363 //
364 // RTSContext
365 //
366 NdisZeroMemory(pRTSContext, sizeof(TX_CONTEXT));
367
368 //Allocate URB
369 LM_USB_ALLOC(pObj, pRTSContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
370 ("<-- ERROR in Alloc TX RTSContext urb!! \n"),
371 out4,
372 ("<-- ERROR in Alloc TX RTSContext TX_BUFFER !! \n"),
373 out5);
374
375 pRTSContext->pAd = pAd;
376 pRTSContext->pIrp = NULL;
377 pRTSContext->InUse = FALSE;
378 pRTSContext->IRPPending = FALSE;
379
380 //
381 // PsPollContext
382 //
383 //NdisZeroMemory(pPsPollContext, sizeof(TX_CONTEXT));
384 //Allocate URB
385 LM_USB_ALLOC(pObj, pPsPollContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
386 ("<-- ERROR in Alloc TX PsPollContext urb!! \n"),
387 out5,
388 ("<-- ERROR in Alloc TX PsPollContext TX_BUFFER !! \n"),
389 out6);
390
391 pPsPollContext->pAd = pAd;
392 pPsPollContext->pIrp = NULL;
393 pPsPollContext->InUse = FALSE;
394 pPsPollContext->IRPPending = FALSE;
395 pPsPollContext->bAggregatible = FALSE;
396 pPsPollContext->LastOne = TRUE;
397
398 } while (FALSE);
399
400
401done:
402 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitTransmit\n"));
403
404 return Status;
405
406 /* --------------------------- ERROR HANDLE --------------------------- */
407out6:
408 LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER));
409
410out5:
411 LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER));
412
413out4:
414 LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER));
415
416out3:
417 for(i=0; i<BEACON_RING_SIZE; i++)
418 {
419 PTX_CONTEXT pBeaconContext = &(pAd->BeaconContext[i]);
420 if (pBeaconContext)
421 LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER));
422 }
423
424out2:
425 if (pAd->MgmtDescRing.AllocVa)
426 {
427 pMgmtRing = &pAd->MgmtRing;
428 for(i=0; i<MGMT_RING_SIZE; i++)
429 {
430 pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
431 if (pMLMEContext)
432 LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER));
433 }
434 NdisFreeMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize, 0);
435 pAd->MgmtDescRing.AllocVa = NULL;
436 }
437
438out1:
439#ifdef CONFIG_STA_SUPPORT
440 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
441 for(acidx=0; acidx<4; acidx++)
442#endif // CONFIG_STA_SUPPORT //
443 {
444 PHT_TX_CONTEXT pTxContext = &(pAd->TxContext[acidx]);
445 if (pTxContext)
446 LM_URB_FREE(pObj, pTxContext, sizeof(HTTX_BUFFER));
447 }
448
449 // Here we didn't have any pre-allocated memory need to free.
450
451 return Status;
452}
453
454
455/*
456========================================================================
457Routine Description:
458 Allocate DMA memory blocks for send, receive.
459
460Arguments:
461 pAd Pointer to our adapter
462
463Return Value:
464 NDIS_STATUS_SUCCESS
465 NDIS_STATUS_FAILURE
466 NDIS_STATUS_RESOURCES
467
468Note:
469========================================================================
470*/
471NDIS_STATUS RTMPAllocTxRxRingMemory(
472 IN PRTMP_ADAPTER pAd)
473{
474// COUNTER_802_11 pCounter = &pAd->WlanCounters;
475 NDIS_STATUS Status;
476 INT num;
477
478
479 DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
480
481
482 do
483 {
484 // Init the CmdQ and CmdQLock
485 NdisAllocateSpinLock(&pAd->CmdQLock);
486 NdisAcquireSpinLock(&pAd->CmdQLock);
487 RTUSBInitializeCmdQ(&pAd->CmdQ);
488 NdisReleaseSpinLock(&pAd->CmdQLock);
489
490
491 NdisAllocateSpinLock(&pAd->MLMEBulkOutLock);
492 //NdisAllocateSpinLock(&pAd->MLMEWaitQueueLock);
493 NdisAllocateSpinLock(&pAd->BulkOutLock[0]);
494 NdisAllocateSpinLock(&pAd->BulkOutLock[1]);
495 NdisAllocateSpinLock(&pAd->BulkOutLock[2]);
496 NdisAllocateSpinLock(&pAd->BulkOutLock[3]);
497 NdisAllocateSpinLock(&pAd->BulkOutLock[4]);
498 NdisAllocateSpinLock(&pAd->BulkOutLock[5]);
499 NdisAllocateSpinLock(&pAd->BulkInLock);
500
501 for (num = 0; num < NUM_OF_TX_RING; num++)
502 {
503 NdisAllocateSpinLock(&pAd->TxContextQueueLock[num]);
504 }
505
506#ifdef RALINK_ATE
507 NdisAllocateSpinLock(&pAd->GenericLock);
508#endif // RALINK_ATE //
509
510// NdisAllocateSpinLock(&pAd->MemLock); // Not used in RT28XX
511
512// NdisAllocateSpinLock(&pAd->MacTabLock); // init it in UserCfgInit()
513// NdisAllocateSpinLock(&pAd->BATabLock); // init it in BATableInit()
514
515// for(num=0; num<MAX_LEN_OF_BA_REC_TABLE; num++)
516// {
517// NdisAllocateSpinLock(&pAd->BATable.BARecEntry[num].RxReRingLock);
518// }
519
520 //
521 // Init Mac Table
522 //
523// MacTableInitialize(pAd);
524
525 //
526 // Init send data structures and related parameters
527 //
528 Status = NICInitTransmit(pAd);
529 if (Status != NDIS_STATUS_SUCCESS)
530 break;
531
532 //
533 // Init receive data structures and related parameters
534 //
535 Status = NICInitRecv(pAd);
536 if (Status != NDIS_STATUS_SUCCESS)
537 break;
538
539 pAd->PendingIoCount = 1;
540
541 } while (FALSE);
542
543 NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME));
544 pAd->FragFrame.pFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
545
546 if (pAd->FragFrame.pFragPacket == NULL)
547 {
548 Status = NDIS_STATUS_RESOURCES;
549 }
550
551 DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status));
552 return Status;
553}
554
555
556/*
557========================================================================
558Routine Description:
559 Calls USB_InterfaceStop and frees memory allocated for the URBs
560 calls NdisMDeregisterDevice and frees the memory
561 allocated in VNetInitialize for the Adapter Object
562
563Arguments:
564 *pAd the raxx interface data pointer
565
566Return Value:
567 None
568
569Note:
570========================================================================
571*/
572VOID RTMPFreeTxRxRingMemory(
573 IN PRTMP_ADAPTER pAd)
574{
575#define LM_URB_FREE(pObj, Context, BufferSize) \
576 if (NULL != Context->pUrb) { \
577 RTUSB_UNLINK_URB(Context->pUrb); \
578 RTUSB_FREE_URB(Context->pUrb); \
579 Context->pUrb = NULL; } \
580 if (NULL != Context->TransferBuffer) { \
581 RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize, \
582 Context->TransferBuffer, \
583 Context->data_dma); \
584 Context->TransferBuffer = NULL; }
585
586
587 UINT i, acidx;
588 PTX_CONTEXT pNullContext = &pAd->NullContext;
589 PTX_CONTEXT pPsPollContext = &pAd->PsPollContext;
590 PTX_CONTEXT pRTSContext = &pAd->RTSContext;
591// PHT_TX_CONTEXT pHTTXContext;
592 //PRTMP_REORDERBUF pReorderBuf;
593 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
594// RTMP_TX_RING *pTxRing;
595
596 DBGPRINT(RT_DEBUG_ERROR, ("---> RTMPFreeTxRxRingMemory\n"));
597 pObj = pObj;
598
599 // Free all resources for the RECEIVE buffer queue.
600 for(i=0; i<(RX_RING_SIZE); i++)
601 {
602 PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
603 if (pRxContext)
604 LM_URB_FREE(pObj, pRxContext, MAX_RXBULK_SIZE);
605 }
606
607 // Free PsPoll frame resource
608 LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER));
609
610 // Free NULL frame resource
611 LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER));
612
613 // Free RTS frame resource
614 LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER));
615
616
617 // Free beacon frame resource
618 for(i=0; i<BEACON_RING_SIZE; i++)
619 {
620 PTX_CONTEXT pBeaconContext = &(pAd->BeaconContext[i]);
621 if (pBeaconContext)
622 LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER));
623 }
624
625
626 // Free mgmt frame resource
627 for(i = 0; i < MGMT_RING_SIZE; i++)
628 {
629 PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa;
630 //LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER));
631 if (NULL != pAd->MgmtRing.Cell[i].pNdisPacket)
632 {
633 RTMPFreeNdisPacket(pAd, pAd->MgmtRing.Cell[i].pNdisPacket);
634 pAd->MgmtRing.Cell[i].pNdisPacket = NULL;
635 pMLMEContext->TransferBuffer = NULL;
636 }
637
638 if (pMLMEContext)
639 {
640 if (NULL != pMLMEContext->pUrb)
641 {
642 RTUSB_UNLINK_URB(pMLMEContext->pUrb);
643 RTUSB_FREE_URB(pMLMEContext->pUrb);
644 pMLMEContext->pUrb = NULL;
645 }
646 }
647 }
648 if (pAd->MgmtDescRing.AllocVa)
649 NdisFreeMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize, 0);
650
651
652 // Free Tx frame resource
653#ifdef CONFIG_STA_SUPPORT
654 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
655 for(acidx=0; acidx<4; acidx++)
656#endif // CONFIG_STA_SUPPORT //
657 {
658 PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]);
659 if (pHTTXContext)
660 LM_URB_FREE(pObj, pHTTXContext, sizeof(HTTX_BUFFER));
661 }
662
663 if (pAd->FragFrame.pFragPacket)
664 RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, NDIS_STATUS_SUCCESS);
665
666 for(i=0; i<6; i++)
667 {
668 NdisFreeSpinLock(&pAd->BulkOutLock[i]);
669 }
670
671 NdisFreeSpinLock(&pAd->BulkInLock);
672 NdisFreeSpinLock(&pAd->MLMEBulkOutLock);
673
674 NdisFreeSpinLock(&pAd->CmdQLock);
675#ifdef RALINK_ATE
676 NdisFreeSpinLock(&pAd->GenericLock);
677#endif // RALINK_ATE //
678 // Clear all pending bulk-out request flags.
679 RTUSB_CLEAR_BULK_FLAG(pAd, 0xffffffff);
680
681// NdisFreeSpinLock(&pAd->MacTabLock);
682
683// for(i=0; i<MAX_LEN_OF_BA_REC_TABLE; i++)
684// {
685// NdisFreeSpinLock(&pAd->BATable.BARecEntry[i].RxReRingLock);
686// }
687
688 DBGPRINT(RT_DEBUG_ERROR, ("<--- ReleaseAdapter\n"));
689}
690
691
692/*
693========================================================================
694Routine Description:
695 Allocate memory for adapter control block.
696
697Arguments:
698 pAd Pointer to our adapter
699
700Return Value:
701 NDIS_STATUS_SUCCESS
702 NDIS_STATUS_FAILURE
703 NDIS_STATUS_RESOURCES
704
705Note:
706========================================================================
707*/
708NDIS_STATUS AdapterBlockAllocateMemory(
709 IN PVOID handle,
710 OUT PVOID *ppAd)
711{
712 PUSB_DEV usb_dev;
713 POS_COOKIE pObj = (POS_COOKIE) handle;
714
715
716 usb_dev = pObj->pUsb_Dev;
717
718 pObj->MLMEThr_pid = NULL;
719 pObj->RTUSBCmdThr_pid = NULL;
720
721 *ppAd = (PVOID)vmalloc(sizeof(RTMP_ADAPTER));
722
723 if (*ppAd)
724 {
725 NdisZeroMemory(*ppAd, sizeof(RTMP_ADAPTER));
726 ((PRTMP_ADAPTER)*ppAd)->OS_Cookie = handle;
727 return (NDIS_STATUS_SUCCESS);
728 }
729 else
730 {
731 return (NDIS_STATUS_FAILURE);
732 }
733}
734
735
736/*
737========================================================================
738Routine Description:
739 Create kernel threads & tasklets.
740
741Arguments:
742 *net_dev Pointer to wireless net device interface
743
744Return Value:
745 NDIS_STATUS_SUCCESS
746 NDIS_STATUS_FAILURE
747
748Note:
749========================================================================
750*/
751NDIS_STATUS CreateThreads(
752 IN struct net_device *net_dev)
753{
754 PRTMP_ADAPTER pAd = net_dev->ml_priv;
755 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
756 pid_t pid_number;
757
758 //init_MUTEX(&(pAd->usbdev_semaphore));
759
760 init_MUTEX_LOCKED(&(pAd->mlme_semaphore));
761 init_completion (&pAd->mlmeComplete);
762
763 init_MUTEX_LOCKED(&(pAd->RTUSBCmd_semaphore));
764 init_completion (&pAd->CmdQComplete);
765
766 init_MUTEX_LOCKED(&(pAd->RTUSBTimer_semaphore));
767 init_completion (&pAd->TimerQComplete);
768
769 // Creat MLME Thread
770 pObj->MLMEThr_pid = NULL;
771 pid_number = kernel_thread(MlmeThread, pAd, CLONE_VM);
772 if (pid_number < 0)
773 {
774 printk (KERN_WARNING "%s: unable to start Mlme thread\n",pAd->net_dev->name);
775 return NDIS_STATUS_FAILURE;
776 }
777 pObj->MLMEThr_pid = find_get_pid(pid_number);
778 // Wait for the thread to start
779 wait_for_completion(&(pAd->mlmeComplete));
780
781 // Creat Command Thread
782 pObj->RTUSBCmdThr_pid = NULL;
783 pid_number = kernel_thread(RTUSBCmdThread, pAd, CLONE_VM);
784 if (pid_number < 0)
785 {
786 printk (KERN_WARNING "%s: unable to start RTUSBCmd thread\n",pAd->net_dev->name);
787 return NDIS_STATUS_FAILURE;
788 }
789 pObj->RTUSBCmdThr_pid = find_get_pid(pid_number);
790 wait_for_completion(&(pAd->CmdQComplete));
791
792 pObj->TimerQThr_pid = NULL;
793 pid_number = kernel_thread(TimerQThread, pAd, CLONE_VM);
794 if (pid_number < 0)
795 {
796 printk (KERN_WARNING "%s: unable to start TimerQThread\n",pAd->net_dev->name);
797 return NDIS_STATUS_FAILURE;
798 }
799 pObj->TimerQThr_pid = find_get_pid(pid_number);
800 // Wait for the thread to start
801 wait_for_completion(&(pAd->TimerQComplete));
802
803 // Create receive tasklet
804 tasklet_init(&pObj->rx_done_task, rx_done_tasklet, (ULONG)pAd);
805 tasklet_init(&pObj->mgmt_dma_done_task, rt2870_mgmt_dma_done_tasklet, (unsigned long)pAd);
806 tasklet_init(&pObj->ac0_dma_done_task, rt2870_ac0_dma_done_tasklet, (unsigned long)pAd);
807 tasklet_init(&pObj->ac1_dma_done_task, rt2870_ac1_dma_done_tasklet, (unsigned long)pAd);
808 tasklet_init(&pObj->ac2_dma_done_task, rt2870_ac2_dma_done_tasklet, (unsigned long)pAd);
809 tasklet_init(&pObj->ac3_dma_done_task, rt2870_ac3_dma_done_tasklet, (unsigned long)pAd);
810 tasklet_init(&pObj->hcca_dma_done_task, rt2870_hcca_dma_done_tasklet, (unsigned long)pAd);
811 tasklet_init(&pObj->tbtt_task, tbtt_tasklet, (unsigned long)pAd);
812 tasklet_init(&pObj->null_frame_complete_task, rt2870_null_frame_complete_tasklet, (unsigned long)pAd);
813 tasklet_init(&pObj->rts_frame_complete_task, rt2870_rts_frame_complete_tasklet, (unsigned long)pAd);
814 tasklet_init(&pObj->pspoll_frame_complete_task, rt2870_pspoll_frame_complete_tasklet, (unsigned long)pAd);
815
816 return NDIS_STATUS_SUCCESS;
817}
818
819
820#ifdef CONFIG_STA_SUPPORT
821/*
822========================================================================
823Routine Description:
824 As STA's BSSID is a WC too, it uses shared key table.
825 This function write correct unicast TX key to ASIC WCID.
826 And we still make a copy in our MacTab.Content[BSSID_WCID].PairwiseKey.
827 Caller guarantee TKIP/AES always has keyidx = 0. (pairwise key)
828 Caller guarantee WEP calls this function when set Txkey, default key index=0~3.
829
830Arguments:
831 pAd Pointer to our adapter
832 pKey Pointer to the where the key stored
833
834Return Value:
835 NDIS_SUCCESS Add key successfully
836
837Note:
838========================================================================
839*/
840VOID RTMPAddBSSIDCipher(
841 IN PRTMP_ADAPTER pAd,
842 IN UCHAR Aid,
843 IN PNDIS_802_11_KEY pKey,
844 IN UCHAR CipherAlg)
845{
846 PUCHAR pTxMic, pRxMic;
847 BOOLEAN bKeyRSC, bAuthenticator; // indicate the receive SC set by KeyRSC value
848// UCHAR CipherAlg;
849 UCHAR i;
850 ULONG WCIDAttri;
851 USHORT offset;
852 UCHAR KeyIdx, IVEIV[8];
853 UINT32 Value;
854
855 DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddBSSIDCipher==> Aid = %d\n",Aid));
856
857 // Bit 29 of Add-key KeyRSC
858 bKeyRSC = (pKey->KeyIndex & 0x20000000) ? TRUE : FALSE;
859
860 // Bit 28 of Add-key Authenticator
861 bAuthenticator = (pKey->KeyIndex & 0x10000000) ? TRUE : FALSE;
862 KeyIdx = (UCHAR)pKey->KeyIndex&0xff;
863
864 if (KeyIdx > 4)
865 return;
866
867
868 if (pAd->MacTab.Content[Aid].PairwiseKey.CipherAlg == CIPHER_TKIP)
869 { if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
870 {
871 // for WPA-None Tx, Rx MIC is the same
872 pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 16;
873 pRxMic = pTxMic;
874 }
875 else if (bAuthenticator == TRUE)
876 {
877 pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 16;
878 pRxMic = (PUCHAR) (&pKey->KeyMaterial) + 24;
879 }
880 else
881 {
882 pRxMic = (PUCHAR) (&pKey->KeyMaterial) + 16;
883 pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 24;
884 }
885
886 offset = PAIRWISE_KEY_TABLE_BASE + (Aid * HW_KEY_ENTRY_SIZE) + 0x10;
887 for (i=0; i<8; )
888 {
889 Value = *(pTxMic+i);
890 Value += (*(pTxMic+i+1)<<8);
891 Value += (*(pTxMic+i+2)<<16);
892 Value += (*(pTxMic+i+3)<<24);
893 RTUSBWriteMACRegister(pAd, offset+i, Value);
894 i+=4;
895 }
896
897 offset = PAIRWISE_KEY_TABLE_BASE + (Aid * HW_KEY_ENTRY_SIZE) + 0x18;
898 for (i=0; i<8; )
899 {
900 Value = *(pRxMic+i);
901 Value += (*(pRxMic+i+1)<<8);
902 Value += (*(pRxMic+i+2)<<16);
903 Value += (*(pRxMic+i+3)<<24);
904 RTUSBWriteMACRegister(pAd, offset+i, Value);
905 i+=4;
906 }
907
908 // Only Key lenth equal to TKIP key have these
909 NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.RxMic, pRxMic, 8);
910 NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.TxMic, pTxMic, 8);
911
912 DBGPRINT(RT_DEBUG_TRACE,
913 (" TxMIC = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x \n",
914 pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],
915 pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
916 DBGPRINT(RT_DEBUG_TRACE,
917 (" RxMIC = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x \n",
918 pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],
919 pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
920 }
921
922 // 2. Record Security Key.
923 pAd->MacTab.Content[BSSID_WCID].PairwiseKey.KeyLen= (UCHAR)pKey->KeyLength;
924 NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.Key, &pKey->KeyMaterial, pKey->KeyLength);
925
926 // 3. Check RxTsc. And used to init to ASIC IV.
927 if (bKeyRSC == TRUE)
928 NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.RxTsc, &pKey->KeyRSC, 6);
929 else
930 NdisZeroMemory(pAd->MacTab.Content[Aid].PairwiseKey.RxTsc, 6);
931
932 // 4. Init TxTsc to one based on WiFi WPA specs
933 pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[0] = 1;
934 pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[1] = 0;
935 pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[2] = 0;
936 pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[3] = 0;
937 pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[4] = 0;
938 pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[5] = 0;
939
940 CipherAlg = pAd->MacTab.Content[Aid].PairwiseKey.CipherAlg;
941
942 offset = PAIRWISE_KEY_TABLE_BASE + (Aid * HW_KEY_ENTRY_SIZE);
943 RTUSBMultiWrite(pAd, (USHORT) offset, pKey->KeyMaterial,
944 ((pKey->KeyLength == LEN_TKIP_KEY) ? 16 : (USHORT)pKey->KeyLength));
945
946 offset = SHARED_KEY_TABLE_BASE + (KeyIdx * HW_KEY_ENTRY_SIZE);
947 RTUSBMultiWrite(pAd, (USHORT) offset, pKey->KeyMaterial, (USHORT)pKey->KeyLength);
948
949 offset = PAIRWISE_IVEIV_TABLE_BASE + (Aid * HW_IVEIV_ENTRY_SIZE);
950 NdisZeroMemory(IVEIV, 8);
951
952 // IV/EIV
953 if ((CipherAlg == CIPHER_TKIP) ||
954 (CipherAlg == CIPHER_TKIP_NO_MIC) ||
955 (CipherAlg == CIPHER_AES))
956 {
957 IVEIV[3] = 0x20; // Eiv bit on. keyid always 0 for pairwise key
958 }
959 // default key idx needs to set.
960 // in TKIP/AES KeyIdx = 0 , WEP KeyIdx is default tx key.
961 else
962 {
963 IVEIV[3] |= (KeyIdx<< 6);
964 }
965 RTUSBMultiWrite(pAd, (USHORT) offset, IVEIV, 8);
966
967 // WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:1=PAIRWISE KEY, BSSIdx is 0
968 if ((CipherAlg == CIPHER_TKIP) ||
969 (CipherAlg == CIPHER_TKIP_NO_MIC) ||
970 (CipherAlg == CIPHER_AES))
971 {
972 WCIDAttri = (CipherAlg<<1)|SHAREDKEYTABLE;
973 }
974 else
975 WCIDAttri = (CipherAlg<<1)|SHAREDKEYTABLE;
976
977 offset = MAC_WCID_ATTRIBUTE_BASE + (Aid* HW_WCID_ATTRI_SIZE);
978 RTUSBWriteMACRegister(pAd, offset, WCIDAttri);
979 RTUSBReadMACRegister(pAd, offset, &Value);
980
981 DBGPRINT(RT_DEBUG_TRACE, ("BSSID_WCID : offset = %x, WCIDAttri = %lx\n",
982 offset, WCIDAttri));
983
984 // pAddr
985 // Add Bssid mac address at linkup. not here. check!
986 /*offset = MAC_WCID_BASE + (BSSID_WCID * HW_WCID_ENTRY_SIZE);
987 *for (i=0; i<MAC_ADDR_LEN; i++)
988 {
989 RTMP_IO_WRITE8(pAd, offset+i, pKey->BSSID[i]);
990 }
991 */
992
993 DBGPRINT(RT_DEBUG_ERROR, ("AddBSSIDasWCIDEntry: Alg=%s, KeyLength = %d\n",
994 CipherName[CipherAlg], pKey->KeyLength));
995 DBGPRINT(RT_DEBUG_TRACE, ("Key [idx=%x] [KeyLen = %d]\n",
996 pKey->KeyIndex, pKey->KeyLength));
997 for(i=0; i<pKey->KeyLength; i++)
998 DBGPRINT_RAW(RT_DEBUG_TRACE,(" %x:", pKey->KeyMaterial[i]));
999 DBGPRINT(RT_DEBUG_TRACE,(" \n"));
1000}
1001#endif // CONFIG_STA_SUPPORT //
1002
1003/*
1004========================================================================
1005Routine Description:
1006 Get a received packet.
1007
1008Arguments:
1009 pAd device control block
1010 pSaveRxD receive descriptor information
1011 *pbReschedule need reschedule flag
1012 *pRxPending pending received packet flag
1013
1014Return Value:
1015 the recieved packet
1016
1017Note:
1018========================================================================
1019*/
1020#define RT2870_RXDMALEN_FIELD_SIZE 4
1021PNDIS_PACKET GetPacketFromRxRing(
1022 IN PRTMP_ADAPTER pAd,
1023 OUT PRT28XX_RXD_STRUC pSaveRxD,
1024 OUT BOOLEAN *pbReschedule,
1025 IN OUT UINT32 *pRxPending)
1026{
1027 PRX_CONTEXT pRxContext;
1028 PNDIS_PACKET pSkb;
1029 PUCHAR pData;
1030 ULONG ThisFrameLen;
1031 ULONG RxBufferLength;
1032 PRXWI_STRUC pRxWI;
1033
1034 pRxContext = &pAd->RxContext[pAd->NextRxBulkInReadIndex];
1035 if ((pRxContext->Readable == FALSE) || (pRxContext->InUse == TRUE))
1036 return NULL;
1037
1038 RxBufferLength = pRxContext->BulkInOffset - pAd->ReadPosition;
1039 if (RxBufferLength < (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXWI_STRUC) + sizeof(RXINFO_STRUC)))
1040 {
1041 goto label_null;
1042 }
1043
1044 pData = &pRxContext->TransferBuffer[pAd->ReadPosition]; /* 4KB */
1045 // The RXDMA field is 4 bytes, now just use the first 2 bytes. The Length including the (RXWI + MSDU + Padding)
1046 ThisFrameLen = *pData + (*(pData+1)<<8);
1047 if (ThisFrameLen == 0)
1048 {
1049 DBGPRINT(RT_DEBUG_TRACE, ("BIRIdx(%d): RXDMALen is zero.[%ld], BulkInBufLen = %ld)\n",
1050 pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset));
1051 goto label_null;
1052 }
1053 if ((ThisFrameLen&0x3) != 0)
1054 {
1055 DBGPRINT(RT_DEBUG_ERROR, ("BIRIdx(%d): RXDMALen not multiple of 4.[%ld], BulkInBufLen = %ld)\n",
1056 pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset));
1057 goto label_null;
1058 }
1059
1060 if ((ThisFrameLen + 8)> RxBufferLength) // 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXINFO_STRUC))
1061 {
1062 DBGPRINT(RT_DEBUG_TRACE,("BIRIdx(%d):FrameLen(0x%lx) outranges. BulkInLen=0x%lx, remaining RxBufLen=0x%lx, ReadPos=0x%lx\n",
1063 pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset, RxBufferLength, pAd->ReadPosition));
1064
1065 // error frame. finish this loop
1066 goto label_null;
1067 }
1068
1069 // skip USB frame length field
1070 pData += RT2870_RXDMALEN_FIELD_SIZE;
1071 pRxWI = (PRXWI_STRUC)pData;
1072#ifdef RT_BIG_ENDIAN
1073 RTMPWIEndianChange(pData, TYPE_RXWI);
1074#endif // RT_BIG_ENDIAN //
1075 if (pRxWI->MPDUtotalByteCount > ThisFrameLen)
1076 {
1077 DBGPRINT(RT_DEBUG_ERROR, ("%s():pRxWIMPDUtotalByteCount(%d) large than RxDMALen(%ld)\n",
1078 __FUNCTION__, pRxWI->MPDUtotalByteCount, ThisFrameLen));
1079 goto label_null;
1080 }
1081#ifdef RT_BIG_ENDIAN
1082 RTMPWIEndianChange(pData, TYPE_RXWI);
1083#endif // RT_BIG_ENDIAN //
1084
1085 // allocate a rx packet
1086 pSkb = dev_alloc_skb(ThisFrameLen);
1087 if (pSkb == NULL)
1088 {
1089 DBGPRINT(RT_DEBUG_ERROR,("%s():Cannot Allocate sk buffer for this Bulk-In buffer!\n", __FUNCTION__));
1090 goto label_null;
1091 }
1092
1093 // copy the rx packet
1094 memcpy(skb_put(pSkb, ThisFrameLen), pData, ThisFrameLen);
1095 RTPKT_TO_OSPKT(pSkb)->dev = get_netdev_from_bssid(pAd, BSS0);
1096 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pSkb), PKTSRC_NDIS);
1097
1098 // copy RxD
1099 *pSaveRxD = *(PRXINFO_STRUC)(pData + ThisFrameLen);
1100#ifdef RT_BIG_ENDIAN
1101 RTMPDescriptorEndianChange((PUCHAR)pSaveRxD, TYPE_RXINFO);
1102#endif // RT_BIG_ENDIAN //
1103
1104 // update next packet read position.
1105 pAd->ReadPosition += (ThisFrameLen + RT2870_RXDMALEN_FIELD_SIZE + RXINFO_SIZE); // 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXINFO_STRUC))
1106
1107 return pSkb;
1108
1109label_null:
1110
1111 return NULL;
1112}
1113
1114
1115/*
1116========================================================================
1117Routine Description:
1118 Handle received packets.
1119
1120Arguments:
1121 data - URB information pointer
1122
1123Return Value:
1124 None
1125
1126Note:
1127========================================================================
1128*/
1129static void rx_done_tasklet(unsigned long data)
1130{
1131 purbb_t pUrb;
1132 PRX_CONTEXT pRxContext;
1133 PRTMP_ADAPTER pAd;
1134 NTSTATUS Status;
1135 unsigned int IrqFlags;
1136
1137 pUrb = (purbb_t)data;
1138 pRxContext = (PRX_CONTEXT)pUrb->context;
1139 pAd = pRxContext->pAd;
1140 Status = pUrb->status;
1141
1142
1143 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1144 pRxContext->InUse = FALSE;
1145 pRxContext->IRPPending = FALSE;
1146 pRxContext->BulkInOffset += pUrb->actual_length;
1147 //NdisInterlockedDecrement(&pAd->PendingRx);
1148 pAd->PendingRx--;
1149
1150 if (Status == USB_ST_NOERROR)
1151 {
1152 pAd->BulkInComplete++;
1153 pAd->NextRxBulkInPosition = 0;
1154 if (pRxContext->BulkInOffset) // As jan's comment, it may bulk-in success but size is zero.
1155 {
1156 pRxContext->Readable = TRUE;
1157 INC_RING_INDEX(pAd->NextRxBulkInIndex, RX_RING_SIZE);
1158 }
1159 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1160 }
1161 else // STATUS_OTHER
1162 {
1163 pAd->BulkInCompleteFail++;
1164 // Still read this packet although it may comtain wrong bytes.
1165 pRxContext->Readable = FALSE;
1166 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1167
1168 // Parsing all packets. because after reset, the index will reset to all zero.
1169 if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
1170 fRTMP_ADAPTER_BULKIN_RESET |
1171 fRTMP_ADAPTER_HALT_IN_PROGRESS |
1172 fRTMP_ADAPTER_NIC_NOT_EXIST))))
1173 {
1174
1175 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk In Failed. Status=%d, BIIdx=0x%x, BIRIdx=0x%x, actual_length= 0x%x\n",
1176 Status, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex, pRxContext->pUrb->actual_length));
1177
1178 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
1179 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0);
1180 }
1181 }
1182
1183 ASSERT((pRxContext->InUse == pRxContext->IRPPending));
1184
1185#ifdef RALINK_ATE
1186 if (ATE_ON(pAd))
1187 {
1188 // If the driver is in ATE mode and Rx frame is set into here.
1189 if (pAd->ContinBulkIn == TRUE)
1190 {
1191 RTUSBBulkReceive(pAd);
1192 }
1193 }
1194 else
1195#endif // RALINK_ATE //
1196 RTUSBBulkReceive(pAd);
1197
1198 return;
1199
1200}
1201
1202
1203static void rt2870_mgmt_dma_done_tasklet(unsigned long data)
1204{
1205 PRTMP_ADAPTER pAd;
1206 PTX_CONTEXT pMLMEContext;
1207 int index;
1208 PNDIS_PACKET pPacket;
1209 purbb_t pUrb;
1210 NTSTATUS Status;
1211 unsigned long IrqFlags;
1212
1213
1214 pUrb = (purbb_t)data;
1215 pMLMEContext = (PTX_CONTEXT)pUrb->context;
1216 pAd = pMLMEContext->pAd;
1217 Status = pUrb->status;
1218 index = pMLMEContext->SelfIdx;
1219
1220 ASSERT((pAd->MgmtRing.TxDmaIdx == index));
1221
1222 RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
1223
1224
1225 if (Status != USB_ST_NOERROR)
1226 {
1227 //Bulk-Out fail status handle
1228 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1229 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1230 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
1231 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
1232 {
1233 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out MLME Failed, Status=%d!\n", Status));
1234 // TODO: How to handle about the MLMEBulkOut failed issue. Need to resend the mgmt pkt?
1235 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1236 pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
1237 }
1238 }
1239
1240 pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
1241 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
1242
1243 RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
1244 // Reset MLME context flags
1245 pMLMEContext->IRPPending = FALSE;
1246 pMLMEContext->InUse = FALSE;
1247 pMLMEContext->bWaitingBulkOut = FALSE;
1248 pMLMEContext->BulkOutSize = 0;
1249
1250 pPacket = pAd->MgmtRing.Cell[index].pNdisPacket;
1251 pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
1252
1253 // Increase MgmtRing Index
1254 INC_RING_INDEX(pAd->MgmtRing.TxDmaIdx, MGMT_RING_SIZE);
1255 pAd->MgmtRing.TxSwFreeIdx++;
1256 RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);
1257
1258 // No-matter success or fail, we free the mgmt packet.
1259 if (pPacket)
1260 RTMPFreeNdisPacket(pAd, pPacket);
1261
1262 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
1263 fRTMP_ADAPTER_HALT_IN_PROGRESS |
1264 fRTMP_ADAPTER_NIC_NOT_EXIST))))
1265 {
1266 // do nothing and return directly.
1267 }
1268 else
1269 {
1270 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET) &&
1271 ((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG))
1272 { // For Mgmt Bulk-Out failed, ignore it now.
1273 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1274 }
1275 else
1276 {
1277
1278 // Always call Bulk routine, even reset bulk.
1279 // The protectioon of rest bulk should be in BulkOut routine
1280 if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE /* pMLMEContext->bWaitingBulkOut == TRUE */)
1281 {
1282 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
1283 }
1284 RTUSBKickBulkOut(pAd);
1285 }
1286 }
1287
1288}
1289
1290
1291static void rt2870_hcca_dma_done_tasklet(unsigned long data)
1292{
1293 PRTMP_ADAPTER pAd;
1294 PHT_TX_CONTEXT pHTTXContext;
1295 UCHAR BulkOutPipeId = 4;
1296 purbb_t pUrb;
1297
1298
1299 pUrb = (purbb_t)data;
1300 pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
1301 pAd = pHTTXContext->pAd;
1302
1303 rt2870_dataout_complete_tasklet((unsigned long)pUrb);
1304
1305 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
1306 fRTMP_ADAPTER_HALT_IN_PROGRESS |
1307 fRTMP_ADAPTER_NIC_NOT_EXIST))))
1308 {
1309 // do nothing and return directly.
1310 }
1311 else
1312 {
1313 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
1314 {
1315 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1316 }
1317 else
1318 { pHTTXContext = &pAd->TxContext[BulkOutPipeId];
1319 if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
1320 /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
1321 (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
1322 (pHTTXContext->bCurWriting == FALSE))
1323 {
1324 RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
1325 }
1326
1327 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<4);
1328 RTUSBKickBulkOut(pAd);
1329 }
1330 }
1331
1332
1333 return;
1334}
1335
1336
1337static void rt2870_ac3_dma_done_tasklet(unsigned long data)
1338{
1339 PRTMP_ADAPTER pAd;
1340 PHT_TX_CONTEXT pHTTXContext;
1341 UCHAR BulkOutPipeId = 3;
1342 purbb_t pUrb;
1343
1344
1345 pUrb = (purbb_t)data;
1346 pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
1347 pAd = pHTTXContext->pAd;
1348
1349 rt2870_dataout_complete_tasklet((unsigned long)pUrb);
1350
1351 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
1352 fRTMP_ADAPTER_HALT_IN_PROGRESS |
1353 fRTMP_ADAPTER_NIC_NOT_EXIST))))
1354 {
1355 // do nothing and return directly.
1356 }
1357 else
1358 {
1359 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
1360 {
1361 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1362 }
1363 else
1364 { pHTTXContext = &pAd->TxContext[BulkOutPipeId];
1365 if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
1366 /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
1367 (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
1368 (pHTTXContext->bCurWriting == FALSE))
1369 {
1370 RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
1371 }
1372
1373 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<3);
1374 RTUSBKickBulkOut(pAd);
1375 }
1376 }
1377
1378
1379 return;
1380}
1381
1382
1383static void rt2870_ac2_dma_done_tasklet(unsigned long data)
1384{
1385 PRTMP_ADAPTER pAd;
1386 PHT_TX_CONTEXT pHTTXContext;
1387 UCHAR BulkOutPipeId = 2;
1388 purbb_t pUrb;
1389
1390
1391 pUrb = (purbb_t)data;
1392 pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
1393 pAd = pHTTXContext->pAd;
1394
1395 rt2870_dataout_complete_tasklet((unsigned long)pUrb);
1396
1397 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
1398 fRTMP_ADAPTER_HALT_IN_PROGRESS |
1399 fRTMP_ADAPTER_NIC_NOT_EXIST))))
1400 {
1401 // do nothing and return directly.
1402 }
1403 else
1404 {
1405 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
1406 {
1407 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1408 }
1409 else
1410 { pHTTXContext = &pAd->TxContext[BulkOutPipeId];
1411 if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
1412 /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
1413 (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
1414 (pHTTXContext->bCurWriting == FALSE))
1415 {
1416 RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
1417 }
1418
1419 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<2);
1420 RTUSBKickBulkOut(pAd);
1421 }
1422 }
1423
1424 return;
1425}
1426
1427
1428static void rt2870_ac1_dma_done_tasklet(unsigned long data)
1429{
1430 PRTMP_ADAPTER pAd;
1431 PHT_TX_CONTEXT pHTTXContext;
1432 UCHAR BulkOutPipeId = 1;
1433 purbb_t pUrb;
1434
1435
1436 pUrb = (purbb_t)data;
1437 pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
1438 pAd = pHTTXContext->pAd;
1439
1440 rt2870_dataout_complete_tasklet((unsigned long)pUrb);
1441
1442 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
1443 fRTMP_ADAPTER_HALT_IN_PROGRESS |
1444 fRTMP_ADAPTER_NIC_NOT_EXIST))))
1445 {
1446 // do nothing and return directly.
1447 }
1448 else
1449 {
1450 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
1451 {
1452 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1453 }
1454 else
1455 { pHTTXContext = &pAd->TxContext[BulkOutPipeId];
1456 if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
1457 /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
1458 (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
1459 (pHTTXContext->bCurWriting == FALSE))
1460 {
1461 RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
1462 }
1463
1464 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<1);
1465 RTUSBKickBulkOut(pAd);
1466 }
1467 }
1468
1469
1470 return;
1471}
1472
1473
1474static void rt2870_ac0_dma_done_tasklet(unsigned long data)
1475{
1476 PRTMP_ADAPTER pAd;
1477 PHT_TX_CONTEXT pHTTXContext;
1478 UCHAR BulkOutPipeId = 0;
1479 purbb_t pUrb;
1480
1481
1482 pUrb = (purbb_t)data;
1483 pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
1484 pAd = pHTTXContext->pAd;
1485
1486 rt2870_dataout_complete_tasklet((unsigned long)pUrb);
1487
1488 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
1489 fRTMP_ADAPTER_HALT_IN_PROGRESS |
1490 fRTMP_ADAPTER_NIC_NOT_EXIST))))
1491 {
1492 // do nothing and return directly.
1493 }
1494 else
1495 {
1496 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
1497 {
1498 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1499 }
1500 else
1501 { pHTTXContext = &pAd->TxContext[BulkOutPipeId];
1502 if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
1503 /* ((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
1504 (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
1505 (pHTTXContext->bCurWriting == FALSE))
1506 {
1507 RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
1508 }
1509
1510 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL);
1511 RTUSBKickBulkOut(pAd);
1512 }
1513 }
1514
1515
1516 return;
1517
1518}
1519
1520
1521static void rt2870_null_frame_complete_tasklet(unsigned long data)
1522{
1523 PRTMP_ADAPTER pAd;
1524 PTX_CONTEXT pNullContext;
1525 purbb_t pUrb;
1526 NTSTATUS Status;
1527 unsigned long irqFlag;
1528
1529
1530 pUrb = (purbb_t)data;
1531 pNullContext = (PTX_CONTEXT)pUrb->context;
1532 pAd = pNullContext->pAd;
1533 Status = pUrb->status;
1534
1535 // Reset Null frame context flags
1536 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag);
1537 pNullContext->IRPPending = FALSE;
1538 pNullContext->InUse = FALSE;
1539 pAd->BulkOutPending[0] = FALSE;
1540 pAd->watchDogTxPendingCnt[0] = 0;
1541
1542 if (Status == USB_ST_NOERROR)
1543 {
1544 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
1545
1546 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1547 }
1548 else // STATUS_OTHER
1549 {
1550 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1551 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1552 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
1553 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
1554 {
1555 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out Null Frame Failed, ReasonCode=%d!\n", Status));
1556 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1557 pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
1558 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
1559 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1560 }
1561 else
1562 {
1563 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
1564 }
1565 }
1566
1567 // Always call Bulk routine, even reset bulk.
1568 // The protectioon of rest bulk should be in BulkOut routine
1569 RTUSBKickBulkOut(pAd);
1570
1571}
1572
1573
1574static void rt2870_rts_frame_complete_tasklet(unsigned long data)
1575{
1576 PRTMP_ADAPTER pAd;
1577 PTX_CONTEXT pRTSContext;
1578 purbb_t pUrb;
1579 NTSTATUS Status;
1580 unsigned long irqFlag;
1581
1582
1583 pUrb = (purbb_t)data;
1584 pRTSContext = (PTX_CONTEXT)pUrb->context;
1585 pAd = pRTSContext->pAd;
1586 Status = pUrb->status;
1587
1588 // Reset RTS frame context flags
1589 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag);
1590 pRTSContext->IRPPending = FALSE;
1591 pRTSContext->InUse = FALSE;
1592
1593 if (Status == USB_ST_NOERROR)
1594 {
1595 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
1596 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1597 }
1598 else // STATUS_OTHER
1599 {
1600 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1601 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1602 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
1603 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
1604 {
1605 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out RTS Frame Failed\n"));
1606 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1607 pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
1608 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
1609 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1610 }
1611 else
1612 {
1613 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
1614 }
1615 }
1616
1617 RTMP_SEM_LOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
1618 pAd->BulkOutPending[pRTSContext->BulkOutPipeId] = FALSE;
1619 RTMP_SEM_UNLOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
1620
1621 // Always call Bulk routine, even reset bulk.
1622 // The protectioon of rest bulk should be in BulkOut routine
1623 RTUSBKickBulkOut(pAd);
1624
1625}
1626
1627
1628static void rt2870_pspoll_frame_complete_tasklet(unsigned long data)
1629{
1630 PRTMP_ADAPTER pAd;
1631 PTX_CONTEXT pPsPollContext;
1632 purbb_t pUrb;
1633 NTSTATUS Status;
1634
1635
1636 pUrb = (purbb_t)data;
1637 pPsPollContext = (PTX_CONTEXT)pUrb->context;
1638 pAd = pPsPollContext->pAd;
1639 Status = pUrb->status;
1640
1641 // Reset PsPoll context flags
1642 pPsPollContext->IRPPending = FALSE;
1643 pPsPollContext->InUse = FALSE;
1644 pAd->watchDogTxPendingCnt[0] = 0;
1645
1646 if (Status == USB_ST_NOERROR)
1647 {
1648 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1649 }
1650 else // STATUS_OTHER
1651 {
1652 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1653 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1654 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
1655 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
1656 {
1657 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out PSPoll Failed\n"));
1658 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1659 pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
1660 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1661 }
1662 }
1663
1664 RTMP_SEM_LOCK(&pAd->BulkOutLock[0]);
1665 pAd->BulkOutPending[0] = FALSE;
1666 RTMP_SEM_UNLOCK(&pAd->BulkOutLock[0]);
1667
1668 // Always call Bulk routine, even reset bulk.
1669 // The protectioon of rest bulk should be in BulkOut routine
1670 RTUSBKickBulkOut(pAd);
1671
1672}
1673
1674
1675static void rt2870_dataout_complete_tasklet(unsigned long data)
1676{
1677 PRTMP_ADAPTER pAd;
1678 purbb_t pUrb;
1679 POS_COOKIE pObj;
1680 PHT_TX_CONTEXT pHTTXContext;
1681 UCHAR BulkOutPipeId;
1682 NTSTATUS Status;
1683 unsigned long IrqFlags;
1684
1685
1686 pUrb = (purbb_t)data;
1687 pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
1688 pAd = pHTTXContext->pAd;
1689 pObj = (POS_COOKIE) pAd->OS_Cookie;
1690 Status = pUrb->status;
1691
1692 // Store BulkOut PipeId
1693 BulkOutPipeId = pHTTXContext->BulkOutPipeId;
1694 pAd->BulkOutDataOneSecCount++;
1695
1696 //DBGPRINT(RT_DEBUG_LOUD, ("Done-B(%d):I=0x%lx, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", BulkOutPipeId, in_interrupt(), pHTTXContext->CurWritePosition,
1697 // pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
1698
1699 RTMP_IRQ_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
1700 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
1701 pHTTXContext->IRPPending = FALSE;
1702 pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;
1703
1704 if (Status == USB_ST_NOERROR)
1705 {
1706 pAd->BulkOutComplete++;
1707
1708 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
1709
1710 pAd->Counters8023.GoodTransmits++;
1711 //RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
1712 FREE_HTTX_RING(pAd, BulkOutPipeId, pHTTXContext);
1713 //RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
1714
1715
1716 }
1717 else // STATUS_OTHER
1718 {
1719 PUCHAR pBuf;
1720
1721 pAd->BulkOutCompleteOther++;
1722
1723 pBuf = &pHTTXContext->TransferBuffer->field.WirelessPacket[pHTTXContext->NextBulkOutPosition];
1724
1725 if (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
1726 fRTMP_ADAPTER_HALT_IN_PROGRESS |
1727 fRTMP_ADAPTER_NIC_NOT_EXIST |
1728 fRTMP_ADAPTER_BULKOUT_RESET)))
1729 {
1730 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1731 pAd->bulkResetPipeid = BulkOutPipeId;
1732 pAd->bulkResetReq[BulkOutPipeId] = pAd->BulkOutReq;
1733 }
1734 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
1735
1736 DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkOutDataPacket failed: ReasonCode=%d!\n", Status));
1737 DBGPRINT_RAW(RT_DEBUG_ERROR, ("\t>>BulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n", pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther));
1738 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]));
1739 //DBGPRINT_RAW(RT_DEBUG_ERROR, (">>BulkOutCompleteCancel=0x%x, BulkOutCompleteOther=0x%x\n", pAd->BulkOutCompleteCancel, pAd->BulkOutCompleteOther));
1740
1741 }
1742
1743 //
1744 // bInUse = TRUE, means some process are filling TX data, after that must turn on bWaitingBulkOut
1745 // bWaitingBulkOut = TRUE, means the TX data are waiting for bulk out.
1746 //
1747 //RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
1748 if ((pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition) &&
1749 (pHTTXContext->ENextBulkOutPosition != (pHTTXContext->CurWritePosition+8)) &&
1750 !RTUSB_TEST_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId)))
1751 {
1752 // Indicate There is data avaliable
1753 RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
1754 }
1755 //RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
1756
1757 // Always call Bulk routine, even reset bulk.
1758 // The protection of rest bulk should be in BulkOut routine
1759 RTUSBKickBulkOut(pAd);
1760}
1761
1762/* End of 2870_rtmp_init.c */
diff --git a/drivers/staging/rt3070/common/action.c b/drivers/staging/rt3070/common/action.c
new file mode 100644
index 000000000000..b8ae53633661
--- /dev/null
+++ b/drivers/staging/rt3070/common/action.c
@@ -0,0 +1,1038 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 action.c
29
30 Abstract:
31 Handle association related requests either from WSTA or from local MLME
32
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36 Jan Lee 2006 created for rt2860
37 */
38
39#include "../rt_config.h"
40#include "../action.h"
41
42
43static VOID ReservedAction(
44 IN PRTMP_ADAPTER pAd,
45 IN MLME_QUEUE_ELEM *Elem);
46
47/*
48 ==========================================================================
49 Description:
50 association state machine init, including state transition and timer init
51 Parameters:
52 S - pointer to the association state machine
53 Note:
54 The state machine looks like the following
55
56 ASSOC_IDLE
57 MT2_MLME_DISASSOC_REQ mlme_disassoc_req_action
58 MT2_PEER_DISASSOC_REQ peer_disassoc_action
59 MT2_PEER_ASSOC_REQ drop
60 MT2_PEER_REASSOC_REQ drop
61 MT2_CLS3ERR cls3err_action
62 ==========================================================================
63 */
64VOID ActionStateMachineInit(
65 IN PRTMP_ADAPTER pAd,
66 IN STATE_MACHINE *S,
67 OUT STATE_MACHINE_FUNC Trans[])
68{
69 StateMachineInit(S, (STATE_MACHINE_FUNC *)Trans, MAX_ACT_STATE, MAX_ACT_MSG, (STATE_MACHINE_FUNC)Drop, ACT_IDLE, ACT_MACHINE_BASE);
70
71 StateMachineSetAction(S, ACT_IDLE, MT2_PEER_SPECTRUM_CATE, (STATE_MACHINE_FUNC)PeerSpectrumAction);
72 StateMachineSetAction(S, ACT_IDLE, MT2_PEER_QOS_CATE, (STATE_MACHINE_FUNC)PeerQOSAction);
73
74 StateMachineSetAction(S, ACT_IDLE, MT2_PEER_DLS_CATE, (STATE_MACHINE_FUNC)ReservedAction);
75#ifdef QOS_DLS_SUPPORT
76 StateMachineSetAction(S, ACT_IDLE, MT2_PEER_DLS_CATE, (STATE_MACHINE_FUNC)PeerDLSAction);
77#endif // QOS_DLS_SUPPORT //
78
79#ifdef DOT11_N_SUPPORT
80 StateMachineSetAction(S, ACT_IDLE, MT2_PEER_BA_CATE, (STATE_MACHINE_FUNC)PeerBAAction);
81 StateMachineSetAction(S, ACT_IDLE, MT2_PEER_HT_CATE, (STATE_MACHINE_FUNC)PeerHTAction);
82 StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ADD_BA_CATE, (STATE_MACHINE_FUNC)MlmeADDBAAction);
83 StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ORI_DELBA_CATE, (STATE_MACHINE_FUNC)MlmeDELBAAction);
84 StateMachineSetAction(S, ACT_IDLE, MT2_MLME_REC_DELBA_CATE, (STATE_MACHINE_FUNC)MlmeDELBAAction);
85#endif // DOT11_N_SUPPORT //
86
87 StateMachineSetAction(S, ACT_IDLE, MT2_PEER_PUBLIC_CATE, (STATE_MACHINE_FUNC)PeerPublicAction);
88 StateMachineSetAction(S, ACT_IDLE, MT2_PEER_RM_CATE, (STATE_MACHINE_FUNC)PeerRMAction);
89
90 StateMachineSetAction(S, ACT_IDLE, MT2_MLME_QOS_CATE, (STATE_MACHINE_FUNC)MlmeQOSAction);
91 StateMachineSetAction(S, ACT_IDLE, MT2_MLME_DLS_CATE, (STATE_MACHINE_FUNC)MlmeDLSAction);
92 StateMachineSetAction(S, ACT_IDLE, MT2_ACT_INVALID, (STATE_MACHINE_FUNC)MlmeInvalidAction);
93}
94
95#ifdef DOT11_N_SUPPORT
96VOID MlmeADDBAAction(
97 IN PRTMP_ADAPTER pAd,
98 IN MLME_QUEUE_ELEM *Elem)
99
100{
101 MLME_ADDBA_REQ_STRUCT *pInfo;
102 UCHAR Addr[6];
103 PUCHAR pOutBuffer = NULL;
104 NDIS_STATUS NStatus;
105 ULONG Idx;
106 FRAME_ADDBA_REQ Frame;
107 ULONG FrameLen;
108 BA_ORI_ENTRY *pBAEntry = NULL;
109
110 pInfo = (MLME_ADDBA_REQ_STRUCT *)Elem->Msg;
111 NdisZeroMemory(&Frame, sizeof(FRAME_ADDBA_REQ));
112
113 if(MlmeAddBAReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr))
114 {
115 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
116 if(NStatus != NDIS_STATUS_SUCCESS)
117 {
118 DBGPRINT(RT_DEBUG_TRACE,("BA - MlmeADDBAAction() allocate memory failed \n"));
119 return;
120 }
121 // 1. find entry
122 Idx = pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID];
123 if (Idx == 0)
124 {
125 MlmeFreeMemory(pAd, pOutBuffer);
126 DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() can't find BAOriEntry \n"));
127 return;
128 }
129 else
130 {
131 pBAEntry =&pAd->BATable.BAOriEntry[Idx];
132 }
133
134#ifdef CONFIG_STA_SUPPORT
135 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
136 {
137 if (ADHOC_ON(pAd))
138 ActHeaderInit(pAd, &Frame.Hdr, pInfo->pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
139 else
140 ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pInfo->pAddr);
141
142 }
143#endif // CONFIG_STA_SUPPORT //
144
145 Frame.Category = CATEGORY_BA;
146 Frame.Action = ADDBA_REQ;
147 Frame.BaParm.AMSDUSupported = 0;
148 Frame.BaParm.BAPolicy = IMMED_BA;
149 Frame.BaParm.TID = pInfo->TID;
150 Frame.BaParm.BufSize = pInfo->BaBufSize;
151 Frame.Token = pInfo->Token;
152 Frame.TimeOutValue = pInfo->TimeOutValue;
153 Frame.BaStartSeq.field.FragNum = 0;
154 Frame.BaStartSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID];
155
156 *(USHORT *)(&Frame.BaParm) = cpu2le16(*(USHORT *)(&Frame.BaParm));
157 Frame.TimeOutValue = cpu2le16(Frame.TimeOutValue);
158 Frame.BaStartSeq.word = cpu2le16(Frame.BaStartSeq.word);
159
160 MakeOutgoingFrame(pOutBuffer, &FrameLen,
161 sizeof(FRAME_ADDBA_REQ), &Frame,
162 END_OF_ARGS);
163 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
164 //MiniportDataMMRequest(pAd, MapUserPriorityToAccessCategory[pInfo->TID], pOutBuffer, FrameLen);
165 MlmeFreeMemory(pAd, pOutBuffer);
166
167 DBGPRINT(RT_DEBUG_TRACE, ("BA - Send ADDBA request. StartSeq = %x, FrameLen = %ld. BufSize = %d\n", Frame.BaStartSeq.field.StartSeq, FrameLen, Frame.BaParm.BufSize));
168 }
169}
170
171/*
172 ==========================================================================
173 Description:
174 send DELBA and delete BaEntry if any
175 Parametrs:
176 Elem - MLME message MLME_DELBA_REQ_STRUCT
177
178 IRQL = DISPATCH_LEVEL
179
180 ==========================================================================
181 */
182VOID MlmeDELBAAction(
183 IN PRTMP_ADAPTER pAd,
184 IN MLME_QUEUE_ELEM *Elem)
185{
186 MLME_DELBA_REQ_STRUCT *pInfo;
187 PUCHAR pOutBuffer = NULL;
188 PUCHAR pOutBuffer2 = NULL;
189 NDIS_STATUS NStatus;
190 ULONG Idx;
191 FRAME_DELBA_REQ Frame;
192 ULONG FrameLen;
193 FRAME_BAR FrameBar;
194
195 pInfo = (MLME_DELBA_REQ_STRUCT *)Elem->Msg;
196 // must send back DELBA
197 NdisZeroMemory(&Frame, sizeof(FRAME_DELBA_REQ));
198 DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeDELBAAction(), Initiator(%d) \n", pInfo->Initiator));
199
200 if(MlmeDelBAReqSanity(pAd, Elem->Msg, Elem->MsgLen))
201 {
202 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
203 if(NStatus != NDIS_STATUS_SUCCESS)
204 {
205 DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeDELBAAction() allocate memory failed 1. \n"));
206 return;
207 }
208
209 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2); //Get an unused nonpaged memory
210 if(NStatus != NDIS_STATUS_SUCCESS)
211 {
212 MlmeFreeMemory(pAd, pOutBuffer);
213 DBGPRINT(RT_DEBUG_ERROR, ("BA - MlmeDELBAAction() allocate memory failed 2. \n"));
214 return;
215 }
216
217 // SEND BAR (Send BAR to refresh peer reordering buffer.)
218 Idx = pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID];
219
220#ifdef CONFIG_STA_SUPPORT
221 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
222 BarHeaderInit(pAd, &FrameBar, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress);
223#endif // CONFIG_STA_SUPPORT //
224
225 FrameBar.StartingSeq.field.FragNum = 0; // make sure sequence not clear in DEL funciton.
226 FrameBar.StartingSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID]; // make sure sequence not clear in DEL funciton.
227 FrameBar.BarControl.TID = pInfo->TID; // make sure sequence not clear in DEL funciton.
228 FrameBar.BarControl.ACKPolicy = IMMED_BA; // make sure sequence not clear in DEL funciton.
229 FrameBar.BarControl.Compressed = 1; // make sure sequence not clear in DEL funciton.
230 FrameBar.BarControl.MTID = 0; // make sure sequence not clear in DEL funciton.
231
232 MakeOutgoingFrame(pOutBuffer2, &FrameLen,
233 sizeof(FRAME_BAR), &FrameBar,
234 END_OF_ARGS);
235 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer2, FrameLen);
236 MlmeFreeMemory(pAd, pOutBuffer2);
237 DBGPRINT(RT_DEBUG_TRACE,("BA - MlmeDELBAAction() . Send BAR to refresh peer reordering buffer \n"));
238
239 // SEND DELBA FRAME
240 FrameLen = 0;
241#ifdef CONFIG_STA_SUPPORT
242 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
243 {
244 if (ADHOC_ON(pAd))
245 ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
246 else
247 ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->MacTab.Content[pInfo->Wcid].Addr);
248 }
249#endif // CONFIG_STA_SUPPORT //
250 Frame.Category = CATEGORY_BA;
251 Frame.Action = DELBA;
252 Frame.DelbaParm.Initiator = pInfo->Initiator;
253 Frame.DelbaParm.TID = pInfo->TID;
254 Frame.ReasonCode = 39; // Time Out
255 *(USHORT *)(&Frame.DelbaParm) = cpu2le16(*(USHORT *)(&Frame.DelbaParm));
256 Frame.ReasonCode = cpu2le16(Frame.ReasonCode);
257
258 MakeOutgoingFrame(pOutBuffer, &FrameLen,
259 sizeof(FRAME_DELBA_REQ), &Frame,
260 END_OF_ARGS);
261 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
262 MlmeFreeMemory(pAd, pOutBuffer);
263 DBGPRINT(RT_DEBUG_TRACE, ("BA - MlmeDELBAAction() . 3 DELBA sent. Initiator(%d)\n", pInfo->Initiator));
264 }
265}
266#endif // DOT11_N_SUPPORT //
267
268VOID MlmeQOSAction(
269 IN PRTMP_ADAPTER pAd,
270 IN MLME_QUEUE_ELEM *Elem)
271{
272}
273
274VOID MlmeDLSAction(
275 IN PRTMP_ADAPTER pAd,
276 IN MLME_QUEUE_ELEM *Elem)
277{
278}
279
280VOID MlmeInvalidAction(
281 IN PRTMP_ADAPTER pAd,
282 IN MLME_QUEUE_ELEM *Elem)
283{
284 //PUCHAR pOutBuffer = NULL;
285 //Return the receiving frame except the MSB of category filed set to 1. 7.3.1.11
286}
287
288VOID PeerQOSAction(
289 IN PRTMP_ADAPTER pAd,
290 IN MLME_QUEUE_ELEM *Elem)
291{
292}
293
294#ifdef QOS_DLS_SUPPORT
295VOID PeerDLSAction(
296 IN PRTMP_ADAPTER pAd,
297 IN MLME_QUEUE_ELEM *Elem)
298{
299 UCHAR Action = Elem->Msg[LENGTH_802_11+1];
300
301 switch(Action)
302 {
303 case ACTION_DLS_REQUEST:
304#ifdef CONFIG_STA_SUPPORT
305 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
306 PeerDlsReqAction(pAd, Elem);
307#endif // CONFIG_STA_SUPPORT //
308 break;
309
310 case ACTION_DLS_RESPONSE:
311#ifdef CONFIG_STA_SUPPORT
312 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
313 PeerDlsRspAction(pAd, Elem);
314#endif // CONFIG_STA_SUPPORT //
315 break;
316
317 case ACTION_DLS_TEARDOWN:
318#ifdef CONFIG_STA_SUPPORT
319 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
320 PeerDlsTearDownAction(pAd, Elem);
321#endif // CONFIG_STA_SUPPORT //
322 break;
323 }
324}
325#endif // QOS_DLS_SUPPORT //
326
327#ifdef DOT11_N_SUPPORT
328VOID PeerBAAction(
329 IN PRTMP_ADAPTER pAd,
330 IN MLME_QUEUE_ELEM *Elem)
331{
332 UCHAR Action = Elem->Msg[LENGTH_802_11+1];
333
334 switch(Action)
335 {
336 case ADDBA_REQ:
337 PeerAddBAReqAction(pAd,Elem);
338 break;
339 case ADDBA_RESP:
340 PeerAddBARspAction(pAd,Elem);
341 break;
342 case DELBA:
343 PeerDelBAAction(pAd,Elem);
344 break;
345 }
346}
347
348
349#ifdef DOT11N_DRAFT3
350
351#ifdef CONFIG_STA_SUPPORT
352VOID StaPublicAction(
353 IN PRTMP_ADAPTER pAd,
354 IN UCHAR Bss2040Coexist)
355{
356 BSS_2040_COEXIST_IE BssCoexist;
357 MLME_SCAN_REQ_STRUCT ScanReq;
358
359 BssCoexist.word = Bss2040Coexist;
360 // 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
361 if ((BssCoexist.field.InfoReq == 1) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SCAN_2040)))
362 {
363 // Clear record first. After scan , will update those bit and send back to transmiter.
364 pAd->CommonCfg.BSSCoexist2040.field.InfoReq = 1;
365 pAd->CommonCfg.BSSCoexist2040.field.Intolerant40 = 0;
366 pAd->CommonCfg.BSSCoexist2040.field.BSS20WidthReq = 0;
367 // Fill out stuff for scan request
368 ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_2040_BSS_COEXIST);
369 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
370 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
371 }
372}
373
374
375/*
376Description : Build Intolerant Channel Rerpot from Trigger event table.
377return : how many bytes copied.
378*/
379ULONG BuildIntolerantChannelRep(
380 IN PRTMP_ADAPTER pAd,
381 IN PUCHAR pDest)
382{
383 ULONG FrameLen = 0;
384 ULONG ReadOffset = 0;
385 UCHAR i;
386 UCHAR LastRegClass = 0xff;
387 PUCHAR pLen;
388
389 for ( i = 0;i < MAX_TRIGGER_EVENT;i++)
390 {
391 if (pAd->CommonCfg.TriggerEventTab.EventA[i].bValid == TRUE)
392 {
393 if (pAd->CommonCfg.TriggerEventTab.EventA[i].RegClass == LastRegClass)
394 {
395 *(pDest + ReadOffset) = (UCHAR)pAd->CommonCfg.TriggerEventTab.EventA[i].Channel;
396 *pLen++;
397 ReadOffset++;
398 FrameLen++;
399 }
400 else
401 {
402 *(pDest + ReadOffset) = IE_2040_BSS_INTOLERANT_REPORT; // IE
403 *(pDest + ReadOffset + 1) = 2; // Len = RegClass byte + channel byte.
404 pLen = pDest + ReadOffset + 1;
405 LastRegClass = pAd->CommonCfg.TriggerEventTab.EventA[i].RegClass;
406 *(pDest + ReadOffset + 2) = LastRegClass; // Len = RegClass byte + channel byte.
407 *(pDest + ReadOffset + 3) = (UCHAR)pAd->CommonCfg.TriggerEventTab.EventA[i].Channel;
408 FrameLen += 4;
409 ReadOffset += 4;
410 }
411
412 }
413 }
414 return FrameLen;
415}
416
417
418/*
419Description : Send 20/40 BSS Coexistence Action frame If one trigger event is triggered.
420*/
421VOID Send2040CoexistAction(
422 IN PRTMP_ADAPTER pAd,
423 IN UCHAR Wcid,
424 IN BOOLEAN bAddIntolerantCha)
425{
426 PUCHAR pOutBuffer = NULL;
427 NDIS_STATUS NStatus;
428 FRAME_ACTION_HDR Frame;
429 ULONG FrameLen;
430 ULONG IntolerantChaRepLen;
431
432 IntolerantChaRepLen = 0;
433 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
434 if(NStatus != NDIS_STATUS_SUCCESS)
435 {
436 DBGPRINT(RT_DEBUG_ERROR,("ACT - Send2040CoexistAction() allocate memory failed \n"));
437 return;
438 }
439 ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[Wcid].Addr, pAd->CommonCfg.Bssid);
440 Frame.Category = CATEGORY_PUBLIC;
441 Frame.Action = ACTION_BSS_2040_COEXIST;
442
443 MakeOutgoingFrame(pOutBuffer, &FrameLen,
444 sizeof(FRAME_ACTION_HDR), &Frame,
445 END_OF_ARGS);
446
447 *(pOutBuffer + FrameLen) = pAd->CommonCfg.BSSCoexist2040.word;
448 FrameLen++;
449
450 if (bAddIntolerantCha == TRUE)
451 IntolerantChaRepLen = BuildIntolerantChannelRep(pAd, pOutBuffer + FrameLen);
452
453 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen + IntolerantChaRepLen);
454 DBGPRINT(RT_DEBUG_ERROR,("ACT - Send2040CoexistAction( BSSCoexist2040 = 0x%x ) \n", pAd->CommonCfg.BSSCoexist2040.word));
455
456}
457
458
459/*
460 ==========================================================================
461 Description:
462 After scan, Update 20/40 BSS Coexistence IE and send out.
463 According to 802.11n D3.03 11.14.10
464
465 Parameters:
466 ==========================================================================
467 */
468VOID Update2040CoexistFrameAndNotify(
469 IN PRTMP_ADAPTER pAd,
470 IN UCHAR Wcid,
471 IN BOOLEAN bAddIntolerantCha)
472{
473 BSS_2040_COEXIST_IE OldValue;
474
475 OldValue.word = pAd->CommonCfg.BSSCoexist2040.word;
476 if ((pAd->CommonCfg.TriggerEventTab.EventANo > 0) || (pAd->CommonCfg.TriggerEventTab.EventBCountDown > 0))
477 pAd->CommonCfg.BSSCoexist2040.field.BSS20WidthReq = 1;
478
479 // Need to check !!!!
480 // How STA will set Intolerant40 if implementation dependent. Now we don't set this bit first.!!!!!
481 // So Only check BSS20WidthReq change.
482 if (OldValue.field.BSS20WidthReq != pAd->CommonCfg.BSSCoexist2040.field.BSS20WidthReq)
483 {
484 Send2040CoexistAction(pAd, Wcid, bAddIntolerantCha);
485 }
486}
487#endif // CONFIG_STA_SUPPORT //
488
489
490BOOLEAN ChannelSwitchSanityCheck(
491 IN PRTMP_ADAPTER pAd,
492 IN UCHAR Wcid,
493 IN UCHAR NewChannel,
494 IN UCHAR Secondary)
495{
496 UCHAR i;
497
498 if (Wcid >= MAX_LEN_OF_MAC_TABLE)
499 return FALSE;
500
501 if ((NewChannel > 7) && (Secondary == 1))
502 return FALSE;
503
504 if ((NewChannel < 5) && (Secondary == 3))
505 return FALSE;
506
507 // 0. Check if new channel is in the channellist.
508 for (i = 0;i < pAd->ChannelListNum;i++)
509 {
510 if (pAd->ChannelList[i].Channel == NewChannel)
511 {
512 break;
513 }
514 }
515
516 if (i == pAd->ChannelListNum)
517 return FALSE;
518
519 return TRUE;
520}
521
522
523VOID ChannelSwitchAction(
524 IN PRTMP_ADAPTER pAd,
525 IN UCHAR Wcid,
526 IN UCHAR NewChannel,
527 IN UCHAR Secondary)
528{
529 UCHAR BBPValue = 0;
530 ULONG MACValue;
531
532 DBGPRINT(RT_DEBUG_TRACE,("SPECTRUM - ChannelSwitchAction(NewChannel = %d , Secondary = %d) \n", NewChannel, Secondary));
533
534 if (ChannelSwitchSanityCheck(pAd, Wcid, NewChannel, Secondary) == FALSE)
535 return;
536
537 // 1. Switches to BW = 20.
538 if (Secondary == 0)
539 {
540 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
541 BBPValue&= (~0x18);
542 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
543 if (pAd->MACVersion == 0x28600100)
544 {
545 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
546 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
547 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
548 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
549 }
550 pAd->CommonCfg.BBPCurrentBW = BW_20;
551 pAd->CommonCfg.Channel = NewChannel;
552 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
553 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel,FALSE);
554 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
555 pAd->MacTab.Content[Wcid].HTPhyMode.field.BW = 0;
556 DBGPRINT(RT_DEBUG_TRACE, ("!!!20MHz !!! \n" ));
557 }
558 // 1. Switches to BW = 40 And Station supports BW = 40.
559 else if (((Secondary == 1) || (Secondary == 3)) && (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == 1))
560 {
561 pAd->CommonCfg.Channel = NewChannel;
562
563 if (Secondary == 1)
564 {
565 // Secondary above.
566 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2;
567 RTMP_IO_READ32(pAd, TX_BAND_CFG, &MACValue);
568 MACValue &= 0xfe;
569 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, MACValue);
570 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
571 BBPValue&= (~0x18);
572 BBPValue|= (0x10);
573 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
574 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPValue);
575 BBPValue&= (~0x20);
576 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPValue);
577 DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
578 }
579 else
580 {
581 // Secondary below.
582 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2;
583 RTMP_IO_READ32(pAd, TX_BAND_CFG, &MACValue);
584 MACValue &= 0xfe;
585 MACValue |= 0x1;
586 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, MACValue);
587 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
588 BBPValue&= (~0x18);
589 BBPValue|= (0x10);
590 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
591 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPValue);
592 BBPValue&= (~0x20);
593 BBPValue|= (0x20);
594 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPValue);
595 DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
596 }
597 pAd->CommonCfg.BBPCurrentBW = BW_40;
598 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
599 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
600 pAd->MacTab.Content[Wcid].HTPhyMode.field.BW = 1;
601 }
602}
603#endif // DOT11N_DRAFT3 //
604#endif // DOT11_N_SUPPORT //
605
606VOID PeerPublicAction(
607 IN PRTMP_ADAPTER pAd,
608 IN MLME_QUEUE_ELEM *Elem)
609{
610#ifdef DOT11N_DRAFT3
611 UCHAR Action = Elem->Msg[LENGTH_802_11+1];
612#endif // DOT11N_DRAFT3 //
613
614 if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
615 return;
616
617#ifdef DOT11N_DRAFT3
618 switch(Action)
619 {
620 case ACTION_BSS_2040_COEXIST: // Format defined in IEEE 7.4.7a.1 in 11n Draf3.03
621 {
622 //UCHAR BssCoexist;
623 BSS_2040_COEXIST_ELEMENT *pCoexistInfo;
624 BSS_2040_COEXIST_IE *pBssCoexistIe;
625 BSS_2040_INTOLERANT_CH_REPORT *pIntolerantReport = NULL;
626
627 if (Elem->MsgLen <= (LENGTH_802_11 + sizeof(BSS_2040_COEXIST_ELEMENT)) )
628 {
629 DBGPRINT(RT_DEBUG_ERROR, ("ACTION - 20/40 BSS Coexistence Management Frame length too short! len = %ld!\n", Elem->MsgLen));
630 break;
631 }
632 DBGPRINT(RT_DEBUG_TRACE, ("ACTION - 20/40 BSS Coexistence Management action----> \n"));
633 hex_dump("CoexistenceMgmtFrame", Elem->Msg, Elem->MsgLen);
634
635
636 pCoexistInfo = (BSS_2040_COEXIST_ELEMENT *) &Elem->Msg[LENGTH_802_11+2];
637 //hex_dump("CoexistInfo", (PUCHAR)pCoexistInfo, sizeof(BSS_2040_COEXIST_ELEMENT));
638 if (Elem->MsgLen >= (LENGTH_802_11 + sizeof(BSS_2040_COEXIST_ELEMENT) + sizeof(BSS_2040_INTOLERANT_CH_REPORT)))
639 {
640 pIntolerantReport = (BSS_2040_INTOLERANT_CH_REPORT *)((PUCHAR)pCoexistInfo + sizeof(BSS_2040_COEXIST_ELEMENT));
641 }
642 //hex_dump("IntolerantReport ", (PUCHAR)pIntolerantReport, sizeof(BSS_2040_INTOLERANT_CH_REPORT));
643
644 pBssCoexistIe = (BSS_2040_COEXIST_IE *)(&pCoexistInfo->BssCoexistIe);
645
646#ifdef CONFIG_STA_SUPPORT
647 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
648 {
649 if (INFRA_ON(pAd))
650 {
651 StaPublicAction(pAd, pCoexistInfo);
652 }
653 }
654#endif // CONFIG_STA_SUPPORT //
655
656 }
657 break;
658 }
659
660#endif // DOT11N_DRAFT3 //
661
662}
663
664
665static VOID ReservedAction(
666 IN PRTMP_ADAPTER pAd,
667 IN MLME_QUEUE_ELEM *Elem)
668{
669 UCHAR Category;
670
671 if (Elem->MsgLen <= LENGTH_802_11)
672 {
673 return;
674 }
675
676 Category = Elem->Msg[LENGTH_802_11];
677 DBGPRINT(RT_DEBUG_TRACE,("Rcv reserved category(%d) Action Frame\n", Category));
678 hex_dump("Reserved Action Frame", &Elem->Msg[0], Elem->MsgLen);
679}
680
681VOID PeerRMAction(
682 IN PRTMP_ADAPTER pAd,
683 IN MLME_QUEUE_ELEM *Elem)
684
685{
686 return;
687}
688
689#ifdef DOT11_N_SUPPORT
690static VOID respond_ht_information_exchange_action(
691 IN PRTMP_ADAPTER pAd,
692 IN MLME_QUEUE_ELEM *Elem)
693{
694 PUCHAR pOutBuffer = NULL;
695 NDIS_STATUS NStatus;
696 ULONG FrameLen;
697 FRAME_HT_INFO HTINFOframe, *pFrame;
698 UCHAR *pAddr;
699
700
701 // 2. Always send back ADDBA Response
702 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
703
704 if (NStatus != NDIS_STATUS_SUCCESS)
705 {
706 DBGPRINT(RT_DEBUG_TRACE,("ACTION - respond_ht_information_exchange_action() allocate memory failed \n"));
707 return;
708 }
709
710 // get RA
711 pFrame = (FRAME_HT_INFO *) &Elem->Msg[0];
712 pAddr = pFrame->Hdr.Addr2;
713
714 NdisZeroMemory(&HTINFOframe, sizeof(FRAME_HT_INFO));
715 // 2-1. Prepare ADDBA Response frame.
716#ifdef CONFIG_STA_SUPPORT
717 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
718 {
719 if (ADHOC_ON(pAd))
720 ActHeaderInit(pAd, &HTINFOframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
721 else
722 ActHeaderInit(pAd, &HTINFOframe.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAddr);
723 }
724#endif // CONFIG_STA_SUPPORT //
725
726 HTINFOframe.Category = CATEGORY_HT;
727 HTINFOframe.Action = HT_INFO_EXCHANGE;
728 HTINFOframe.HT_Info.Request = 0;
729 HTINFOframe.HT_Info.Forty_MHz_Intolerant = pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant;
730 HTINFOframe.HT_Info.STA_Channel_Width = pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth;
731
732 MakeOutgoingFrame(pOutBuffer, &FrameLen,
733 sizeof(FRAME_HT_INFO), &HTINFOframe,
734 END_OF_ARGS);
735
736 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
737 MlmeFreeMemory(pAd, pOutBuffer);
738}
739
740
741#ifdef DOT11N_DRAFT3
742VOID SendNotifyBWActionFrame(
743 IN PRTMP_ADAPTER pAd,
744 IN UCHAR Wcid,
745 IN UCHAR apidx)
746{
747 PUCHAR pOutBuffer = NULL;
748 NDIS_STATUS NStatus;
749 FRAME_ACTION_HDR Frame;
750 ULONG FrameLen;
751 PUCHAR pAddr1;
752
753
754 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
755 if(NStatus != NDIS_STATUS_SUCCESS)
756 {
757 DBGPRINT(RT_DEBUG_ERROR,("ACT - SendNotifyBWAction() allocate memory failed \n"));
758 return;
759 }
760
761 if (Wcid == MCAST_WCID)
762 pAddr1 = &BROADCAST_ADDR[0];
763 else
764 pAddr1 = pAd->MacTab.Content[Wcid].Addr;
765 ActHeaderInit(pAd, &Frame.Hdr, pAddr1, pAd->ApCfg.MBSSID[apidx].Bssid, pAd->ApCfg.MBSSID[apidx].Bssid);
766
767 Frame.Category = CATEGORY_HT;
768 Frame.Action = NOTIFY_BW_ACTION;
769
770 MakeOutgoingFrame(pOutBuffer, &FrameLen,
771 sizeof(FRAME_ACTION_HDR), &Frame,
772 END_OF_ARGS);
773
774 *(pOutBuffer + FrameLen) = pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth;
775 FrameLen++;
776
777
778 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
779 DBGPRINT(RT_DEBUG_TRACE,("ACT - SendNotifyBWAction(NotifyBW= %d)!\n", pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth));
780
781}
782#endif // DOT11N_DRAFT3 //
783
784
785VOID PeerHTAction(
786 IN PRTMP_ADAPTER pAd,
787 IN MLME_QUEUE_ELEM *Elem)
788{
789 UCHAR Action = Elem->Msg[LENGTH_802_11+1];
790
791 if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
792 return;
793
794 switch(Action)
795 {
796 case NOTIFY_BW_ACTION:
797 DBGPRINT(RT_DEBUG_TRACE,("ACTION - HT Notify Channel bandwidth action----> \n"));
798#ifdef CONFIG_STA_SUPPORT
799 if(pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
800 {
801 // Note, this is to patch DIR-1353 AP. When the AP set to Wep, it will use legacy mode. But AP still keeps
802 // sending BW_Notify Action frame, and cause us to linkup and linkdown.
803 // In legacy mode, don't need to parse HT action frame.
804 DBGPRINT(RT_DEBUG_TRACE,("ACTION -Ignore HT Notify Channel BW when link as legacy mode. BW = %d---> \n",
805 Elem->Msg[LENGTH_802_11+2] ));
806 break;
807 }
808#endif // CONFIG_STA_SUPPORT //
809
810 if (Elem->Msg[LENGTH_802_11+2] == 0) // 7.4.8.2. if value is 1, keep the same as supported channel bandwidth.
811 pAd->MacTab.Content[Elem->Wcid].HTPhyMode.field.BW = 0;
812
813 break;
814
815 case SMPS_ACTION:
816 // 7.3.1.25
817 DBGPRINT(RT_DEBUG_TRACE,("ACTION - SMPS action----> \n"));
818 if (((Elem->Msg[LENGTH_802_11+2]&0x1) == 0))
819 {
820 pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_ENABLE;
821 }
822 else if (((Elem->Msg[LENGTH_802_11+2]&0x2) == 0))
823 {
824 pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_STATIC;
825 }
826 else
827 {
828 pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_DYNAMIC;
829 }
830
831 DBGPRINT(RT_DEBUG_TRACE,("Aid(%d) MIMO PS = %d\n", Elem->Wcid, pAd->MacTab.Content[Elem->Wcid].MmpsMode));
832 // rt2860c : add something for smps change.
833 break;
834
835 case SETPCO_ACTION:
836 break;
837
838 case MIMO_CHA_MEASURE_ACTION:
839 break;
840
841 case HT_INFO_EXCHANGE:
842 {
843 HT_INFORMATION_OCTET *pHT_info;
844
845 pHT_info = (HT_INFORMATION_OCTET *) &Elem->Msg[LENGTH_802_11+2];
846 // 7.4.8.10
847 DBGPRINT(RT_DEBUG_TRACE,("ACTION - HT Information Exchange action----> \n"));
848 if (pHT_info->Request)
849 {
850 respond_ht_information_exchange_action(pAd, Elem);
851 }
852 }
853 break;
854 }
855}
856
857
858/*
859 ==========================================================================
860 Description:
861 Retry sending ADDBA Reqest.
862
863 IRQL = DISPATCH_LEVEL
864
865 Parametrs:
866 p8023Header: if this is already 802.3 format, p8023Header is NULL
867
868 Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
869 FALSE , then continue indicaterx at this moment.
870 ==========================================================================
871 */
872VOID ORIBATimerTimeout(
873 IN PRTMP_ADAPTER pAd)
874{
875 MAC_TABLE_ENTRY *pEntry;
876 INT i, total;
877// FRAME_BAR FrameBar;
878// ULONG FrameLen;
879// NDIS_STATUS NStatus;
880// PUCHAR pOutBuffer = NULL;
881// USHORT Sequence;
882 UCHAR TID;
883
884#ifdef RALINK_ATE
885 if (ATE_ON(pAd))
886 return;
887#endif // RALINK_ATE //
888
889 total = pAd->MacTab.Size * NUM_OF_TID;
890
891 for (i = 1; ((i <MAX_LEN_OF_BA_ORI_TABLE) && (total > 0)) ; i++)
892 {
893 if (pAd->BATable.BAOriEntry[i].ORI_BA_Status == Originator_Done)
894 {
895 pEntry = &pAd->MacTab.Content[pAd->BATable.BAOriEntry[i].Wcid];
896 TID = pAd->BATable.BAOriEntry[i].TID;
897
898 ASSERT(pAd->BATable.BAOriEntry[i].Wcid < MAX_LEN_OF_MAC_TABLE);
899 }
900 total --;
901 }
902}
903
904
905VOID SendRefreshBAR(
906 IN PRTMP_ADAPTER pAd,
907 IN MAC_TABLE_ENTRY *pEntry)
908{
909 FRAME_BAR FrameBar;
910 ULONG FrameLen;
911 NDIS_STATUS NStatus;
912 PUCHAR pOutBuffer = NULL;
913 USHORT Sequence;
914 UCHAR i, TID;
915 USHORT idx;
916 BA_ORI_ENTRY *pBAEntry;
917
918 for (i = 0; i <NUM_OF_TID; i++)
919 {
920 idx = pEntry->BAOriWcidArray[i];
921 if (idx == 0)
922 {
923 continue;
924 }
925 pBAEntry = &pAd->BATable.BAOriEntry[idx];
926
927 if (pBAEntry->ORI_BA_Status == Originator_Done)
928 {
929 TID = pBAEntry->TID;
930
931 ASSERT(pBAEntry->Wcid < MAX_LEN_OF_MAC_TABLE);
932
933 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
934 if(NStatus != NDIS_STATUS_SUCCESS)
935 {
936 DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() allocate memory failed \n"));
937 return;
938 }
939
940 Sequence = pEntry->TxSeq[TID];
941
942
943#ifdef CONFIG_STA_SUPPORT
944 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
945 BarHeaderInit(pAd, &FrameBar, pEntry->Addr, pAd->CurrentAddress);
946#endif // CONFIG_STA_SUPPORT //
947
948 FrameBar.StartingSeq.field.FragNum = 0; // make sure sequence not clear in DEL function.
949 FrameBar.StartingSeq.field.StartSeq = Sequence; // make sure sequence not clear in DEL funciton.
950 FrameBar.BarControl.TID = TID; // make sure sequence not clear in DEL funciton.
951
952 MakeOutgoingFrame(pOutBuffer, &FrameLen,
953 sizeof(FRAME_BAR), &FrameBar,
954 END_OF_ARGS);
955 //if (!(CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET)))
956 if (1) // Now we always send BAR.
957 {
958 //MiniportMMRequestUnlock(pAd, 0, pOutBuffer, FrameLen);
959 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
960 //MiniportDataMMRequest(pAd, MapUserPriorityToAccessCategory[TID], pOutBuffer, FrameLen);
961 }
962 MlmeFreeMemory(pAd, pOutBuffer);
963 }
964 }
965}
966#endif // DOT11_N_SUPPORT //
967
968VOID ActHeaderInit(
969 IN PRTMP_ADAPTER pAd,
970 IN OUT PHEADER_802_11 pHdr80211,
971 IN PUCHAR Addr1,
972 IN PUCHAR Addr2,
973 IN PUCHAR Addr3)
974{
975 NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
976 pHdr80211->FC.Type = BTYPE_MGMT;
977 pHdr80211->FC.SubType = SUBTYPE_ACTION;
978
979 COPY_MAC_ADDR(pHdr80211->Addr1, Addr1);
980 COPY_MAC_ADDR(pHdr80211->Addr2, Addr2);
981 COPY_MAC_ADDR(pHdr80211->Addr3, Addr3);
982}
983
984VOID BarHeaderInit(
985 IN PRTMP_ADAPTER pAd,
986 IN OUT PFRAME_BAR pCntlBar,
987 IN PUCHAR pDA,
988 IN PUCHAR pSA)
989{
990// USHORT Duration;
991
992 NdisZeroMemory(pCntlBar, sizeof(FRAME_BAR));
993 pCntlBar->FC.Type = BTYPE_CNTL;
994 pCntlBar->FC.SubType = SUBTYPE_BLOCK_ACK_REQ;
995 pCntlBar->BarControl.MTID = 0;
996 pCntlBar->BarControl.Compressed = 1;
997 pCntlBar->BarControl.ACKPolicy = 0;
998
999
1000 pCntlBar->Duration = 16 + RTMPCalcDuration(pAd, RATE_1, sizeof(FRAME_BA));
1001
1002 COPY_MAC_ADDR(pCntlBar->Addr1, pDA);
1003 COPY_MAC_ADDR(pCntlBar->Addr2, pSA);
1004}
1005
1006
1007/*
1008 ==========================================================================
1009 Description:
1010 Insert Category and action code into the action frame.
1011
1012 Parametrs:
1013 1. frame buffer pointer.
1014 2. frame length.
1015 3. category code of the frame.
1016 4. action code of the frame.
1017
1018 Return : None.
1019 ==========================================================================
1020 */
1021VOID InsertActField(
1022 IN PRTMP_ADAPTER pAd,
1023 OUT PUCHAR pFrameBuf,
1024 OUT PULONG pFrameLen,
1025 IN UINT8 Category,
1026 IN UINT8 ActCode)
1027{
1028 ULONG TempLen;
1029
1030 MakeOutgoingFrame( pFrameBuf, &TempLen,
1031 1, &Category,
1032 1, &ActCode,
1033 END_OF_ARGS);
1034
1035 *pFrameLen = *pFrameLen + TempLen;
1036
1037 return;
1038}
diff --git a/drivers/staging/rt3070/common/ba_action.c b/drivers/staging/rt3070/common/ba_action.c
new file mode 100644
index 000000000000..17e1f87d98db
--- /dev/null
+++ b/drivers/staging/rt3070/common/ba_action.c
@@ -0,0 +1,1810 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26 */
27
28
29#ifdef DOT11_N_SUPPORT
30
31#include "../rt_config.h"
32
33
34
35#define BA_ORI_INIT_SEQ (pEntry->TxSeq[TID]) //1 // inital sequence number of BA session
36
37#define ORI_SESSION_MAX_RETRY 8
38#define ORI_BA_SESSION_TIMEOUT (2000) // ms
39#define REC_BA_SESSION_IDLE_TIMEOUT (1000) // ms
40
41#define REORDERING_PACKET_TIMEOUT ((100 * HZ)/1000) // system ticks -- 100 ms
42#define MAX_REORDERING_PACKET_TIMEOUT ((3000 * HZ)/1000) // system ticks -- 100 ms
43
44#define RESET_RCV_SEQ (0xFFFF)
45
46static void ba_mpdu_blk_free(PRTMP_ADAPTER pAd, struct reordering_mpdu *mpdu_blk);
47
48
49BA_ORI_ENTRY *BATableAllocOriEntry(
50 IN PRTMP_ADAPTER pAd,
51 OUT USHORT *Idx);
52
53BA_REC_ENTRY *BATableAllocRecEntry(
54 IN PRTMP_ADAPTER pAd,
55 OUT USHORT *Idx);
56
57VOID BAOriSessionSetupTimeout(
58 IN PVOID SystemSpecific1,
59 IN PVOID FunctionContext,
60 IN PVOID SystemSpecific2,
61 IN PVOID SystemSpecific3);
62
63VOID BARecSessionIdleTimeout(
64 IN PVOID SystemSpecific1,
65 IN PVOID FunctionContext,
66 IN PVOID SystemSpecific2,
67 IN PVOID SystemSpecific3);
68
69
70BUILD_TIMER_FUNCTION(BAOriSessionSetupTimeout);
71BUILD_TIMER_FUNCTION(BARecSessionIdleTimeout);
72
73#define ANNOUNCE_REORDERING_PACKET(_pAd, _mpdu_blk) \
74 Announce_Reordering_Packet(_pAd, _mpdu_blk);
75
76VOID BA_MaxWinSizeReasign(
77 IN PRTMP_ADAPTER pAd,
78 IN MAC_TABLE_ENTRY *pEntryPeer,
79 OUT UCHAR *pWinSize)
80{
81 UCHAR MaxSize;
82
83
84 if (pAd->MACVersion >= RALINK_2883_VERSION) // 3*3
85 {
86 if (pAd->MACVersion >= RALINK_3070_VERSION)
87 {
88 if (pEntryPeer->WepStatus != Ndis802_11EncryptionDisabled)
89 MaxSize = 7; // for non-open mode
90 else
91 MaxSize = 13;
92 }
93 else
94 MaxSize = 31;
95 }
96 else if (pAd->MACVersion >= RALINK_2880E_VERSION) // 2880 e
97 {
98 if (pEntryPeer->WepStatus != Ndis802_11EncryptionDisabled)
99 MaxSize = 7; // for non-open mode
100 else
101 MaxSize = 13;
102 }
103 else
104 MaxSize = 7;
105
106 DBGPRINT(RT_DEBUG_TRACE, ("ba> Win Size = %d, Max Size = %d\n",
107 *pWinSize, MaxSize));
108
109 if ((*pWinSize) > MaxSize)
110 {
111 DBGPRINT(RT_DEBUG_TRACE, ("ba> reassign max win size from %d to %d\n",
112 *pWinSize, MaxSize));
113
114 *pWinSize = MaxSize;
115 }
116}
117
118void Announce_Reordering_Packet(IN PRTMP_ADAPTER pAd,
119 IN struct reordering_mpdu *mpdu)
120{
121 PNDIS_PACKET pPacket;
122
123 pPacket = mpdu->pPacket;
124
125 if (mpdu->bAMSDU)
126 {
127 ASSERT(0);
128 BA_Reorder_AMSDU_Annnounce(pAd, pPacket);
129 }
130 else
131 {
132 //
133 // pass this 802.3 packet to upper layer or forward this packet to WM directly
134 //
135
136#ifdef CONFIG_STA_SUPPORT
137 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
138 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket, RTMP_GET_PACKET_IF(pPacket));
139#endif // CONFIG_STA_SUPPORT //
140 }
141}
142
143/*
144 * Insert a reordering mpdu into sorted linked list by sequence no.
145 */
146BOOLEAN ba_reordering_mpdu_insertsorted(struct reordering_list *list, struct reordering_mpdu *mpdu)
147{
148
149 struct reordering_mpdu **ppScan = &list->next;
150
151 while (*ppScan != NULL)
152 {
153 if (SEQ_SMALLER((*ppScan)->Sequence, mpdu->Sequence, MAXSEQ))
154 {
155 ppScan = &(*ppScan)->next;
156 }
157 else if ((*ppScan)->Sequence == mpdu->Sequence)
158 {
159 /* give up this duplicated frame */
160 return(FALSE);
161 }
162 else
163 {
164 /* find position */
165 break;
166 }
167 }
168
169 mpdu->next = *ppScan;
170 *ppScan = mpdu;
171 list->qlen++;
172 return TRUE;
173}
174
175
176/*
177 * caller lock critical section if necessary
178 */
179static inline void ba_enqueue(struct reordering_list *list, struct reordering_mpdu *mpdu_blk)
180{
181 list->qlen++;
182 mpdu_blk->next = list->next;
183 list->next = mpdu_blk;
184}
185
186/*
187 * caller lock critical section if necessary
188 */
189static inline struct reordering_mpdu * ba_dequeue(struct reordering_list *list)
190{
191 struct reordering_mpdu *mpdu_blk = NULL;
192
193 ASSERT(list);
194
195 if (list->qlen)
196 {
197 list->qlen--;
198 mpdu_blk = list->next;
199 if (mpdu_blk)
200 {
201 list->next = mpdu_blk->next;
202 mpdu_blk->next = NULL;
203 }
204 }
205 return mpdu_blk;
206}
207
208
209static inline struct reordering_mpdu *ba_reordering_mpdu_dequeue(struct reordering_list *list)
210{
211 return(ba_dequeue(list));
212}
213
214
215static inline struct reordering_mpdu *ba_reordering_mpdu_probe(struct reordering_list *list)
216 {
217 ASSERT(list);
218
219 return(list->next);
220 }
221
222
223/*
224 * free all resource for reordering mechanism
225 */
226void ba_reordering_resource_release(PRTMP_ADAPTER pAd)
227{
228 BA_TABLE *Tab;
229 PBA_REC_ENTRY pBAEntry;
230 struct reordering_mpdu *mpdu_blk;
231 int i;
232
233 Tab = &pAd->BATable;
234
235 /* I. release all pending reordering packet */
236 NdisAcquireSpinLock(&pAd->BATabLock);
237 for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++)
238 {
239 pBAEntry = &Tab->BARecEntry[i];
240 if (pBAEntry->REC_BA_Status != Recipient_NONE)
241 {
242 while ((mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list)))
243 {
244 ASSERT(mpdu_blk->pPacket);
245 RELEASE_NDIS_PACKET(pAd, mpdu_blk->pPacket, NDIS_STATUS_FAILURE);
246 ba_mpdu_blk_free(pAd, mpdu_blk);
247 }
248 }
249 }
250 NdisReleaseSpinLock(&pAd->BATabLock);
251
252 ASSERT(pBAEntry->list.qlen == 0);
253 /* II. free memory of reordering mpdu table */
254 NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock);
255 os_free_mem(pAd, pAd->mpdu_blk_pool.mem);
256 NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock);
257}
258
259
260
261/*
262 * Allocate all resource for reordering mechanism
263 */
264BOOLEAN ba_reordering_resource_init(PRTMP_ADAPTER pAd, int num)
265{
266 int i;
267 PUCHAR mem;
268 struct reordering_mpdu *mpdu_blk;
269 struct reordering_list *freelist;
270
271 /* allocate spinlock */
272 NdisAllocateSpinLock(&pAd->mpdu_blk_pool.lock);
273
274 /* initialize freelist */
275 freelist = &pAd->mpdu_blk_pool.freelist;
276 freelist->next = NULL;
277 freelist->qlen = 0;
278
279 DBGPRINT(RT_DEBUG_TRACE, ("Allocate %d memory for BA reordering\n", (UINT32)(num*sizeof(struct reordering_mpdu))));
280
281 /* allocate number of mpdu_blk memory */
282 os_alloc_mem(pAd, (PUCHAR *)&mem, (num*sizeof(struct reordering_mpdu)));
283
284 pAd->mpdu_blk_pool.mem = mem;
285
286 if (mem == NULL)
287 {
288 DBGPRINT(RT_DEBUG_ERROR, ("Can't Allocate Memory for BA Reordering\n"));
289 return(FALSE);
290 }
291
292 /* build mpdu_blk free list */
293 for (i=0; i<num; i++)
294 {
295 /* get mpdu_blk */
296 mpdu_blk = (struct reordering_mpdu *) mem;
297 /* initial mpdu_blk */
298 NdisZeroMemory(mpdu_blk, sizeof(struct reordering_mpdu));
299 /* next mpdu_blk */
300 mem += sizeof(struct reordering_mpdu);
301 /* insert mpdu_blk into freelist */
302 ba_enqueue(freelist, mpdu_blk);
303 }
304
305 return(TRUE);
306}
307
308//static int blk_count=0; // sample take off, no use
309
310static struct reordering_mpdu *ba_mpdu_blk_alloc(PRTMP_ADAPTER pAd)
311{
312 struct reordering_mpdu *mpdu_blk;
313
314 NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock);
315 mpdu_blk = ba_dequeue(&pAd->mpdu_blk_pool.freelist);
316 if (mpdu_blk)
317 {
318// blk_count++;
319 /* reset mpdu_blk */
320 NdisZeroMemory(mpdu_blk, sizeof(struct reordering_mpdu));
321 }
322 NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock);
323 return mpdu_blk;
324}
325
326static void ba_mpdu_blk_free(PRTMP_ADAPTER pAd, struct reordering_mpdu *mpdu_blk)
327{
328 ASSERT(mpdu_blk);
329
330 NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock);
331// blk_count--;
332 ba_enqueue(&pAd->mpdu_blk_pool.freelist, mpdu_blk);
333 NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock);
334}
335
336
337static USHORT ba_indicate_reordering_mpdus_in_order(
338 IN PRTMP_ADAPTER pAd,
339 IN PBA_REC_ENTRY pBAEntry,
340 IN USHORT StartSeq)
341{
342 struct reordering_mpdu *mpdu_blk;
343 USHORT LastIndSeq = RESET_RCV_SEQ;
344
345 NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
346
347 while ((mpdu_blk = ba_reordering_mpdu_probe(&pBAEntry->list)))
348 {
349 /* find in-order frame */
350 if (!SEQ_STEPONE(mpdu_blk->Sequence, StartSeq, MAXSEQ))
351 {
352 break;
353 }
354 /* dequeue in-order frame from reodering list */
355 mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list);
356 /* pass this frame up */
357 ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
358 /* move to next sequence */
359 StartSeq = mpdu_blk->Sequence;
360 LastIndSeq = StartSeq;
361 /* free mpdu_blk */
362 ba_mpdu_blk_free(pAd, mpdu_blk);
363 }
364
365 NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
366
367 /* update last indicated sequence */
368 return LastIndSeq;
369}
370
371static void ba_indicate_reordering_mpdus_le_seq(
372 IN PRTMP_ADAPTER pAd,
373 IN PBA_REC_ENTRY pBAEntry,
374 IN USHORT Sequence)
375{
376 struct reordering_mpdu *mpdu_blk;
377
378 NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
379 while ((mpdu_blk = ba_reordering_mpdu_probe(&pBAEntry->list)))
380 {
381 /* find in-order frame */
382 if ((mpdu_blk->Sequence == Sequence) || SEQ_SMALLER(mpdu_blk->Sequence, Sequence, MAXSEQ))
383 {
384 /* dequeue in-order frame from reodering list */
385 mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list);
386 /* pass this frame up */
387 ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
388 /* free mpdu_blk */
389 ba_mpdu_blk_free(pAd, mpdu_blk);
390 }
391 else
392 {
393 break;
394 }
395 }
396 NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
397}
398
399
400static void ba_refresh_reordering_mpdus(
401 IN PRTMP_ADAPTER pAd,
402 PBA_REC_ENTRY pBAEntry)
403{
404 struct reordering_mpdu *mpdu_blk;
405
406 NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
407
408 /* dequeue in-order frame from reodering list */
409 while ((mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list)))
410 {
411 /* pass this frame up */
412 ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
413
414 pBAEntry->LastIndSeq = mpdu_blk->Sequence;
415 ba_mpdu_blk_free(pAd, mpdu_blk);
416
417 /* update last indicated sequence */
418 }
419 ASSERT(pBAEntry->list.qlen == 0);
420 pBAEntry->LastIndSeq = RESET_RCV_SEQ;
421 NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
422}
423
424
425//static
426void ba_flush_reordering_timeout_mpdus(
427 IN PRTMP_ADAPTER pAd,
428 IN PBA_REC_ENTRY pBAEntry,
429 IN ULONG Now32)
430
431{
432 USHORT Sequence;
433
434// if ((RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+REORDERING_PACKET_TIMEOUT)) &&
435// (pBAEntry->list.qlen > ((pBAEntry->BAWinSize*7)/8))) //||
436// (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(10*REORDERING_PACKET_TIMEOUT))) &&
437// (pBAEntry->list.qlen > (pBAEntry->BAWinSize/8)))
438 if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(MAX_REORDERING_PACKET_TIMEOUT/6)))
439 &&(pBAEntry->list.qlen > 1)
440 )
441 {
442 DBGPRINT(RT_DEBUG_TRACE,("timeout[%d] (%08lx-%08lx = %d > %d): %x, flush all!\n ", pBAEntry->list.qlen, Now32, (pBAEntry->LastIndSeqAtTimer),
443 (int)((long) Now32 - (long)(pBAEntry->LastIndSeqAtTimer)), MAX_REORDERING_PACKET_TIMEOUT,
444 pBAEntry->LastIndSeq));
445 ba_refresh_reordering_mpdus(pAd, pBAEntry);
446 pBAEntry->LastIndSeqAtTimer = Now32;
447 }
448 else
449 if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(REORDERING_PACKET_TIMEOUT)))
450 && (pBAEntry->list.qlen > 0)
451 )
452 {
453// printk("timeout[%d] (%lx-%lx = %d > %d): %x, ", pBAEntry->list.qlen, Now32, (pBAEntry->LastIndSeqAtTimer),
454// (int)((long) Now32 - (long)(pBAEntry->LastIndSeqAtTimer)), REORDERING_PACKET_TIMEOUT,
455// pBAEntry->LastIndSeq);
456 //
457 // force LastIndSeq to shift to LastIndSeq+1
458 //
459 Sequence = (pBAEntry->LastIndSeq+1) & MAXSEQ;
460 ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, Sequence);
461 pBAEntry->LastIndSeqAtTimer = Now32;
462 pBAEntry->LastIndSeq = Sequence;
463 //
464 // indicate in-order mpdus
465 //
466 Sequence = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, Sequence);
467 if (Sequence != RESET_RCV_SEQ)
468 {
469 pBAEntry->LastIndSeq = Sequence;
470 }
471
472 //printk("%x, flush one!\n", pBAEntry->LastIndSeq);
473
474 }
475}
476
477
478/*
479 * generate ADDBA request to
480 * set up BA agreement
481 */
482VOID BAOriSessionSetUp(
483 IN PRTMP_ADAPTER pAd,
484 IN MAC_TABLE_ENTRY *pEntry,
485 IN UCHAR TID,
486 IN USHORT TimeOut,
487 IN ULONG DelayTime,
488 IN BOOLEAN isForced)
489
490{
491 //MLME_ADDBA_REQ_STRUCT AddbaReq;
492 BA_ORI_ENTRY *pBAEntry = NULL;
493 USHORT Idx;
494 BOOLEAN Cancelled;
495
496 if ((pAd->CommonCfg.BACapability.field.AutoBA != TRUE) && (isForced == FALSE))
497 return;
498
499 // if this entry is limited to use legacy tx mode, it doesn't generate BA.
500 if (RTMPStaFixedTxMode(pAd, pEntry) != FIXED_TXMODE_HT)
501 return;
502
503 if ((pEntry->BADeclineBitmap & (1<<TID)) && (isForced == FALSE))
504 {
505 // try again after 3 secs
506 DelayTime = 3000;
507// printk("DeCline BA from Peer\n");
508// return;
509 }
510
511
512 Idx = pEntry->BAOriWcidArray[TID];
513 if (Idx == 0)
514 {
515 // allocate a BA session
516 pBAEntry = BATableAllocOriEntry(pAd, &Idx);
517 if (pBAEntry == NULL)
518 {
519 DBGPRINT(RT_DEBUG_TRACE,("ADDBA - MlmeADDBAAction() allocate BA session failed \n"));
520 return;
521 }
522 }
523 else
524 {
525 pBAEntry =&pAd->BATable.BAOriEntry[Idx];
526 }
527
528 if (pBAEntry->ORI_BA_Status >= Originator_WaitRes)
529 {
530 return;
531 }
532
533 pEntry->BAOriWcidArray[TID] = Idx;
534
535 // Initialize BA session
536 pBAEntry->ORI_BA_Status = Originator_WaitRes;
537 pBAEntry->Wcid = pEntry->Aid;
538 pBAEntry->BAWinSize = pAd->CommonCfg.BACapability.field.RxBAWinLimit;
539 pBAEntry->Sequence = BA_ORI_INIT_SEQ;
540 pBAEntry->Token = 1; // (2008-01-21) Jan Lee recommends it - this token can't be 0
541 pBAEntry->TID = TID;
542 pBAEntry->TimeOutValue = TimeOut;
543 pBAEntry->pAdapter = pAd;
544
545 DBGPRINT(RT_DEBUG_TRACE,("Send AddBA to %02x:%02x:%02x:%02x:%02x:%02x Tid:%d isForced:%d Wcid:%d\n"
546 ,pEntry->Addr[0],pEntry->Addr[1],pEntry->Addr[2]
547 ,pEntry->Addr[3],pEntry->Addr[4],pEntry->Addr[5]
548 ,TID,isForced,pEntry->Aid));
549
550 if (!(pEntry->TXBAbitmap & (1<<TID)))
551 {
552 RTMPInitTimer(pAd, &pBAEntry->ORIBATimer, GET_TIMER_FUNCTION(BAOriSessionSetupTimeout), pBAEntry, FALSE);
553 }
554 else
555 RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
556
557 // set timer to send ADDBA request
558 RTMPSetTimer(&pBAEntry->ORIBATimer, DelayTime);
559}
560
561VOID BAOriSessionAdd(
562 IN PRTMP_ADAPTER pAd,
563 IN MAC_TABLE_ENTRY *pEntry,
564 IN PFRAME_ADDBA_RSP pFrame)
565{
566 BA_ORI_ENTRY *pBAEntry = NULL;
567 BOOLEAN Cancelled;
568 UCHAR TID;
569 USHORT Idx;
570 PUCHAR pOutBuffer2 = NULL;
571 NDIS_STATUS NStatus;
572 ULONG FrameLen;
573 FRAME_BAR FrameBar;
574
575 TID = pFrame->BaParm.TID;
576 Idx = pEntry->BAOriWcidArray[TID];
577 pBAEntry =&pAd->BATable.BAOriEntry[Idx];
578
579 // Start fill in parameters.
580 if ((Idx !=0) && (pBAEntry->TID == TID) && (pBAEntry->ORI_BA_Status == Originator_WaitRes))
581 {
582 pBAEntry->BAWinSize = min(pBAEntry->BAWinSize, ((UCHAR)pFrame->BaParm.BufSize));
583 BA_MaxWinSizeReasign(pAd, pEntry, &pBAEntry->BAWinSize);
584
585 pBAEntry->TimeOutValue = pFrame->TimeOutValue;
586 pBAEntry->ORI_BA_Status = Originator_Done;
587 // reset sequence number
588 pBAEntry->Sequence = BA_ORI_INIT_SEQ;
589 // Set Bitmap flag.
590 pEntry->TXBAbitmap |= (1<<TID);
591 RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
592
593 pBAEntry->ORIBATimer.TimerValue = 0; //pFrame->TimeOutValue;
594
595 DBGPRINT(RT_DEBUG_TRACE,("%s : TXBAbitmap = %x, BAWinSize = %d, TimeOut = %ld\n", __FUNCTION__, pEntry->TXBAbitmap,
596 pBAEntry->BAWinSize, pBAEntry->ORIBATimer.TimerValue));
597
598 // SEND BAR ;
599 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2); //Get an unused nonpaged memory
600 if (NStatus != NDIS_STATUS_SUCCESS)
601 {
602 DBGPRINT(RT_DEBUG_TRACE,("BA - BAOriSessionAdd() allocate memory failed \n"));
603 return;
604 }
605
606
607#ifdef CONFIG_STA_SUPPORT
608 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
609 BarHeaderInit(pAd, &FrameBar, pAd->MacTab.Content[pBAEntry->Wcid].Addr, pAd->CurrentAddress);
610#endif // CONFIG_STA_SUPPORT //
611
612 FrameBar.StartingSeq.field.FragNum = 0; // make sure sequence not clear in DEL function.
613 FrameBar.StartingSeq.field.StartSeq = pBAEntry->Sequence; // make sure sequence not clear in DEL funciton.
614 FrameBar.BarControl.TID = pBAEntry->TID; // make sure sequence not clear in DEL funciton.
615 MakeOutgoingFrame(pOutBuffer2, &FrameLen,
616 sizeof(FRAME_BAR), &FrameBar,
617 END_OF_ARGS);
618 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer2, FrameLen);
619 MlmeFreeMemory(pAd, pOutBuffer2);
620
621
622 if (pBAEntry->ORIBATimer.TimerValue)
623 RTMPSetTimer(&pBAEntry->ORIBATimer, pBAEntry->ORIBATimer.TimerValue); // in mSec
624 }
625}
626
627BOOLEAN BARecSessionAdd(
628 IN PRTMP_ADAPTER pAd,
629 IN MAC_TABLE_ENTRY *pEntry,
630 IN PFRAME_ADDBA_REQ pFrame)
631{
632 BA_REC_ENTRY *pBAEntry = NULL;
633 BOOLEAN Status = TRUE;
634 BOOLEAN Cancelled;
635 USHORT Idx;
636 UCHAR TID;
637 UCHAR BAWinSize;
638 //UINT32 Value;
639 //UINT offset;
640
641
642 ASSERT(pEntry);
643
644 // find TID
645 TID = pFrame->BaParm.TID;
646
647 BAWinSize = min(((UCHAR)pFrame->BaParm.BufSize), (UCHAR)pAd->CommonCfg.BACapability.field.RxBAWinLimit);
648
649 // Intel patch
650 if (BAWinSize == 0)
651 {
652 BAWinSize = 64;
653 }
654
655 Idx = pEntry->BARecWcidArray[TID];
656
657
658 if (Idx == 0)
659 {
660 pBAEntry = BATableAllocRecEntry(pAd, &Idx);
661 }
662 else
663 {
664 pBAEntry = &pAd->BATable.BARecEntry[Idx];
665 // flush all pending reordering mpdus
666 ba_refresh_reordering_mpdus(pAd, pBAEntry);
667 }
668
669 DBGPRINT(RT_DEBUG_TRACE,("%s(%ld): Idx = %d, BAWinSize(req %d) = %d\n", __FUNCTION__, pAd->BATable.numAsRecipient, Idx,
670 pFrame->BaParm.BufSize, BAWinSize));
671
672 // Start fill in parameters.
673 if (pBAEntry != NULL)
674 {
675 ASSERT(pBAEntry->list.qlen == 0);
676
677 pBAEntry->REC_BA_Status = Recipient_HandleRes;
678 pBAEntry->BAWinSize = BAWinSize;
679 pBAEntry->Wcid = pEntry->Aid;
680 pBAEntry->TID = TID;
681 pBAEntry->TimeOutValue = pFrame->TimeOutValue;
682 pBAEntry->REC_BA_Status = Recipient_Accept;
683 // initial sequence number
684 pBAEntry->LastIndSeq = RESET_RCV_SEQ; //pFrame->BaStartSeq.field.StartSeq;
685
686 printk("Start Seq = %08x\n", pFrame->BaStartSeq.field.StartSeq);
687
688 if (pEntry->RXBAbitmap & (1<<TID))
689 {
690 RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled);
691 }
692 else
693 {
694 RTMPInitTimer(pAd, &pBAEntry->RECBATimer, GET_TIMER_FUNCTION(BARecSessionIdleTimeout), pBAEntry, TRUE);
695 }
696
697 // Set Bitmap flag.
698 pEntry->RXBAbitmap |= (1<<TID);
699 pEntry->BARecWcidArray[TID] = Idx;
700
701 pEntry->BADeclineBitmap &= ~(1<<TID);
702
703 // Set BA session mask in WCID table.
704 RT28XX_ADD_BA_SESSION_TO_ASIC(pAd, pEntry->Aid, TID);
705
706 DBGPRINT(RT_DEBUG_TRACE,("MACEntry[%d]RXBAbitmap = 0x%x. BARecWcidArray=%d\n",
707 pEntry->Aid, pEntry->RXBAbitmap, pEntry->BARecWcidArray[TID]));
708 }
709 else
710 {
711 Status = FALSE;
712 DBGPRINT(RT_DEBUG_TRACE,("Can't Accept ADDBA for %02x:%02x:%02x:%02x:%02x:%02x TID = %d\n",
713 PRINT_MAC(pEntry->Addr), TID));
714 }
715 return(Status);
716}
717
718
719BA_REC_ENTRY *BATableAllocRecEntry(
720 IN PRTMP_ADAPTER pAd,
721 OUT USHORT *Idx)
722{
723 int i;
724 BA_REC_ENTRY *pBAEntry = NULL;
725
726
727 NdisAcquireSpinLock(&pAd->BATabLock);
728
729 if (pAd->BATable.numAsRecipient >= MAX_BARECI_SESSION)
730 {
731 printk("BA Recipeint Session (%ld) > %d\n", pAd->BATable.numAsRecipient,
732 MAX_BARECI_SESSION);
733 goto done;
734 }
735
736 // reserve idx 0 to identify BAWcidArray[TID] as empty
737 for (i=1; i < MAX_LEN_OF_BA_REC_TABLE; i++)
738 {
739 pBAEntry =&pAd->BATable.BARecEntry[i];
740 if ((pBAEntry->REC_BA_Status == Recipient_NONE))
741 {
742 // get one
743 pAd->BATable.numAsRecipient++;
744 pBAEntry->REC_BA_Status = Recipient_USED;
745 *Idx = i;
746 break;
747 }
748 }
749
750done:
751 NdisReleaseSpinLock(&pAd->BATabLock);
752 return pBAEntry;
753}
754
755BA_ORI_ENTRY *BATableAllocOriEntry(
756 IN PRTMP_ADAPTER pAd,
757 OUT USHORT *Idx)
758{
759 int i;
760 BA_ORI_ENTRY *pBAEntry = NULL;
761
762 NdisAcquireSpinLock(&pAd->BATabLock);
763
764 if (pAd->BATable.numAsOriginator >= (MAX_LEN_OF_BA_ORI_TABLE))
765 {
766 goto done;
767 }
768
769 // reserve idx 0 to identify BAWcidArray[TID] as empty
770 for (i=1; i<MAX_LEN_OF_BA_ORI_TABLE; i++)
771 {
772 pBAEntry =&pAd->BATable.BAOriEntry[i];
773 if ((pBAEntry->ORI_BA_Status == Originator_NONE))
774 {
775 // get one
776 pAd->BATable.numAsOriginator++;
777 pBAEntry->ORI_BA_Status = Originator_USED;
778 pBAEntry->pAdapter = pAd;
779 *Idx = i;
780 break;
781 }
782 }
783
784done:
785 NdisReleaseSpinLock(&pAd->BATabLock);
786 return pBAEntry;
787}
788
789
790VOID BATableFreeOriEntry(
791 IN PRTMP_ADAPTER pAd,
792 IN ULONG Idx)
793{
794 BA_ORI_ENTRY *pBAEntry = NULL;
795 MAC_TABLE_ENTRY *pEntry;
796
797
798 if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_ORI_TABLE))
799 return;
800
801 pBAEntry =&pAd->BATable.BAOriEntry[Idx];
802
803 if (pBAEntry->ORI_BA_Status != Originator_NONE)
804 {
805 pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
806 pEntry->BAOriWcidArray[pBAEntry->TID] = 0;
807
808
809 NdisAcquireSpinLock(&pAd->BATabLock);
810 if (pBAEntry->ORI_BA_Status == Originator_Done)
811 {
812 pEntry->TXBAbitmap &= (~(1<<(pBAEntry->TID) ));
813 DBGPRINT(RT_DEBUG_TRACE, ("BATableFreeOriEntry numAsOriginator= %ld\n", pAd->BATable.numAsRecipient));
814 // Erase Bitmap flag.
815 }
816
817 ASSERT(pAd->BATable.numAsOriginator != 0);
818
819 pAd->BATable.numAsOriginator -= 1;
820
821 pBAEntry->ORI_BA_Status = Originator_NONE;
822 pBAEntry->Token = 0;
823 NdisReleaseSpinLock(&pAd->BATabLock);
824 }
825}
826
827
828VOID BATableFreeRecEntry(
829 IN PRTMP_ADAPTER pAd,
830 IN ULONG Idx)
831{
832 BA_REC_ENTRY *pBAEntry = NULL;
833 MAC_TABLE_ENTRY *pEntry;
834
835
836 if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_REC_TABLE))
837 return;
838
839 pBAEntry =&pAd->BATable.BARecEntry[Idx];
840
841 if (pBAEntry->REC_BA_Status != Recipient_NONE)
842 {
843 pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
844 pEntry->BARecWcidArray[pBAEntry->TID] = 0;
845
846 NdisAcquireSpinLock(&pAd->BATabLock);
847
848 ASSERT(pAd->BATable.numAsRecipient != 0);
849
850 pAd->BATable.numAsRecipient -= 1;
851
852 pBAEntry->REC_BA_Status = Recipient_NONE;
853 NdisReleaseSpinLock(&pAd->BATabLock);
854 }
855}
856
857
858VOID BAOriSessionTearDown(
859 IN OUT PRTMP_ADAPTER pAd,
860 IN UCHAR Wcid,
861 IN UCHAR TID,
862 IN BOOLEAN bPassive,
863 IN BOOLEAN bForceSend)
864{
865 ULONG Idx = 0;
866 BA_ORI_ENTRY *pBAEntry;
867 BOOLEAN Cancelled;
868
869 if (Wcid >= MAX_LEN_OF_MAC_TABLE)
870 {
871 return;
872 }
873
874 //
875 // Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID).
876 //
877 Idx = pAd->MacTab.Content[Wcid].BAOriWcidArray[TID];
878 if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_ORI_TABLE))
879 {
880 if (bForceSend == TRUE)
881 {
882 // force send specified TID DelBA
883 MLME_DELBA_REQ_STRUCT DelbaReq;
884 MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
885
886 NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
887 NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
888
889 COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr);
890 DelbaReq.Wcid = Wcid;
891 DelbaReq.TID = TID;
892 DelbaReq.Initiator = ORIGINATOR;
893#if 1
894 Elem->MsgLen = sizeof(DelbaReq);
895 NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
896 MlmeDELBAAction(pAd, Elem);
897 kfree(Elem);
898#else
899 MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq);
900 RT28XX_MLME_HANDLER(pAd);
901#endif
902 }
903
904 return;
905 }
906
907 DBGPRINT(RT_DEBUG_TRACE,("%s===>Wcid=%d.TID=%d \n", __FUNCTION__, Wcid, TID));
908
909 pBAEntry = &pAd->BATable.BAOriEntry[Idx];
910 DBGPRINT(RT_DEBUG_TRACE,("\t===>Idx = %ld, Wcid=%d.TID=%d, ORI_BA_Status = %d \n", Idx, Wcid, TID, pBAEntry->ORI_BA_Status));
911 //
912 // Prepare DelBA action frame and send to the peer.
913 //
914 if ((bPassive == FALSE) && (TID == pBAEntry->TID) && (pBAEntry->ORI_BA_Status == Originator_Done))
915 {
916 MLME_DELBA_REQ_STRUCT DelbaReq;
917 MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
918
919 NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
920 NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
921
922 COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr);
923 DelbaReq.Wcid = Wcid;
924 DelbaReq.TID = pBAEntry->TID;
925 DelbaReq.Initiator = ORIGINATOR;
926#if 1
927 Elem->MsgLen = sizeof(DelbaReq);
928 NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
929 MlmeDELBAAction(pAd, Elem);
930 kfree(Elem);
931#else
932 MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq);
933 RT28XX_MLME_HANDLER(pAd);
934#endif
935 }
936 RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
937 BATableFreeOriEntry(pAd, Idx);
938
939 if (bPassive)
940 {
941 //BAOriSessionSetUp(pAd, &pAd->MacTab.Content[Wcid], TID, 0, 10000, TRUE);
942 }
943}
944
945VOID BARecSessionTearDown(
946 IN OUT PRTMP_ADAPTER pAd,
947 IN UCHAR Wcid,
948 IN UCHAR TID,
949 IN BOOLEAN bPassive)
950{
951 ULONG Idx = 0;
952 BA_REC_ENTRY *pBAEntry;
953
954 if (Wcid >= MAX_LEN_OF_MAC_TABLE)
955 {
956 return;
957 }
958
959 //
960 // Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID).
961 //
962 Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
963 if (Idx == 0)
964 return;
965
966 DBGPRINT(RT_DEBUG_TRACE,("%s===>Wcid=%d.TID=%d \n", __FUNCTION__, Wcid, TID));
967
968
969 pBAEntry = &pAd->BATable.BARecEntry[Idx];
970 DBGPRINT(RT_DEBUG_TRACE,("\t===>Idx = %ld, Wcid=%d.TID=%d, REC_BA_Status = %d \n", Idx, Wcid, TID, pBAEntry->REC_BA_Status));
971 //
972 // Prepare DelBA action frame and send to the peer.
973 //
974 if ((TID == pBAEntry->TID) && (pBAEntry->REC_BA_Status == Recipient_Accept))
975 {
976 MLME_DELBA_REQ_STRUCT DelbaReq;
977 BOOLEAN Cancelled;
978 MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
979 //ULONG offset;
980 //UINT32 VALUE;
981
982 RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled);
983
984 //
985 // 1. Send DELBA Action Frame
986 //
987 if (bPassive == FALSE)
988 {
989 NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
990 NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
991
992 COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr);
993 DelbaReq.Wcid = Wcid;
994 DelbaReq.TID = TID;
995 DelbaReq.Initiator = RECIPIENT;
996#if 1
997 Elem->MsgLen = sizeof(DelbaReq);
998 NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
999 MlmeDELBAAction(pAd, Elem);
1000 kfree(Elem);
1001#else
1002 MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq);
1003 RT28XX_MLME_HANDLER(pAd);
1004#endif
1005 }
1006
1007
1008 //
1009 // 2. Free resource of BA session
1010 //
1011 // flush all pending reordering mpdus
1012 ba_refresh_reordering_mpdus(pAd, pBAEntry);
1013
1014 NdisAcquireSpinLock(&pAd->BATabLock);
1015
1016 // Erase Bitmap flag.
1017 pBAEntry->LastIndSeq = RESET_RCV_SEQ;
1018 pBAEntry->BAWinSize = 0;
1019 // Erase Bitmap flag at software mactable
1020 pAd->MacTab.Content[Wcid].RXBAbitmap &= (~(1<<(pBAEntry->TID)));
1021 pAd->MacTab.Content[Wcid].BARecWcidArray[TID] = 0;
1022
1023 RT28XX_DEL_BA_SESSION_FROM_ASIC(pAd, Wcid, TID);
1024
1025 NdisReleaseSpinLock(&pAd->BATabLock);
1026
1027 }
1028
1029 BATableFreeRecEntry(pAd, Idx);
1030}
1031
1032VOID BASessionTearDownALL(
1033 IN OUT PRTMP_ADAPTER pAd,
1034 IN UCHAR Wcid)
1035{
1036 int i;
1037
1038 for (i=0; i<NUM_OF_TID; i++)
1039 {
1040 BAOriSessionTearDown(pAd, Wcid, i, FALSE, FALSE);
1041 BARecSessionTearDown(pAd, Wcid, i, FALSE);
1042 }
1043}
1044
1045
1046/*
1047 ==========================================================================
1048 Description:
1049 Retry sending ADDBA Reqest.
1050
1051 IRQL = DISPATCH_LEVEL
1052
1053 Parametrs:
1054 p8023Header: if this is already 802.3 format, p8023Header is NULL
1055
1056 Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
1057 FALSE , then continue indicaterx at this moment.
1058 ==========================================================================
1059 */
1060VOID BAOriSessionSetupTimeout(
1061 IN PVOID SystemSpecific1,
1062 IN PVOID FunctionContext,
1063 IN PVOID SystemSpecific2,
1064 IN PVOID SystemSpecific3)
1065{
1066 BA_ORI_ENTRY *pBAEntry = (BA_ORI_ENTRY *)FunctionContext;
1067 MAC_TABLE_ENTRY *pEntry;
1068 PRTMP_ADAPTER pAd;
1069
1070 if (pBAEntry == NULL)
1071 return;
1072
1073 pAd = pBAEntry->pAdapter;
1074
1075#ifdef CONFIG_STA_SUPPORT
1076 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1077 {
1078 // Do nothing if monitor mode is on
1079 if (MONITOR_ON(pAd))
1080 return;
1081 }
1082#endif // CONFIG_STA_SUPPORT //
1083
1084#ifdef RALINK_ATE
1085 // Nothing to do in ATE mode.
1086 if (ATE_ON(pAd))
1087 return;
1088#endif // RALINK_ATE //
1089
1090 pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
1091
1092 if ((pBAEntry->ORI_BA_Status == Originator_WaitRes) && (pBAEntry->Token < ORI_SESSION_MAX_RETRY))
1093 {
1094 MLME_ADDBA_REQ_STRUCT AddbaReq;
1095
1096 NdisZeroMemory(&AddbaReq, sizeof(AddbaReq));
1097 COPY_MAC_ADDR(AddbaReq.pAddr, pEntry->Addr);
1098 AddbaReq.Wcid = (UCHAR)(pEntry->Aid);
1099 AddbaReq.TID = pBAEntry->TID;
1100 AddbaReq.BaBufSize = pAd->CommonCfg.BACapability.field.RxBAWinLimit;
1101 AddbaReq.TimeOutValue = 0;
1102 AddbaReq.Token = pBAEntry->Token;
1103 MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ADD_BA_CATE, sizeof(MLME_ADDBA_REQ_STRUCT), (PVOID)&AddbaReq);
1104 RT28XX_MLME_HANDLER(pAd);
1105 //DBGPRINT(RT_DEBUG_TRACE,("BA Ori Session Timeout(%d) : Send ADD BA again\n", pBAEntry->Token));
1106
1107 DBGPRINT(RT_DEBUG_TRACE,("BA Ori Session Timeout(%d) to %02x:%02x:%02x:%02x:%02x:%02x Tid:%d Wcid:%d\n"
1108 ,pBAEntry->Token
1109 ,pEntry->Addr[0],pEntry->Addr[1],pEntry->Addr[2]
1110 ,pEntry->Addr[3],pEntry->Addr[4],pEntry->Addr[5]
1111 ,pBAEntry->TID,pEntry->Aid));
1112
1113 pBAEntry->Token++;
1114 RTMPSetTimer(&pBAEntry->ORIBATimer, ORI_BA_SESSION_TIMEOUT);
1115 }
1116 else
1117 {
1118 BATableFreeOriEntry(pAd, pEntry->BAOriWcidArray[pBAEntry->TID]);
1119 }
1120}
1121
1122/*
1123 ==========================================================================
1124 Description:
1125 Retry sending ADDBA Reqest.
1126
1127 IRQL = DISPATCH_LEVEL
1128
1129 Parametrs:
1130 p8023Header: if this is already 802.3 format, p8023Header is NULL
1131
1132 Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
1133 FALSE , then continue indicaterx at this moment.
1134 ==========================================================================
1135 */
1136VOID BARecSessionIdleTimeout(
1137 IN PVOID SystemSpecific1,
1138 IN PVOID FunctionContext,
1139 IN PVOID SystemSpecific2,
1140 IN PVOID SystemSpecific3)
1141{
1142
1143 BA_REC_ENTRY *pBAEntry = (BA_REC_ENTRY *)FunctionContext;
1144 PRTMP_ADAPTER pAd;
1145 ULONG Now32;
1146
1147 if (pBAEntry == NULL)
1148 return;
1149
1150 if ((pBAEntry->REC_BA_Status == Recipient_Accept))
1151 {
1152 NdisGetSystemUpTime(&Now32);
1153
1154 if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer + REC_BA_SESSION_IDLE_TIMEOUT)))
1155 {
1156 pAd = pBAEntry->pAdapter;
1157 // flush all pending reordering mpdus
1158 ba_refresh_reordering_mpdus(pAd, pBAEntry);
1159 printk("%ld: REC BA session Timeout\n", Now32);
1160 }
1161 }
1162}
1163
1164
1165VOID PeerAddBAReqAction(
1166 IN PRTMP_ADAPTER pAd,
1167 IN MLME_QUEUE_ELEM *Elem)
1168
1169{
1170 // 7.4.4.1
1171 //ULONG Idx;
1172 UCHAR Status = 1;
1173 UCHAR pAddr[6];
1174 FRAME_ADDBA_RSP ADDframe;
1175 PUCHAR pOutBuffer = NULL;
1176 NDIS_STATUS NStatus;
1177 PFRAME_ADDBA_REQ pAddreqFrame = NULL;
1178 //UCHAR BufSize;
1179 ULONG FrameLen;
1180 PULONG ptemp;
1181 PMAC_TABLE_ENTRY pMacEntry;
1182
1183 DBGPRINT(RT_DEBUG_TRACE, ("%s ==> (Wcid = %d)\n", __FUNCTION__, Elem->Wcid));
1184
1185 //hex_dump("AddBAReq", Elem->Msg, Elem->MsgLen);
1186
1187 //ADDBA Request from unknown peer, ignore this.
1188 if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
1189 return;
1190
1191 pMacEntry = &pAd->MacTab.Content[Elem->Wcid];
1192 DBGPRINT(RT_DEBUG_TRACE,("BA - PeerAddBAReqAction----> \n"));
1193 ptemp = (PULONG)Elem->Msg;
1194 //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)));
1195
1196 if (PeerAddBAReqActionSanity(pAd, Elem->Msg, Elem->MsgLen, pAddr))
1197 {
1198
1199 if ((pAd->CommonCfg.bBADecline == FALSE) && IS_HT_STA(pMacEntry))
1200 {
1201 pAddreqFrame = (PFRAME_ADDBA_REQ)(&Elem->Msg[0]);
1202 printk("Rcv Wcid(%d) AddBAReq\n", Elem->Wcid);
1203 if (BARecSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid], pAddreqFrame))
1204 Status = 0;
1205 else
1206 Status = 38; // more parameters have invalid values
1207 }
1208 else
1209 {
1210 Status = 37; // the request has been declined.
1211 }
1212 }
1213
1214 if (pAd->MacTab.Content[Elem->Wcid].ValidAsCLI)
1215 ASSERT(pAd->MacTab.Content[Elem->Wcid].Sst == SST_ASSOC);
1216
1217 pAddreqFrame = (PFRAME_ADDBA_REQ)(&Elem->Msg[0]);
1218 // 2. Always send back ADDBA Response
1219 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1220 if (NStatus != NDIS_STATUS_SUCCESS)
1221 {
1222 DBGPRINT(RT_DEBUG_TRACE,("ACTION - PeerBAAction() allocate memory failed \n"));
1223 return;
1224 }
1225
1226 NdisZeroMemory(&ADDframe, sizeof(FRAME_ADDBA_RSP));
1227 // 2-1. Prepare ADDBA Response frame.
1228#ifdef CONFIG_STA_SUPPORT
1229 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1230 {
1231 if (ADHOC_ON(pAd))
1232 ActHeaderInit(pAd, &ADDframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
1233 else
1234 ActHeaderInit(pAd, &ADDframe.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAddr);
1235 }
1236#endif // CONFIG_STA_SUPPORT //
1237 ADDframe.Category = CATEGORY_BA;
1238 ADDframe.Action = ADDBA_RESP;
1239 ADDframe.Token = pAddreqFrame->Token;
1240 // What is the Status code?? need to check.
1241 ADDframe.StatusCode = Status;
1242 ADDframe.BaParm.BAPolicy = IMMED_BA;
1243 ADDframe.BaParm.AMSDUSupported = 0;
1244 ADDframe.BaParm.TID = pAddreqFrame->BaParm.TID;
1245 ADDframe.BaParm.BufSize = min(((UCHAR)pAddreqFrame->BaParm.BufSize), (UCHAR)pAd->CommonCfg.BACapability.field.RxBAWinLimit);
1246 if (ADDframe.BaParm.BufSize == 0)
1247 {
1248 ADDframe.BaParm.BufSize = 64;
1249 }
1250 ADDframe.TimeOutValue = 0; //pAddreqFrame->TimeOutValue;
1251
1252 *(USHORT *)(&ADDframe.BaParm) = cpu2le16(*(USHORT *)(&ADDframe.BaParm));
1253 ADDframe.StatusCode = cpu2le16(ADDframe.StatusCode);
1254 ADDframe.TimeOutValue = cpu2le16(ADDframe.TimeOutValue);
1255
1256 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1257 sizeof(FRAME_ADDBA_RSP), &ADDframe,
1258 END_OF_ARGS);
1259 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
1260 MlmeFreeMemory(pAd, pOutBuffer);
1261
1262 DBGPRINT(RT_DEBUG_TRACE, ("%s(%d): TID(%d), BufSize(%d) <== \n", __FUNCTION__, Elem->Wcid, ADDframe.BaParm.TID,
1263 ADDframe.BaParm.BufSize));
1264}
1265
1266
1267VOID PeerAddBARspAction(
1268 IN PRTMP_ADAPTER pAd,
1269 IN MLME_QUEUE_ELEM *Elem)
1270
1271{
1272 //UCHAR Idx, i;
1273 //PUCHAR pOutBuffer = NULL;
1274 PFRAME_ADDBA_RSP pFrame = NULL;
1275 //PBA_ORI_ENTRY pBAEntry;
1276
1277 //ADDBA Response from unknown peer, ignore this.
1278 if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
1279 return;
1280
1281 DBGPRINT(RT_DEBUG_TRACE, ("%s ==> Wcid(%d)\n", __FUNCTION__, Elem->Wcid));
1282
1283 //hex_dump("PeerAddBARspAction()", Elem->Msg, Elem->MsgLen);
1284
1285 if (PeerAddBARspActionSanity(pAd, Elem->Msg, Elem->MsgLen))
1286 {
1287 pFrame = (PFRAME_ADDBA_RSP)(&Elem->Msg[0]);
1288
1289 DBGPRINT(RT_DEBUG_TRACE, ("\t\t StatusCode = %d\n", pFrame->StatusCode));
1290 switch (pFrame->StatusCode)
1291 {
1292 case 0:
1293 // I want a BAsession with this peer as an originator.
1294 BAOriSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid], pFrame);
1295 break;
1296 default:
1297 // check status == USED ???
1298 BAOriSessionTearDown(pAd, Elem->Wcid, pFrame->BaParm.TID, TRUE, FALSE);
1299 break;
1300 }
1301 // Rcv Decline StatusCode
1302 if ((pFrame->StatusCode == 37)
1303#ifdef CONFIG_STA_SUPPORT
1304 || ((pAd->OpMode == OPMODE_STA) && STA_TGN_WIFI_ON(pAd) && (pFrame->StatusCode != 0))
1305#endif // CONFIG_STA_SUPPORT //
1306 )
1307 {
1308 pAd->MacTab.Content[Elem->Wcid].BADeclineBitmap |= 1<<pFrame->BaParm.TID;
1309 }
1310 }
1311}
1312
1313VOID PeerDelBAAction(
1314 IN PRTMP_ADAPTER pAd,
1315 IN MLME_QUEUE_ELEM *Elem)
1316
1317{
1318 //UCHAR Idx;
1319 //PUCHAR pOutBuffer = NULL;
1320 PFRAME_DELBA_REQ pDelFrame = NULL;
1321
1322 DBGPRINT(RT_DEBUG_TRACE,("%s ==>\n", __FUNCTION__));
1323 //DELBA Request from unknown peer, ignore this.
1324 if (PeerDelBAActionSanity(pAd, Elem->Wcid, Elem->Msg, Elem->MsgLen))
1325 {
1326 pDelFrame = (PFRAME_DELBA_REQ)(&Elem->Msg[0]);
1327 if (pDelFrame->DelbaParm.Initiator == ORIGINATOR)
1328 {
1329 DBGPRINT(RT_DEBUG_TRACE,("BA - PeerDelBAAction----> ORIGINATOR\n"));
1330 BARecSessionTearDown(pAd, Elem->Wcid, pDelFrame->DelbaParm.TID, TRUE);
1331 }
1332 else
1333 {
1334 DBGPRINT(RT_DEBUG_TRACE,("BA - PeerDelBAAction----> RECIPIENT, Reason = %d\n", pDelFrame->ReasonCode));
1335 //hex_dump("DelBA Frame", pDelFrame, Elem->MsgLen);
1336 BAOriSessionTearDown(pAd, Elem->Wcid, pDelFrame->DelbaParm.TID, TRUE, FALSE);
1337 }
1338 }
1339}
1340
1341
1342BOOLEAN CntlEnqueueForRecv(
1343 IN PRTMP_ADAPTER pAd,
1344 IN ULONG Wcid,
1345 IN ULONG MsgLen,
1346 IN PFRAME_BA_REQ pMsg)
1347{
1348 PFRAME_BA_REQ pFrame = pMsg;
1349 //PRTMP_REORDERBUF pBuffer;
1350 //PRTMP_REORDERBUF pDmaBuf;
1351 PBA_REC_ENTRY pBAEntry;
1352 //BOOLEAN Result;
1353 ULONG Idx;
1354 //UCHAR NumRxPkt;
1355 UCHAR TID;//, i;
1356
1357 TID = (UCHAR)pFrame->BARControl.TID;
1358
1359 DBGPRINT(RT_DEBUG_TRACE, ("%s(): BAR-Wcid(%ld), Tid (%d)\n", __FUNCTION__, Wcid, TID));
1360 //hex_dump("BAR", (PCHAR) pFrame, MsgLen);
1361 // Do nothing if the driver is starting halt state.
1362 // This might happen when timer already been fired before cancel timer with mlmehalt
1363 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
1364 return FALSE;
1365
1366 // First check the size, it MUST not exceed the mlme queue size
1367 if (MsgLen > MGMT_DMA_BUFFER_SIZE)
1368 {
1369 DBGPRINT_ERR(("CntlEnqueueForRecv: frame too large, size = %ld \n", MsgLen));
1370 return FALSE;
1371 }
1372 else if (MsgLen != sizeof(FRAME_BA_REQ))
1373 {
1374 DBGPRINT_ERR(("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen));
1375 return FALSE;
1376 }
1377 else if (MsgLen != sizeof(FRAME_BA_REQ))
1378 {
1379 DBGPRINT_ERR(("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen));
1380 return FALSE;
1381 }
1382
1383 if ((Wcid < MAX_LEN_OF_MAC_TABLE) && (TID < 8))
1384 {
1385 // if this receiving packet is from SA that is in our OriEntry. Since WCID <9 has direct mapping. no need search.
1386 Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
1387 pBAEntry = &pAd->BATable.BARecEntry[Idx];
1388 }
1389 else
1390 {
1391 return FALSE;
1392 }
1393
1394 DBGPRINT(RT_DEBUG_TRACE, ("BAR(%ld) : Tid (%d) - %04x:%04x\n", Wcid, TID, pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq ));
1395
1396 if (SEQ_SMALLER(pBAEntry->LastIndSeq, pFrame->BAStartingSeq.field.StartSeq, MAXSEQ))
1397 {
1398 //printk("BAR Seq = %x, LastIndSeq = %x\n", pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq);
1399 ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, pFrame->BAStartingSeq.field.StartSeq);
1400 pBAEntry->LastIndSeq = (pFrame->BAStartingSeq.field.StartSeq == 0) ? MAXSEQ :(pFrame->BAStartingSeq.field.StartSeq -1);
1401 }
1402 //ba_refresh_reordering_mpdus(pAd, pBAEntry);
1403 return TRUE;
1404}
1405
1406/*
1407Description : Send PSMP Action frame If PSMP mode switches.
1408*/
1409VOID SendPSMPAction(
1410 IN PRTMP_ADAPTER pAd,
1411 IN UCHAR Wcid,
1412 IN UCHAR Psmp)
1413{
1414 PUCHAR pOutBuffer = NULL;
1415 NDIS_STATUS NStatus;
1416 //ULONG Idx;
1417 FRAME_PSMP_ACTION Frame;
1418 ULONG FrameLen;
1419#ifdef RT30xx
1420 UCHAR bbpdata=0;
1421 UINT32 macdata;
1422#endif // RT30xx //
1423
1424 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1425 if (NStatus != NDIS_STATUS_SUCCESS)
1426 {
1427 DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() allocate memory failed \n"));
1428 return;
1429 }
1430#ifdef CONFIG_STA_SUPPORT
1431 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1432 ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->MacTab.Content[Wcid].Addr);
1433#endif // CONFIG_STA_SUPPORT //
1434
1435 Frame.Category = CATEGORY_HT;
1436 Frame.Action = SMPS_ACTION;
1437 switch (Psmp)
1438 {
1439 case MMPS_ENABLE:
1440#ifdef RT30xx
1441 if (IS_RT3090(pAd))
1442 {
1443 // disable MMPS BBP control register
1444 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpdata);
1445 bbpdata &= ~(0x04); //bit 2
1446 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpdata);
1447
1448 // disable MMPS MAC control register
1449 RTMP_IO_READ32(pAd, 0x1210, &macdata);
1450 macdata &= ~(0x09); //bit 0, 3
1451 RTMP_IO_WRITE32(pAd, 0x1210, macdata);
1452 }
1453#endif // RT30xx //
1454 Frame.Psmp = 0;
1455 break;
1456 case MMPS_DYNAMIC:
1457#ifdef RT30xx
1458 if (IS_RT3090(pAd))
1459 {
1460 // enable MMPS BBP control register
1461 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpdata);
1462 bbpdata |= 0x04; //bit 2
1463 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpdata);
1464
1465 // enable MMPS MAC control register
1466 RTMP_IO_READ32(pAd, 0x1210, &macdata);
1467 macdata |= 0x09; //bit 0, 3
1468 RTMP_IO_WRITE32(pAd, 0x1210, macdata);
1469 }
1470#endif // RT30xx //
1471 Frame.Psmp = 3;
1472 break;
1473 case MMPS_STATIC:
1474#ifdef RT30xx
1475 if (IS_RT3090(pAd))
1476 {
1477 // enable MMPS BBP control register
1478 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpdata);
1479 bbpdata |= 0x04; //bit 2
1480 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpdata);
1481
1482 // enable MMPS MAC control register
1483 RTMP_IO_READ32(pAd, 0x1210, &macdata);
1484 macdata |= 0x09; //bit 0, 3
1485 RTMP_IO_WRITE32(pAd, 0x1210, macdata);
1486 }
1487#endif // RT30xx //
1488 Frame.Psmp = 1;
1489 break;
1490 }
1491 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1492 sizeof(FRAME_PSMP_ACTION), &Frame,
1493 END_OF_ARGS);
1494 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
1495 MlmeFreeMemory(pAd, pOutBuffer);
1496 DBGPRINT(RT_DEBUG_ERROR,("HT - SendPSMPAction( %d ) \n", Frame.Psmp));
1497}
1498
1499
1500#define RADIO_MEASUREMENT_REQUEST_ACTION 0
1501
1502typedef struct PACKED
1503{
1504 UCHAR RegulatoryClass;
1505 UCHAR ChannelNumber;
1506 USHORT RandomInterval;
1507 USHORT MeasurementDuration;
1508 UCHAR MeasurementMode;
1509 UCHAR BSSID[MAC_ADDR_LEN];
1510 UCHAR ReportingCondition;
1511 UCHAR Threshold;
1512 UCHAR SSIDIE[2]; // 2 byte
1513} BEACON_REQUEST;
1514
1515typedef struct PACKED
1516{
1517 UCHAR ID;
1518 UCHAR Length;
1519 UCHAR Token;
1520 UCHAR RequestMode;
1521 UCHAR Type;
1522} MEASUREMENT_REQ;
1523
1524
1525
1526
1527void convert_reordering_packet_to_preAMSDU_or_802_3_packet(
1528 IN PRTMP_ADAPTER pAd,
1529 IN RX_BLK *pRxBlk,
1530 IN UCHAR FromWhichBSSID)
1531{
1532 PNDIS_PACKET pRxPkt;
1533 UCHAR Header802_3[LENGTH_802_3];
1534
1535 // 1. get 802.3 Header
1536 // 2. remove LLC
1537 // a. pointer pRxBlk->pData to payload
1538 // b. modify pRxBlk->DataSize
1539
1540#ifdef CONFIG_STA_SUPPORT
1541 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1542 RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
1543#endif // CONFIG_STA_SUPPORT //
1544
1545 ASSERT(pRxBlk->pRxPacket);
1546 pRxPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
1547
1548 RTPKT_TO_OSPKT(pRxPkt)->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
1549 RTPKT_TO_OSPKT(pRxPkt)->data = pRxBlk->pData;
1550 RTPKT_TO_OSPKT(pRxPkt)->len = pRxBlk->DataSize;
1551 RTPKT_TO_OSPKT(pRxPkt)->tail = RTPKT_TO_OSPKT(pRxPkt)->data + RTPKT_TO_OSPKT(pRxPkt)->len;
1552
1553 //
1554 // copy 802.3 header, if necessary
1555 //
1556 if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU))
1557 {
1558
1559#ifdef CONFIG_STA_SUPPORT
1560 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1561 {
1562#ifdef LINUX
1563 NdisMoveMemory(skb_push(pRxPkt, LENGTH_802_3), Header802_3, LENGTH_802_3);
1564#endif
1565#ifdef UCOS
1566 NdisMoveMemory(net_pkt_push(pRxPkt, LENGTH_802_3), Header802_3, LENGTH_802_3);
1567#endif
1568 }
1569#endif // CONFIG_STA_SUPPORT //
1570 }
1571}
1572
1573
1574#define INDICATE_LEGACY_OR_AMSDU(_pAd, _pRxBlk, _fromWhichBSSID) \
1575 do \
1576 { \
1577 if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_AMSDU)) \
1578 { \
1579 Indicate_AMSDU_Packet(_pAd, _pRxBlk, _fromWhichBSSID); \
1580 } \
1581 else if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_EAP)) \
1582 { \
1583 Indicate_EAPOL_Packet(_pAd, _pRxBlk, _fromWhichBSSID); \
1584 } \
1585 else \
1586 { \
1587 Indicate_Legacy_Packet(_pAd, _pRxBlk, _fromWhichBSSID); \
1588 } \
1589 } while (0);
1590
1591
1592
1593static VOID ba_enqueue_reordering_packet(
1594 IN PRTMP_ADAPTER pAd,
1595 IN PBA_REC_ENTRY pBAEntry,
1596 IN RX_BLK *pRxBlk,
1597 IN UCHAR FromWhichBSSID)
1598{
1599 struct reordering_mpdu *mpdu_blk;
1600 UINT16 Sequence = (UINT16) pRxBlk->pHeader->Sequence;
1601
1602 mpdu_blk = ba_mpdu_blk_alloc(pAd);
1603 if (mpdu_blk != NULL)
1604 {
1605 // Write RxD buffer address & allocated buffer length
1606 NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
1607
1608 mpdu_blk->Sequence = Sequence;
1609
1610 mpdu_blk->bAMSDU = RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU);
1611
1612 convert_reordering_packet_to_preAMSDU_or_802_3_packet(pAd, pRxBlk, FromWhichBSSID);
1613
1614 STATS_INC_RX_PACKETS(pAd, FromWhichBSSID);
1615
1616 //
1617 // it is necessary for reordering packet to record
1618 // which BSS it come from
1619 //
1620 RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID);
1621
1622 mpdu_blk->pPacket = pRxBlk->pRxPacket;
1623
1624 if (ba_reordering_mpdu_insertsorted(&pBAEntry->list, mpdu_blk) == FALSE)
1625 {
1626 // had been already within reordering list
1627 // don't indicate
1628 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_SUCCESS);
1629 ba_mpdu_blk_free(pAd, mpdu_blk);
1630 }
1631
1632 ASSERT((0<= pBAEntry->list.qlen) && (pBAEntry->list.qlen <= pBAEntry->BAWinSize));
1633 NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
1634 }
1635 else
1636 {
1637 DBGPRINT(RT_DEBUG_ERROR, ("!!! (%d) Can't allocate reordering mpdu blk\n",
1638 pBAEntry->list.qlen));
1639 /*
1640 * flush all pending reordering mpdus
1641 * and receving mpdu to upper layer
1642 * make tcp/ip to take care reordering mechanism
1643 */
1644 //ba_refresh_reordering_mpdus(pAd, pBAEntry);
1645 ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, Sequence);
1646
1647 pBAEntry->LastIndSeq = Sequence;
1648 INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
1649 }
1650}
1651
1652
1653/*
1654 ==========================================================================
1655 Description:
1656 Indicate this packet to upper layer or put it into reordering buffer
1657
1658 Parametrs:
1659 pRxBlk : carry necessary packet info 802.11 format
1660 FromWhichBSSID : the packet received from which BSS
1661
1662 Return :
1663 none
1664
1665 Note :
1666 the packet queued into reordering buffer need to cover to 802.3 format
1667 or pre_AMSDU format
1668 ==========================================================================
1669 */
1670
1671VOID Indicate_AMPDU_Packet(
1672 IN PRTMP_ADAPTER pAd,
1673 IN RX_BLK *pRxBlk,
1674 IN UCHAR FromWhichBSSID)
1675{
1676 USHORT Idx;
1677 PBA_REC_ENTRY pBAEntry = NULL;
1678 UINT16 Sequence = pRxBlk->pHeader->Sequence;
1679 ULONG Now32;
1680 UCHAR Wcid = pRxBlk->pRxWI->WirelessCliID;
1681 UCHAR TID = pRxBlk->pRxWI->TID;
1682
1683
1684 if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU) && (pRxBlk->DataSize > MAX_RX_PKT_LEN))
1685 {
1686 // release packet
1687 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
1688 return;
1689 }
1690
1691 if (Wcid < MAX_LEN_OF_MAC_TABLE)
1692 {
1693 Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
1694 if (Idx == 0)
1695 {
1696 /* Rec BA Session had been torn down */
1697 INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
1698 return;
1699 }
1700 pBAEntry = &pAd->BATable.BARecEntry[Idx];
1701 }
1702 else
1703 {
1704 // impossible !!!
1705 ASSERT(0);
1706 // release packet
1707 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
1708 return;
1709 }
1710
1711 ASSERT(pBAEntry);
1712
1713 // update last rx time
1714 NdisGetSystemUpTime(&Now32);
1715
1716 pBAEntry->rcvSeq = Sequence;
1717
1718
1719 ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32);
1720 pBAEntry->LastIndSeqAtTimer = Now32;
1721
1722 //
1723 // Reset Last Indicate Sequence
1724 //
1725 if (pBAEntry->LastIndSeq == RESET_RCV_SEQ)
1726 {
1727 ASSERT((pBAEntry->list.qlen == 0) && (pBAEntry->list.next == NULL));
1728
1729 // reset rcv sequence of BA session
1730 pBAEntry->LastIndSeq = Sequence;
1731 pBAEntry->LastIndSeqAtTimer = Now32;
1732 INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
1733 return;
1734 }
1735
1736
1737 //
1738 // I. Check if in order.
1739 //
1740 if (SEQ_STEPONE(Sequence, pBAEntry->LastIndSeq, MAXSEQ))
1741 {
1742 USHORT LastIndSeq;
1743
1744 pBAEntry->LastIndSeq = Sequence;
1745 INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
1746 LastIndSeq = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, pBAEntry->LastIndSeq);
1747 if (LastIndSeq != RESET_RCV_SEQ)
1748 {
1749 pBAEntry->LastIndSeq = LastIndSeq;
1750 }
1751 pBAEntry->LastIndSeqAtTimer = Now32;
1752 }
1753 //
1754 // II. Drop Duplicated Packet
1755 //
1756 else if (Sequence == pBAEntry->LastIndSeq)
1757 {
1758
1759 // drop and release packet
1760 pBAEntry->nDropPacket++;
1761 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
1762 }
1763 //
1764 // III. Drop Old Received Packet
1765 //
1766 else if (SEQ_SMALLER(Sequence, pBAEntry->LastIndSeq, MAXSEQ))
1767 {
1768
1769 // drop and release packet
1770 pBAEntry->nDropPacket++;
1771 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
1772 }
1773 //
1774 // IV. Receive Sequence within Window Size
1775 //
1776 else if (SEQ_SMALLER(Sequence, (((pBAEntry->LastIndSeq+pBAEntry->BAWinSize+1)) & MAXSEQ), MAXSEQ))
1777 {
1778 ba_enqueue_reordering_packet(pAd, pBAEntry, pRxBlk, FromWhichBSSID);
1779 }
1780 //
1781 // V. Receive seq surpasses Win(lastseq + nMSDU). So refresh all reorder buffer
1782 //
1783 else
1784 {
1785 LONG WinStartSeq, TmpSeq;
1786
1787
1788 TmpSeq = Sequence - (pBAEntry->BAWinSize) -1;
1789 if (TmpSeq < 0)
1790 {
1791 TmpSeq = (MAXSEQ+1) + TmpSeq;
1792 }
1793 WinStartSeq = (TmpSeq+1) & MAXSEQ;
1794 ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, WinStartSeq);
1795 pBAEntry->LastIndSeq = WinStartSeq; //TmpSeq;
1796
1797 pBAEntry->LastIndSeqAtTimer = Now32;
1798
1799 ba_enqueue_reordering_packet(pAd, pBAEntry, pRxBlk, FromWhichBSSID);
1800
1801 TmpSeq = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, pBAEntry->LastIndSeq);
1802 if (TmpSeq != RESET_RCV_SEQ)
1803 {
1804 pBAEntry->LastIndSeq = TmpSeq;
1805 }
1806 }
1807}
1808
1809#endif // DOT11_N_SUPPORT //
1810
diff --git a/drivers/staging/rt3070/common/cmm_data.c b/drivers/staging/rt3070/common/cmm_data.c
new file mode 100644
index 000000000000..85f92b9f83da
--- /dev/null
+++ b/drivers/staging/rt3070/common/cmm_data.c
@@ -0,0 +1,2827 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26*/
27
28#include "../rt_config.h"
29
30#define MAX_TX_IN_TBTT (16)
31
32
33UCHAR SNAP_802_1H[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
34UCHAR SNAP_BRIDGE_TUNNEL[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8};
35// Add Cisco Aironet SNAP heade for CCX2 support
36UCHAR SNAP_AIRONET[] = {0xaa, 0xaa, 0x03, 0x00, 0x40, 0x96, 0x00, 0x00};
37UCHAR CKIP_LLC_SNAP[] = {0xaa, 0xaa, 0x03, 0x00, 0x40, 0x96, 0x00, 0x02};
38UCHAR EAPOL_LLC_SNAP[]= {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8e};
39UCHAR EAPOL[] = {0x88, 0x8e};
40UCHAR TPID[] = {0x81, 0x00}; /* VLAN related */
41
42UCHAR IPX[] = {0x81, 0x37};
43UCHAR APPLE_TALK[] = {0x80, 0xf3};
44UCHAR RateIdToPlcpSignal[12] = {
45 0, /* RATE_1 */ 1, /* RATE_2 */ 2, /* RATE_5_5 */ 3, /* RATE_11 */ // see BBP spec
46 11, /* RATE_6 */ 15, /* RATE_9 */ 10, /* RATE_12 */ 14, /* RATE_18 */ // see IEEE802.11a-1999 p.14
47 9, /* RATE_24 */ 13, /* RATE_36 */ 8, /* RATE_48 */ 12 /* RATE_54 */ }; // see IEEE802.11a-1999 p.14
48
49UCHAR OfdmSignalToRateId[16] = {
50 RATE_54, RATE_54, RATE_54, RATE_54, // OFDM PLCP Signal = 0, 1, 2, 3 respectively
51 RATE_54, RATE_54, RATE_54, RATE_54, // OFDM PLCP Signal = 4, 5, 6, 7 respectively
52 RATE_48, RATE_24, RATE_12, RATE_6, // OFDM PLCP Signal = 8, 9, 10, 11 respectively
53 RATE_54, RATE_36, RATE_18, RATE_9, // OFDM PLCP Signal = 12, 13, 14, 15 respectively
54};
55
56UCHAR OfdmRateToRxwiMCS[12] = {
57 0, 0, 0, 0,
58 0, 1, 2, 3, // OFDM rate 6,9,12,18 = rxwi mcs 0,1,2,3
59 4, 5, 6, 7, // OFDM rate 24,36,48,54 = rxwi mcs 4,5,6,7
60};
61UCHAR RxwiMCSToOfdmRate[12] = {
62 RATE_6, RATE_9, RATE_12, RATE_18,
63 RATE_24, RATE_36, RATE_48, RATE_54, // OFDM rate 6,9,12,18 = rxwi mcs 0,1,2,3
64 4, 5, 6, 7, // OFDM rate 24,36,48,54 = rxwi mcs 4,5,6,7
65};
66
67char* 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"};
68
69UCHAR default_cwmin[]={CW_MIN_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS-1, CW_MIN_IN_BITS-2};
70//UCHAR default_cwmax[]={CW_MAX_IN_BITS, CW_MAX_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS-1};
71UCHAR default_sta_aifsn[]={3,7,2,2};
72
73UCHAR 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};
74
75
76/*
77 ========================================================================
78
79 Routine Description:
80 API for MLME to transmit management frame to AP (BSS Mode)
81 or station (IBSS Mode)
82
83 Arguments:
84 pAd Pointer to our adapter
85 pData Pointer to the outgoing 802.11 frame
86 Length Size of outgoing management frame
87
88 Return Value:
89 NDIS_STATUS_FAILURE
90 NDIS_STATUS_PENDING
91 NDIS_STATUS_SUCCESS
92
93 IRQL = PASSIVE_LEVEL
94 IRQL = DISPATCH_LEVEL
95
96 Note:
97
98 ========================================================================
99*/
100NDIS_STATUS MiniportMMRequest(
101 IN PRTMP_ADAPTER pAd,
102 IN UCHAR QueIdx,
103 IN PUCHAR pData,
104 IN UINT Length)
105{
106 PNDIS_PACKET pPacket;
107 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
108 ULONG FreeNum;
109 UCHAR IrqState;
110 UCHAR rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; //RTMP_HW_HDR_LEN];
111
112 ASSERT(Length <= MGMT_DMA_BUFFER_SIZE);
113
114 QueIdx=3;
115
116 // 2860C use Tx Ring
117
118 IrqState = pAd->irq_disabled;
119
120 do
121 {
122 // Reset is in progress, stop immediately
123 if ( RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
124 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)||
125 !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
126 {
127 Status = NDIS_STATUS_FAILURE;
128 break;
129 }
130
131 // Check Free priority queue
132 // Since we use PBF Queue2 for management frame. Its corresponding DMA ring should be using TxRing.
133
134 // 2860C use Tx Ring
135 if (pAd->MACVersion == 0x28600100)
136 {
137 FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
138 }
139 else
140 {
141 FreeNum = GET_MGMTRING_FREENO(pAd);
142 }
143
144 if ((FreeNum > 0))
145 {
146 // We need to reserve space for rtmp hardware header. i.e., TxWI for RT2860 and TxInfo+TxWI for RT2870
147 NdisZeroMemory(&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE));
148 Status = RTMPAllocateNdisPacket(pAd, &pPacket, (PUCHAR)&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE), pData, Length);
149 if (Status != NDIS_STATUS_SUCCESS)
150 {
151 DBGPRINT(RT_DEBUG_WARN, ("MiniportMMRequest (error:: can't allocate NDIS PACKET)\n"));
152 break;
153 }
154
155 //pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
156 //pAd->CommonCfg.MlmeRate = RATE_2;
157
158
159 Status = MlmeHardTransmit(pAd, QueIdx, pPacket);
160 if (Status != NDIS_STATUS_SUCCESS)
161 RTMPFreeNdisPacket(pAd, pPacket);
162 }
163 else
164 {
165 pAd->RalinkCounters.MgmtRingFullCount++;
166 DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in MgmtRing, MgmtRingFullCount=%ld!\n",
167 QueIdx, pAd->RalinkCounters.MgmtRingFullCount));
168 }
169
170 } while (FALSE);
171
172
173 return Status;
174}
175
176
177
178NDIS_STATUS MlmeDataHardTransmit(
179 IN PRTMP_ADAPTER pAd,
180 IN UCHAR QueIdx,
181 IN PNDIS_PACKET pPacket);
182
183#define MAX_DATAMM_RETRY 3
184/*
185 ========================================================================
186
187 Routine Description:
188 API for MLME to transmit management frame to AP (BSS Mode)
189 or station (IBSS Mode)
190
191 Arguments:
192 pAd Pointer to our adapter
193 pData Pointer to the outgoing 802.11 frame
194 Length Size of outgoing management frame
195
196 Return Value:
197 NDIS_STATUS_FAILURE
198 NDIS_STATUS_PENDING
199 NDIS_STATUS_SUCCESS
200
201 IRQL = PASSIVE_LEVEL
202 IRQL = DISPATCH_LEVEL
203
204 Note:
205
206 ========================================================================
207*/
208NDIS_STATUS MiniportDataMMRequest(
209 IN PRTMP_ADAPTER pAd,
210 IN UCHAR QueIdx,
211 IN PUCHAR pData,
212 IN UINT Length)
213{
214 PNDIS_PACKET pPacket;
215 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
216 ULONG FreeNum;
217 int retry = 0;
218 UCHAR IrqState;
219 UCHAR rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; //RTMP_HW_HDR_LEN];
220
221 ASSERT(Length <= MGMT_DMA_BUFFER_SIZE);
222
223 // 2860C use Tx Ring
224 IrqState = pAd->irq_disabled;
225
226 do
227 {
228 // Reset is in progress, stop immediately
229 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
230 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)||
231 !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
232 {
233 Status = NDIS_STATUS_FAILURE;
234 break;
235 }
236
237 // Check Free priority queue
238 // Since we use PBF Queue2 for management frame. Its corresponding DMA ring should be using TxRing.
239
240 // 2860C use Tx Ring
241
242 // free Tx(QueIdx) resources
243 FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
244
245 if ((FreeNum > 0))
246 {
247 // We need to reserve space for rtmp hardware header. i.e., TxWI for RT2860 and TxInfo+TxWI for RT2870
248 NdisZeroMemory(&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE));
249 Status = RTMPAllocateNdisPacket(pAd, &pPacket, (PUCHAR)&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE), pData, Length);
250 if (Status != NDIS_STATUS_SUCCESS)
251 {
252 DBGPRINT(RT_DEBUG_WARN, ("MiniportMMRequest (error:: can't allocate NDIS PACKET)\n"));
253 break;
254 }
255
256 //pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
257 //pAd->CommonCfg.MlmeRate = RATE_2;
258
259
260 Status = MlmeDataHardTransmit(pAd, QueIdx, pPacket);
261 if (Status != NDIS_STATUS_SUCCESS)
262 RTMPFreeNdisPacket(pAd, pPacket);
263 retry = MAX_DATAMM_RETRY;
264 }
265 else
266 {
267 retry ++;
268
269 printk("retry %d\n", retry);
270 pAd->RalinkCounters.MgmtRingFullCount++;
271
272 if (retry >= MAX_DATAMM_RETRY)
273 {
274 DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in DataRing, MgmtRingFullCount=%ld!\n",
275 QueIdx, pAd->RalinkCounters.MgmtRingFullCount));
276 }
277 }
278
279 } while (retry < MAX_DATAMM_RETRY);
280
281
282 return Status;
283}
284
285
286
287
288
289
290/*
291 ========================================================================
292
293 Routine Description:
294 Copy frame from waiting queue into relative ring buffer and set
295 appropriate ASIC register to kick hardware transmit function
296
297 Arguments:
298 pAd Pointer to our adapter
299 pBuffer Pointer to memory of outgoing frame
300 Length Size of outgoing management frame
301
302 Return Value:
303 NDIS_STATUS_FAILURE
304 NDIS_STATUS_PENDING
305 NDIS_STATUS_SUCCESS
306
307 IRQL = PASSIVE_LEVEL
308 IRQL = DISPATCH_LEVEL
309
310 Note:
311
312 ========================================================================
313*/
314NDIS_STATUS MlmeHardTransmit(
315 IN PRTMP_ADAPTER pAd,
316 IN UCHAR QueIdx,
317 IN PNDIS_PACKET pPacket)
318{
319 if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
320#ifdef CARRIER_DETECTION_SUPPORT
321#endif // CARRIER_DETECTION_SUPPORT //
322 )
323 {
324 return NDIS_STATUS_FAILURE;
325 }
326
327 return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
328
329}
330
331NDIS_STATUS MlmeDataHardTransmit(
332 IN PRTMP_ADAPTER pAd,
333 IN UCHAR QueIdx,
334 IN PNDIS_PACKET pPacket)
335{
336 if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
337#ifdef CARRIER_DETECTION_SUPPORT
338#endif // CARRIER_DETECTION_SUPPORT //
339 )
340 {
341 return NDIS_STATUS_FAILURE;
342 }
343
344#ifdef RT2870
345 return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
346#endif // RT2870 //
347}
348
349
350
351
352
353NDIS_STATUS MlmeHardTransmitMgmtRing(
354 IN PRTMP_ADAPTER pAd,
355 IN UCHAR QueIdx,
356 IN PNDIS_PACKET pPacket)
357{
358 PACKET_INFO PacketInfo;
359 PUCHAR pSrcBufVA;
360 UINT SrcBufLen;
361 PHEADER_802_11 pHeader_802_11;
362 BOOLEAN bAckRequired, bInsertTimestamp;
363 UCHAR MlmeRate;
364 PTXWI_STRUC pFirstTxWI;
365 MAC_TABLE_ENTRY *pMacEntry = NULL;
366
367 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
368
369 // Make sure MGMT ring resource won't be used by other threads
370// sample, for IRQ LOCK -> SEM LOCK
371// IrqState = pAd->irq_disabled;
372// if (!IrqState)
373 RTMP_SEM_LOCK(&pAd->MgmtRingLock);
374
375
376 if (pSrcBufVA == NULL)
377 {
378 // The buffer shouldn't be NULL
379// if (!IrqState)
380 RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
381 return NDIS_STATUS_FAILURE;
382 }
383
384#ifdef CONFIG_STA_SUPPORT
385 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
386 {
387 // outgoing frame always wakeup PHY to prevent frame lost
388 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
389 AsicForceWakeup(pAd, TRUE);
390 }
391#endif // CONFIG_STA_SUPPORT //
392
393 pFirstTxWI = (PTXWI_STRUC)(pSrcBufVA + TXINFO_SIZE);
394 pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE); //TXWI_SIZE);
395
396 if (pHeader_802_11->Addr1[0] & 0x01)
397 {
398 MlmeRate = pAd->CommonCfg.BasicMlmeRate;
399 }
400 else
401 {
402 MlmeRate = pAd->CommonCfg.MlmeRate;
403 }
404
405 // Verify Mlme rate for a / g bands.
406 if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) // 11A band
407 MlmeRate = RATE_6;
408
409 if ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
410 (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL))
411 {
412 pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1);
413 }
414
415#ifdef CONFIG_STA_SUPPORT
416 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
417 {
418 // Fixed W52 with Activity scan issue in ABG_MIXED and ABGN_MIXED mode.
419 if (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED
420#ifdef DOT11_N_SUPPORT
421 || pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED
422#endif // DOT11_N_SUPPORT //
423 )
424 {
425 if (pAd->LatchRfRegs.Channel > 14)
426 pAd->CommonCfg.MlmeTransmit.field.MODE = 1;
427 else
428 pAd->CommonCfg.MlmeTransmit.field.MODE = 0;
429 }
430 }
431#endif // CONFIG_STA_SUPPORT //
432
433 //
434 // Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE)
435 // Snice it's been set to 0 while on MgtMacHeaderInit
436 // By the way this will cause frame to be send on PWR_SAVE failed.
437 //
438 // pHeader_802_11->FC.PwrMgmt = 0; // (pAd->StaCfg.Psm == PWR_SAVE);
439 //
440 // In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame
441#ifdef CONFIG_STA_SUPPORT
442 // Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD
443 if ((pHeader_802_11->FC.Type != BTYPE_DATA) && (pHeader_802_11->FC.Type != BTYPE_CNTL))
444 {
445 if ((pAd->StaCfg.Psm == PWR_SAVE) &&
446 (pHeader_802_11->FC.SubType == SUBTYPE_ACTION))
447 pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
448 else
449 pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE;
450 }
451#endif // CONFIG_STA_SUPPORT //
452
453 bInsertTimestamp = FALSE;
454 if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL
455 {
456#ifdef CONFIG_STA_SUPPORT
457 //Set PM bit in ps-poll, to fix WLK 1.2 PowerSaveMode_ext failure issue.
458 if ((pAd->OpMode == OPMODE_STA) && (pHeader_802_11->FC.SubType == SUBTYPE_PS_POLL))
459 {
460 pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
461 }
462#endif // CONFIG_STA_SUPPORT //
463 bAckRequired = FALSE;
464 }
465 else // BTYPE_MGMT or BTYPE_DATA(must be NULL frame)
466 {
467 //pAd->Sequence++;
468 //pHeader_802_11->Sequence = pAd->Sequence;
469
470 if (pHeader_802_11->Addr1[0] & 0x01) // MULTICAST, BROADCAST
471 {
472 bAckRequired = FALSE;
473 pHeader_802_11->Duration = 0;
474 }
475 else
476 {
477 bAckRequired = TRUE;
478 pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14);
479 if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP)
480 {
481 bInsertTimestamp = TRUE;
482 }
483 }
484 }
485
486 pHeader_802_11->Sequence = pAd->Sequence++;
487 if (pAd->Sequence >0xfff)
488 pAd->Sequence = 0;
489
490 // Before radar detection done, mgmt frame can not be sent but probe req
491 // Because we need to use probe req to trigger driver to send probe req in passive scan
492 if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ)
493 && (pAd->CommonCfg.bIEEE80211H == 1)
494 && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE))
495 {
496 DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n"));
497// if (!IrqState)
498 RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
499 return (NDIS_STATUS_FAILURE);
500 }
501
502#ifdef RT_BIG_ENDIAN
503 RTMPFrameEndianChange(pAd, (PUCHAR)pHeader_802_11, DIR_WRITE, FALSE);
504#endif
505
506 //
507 // fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET
508 // should always has only one ohysical buffer, and the whole frame size equals
509 // to the first scatter buffer size
510 //
511
512 // Initialize TX Descriptor
513 // For inter-frame gap, the number is for this frame and next frame
514 // For MLME rate, we will fix as 2Mb to match other vendor's implement
515// pAd->CommonCfg.MlmeTransmit.field.MODE = 1;
516
517// management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not.
518 if (pMacEntry == NULL)
519 {
520 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE,
521 0, RESERVED_WCID, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE), PID_MGMT, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
522 }
523 else
524 {
525 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE,
526 bInsertTimestamp, FALSE, bAckRequired, FALSE,
527 0, pMacEntry->Aid, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE),
528 pMacEntry->MaxHTPhyMode.field.MCS, 0,
529 (UCHAR)pMacEntry->MaxHTPhyMode.field.MCS,
530 IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
531 }
532
533#ifdef RT_BIG_ENDIAN
534 RTMPWIEndianChange((PUCHAR)pFirstTxWI, TYPE_TXWI);
535#endif
536
537 // Now do hardware-depened kick out.
538 HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen);
539
540 // Make sure to release MGMT ring resource
541// if (!IrqState)
542 RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
543 return NDIS_STATUS_SUCCESS;
544}
545
546
547/********************************************************************************
548
549 New DeQueue Procedures.
550
551 ********************************************************************************/
552
553#define DEQUEUE_LOCK(lock, bIntContext, IrqFlags) \
554 do{ \
555 if (bIntContext == FALSE) \
556 RTMP_IRQ_LOCK((lock), IrqFlags); \
557 }while(0)
558
559#define DEQUEUE_UNLOCK(lock, bIntContext, IrqFlags) \
560 do{ \
561 if (bIntContext == FALSE) \
562 RTMP_IRQ_UNLOCK((lock), IrqFlags); \
563 }while(0)
564
565
566/*
567 ========================================================================
568 Tx Path design algorithm:
569 Basically, we divide the packets into four types, Broadcast/Multicast, 11N Rate(AMPDU, AMSDU, Normal), B/G Rate(ARALINK, Normal),
570 Specific Packet Type. Following show the classification rule and policy for each kinds of packets.
571 Classification Rule=>
572 Multicast: (*addr1 & 0x01) == 0x01
573 Specific : bDHCPFrame, bARPFrame, bEAPOLFrame, etc.
574 11N Rate : If peer support HT
575 (1).AMPDU -- If TXBA is negotiated.
576 (2).AMSDU -- If AMSDU is capable for both peer and ourself.
577 *). AMSDU can embedded in a AMPDU, but now we didn't support it.
578 (3).Normal -- Other packets which send as 11n rate.
579
580 B/G Rate : If peer is b/g only.
581 (1).ARALINK-- If both of peer/us supprot Ralink proprietary Aggregation and the TxRate is large than RATE_6
582 (2).Normal -- Other packets which send as b/g rate.
583 Fragment:
584 The packet must be unicast, NOT A-RALINK, NOT A-MSDU, NOT 11n, then can consider about fragment.
585
586 Classified Packet Handle Rule=>
587 Multicast:
588 No ACK, //pTxBlk->bAckRequired = FALSE;
589 No WMM, //pTxBlk->bWMM = FALSE;
590 No piggyback, //pTxBlk->bPiggyBack = FALSE;
591 Force LowRate, //pTxBlk->bForceLowRate = TRUE;
592 Specific : Basically, for specific packet, we should handle it specifically, but now all specific packets are use
593 the same policy to handle it.
594 Force LowRate, //pTxBlk->bForceLowRate = TRUE;
595
596 11N Rate :
597 No piggyback, //pTxBlk->bPiggyBack = FALSE;
598
599 (1).AMSDU
600 pTxBlk->bWMM = TRUE;
601 (2).AMPDU
602 pTxBlk->bWMM = TRUE;
603 (3).Normal
604
605 B/G Rate :
606 (1).ARALINK
607
608 (2).Normal
609 ========================================================================
610*/
611static UCHAR TxPktClassification(
612 IN RTMP_ADAPTER *pAd,
613 IN PNDIS_PACKET pPacket)
614{
615 UCHAR TxFrameType = TX_UNKOWN_FRAME;
616 UCHAR Wcid;
617 MAC_TABLE_ENTRY *pMacEntry = NULL;
618#ifdef DOT11_N_SUPPORT
619 BOOLEAN bHTRate = FALSE;
620#endif // DOT11_N_SUPPORT //
621
622 Wcid = RTMP_GET_PACKET_WCID(pPacket);
623 if (Wcid == MCAST_WCID)
624 { // Handle for RA is Broadcast/Multicast Address.
625 return TX_MCAST_FRAME;
626 }
627
628 // Handle for unicast packets
629 pMacEntry = &pAd->MacTab.Content[Wcid];
630 if (RTMP_GET_PACKET_LOWRATE(pPacket))
631 { // It's a specific packet need to force low rate, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame
632 TxFrameType = TX_LEGACY_FRAME;
633 }
634#ifdef DOT11_N_SUPPORT
635 else if (IS_HT_RATE(pMacEntry))
636 { // it's a 11n capable packet
637
638 // Depends on HTPhyMode to check if the peer support the HTRate transmission.
639 // Currently didn't support A-MSDU embedded in A-MPDU
640 bHTRate = TRUE;
641 if (RTMP_GET_PACKET_MOREDATA(pPacket) || (pMacEntry->PsMode == PWR_SAVE))
642 TxFrameType = TX_LEGACY_FRAME;
643#ifdef UAPSD_AP_SUPPORT
644 else if (RTMP_GET_PACKET_EOSP(pPacket))
645 TxFrameType = TX_LEGACY_FRAME;
646#endif // UAPSD_AP_SUPPORT //
647 else if((pMacEntry->TXBAbitmap & (1<<(RTMP_GET_PACKET_UP(pPacket)))) != 0)
648 return TX_AMPDU_FRAME;
649 else if(CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AMSDU_INUSED))
650 return TX_AMSDU_FRAME;
651 else
652 TxFrameType = TX_LEGACY_FRAME;
653 }
654#endif // DOT11_N_SUPPORT //
655 else
656 { // it's a legacy b/g packet.
657 if ((CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE) && pAd->CommonCfg.bAggregationCapable) &&
658 (RTMP_GET_PACKET_TXRATE(pPacket) >= RATE_6) &&
659 (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))))
660 { // if peer support Ralink Aggregation, we use it.
661 TxFrameType = TX_RALINK_FRAME;
662 }
663 else
664 {
665 TxFrameType = TX_LEGACY_FRAME;
666 }
667 }
668
669 // Currently, our fragment only support when a unicast packet send as NOT-ARALINK, NOT-AMSDU and NOT-AMPDU.
670 if ((RTMP_GET_PACKET_FRAGMENTS(pPacket) > 1) && (TxFrameType == TX_LEGACY_FRAME))
671 TxFrameType = TX_FRAG_FRAME;
672
673 return TxFrameType;
674}
675
676
677BOOLEAN RTMP_FillTxBlkInfo(
678 IN RTMP_ADAPTER *pAd,
679 IN TX_BLK *pTxBlk)
680{
681 PACKET_INFO PacketInfo;
682 PNDIS_PACKET pPacket;
683 PMAC_TABLE_ENTRY pMacEntry = NULL;
684
685 pPacket = pTxBlk->pPacket;
686 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen);
687
688 pTxBlk->Wcid = RTMP_GET_PACKET_WCID(pPacket);
689 pTxBlk->apidx = RTMP_GET_PACKET_IF(pPacket);
690 pTxBlk->UserPriority = RTMP_GET_PACKET_UP(pPacket);
691 pTxBlk->FrameGap = IFS_HTTXOP; // ASIC determine Frame Gap
692
693 if (RTMP_GET_PACKET_CLEAR_EAP_FRAME(pTxBlk->pPacket))
694 TX_BLK_SET_FLAG(pTxBlk, fTX_bClearEAPFrame);
695 else
696 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bClearEAPFrame);
697
698 // Default to clear this flag
699 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bForceNonQoS);
700
701
702 if (pTxBlk->Wcid == MCAST_WCID)
703 {
704 pTxBlk->pMacEntry = NULL;
705 {
706#ifdef MCAST_RATE_SPECIFIC
707 PUCHAR pDA = GET_OS_PKT_DATAPTR(pPacket);
708 if (((*pDA & 0x01) == 0x01) && (*pDA != 0xff))
709 pTxBlk->pTransmit = &pAd->CommonCfg.MCastPhyMode;
710 else
711#endif // MCAST_RATE_SPECIFIC //
712 pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
713 }
714
715 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired); // AckRequired = FALSE, when broadcast packet in Adhoc mode.
716 //TX_BLK_SET_FLAG(pTxBlk, fTX_bForceLowRate);
717 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAllowFrag);
718 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
719 if (RTMP_GET_PACKET_MOREDATA(pPacket))
720 {
721 TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
722 }
723
724 }
725 else
726 {
727 pTxBlk->pMacEntry = &pAd->MacTab.Content[pTxBlk->Wcid];
728 pTxBlk->pTransmit = &pTxBlk->pMacEntry->HTPhyMode;
729
730 pMacEntry = pTxBlk->pMacEntry;
731
732
733 // For all unicast packets, need Ack unless the Ack Policy is not set as NORMAL_ACK.
734 if (pAd->CommonCfg.AckPolicy[pTxBlk->QueIdx] != NORMAL_ACK)
735 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired);
736 else
737 TX_BLK_SET_FLAG(pTxBlk, fTX_bAckRequired);
738
739 {
740
741#ifdef CONFIG_STA_SUPPORT
742 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
743 {
744
745 // If support WMM, enable it.
746 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
747 CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))
748 TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM);
749
750// if (pAd->StaCfg.bAutoTxRateSwitch)
751// TX_BLK_SET_FLAG(pTxBlk, fTX_AutoRateSwitch);
752 }
753#endif // CONFIG_STA_SUPPORT //
754 }
755
756 if (pTxBlk->TxFrameType == TX_LEGACY_FRAME)
757 {
758 if ( (RTMP_GET_PACKET_LOWRATE(pPacket)) ||
759 ((pAd->OpMode == OPMODE_AP) && (pMacEntry->MaxHTPhyMode.field.MODE == MODE_CCK) && (pMacEntry->MaxHTPhyMode.field.MCS == RATE_1)))
760 { // Specific packet, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame, need force low rate.
761 pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
762#ifdef DOT11_N_SUPPORT
763 // Modify the WMM bit for ICV issue. If we have a packet with EOSP field need to set as 1, how to handle it???
764 if (IS_HT_STA(pTxBlk->pMacEntry) &&
765 (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_RALINK_CHIPSET)) &&
766 ((pAd->CommonCfg.bRdg == TRUE) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_RDG_CAPABLE)))
767 {
768 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
769 TX_BLK_SET_FLAG(pTxBlk, fTX_bForceNonQoS);
770 }
771#endif // DOT11_N_SUPPORT //
772 }
773
774#ifdef DOT11_N_SUPPORT
775 if ( (IS_HT_RATE(pMacEntry) == FALSE) &&
776 (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE)))
777 { // Currently piggy-back only support when peer is operate in b/g mode.
778 TX_BLK_SET_FLAG(pTxBlk, fTX_bPiggyBack);
779 }
780#endif // DOT11_N_SUPPORT //
781
782 if (RTMP_GET_PACKET_MOREDATA(pPacket))
783 {
784 TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
785 }
786#ifdef UAPSD_AP_SUPPORT
787 if (RTMP_GET_PACKET_EOSP(pPacket))
788 {
789 TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM_UAPSD_EOSP);
790 }
791#endif // UAPSD_AP_SUPPORT //
792 }
793 else if (pTxBlk->TxFrameType == TX_FRAG_FRAME)
794 {
795 TX_BLK_SET_FLAG(pTxBlk, fTX_bAllowFrag);
796 }
797
798 pMacEntry->DebugTxCount++;
799 }
800
801 return TRUE;
802
803FillTxBlkErr:
804 return FALSE;
805}
806
807
808BOOLEAN CanDoAggregateTransmit(
809 IN RTMP_ADAPTER *pAd,
810 IN NDIS_PACKET *pPacket,
811 IN TX_BLK *pTxBlk)
812{
813
814 //printk("Check if can do aggregation! TxFrameType=%d!\n", pTxBlk->TxFrameType);
815
816 if (RTMP_GET_PACKET_WCID(pPacket) == MCAST_WCID)
817 return FALSE;
818
819 if (RTMP_GET_PACKET_DHCP(pPacket) ||
820 RTMP_GET_PACKET_EAPOL(pPacket) ||
821 RTMP_GET_PACKET_WAI(pPacket))
822 return FALSE;
823
824 if ((pTxBlk->TxFrameType == TX_AMSDU_FRAME) &&
825 ((pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket))> (RX_BUFFER_AGGRESIZE - 100)))
826 { // For AMSDU, allow the packets with total length < max-amsdu size
827 return FALSE;
828 }
829
830 if ((pTxBlk->TxFrameType == TX_RALINK_FRAME) &&
831 (pTxBlk->TxPacketList.Number == 2))
832 { // For RALINK-Aggregation, allow two frames in one batch.
833 return FALSE;
834 }
835
836#ifdef CONFIG_STA_SUPPORT
837 if ((INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) // must be unicast to AP
838 return TRUE;
839 else
840#endif // CONFIG_STA_SUPPORT //
841 return FALSE;
842
843}
844
845
846/*
847 ========================================================================
848
849 Routine Description:
850 To do the enqueue operation and extract the first item of waiting
851 list. If a number of available shared memory segments could meet
852 the request of extracted item, the extracted item will be fragmented
853 into shared memory segments.
854
855 Arguments:
856 pAd Pointer to our adapter
857 pQueue Pointer to Waiting Queue
858
859 Return Value:
860 None
861
862 IRQL = DISPATCH_LEVEL
863
864 Note:
865
866 ========================================================================
867*/
868VOID RTMPDeQueuePacket(
869 IN PRTMP_ADAPTER pAd,
870 IN BOOLEAN bIntContext,
871 IN UCHAR QIdx, /* BulkOutPipeId */
872 IN UCHAR Max_Tx_Packets)
873{
874 PQUEUE_ENTRY pEntry = NULL;
875 PNDIS_PACKET pPacket;
876 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
877 UCHAR Count=0;
878 PQUEUE_HEADER pQueue;
879 ULONG FreeNumber[NUM_OF_TX_RING];
880 UCHAR QueIdx, sQIdx, eQIdx;
881 unsigned long IrqFlags = 0;
882 BOOLEAN hasTxDesc = FALSE;
883 TX_BLK TxBlk;
884 TX_BLK *pTxBlk;
885
886#ifdef DBG_DIAGNOSE
887 BOOLEAN firstRound;
888 RtmpDiagStruct *pDiagStruct = &pAd->DiagStruct;
889#endif
890
891
892 if (QIdx == NUM_OF_TX_RING)
893 {
894 sQIdx = 0;
895//PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
896#ifdef CONFIG_STA_SUPPORT
897 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
898 eQIdx = 3; // 4 ACs, start from 0.
899#endif // CONFIG_STA_SUPPORT //
900 }
901 else
902 {
903 sQIdx = eQIdx = QIdx;
904 }
905
906 for (QueIdx=sQIdx; QueIdx <= eQIdx; QueIdx++)
907 {
908 Count=0;
909
910 RT28XX_START_DEQUEUE(pAd, QueIdx, IrqFlags);
911
912#ifdef DBG_DIAGNOSE
913 firstRound = ((QueIdx == 0) ? TRUE : FALSE);
914#endif // DBG_DIAGNOSE //
915
916 while (1)
917 {
918 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS |
919 fRTMP_ADAPTER_RADIO_OFF |
920 fRTMP_ADAPTER_RESET_IN_PROGRESS |
921 fRTMP_ADAPTER_HALT_IN_PROGRESS |
922 fRTMP_ADAPTER_NIC_NOT_EXIST))))
923 {
924 RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
925 return;
926 }
927
928 if (Count >= Max_Tx_Packets)
929 break;
930
931 DEQUEUE_LOCK(&pAd->irq_lock, bIntContext, IrqFlags);
932 if (&pAd->TxSwQueue[QueIdx] == NULL)
933 {
934#ifdef DBG_DIAGNOSE
935 if (firstRound == TRUE)
936 pDiagStruct->TxSWQueCnt[pDiagStruct->ArrayCurIdx][0]++;
937#endif // DBG_DIAGNOSE //
938 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
939 break;
940 }
941
942
943 // probe the Queue Head
944 pQueue = &pAd->TxSwQueue[QueIdx];
945 if ((pEntry = pQueue->Head) == NULL)
946 {
947 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
948 break;
949 }
950
951 pTxBlk = &TxBlk;
952 NdisZeroMemory((PUCHAR)pTxBlk, sizeof(TX_BLK));
953 //InitializeQueueHeader(&pTxBlk->TxPacketList); // Didn't need it because we already memzero it.
954 pTxBlk->QueIdx = QueIdx;
955
956 pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
957
958 // Early check to make sure we have enoguh Tx Resource.
959 hasTxDesc = RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket);
960 if (!hasTxDesc)
961 {
962 pAd->PrivateInfo.TxRingFullCnt++;
963
964 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
965
966 break;
967 }
968
969 pTxBlk->TxFrameType = TxPktClassification(pAd, pPacket);
970 pEntry = RemoveHeadQueue(pQueue);
971 pTxBlk->TotalFrameNum++;
972 pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket); // The real fragment number maybe vary
973 pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket);
974 pTxBlk->pPacket = pPacket;
975 InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket));
976
977 if (pTxBlk->TxFrameType == TX_RALINK_FRAME || pTxBlk->TxFrameType == TX_AMSDU_FRAME)
978 {
979 // Enhance SW Aggregation Mechanism
980 if (NEED_QUEUE_BACK_FOR_AGG(pAd, QueIdx, FreeNumber[QueIdx], pTxBlk->TxFrameType))
981 {
982 InsertHeadQueue(pQueue, PACKET_TO_QUEUE_ENTRY(pPacket));
983 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
984 break;
985 }
986
987 do{
988 if((pEntry = pQueue->Head) == NULL)
989 break;
990
991 // For TX_AMSDU_FRAME/TX_RALINK_FRAME, Need to check if next pakcet can do aggregation.
992 pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
993 FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
994 hasTxDesc = RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket);
995 if ((hasTxDesc == FALSE) || (CanDoAggregateTransmit(pAd, pPacket, pTxBlk) == FALSE))
996 break;
997
998 //Remove the packet from the TxSwQueue and insert into pTxBlk
999 pEntry = RemoveHeadQueue(pQueue);
1000 ASSERT(pEntry);
1001 pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
1002 pTxBlk->TotalFrameNum++;
1003 pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket); // The real fragment number maybe vary
1004 pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket);
1005 InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket));
1006 }while(1);
1007
1008 if (pTxBlk->TxPacketList.Number == 1)
1009 pTxBlk->TxFrameType = TX_LEGACY_FRAME;
1010 }
1011
1012#ifdef RT2870
1013 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
1014#endif // RT2870 //
1015
1016 Count += pTxBlk->TxPacketList.Number;
1017
1018 // Do HardTransmit now.
1019#ifdef CONFIG_STA_SUPPORT
1020 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1021 Status = STAHardTransmit(pAd, pTxBlk, QueIdx);
1022#endif // CONFIG_STA_SUPPORT //
1023 }
1024
1025 RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
1026
1027#ifdef RT2870
1028 if (!hasTxDesc)
1029 RTUSBKickBulkOut(pAd);
1030#endif // RT2870 //
1031
1032#ifdef BLOCK_NET_IF
1033 if ((pAd->blockQueueTab[QueIdx].SwTxQueueBlockFlag == TRUE)
1034 && (pAd->TxSwQueue[QueIdx].Number < 1))
1035 {
1036 releaseNetIf(&pAd->blockQueueTab[QueIdx]);
1037 }
1038#endif // BLOCK_NET_IF //
1039
1040 }
1041
1042}
1043
1044
1045/*
1046 ========================================================================
1047
1048 Routine Description:
1049 Calculates the duration which is required to transmit out frames
1050 with given size and specified rate.
1051
1052 Arguments:
1053 pAd Pointer to our adapter
1054 Rate Transmit rate
1055 Size Frame size in units of byte
1056
1057 Return Value:
1058 Duration number in units of usec
1059
1060 IRQL = PASSIVE_LEVEL
1061 IRQL = DISPATCH_LEVEL
1062
1063 Note:
1064
1065 ========================================================================
1066*/
1067USHORT RTMPCalcDuration(
1068 IN PRTMP_ADAPTER pAd,
1069 IN UCHAR Rate,
1070 IN ULONG Size)
1071{
1072 ULONG Duration = 0;
1073
1074 if (Rate < RATE_FIRST_OFDM_RATE) // CCK
1075 {
1076 if ((Rate > RATE_1) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED))
1077 Duration = 96; // 72+24 preamble+plcp
1078 else
1079 Duration = 192; // 144+48 preamble+plcp
1080
1081 Duration += (USHORT)((Size << 4) / RateIdTo500Kbps[Rate]);
1082 if ((Size << 4) % RateIdTo500Kbps[Rate])
1083 Duration ++;
1084 }
1085 else if (Rate <= RATE_LAST_OFDM_RATE)// OFDM rates
1086 {
1087 Duration = 20 + 6; // 16+4 preamble+plcp + Signal Extension
1088 Duration += 4 * (USHORT)((11 + Size * 4) / RateIdTo500Kbps[Rate]);
1089 if ((11 + Size * 4) % RateIdTo500Kbps[Rate])
1090 Duration += 4;
1091 }
1092 else //mimo rate
1093 {
1094 Duration = 20 + 6; // 16+4 preamble+plcp + Signal Extension
1095 }
1096
1097 return (USHORT)Duration;
1098}
1099
1100
1101/*
1102 ========================================================================
1103
1104 Routine Description:
1105 Calculates the duration which is required to transmit out frames
1106 with given size and specified rate.
1107
1108 Arguments:
1109 pTxWI Pointer to head of each MPDU to HW.
1110 Ack Setting for Ack requirement bit
1111 Fragment Setting for Fragment bit
1112 RetryMode Setting for retry mode
1113 Ifs Setting for IFS gap
1114 Rate Setting for transmit rate
1115 Service Setting for service
1116 Length Frame length
1117 TxPreamble Short or Long preamble when using CCK rates
1118 QueIdx - 0-3, according to 802.11e/d4.4 June/2003
1119
1120 Return Value:
1121 None
1122
1123 IRQL = PASSIVE_LEVEL
1124 IRQL = DISPATCH_LEVEL
1125
1126 See also : BASmartHardTransmit() !!!
1127
1128 ========================================================================
1129*/
1130VOID RTMPWriteTxWI(
1131 IN PRTMP_ADAPTER pAd,
1132 IN PTXWI_STRUC pOutTxWI,
1133 IN BOOLEAN FRAG,
1134 IN BOOLEAN CFACK,
1135 IN BOOLEAN InsTimestamp,
1136 IN BOOLEAN AMPDU,
1137 IN BOOLEAN Ack,
1138 IN BOOLEAN NSeq, // HW new a sequence.
1139 IN UCHAR BASize,
1140 IN UCHAR WCID,
1141 IN ULONG Length,
1142 IN UCHAR PID,
1143 IN UCHAR TID,
1144 IN UCHAR TxRate,
1145 IN UCHAR Txopmode,
1146 IN BOOLEAN CfAck,
1147 IN HTTRANSMIT_SETTING *pTransmit)
1148{
1149 PMAC_TABLE_ENTRY pMac = NULL;
1150 TXWI_STRUC TxWI;
1151 PTXWI_STRUC pTxWI;
1152
1153 if (WCID < MAX_LEN_OF_MAC_TABLE)
1154 pMac = &pAd->MacTab.Content[WCID];
1155
1156 //
1157 // Always use Long preamble before verifiation short preamble functionality works well.
1158 // Todo: remove the following line if short preamble functionality works
1159 //
1160 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
1161 NdisZeroMemory(&TxWI, TXWI_SIZE);
1162 pTxWI = &TxWI;
1163
1164 pTxWI->FRAG= FRAG;
1165
1166 pTxWI->CFACK = CFACK;
1167 pTxWI->TS= InsTimestamp;
1168 pTxWI->AMPDU = AMPDU;
1169 pTxWI->ACK = Ack;
1170 pTxWI->txop= Txopmode;
1171
1172 pTxWI->NSEQ = NSeq;
1173 // John tune the performace with Intel Client in 20 MHz performance
1174#ifdef DOT11_N_SUPPORT
1175 BASize = pAd->CommonCfg.TxBASize;
1176
1177 if( BASize >7 )
1178 BASize =7;
1179 pTxWI->BAWinSize = BASize;
1180 pTxWI->ShortGI = pTransmit->field.ShortGI;
1181 pTxWI->STBC = pTransmit->field.STBC;
1182#endif // DOT11_N_SUPPORT //
1183
1184 pTxWI->WirelessCliID = WCID;
1185 pTxWI->MPDUtotalByteCount = Length;
1186 pTxWI->PacketId = PID;
1187
1188 // If CCK or OFDM, BW must be 20
1189 pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
1190#ifdef DOT11N_DRAFT3
1191 if (pTxWI->BW)
1192 pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
1193#endif // DOT11N_DRAFT3 //
1194
1195 pTxWI->MCS = pTransmit->field.MCS;
1196 pTxWI->PHYMODE = pTransmit->field.MODE;
1197 pTxWI->CFACK = CfAck;
1198
1199#ifdef DOT11_N_SUPPORT
1200 if (pMac)
1201 {
1202 if (pAd->CommonCfg.bMIMOPSEnable)
1203 {
1204 if ((pMac->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
1205 {
1206 // Dynamic MIMO Power Save Mode
1207 pTxWI->MIMOps = 1;
1208 }
1209 else if (pMac->MmpsMode == MMPS_STATIC)
1210 {
1211 // Static MIMO Power Save Mode
1212 if (pTransmit->field.MODE >= MODE_HTMIX && pTransmit->field.MCS > 7)
1213 {
1214 pTxWI->MCS = 7;
1215 pTxWI->MIMOps = 0;
1216 }
1217 }
1218 }
1219 //pTxWI->MIMOps = (pMac->PsMode == PWR_MMPS)? 1:0;
1220 if (pMac->bIAmBadAtheros && (pMac->WepStatus != Ndis802_11WEPDisabled))
1221 {
1222 pTxWI->MpduDensity = 7;
1223 }
1224 else
1225 {
1226 pTxWI->MpduDensity = pMac->MpduDensity;
1227 }
1228 }
1229#endif // DOT11_N_SUPPORT //
1230
1231 pTxWI->PacketId = pTxWI->MCS;
1232 NdisMoveMemory(pOutTxWI, &TxWI, sizeof(TXWI_STRUC));
1233}
1234
1235
1236VOID RTMPWriteTxWI_Data(
1237 IN PRTMP_ADAPTER pAd,
1238 IN OUT PTXWI_STRUC pTxWI,
1239 IN TX_BLK *pTxBlk)
1240{
1241 HTTRANSMIT_SETTING *pTransmit;
1242 PMAC_TABLE_ENTRY pMacEntry;
1243#ifdef DOT11_N_SUPPORT
1244 UCHAR BASize;
1245#endif // DOT11_N_SUPPORT //
1246
1247
1248 ASSERT(pTxWI);
1249
1250 pTransmit = pTxBlk->pTransmit;
1251 pMacEntry = pTxBlk->pMacEntry;
1252
1253
1254 //
1255 // Always use Long preamble before verifiation short preamble functionality works well.
1256 // Todo: remove the following line if short preamble functionality works
1257 //
1258 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
1259 NdisZeroMemory(pTxWI, TXWI_SIZE);
1260
1261 pTxWI->FRAG = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag);
1262 pTxWI->ACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAckRequired);
1263 pTxWI->txop = pTxBlk->FrameGap;
1264
1265#ifdef CONFIG_STA_SUPPORT
1266#ifdef QOS_DLS_SUPPORT
1267 if (pMacEntry &&
1268 (pAd->StaCfg.BssType == BSS_INFRA) &&
1269 (pMacEntry->ValidAsDls == TRUE))
1270 pTxWI->WirelessCliID = BSSID_WCID;
1271 else
1272#endif // QOS_DLS_SUPPORT //
1273#endif // CONFIG_STA_SUPPORT //
1274 pTxWI->WirelessCliID = pTxBlk->Wcid;
1275
1276 pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
1277 pTxWI->CFACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bPiggyBack);
1278
1279 // If CCK or OFDM, BW must be 20
1280 pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
1281#ifdef DOT11_N_SUPPORT
1282#ifdef DOT11N_DRAFT3
1283 if (pTxWI->BW)
1284 pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
1285#endif // DOT11N_DRAFT3 //
1286 pTxWI->AMPDU = ((pTxBlk->TxFrameType == TX_AMPDU_FRAME) ? TRUE : FALSE);
1287
1288 // John tune the performace with Intel Client in 20 MHz performance
1289 BASize = pAd->CommonCfg.TxBASize;
1290 if((pTxBlk->TxFrameType == TX_AMPDU_FRAME) && (pMacEntry))
1291 {
1292 UCHAR RABAOriIdx = 0; //The RA's BA Originator table index.
1293
1294 RABAOriIdx = pTxBlk->pMacEntry->BAOriWcidArray[pTxBlk->UserPriority];
1295 BASize = pAd->BATable.BAOriEntry[RABAOriIdx].BAWinSize;
1296 }
1297
1298 pTxWI->TxBF = pTransmit->field.TxBF;
1299 pTxWI->BAWinSize = BASize;
1300 pTxWI->ShortGI = pTransmit->field.ShortGI;
1301 pTxWI->STBC = pTransmit->field.STBC;
1302#endif // DOT11_N_SUPPORT //
1303
1304 pTxWI->MCS = pTransmit->field.MCS;
1305 pTxWI->PHYMODE = pTransmit->field.MODE;
1306
1307#ifdef DOT11_N_SUPPORT
1308 if (pMacEntry)
1309 {
1310 if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
1311 {
1312 // Dynamic MIMO Power Save Mode
1313 pTxWI->MIMOps = 1;
1314 }
1315 else if (pMacEntry->MmpsMode == MMPS_STATIC)
1316 {
1317 // Static MIMO Power Save Mode
1318 if (pTransmit->field.MODE >= MODE_HTMIX && pTransmit->field.MCS > 7)
1319 {
1320 pTxWI->MCS = 7;
1321 pTxWI->MIMOps = 0;
1322 }
1323 }
1324
1325 if (pMacEntry->bIAmBadAtheros && (pMacEntry->WepStatus != Ndis802_11WEPDisabled))
1326 {
1327 pTxWI->MpduDensity = 7;
1328 }
1329 else
1330 {
1331 pTxWI->MpduDensity = pMacEntry->MpduDensity;
1332 }
1333 }
1334#endif // DOT11_N_SUPPORT //
1335
1336#ifdef DBG_DIAGNOSE
1337 if (pTxBlk->QueIdx== 0)
1338 {
1339 pAd->DiagStruct.TxDataCnt[pAd->DiagStruct.ArrayCurIdx]++;
1340 pAd->DiagStruct.TxMcsCnt[pAd->DiagStruct.ArrayCurIdx][pTxWI->MCS]++;
1341 }
1342#endif // DBG_DIAGNOSE //
1343
1344 // for rate adapation
1345 pTxWI->PacketId = pTxWI->MCS;
1346#ifdef INF_AMAZON_SE
1347/*Iverson patch for WMM A5-T07 ,WirelessStaToWirelessSta do not bulk out aggregate */
1348 if( RTMP_GET_PACKET_NOBULKOUT(pTxBlk->pPacket))
1349 {
1350 if(pTxWI->PHYMODE == MODE_CCK)
1351 {
1352 pTxWI->PacketId = 6;
1353 }
1354 }
1355#endif // INF_AMAZON_SE //
1356}
1357
1358
1359VOID RTMPWriteTxWI_Cache(
1360 IN PRTMP_ADAPTER pAd,
1361 IN OUT PTXWI_STRUC pTxWI,
1362 IN TX_BLK *pTxBlk)
1363{
1364 PHTTRANSMIT_SETTING /*pTxHTPhyMode,*/ pTransmit;
1365 PMAC_TABLE_ENTRY pMacEntry;
1366
1367 //
1368 // update TXWI
1369 //
1370 pMacEntry = pTxBlk->pMacEntry;
1371 pTransmit = pTxBlk->pTransmit;
1372
1373 //if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))
1374 //if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pMacEntry))
1375 //if (TX_BLK_TEST_FLAG(pTxBlk, fTX_AutoRateSwitch))
1376 if (pMacEntry->bAutoTxRateSwitch)
1377 {
1378 pTxWI->txop = IFS_HTTXOP;
1379
1380 // If CCK or OFDM, BW must be 20
1381 pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
1382 pTxWI->ShortGI = pTransmit->field.ShortGI;
1383 pTxWI->STBC = pTransmit->field.STBC;
1384
1385 pTxWI->MCS = pTransmit->field.MCS;
1386 pTxWI->PHYMODE = pTransmit->field.MODE;
1387
1388 // set PID for TxRateSwitching
1389 pTxWI->PacketId = pTransmit->field.MCS;
1390 }
1391
1392#ifdef DOT11_N_SUPPORT
1393 pTxWI->AMPDU = ((pMacEntry->NoBADataCountDown == 0) ? TRUE: FALSE);
1394 pTxWI->MIMOps = 0;
1395
1396#ifdef DOT11N_DRAFT3
1397 if (pTxWI->BW)
1398 pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
1399#endif // DOT11N_DRAFT3 //
1400
1401 if (pAd->CommonCfg.bMIMOPSEnable)
1402 {
1403 // MIMO Power Save Mode
1404 if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
1405 {
1406 // Dynamic MIMO Power Save Mode
1407 pTxWI->MIMOps = 1;
1408 }
1409 else if (pMacEntry->MmpsMode == MMPS_STATIC)
1410 {
1411 // Static MIMO Power Save Mode
1412 if ((pTransmit->field.MODE >= MODE_HTMIX) && (pTransmit->field.MCS > 7))
1413 {
1414 pTxWI->MCS = 7;
1415 pTxWI->MIMOps = 0;
1416 }
1417 }
1418 }
1419#endif // DOT11_N_SUPPORT //
1420
1421#ifdef DBG_DIAGNOSE
1422 if (pTxBlk->QueIdx== 0)
1423 {
1424 pAd->DiagStruct.TxDataCnt[pAd->DiagStruct.ArrayCurIdx]++;
1425 pAd->DiagStruct.TxMcsCnt[pAd->DiagStruct.ArrayCurIdx][pTxWI->MCS]++;
1426 }
1427#endif // DBG_DIAGNOSE //
1428
1429 pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
1430
1431}
1432
1433
1434/*
1435 ========================================================================
1436
1437 Routine Description:
1438 Calculates the duration which is required to transmit out frames
1439 with given size and specified rate.
1440
1441 Arguments:
1442 pTxD Pointer to transmit descriptor
1443 Ack Setting for Ack requirement bit
1444 Fragment Setting for Fragment bit
1445 RetryMode Setting for retry mode
1446 Ifs Setting for IFS gap
1447 Rate Setting for transmit rate
1448 Service Setting for service
1449 Length Frame length
1450 TxPreamble Short or Long preamble when using CCK rates
1451 QueIdx - 0-3, according to 802.11e/d4.4 June/2003
1452
1453 Return Value:
1454 None
1455
1456 IRQL = PASSIVE_LEVEL
1457 IRQL = DISPATCH_LEVEL
1458
1459 ========================================================================
1460*/
1461VOID RTMPWriteTxDescriptor(
1462 IN PRTMP_ADAPTER pAd,
1463 IN PTXD_STRUC pTxD,
1464 IN BOOLEAN bWIV,
1465 IN UCHAR QueueSEL)
1466{
1467 //
1468 // Always use Long preamble before verifiation short preamble functionality works well.
1469 // Todo: remove the following line if short preamble functionality works
1470 //
1471 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
1472
1473 pTxD->WIV = (bWIV) ? 1: 0;
1474 pTxD->QSEL= (QueueSEL);
1475 if (pAd->bGenOneHCCA == TRUE)
1476 pTxD->QSEL= FIFO_HCCA;
1477 pTxD->DMADONE = 0;
1478}
1479
1480
1481// should be called only when -
1482// 1. MEADIA_CONNECTED
1483// 2. AGGREGATION_IN_USED
1484// 3. Fragmentation not in used
1485// 4. either no previous frame (pPrevAddr1=NULL) .OR. previoud frame is aggregatible
1486BOOLEAN TxFrameIsAggregatible(
1487 IN PRTMP_ADAPTER pAd,
1488 IN PUCHAR pPrevAddr1,
1489 IN PUCHAR p8023hdr)
1490{
1491
1492 // can't aggregate EAPOL (802.1x) frame
1493 if ((p8023hdr[12] == 0x88) && (p8023hdr[13] == 0x8e))
1494 return FALSE;
1495
1496 // can't aggregate multicast/broadcast frame
1497 if (p8023hdr[0] & 0x01)
1498 return FALSE;
1499
1500 if (INFRA_ON(pAd)) // must be unicast to AP
1501 return TRUE;
1502 else if ((pPrevAddr1 == NULL) || MAC_ADDR_EQUAL(pPrevAddr1, p8023hdr)) // unicast to same STA
1503 return TRUE;
1504 else
1505 return FALSE;
1506}
1507
1508
1509/*
1510 ========================================================================
1511
1512 Routine Description:
1513 Check the MSDU Aggregation policy
1514 1.HT aggregation is A-MSDU
1515 2.legaacy rate aggregation is software aggregation by Ralink.
1516
1517 Arguments:
1518
1519 Return Value:
1520
1521 Note:
1522
1523 ========================================================================
1524*/
1525BOOLEAN PeerIsAggreOn(
1526 IN PRTMP_ADAPTER pAd,
1527 IN ULONG TxRate,
1528 IN PMAC_TABLE_ENTRY pMacEntry)
1529{
1530 ULONG AFlags = (fCLIENT_STATUS_AMSDU_INUSED | fCLIENT_STATUS_AGGREGATION_CAPABLE);
1531
1532 if (pMacEntry != NULL && CLIENT_STATUS_TEST_FLAG(pMacEntry, AFlags))
1533 {
1534#ifdef DOT11_N_SUPPORT
1535 if (pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
1536 {
1537 return TRUE;
1538 }
1539#endif // DOT11_N_SUPPORT //
1540
1541#ifdef AGGREGATION_SUPPORT
1542 if (TxRate >= RATE_6 && pAd->CommonCfg.bAggregationCapable && (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))))
1543 { // legacy Ralink Aggregation support
1544 return TRUE;
1545 }
1546#endif // AGGREGATION_SUPPORT //
1547 }
1548
1549 return FALSE;
1550
1551}
1552
1553
1554/*
1555 ========================================================================
1556
1557 Routine Description:
1558 Check and fine the packet waiting in SW queue with highest priority
1559
1560 Arguments:
1561 pAd Pointer to our adapter
1562
1563 Return Value:
1564 pQueue Pointer to Waiting Queue
1565
1566 IRQL = DISPATCH_LEVEL
1567
1568 Note:
1569
1570 ========================================================================
1571*/
1572PQUEUE_HEADER RTMPCheckTxSwQueue(
1573 IN PRTMP_ADAPTER pAd,
1574 OUT PUCHAR pQueIdx)
1575{
1576
1577 ULONG Number;
1578 // 2004-11-15 to be removed. test aggregation only
1579// if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)) && (*pNumber < 2))
1580// return NULL;
1581
1582 Number = pAd->TxSwQueue[QID_AC_BK].Number
1583 + pAd->TxSwQueue[QID_AC_BE].Number
1584 + pAd->TxSwQueue[QID_AC_VI].Number
1585 + pAd->TxSwQueue[QID_AC_VO].Number
1586 + pAd->TxSwQueue[QID_HCCA].Number;
1587
1588 if (pAd->TxSwQueue[QID_AC_VO].Head != NULL)
1589 {
1590 *pQueIdx = QID_AC_VO;
1591 return (&pAd->TxSwQueue[QID_AC_VO]);
1592 }
1593 else if (pAd->TxSwQueue[QID_AC_VI].Head != NULL)
1594 {
1595 *pQueIdx = QID_AC_VI;
1596 return (&pAd->TxSwQueue[QID_AC_VI]);
1597 }
1598 else if (pAd->TxSwQueue[QID_AC_BE].Head != NULL)
1599 {
1600 *pQueIdx = QID_AC_BE;
1601 return (&pAd->TxSwQueue[QID_AC_BE]);
1602 }
1603 else if (pAd->TxSwQueue[QID_AC_BK].Head != NULL)
1604 {
1605 *pQueIdx = QID_AC_BK;
1606 return (&pAd->TxSwQueue[QID_AC_BK]);
1607 }
1608 else if (pAd->TxSwQueue[QID_HCCA].Head != NULL)
1609 {
1610 *pQueIdx = QID_HCCA;
1611 return (&pAd->TxSwQueue[QID_HCCA]);
1612 }
1613
1614 // No packet pending in Tx Sw queue
1615 *pQueIdx = QID_AC_BK;
1616
1617 return (NULL);
1618}
1619
1620
1621
1622/*
1623 ========================================================================
1624
1625 Routine Description:
1626 Suspend MSDU transmission
1627
1628 Arguments:
1629 pAd Pointer to our adapter
1630
1631 Return Value:
1632 None
1633
1634 Note:
1635
1636 ========================================================================
1637*/
1638VOID RTMPSuspendMsduTransmission(
1639 IN PRTMP_ADAPTER pAd)
1640{
1641 DBGPRINT(RT_DEBUG_TRACE,("SCANNING, suspend MSDU transmission ...\n"));
1642
1643
1644 //
1645 // Before BSS_SCAN_IN_PROGRESS, we need to keep Current R66 value and
1646 // use Lowbound as R66 value on ScanNextChannel(...)
1647 //
1648 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
1649
1650 // set BBP_R66 to 0x30/0x40 when scanning (AsicSwitchChannel will set R66 according to channel when scanning)
1651 //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x26 + GET_LNA_GAIN(pAd)));
1652 RTMPSetAGCInitValue(pAd, BW_20);
1653
1654 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1655 //RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x000f0000); // abort all TX rings
1656}
1657
1658
1659/*
1660 ========================================================================
1661
1662 Routine Description:
1663 Resume MSDU transmission
1664
1665 Arguments:
1666 pAd Pointer to our adapter
1667
1668 Return Value:
1669 None
1670
1671 IRQL = DISPATCH_LEVEL
1672
1673 Note:
1674
1675 ========================================================================
1676*/
1677VOID RTMPResumeMsduTransmission(
1678 IN PRTMP_ADAPTER pAd)
1679{
1680// UCHAR IrqState;
1681
1682 DBGPRINT(RT_DEBUG_TRACE,("SCAN done, resume MSDU transmission ...\n"));
1683
1684
1685 // After finish BSS_SCAN_IN_PROGRESS, we need to restore Current R66 value
1686 // R66 should not be 0
1687 if (pAd->BbpTuning.R66CurrentValue == 0)
1688 {
1689 pAd->BbpTuning.R66CurrentValue = 0x38;
1690 DBGPRINT_ERR(("RTMPResumeMsduTransmission, R66CurrentValue=0...\n"));
1691 }
1692 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, pAd->BbpTuning.R66CurrentValue);
1693
1694 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1695// sample, for IRQ LOCK to SEM LOCK
1696// IrqState = pAd->irq_disabled;
1697// if (IrqState)
1698// RTMPDeQueuePacket(pAd, TRUE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1699// else
1700 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1701}
1702
1703
1704UINT deaggregate_AMSDU_announce(
1705 IN PRTMP_ADAPTER pAd,
1706 PNDIS_PACKET pPacket,
1707 IN PUCHAR pData,
1708 IN ULONG DataSize)
1709{
1710 USHORT PayloadSize;
1711 USHORT SubFrameSize;
1712 PHEADER_802_3 pAMSDUsubheader;
1713 UINT nMSDU;
1714 UCHAR Header802_3[14];
1715
1716 PUCHAR pPayload, pDA, pSA, pRemovedLLCSNAP;
1717 PNDIS_PACKET pClonePacket;
1718
1719
1720
1721 nMSDU = 0;
1722
1723 while (DataSize > LENGTH_802_3)
1724 {
1725
1726 nMSDU++;
1727
1728 //hex_dump("subheader", pData, 64);
1729 pAMSDUsubheader = (PHEADER_802_3)pData;
1730 //pData += LENGTH_802_3;
1731 PayloadSize = pAMSDUsubheader->Octet[1] + (pAMSDUsubheader->Octet[0]<<8);
1732 SubFrameSize = PayloadSize + LENGTH_802_3;
1733
1734
1735 if ((DataSize < SubFrameSize) || (PayloadSize > 1518 ))
1736 {
1737 break;
1738 }
1739
1740 //printk("%d subframe: Size = %d\n", nMSDU, PayloadSize);
1741
1742 pPayload = pData + LENGTH_802_3;
1743 pDA = pData;
1744 pSA = pData + MAC_ADDR_LEN;
1745
1746 // convert to 802.3 header
1747 CONVERT_TO_802_3(Header802_3, pDA, pSA, pPayload, PayloadSize, pRemovedLLCSNAP);
1748
1749#ifdef CONFIG_STA_SUPPORT
1750 if ((Header802_3[12] == 0x88) && (Header802_3[13] == 0x8E) )
1751 {
1752 // avoid local heap overflow, use dyanamic allocation
1753 MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
1754 memmove(Elem->Msg+(LENGTH_802_11 + LENGTH_802_1_H), pPayload, PayloadSize);
1755 Elem->MsgLen = LENGTH_802_11 + LENGTH_802_1_H + PayloadSize;
1756 WpaEAPOLKeyAction(pAd, Elem);
1757 kfree(Elem);
1758 }
1759#endif // CONFIG_STA_SUPPORT //
1760
1761#ifdef CONFIG_STA_SUPPORT
1762 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1763 {
1764 if (pRemovedLLCSNAP)
1765 {
1766 pPayload -= LENGTH_802_3;
1767 PayloadSize += LENGTH_802_3;
1768 NdisMoveMemory(pPayload, &Header802_3[0], LENGTH_802_3);
1769 }
1770 }
1771#endif // CONFIG_STA_SUPPORT //
1772
1773 pClonePacket = ClonePacket(pAd, pPacket, pPayload, PayloadSize);
1774 if (pClonePacket)
1775 {
1776#ifdef CONFIG_STA_SUPPORT
1777 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1778 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pClonePacket, RTMP_GET_PACKET_IF(pPacket));
1779#endif // CONFIG_STA_SUPPORT //
1780 }
1781
1782
1783 // A-MSDU has padding to multiple of 4 including subframe header.
1784 // align SubFrameSize up to multiple of 4
1785 SubFrameSize = (SubFrameSize+3)&(~0x3);
1786
1787
1788 if (SubFrameSize > 1528 || SubFrameSize < 32)
1789 {
1790 break;
1791 }
1792
1793 if (DataSize > SubFrameSize)
1794 {
1795 pData += SubFrameSize;
1796 DataSize -= SubFrameSize;
1797 }
1798 else
1799 {
1800 // end of A-MSDU
1801 DataSize = 0;
1802 }
1803 }
1804
1805 // finally release original rx packet
1806 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
1807
1808 return nMSDU;
1809}
1810
1811
1812UINT BA_Reorder_AMSDU_Annnounce(
1813 IN PRTMP_ADAPTER pAd,
1814 IN PNDIS_PACKET pPacket)
1815{
1816 PUCHAR pData;
1817 USHORT DataSize;
1818 UINT nMSDU = 0;
1819
1820 pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
1821 DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
1822
1823 nMSDU = deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize);
1824
1825 return nMSDU;
1826}
1827
1828
1829/*
1830 ==========================================================================
1831 Description:
1832 Look up the MAC address in the MAC table. Return NULL if not found.
1833 Return:
1834 pEntry - pointer to the MAC entry; NULL is not found
1835 ==========================================================================
1836*/
1837MAC_TABLE_ENTRY *MacTableLookup(
1838 IN PRTMP_ADAPTER pAd,
1839 PUCHAR pAddr)
1840{
1841 ULONG HashIdx;
1842 MAC_TABLE_ENTRY *pEntry = NULL;
1843
1844 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
1845 pEntry = pAd->MacTab.Hash[HashIdx];
1846
1847 while (pEntry && (pEntry->ValidAsCLI || pEntry->ValidAsWDS || pEntry->ValidAsApCli || pEntry->ValidAsMesh))
1848 {
1849 if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
1850 {
1851 break;
1852 }
1853 else
1854 pEntry = pEntry->pNext;
1855 }
1856
1857 return pEntry;
1858}
1859
1860MAC_TABLE_ENTRY *MacTableInsertEntry(
1861 IN PRTMP_ADAPTER pAd,
1862 IN PUCHAR pAddr,
1863 IN UCHAR apidx,
1864 IN BOOLEAN CleanAll)
1865{
1866 UCHAR HashIdx;
1867 int i, FirstWcid;
1868 MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
1869// USHORT offset;
1870// ULONG addr;
1871
1872 // if FULL, return
1873 if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
1874 return NULL;
1875
1876 FirstWcid = 1;
1877#ifdef CONFIG_STA_SUPPORT
1878 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1879 if (pAd->StaCfg.BssType == BSS_INFRA)
1880 FirstWcid = 2;
1881#endif // CONFIG_STA_SUPPORT //
1882
1883 // allocate one MAC entry
1884 NdisAcquireSpinLock(&pAd->MacTabLock);
1885 for (i = FirstWcid; i< MAX_LEN_OF_MAC_TABLE; i++) // skip entry#0 so that "entry index == AID" for fast lookup
1886 {
1887 // pick up the first available vacancy
1888 if ((pAd->MacTab.Content[i].ValidAsCLI == FALSE) &&
1889 (pAd->MacTab.Content[i].ValidAsWDS == FALSE) &&
1890 (pAd->MacTab.Content[i].ValidAsApCli== FALSE) &&
1891 (pAd->MacTab.Content[i].ValidAsMesh == FALSE)
1892#ifdef CONFIG_STA_SUPPORT
1893#ifdef QOS_DLS_SUPPORT
1894 && (pAd->MacTab.Content[i].ValidAsDls == FALSE)
1895#endif // QOS_DLS_SUPPORT //
1896#endif // CONFIG_STA_SUPPORT //
1897 )
1898 {
1899 pEntry = &pAd->MacTab.Content[i];
1900 if (CleanAll == TRUE)
1901 {
1902 pEntry->MaxSupportedRate = RATE_11;
1903 pEntry->CurrTxRate = RATE_11;
1904 NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
1905 pEntry->PairwiseKey.KeyLen = 0;
1906 pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
1907 }
1908#ifdef CONFIG_STA_SUPPORT
1909#ifdef QOS_DLS_SUPPORT
1910 if (apidx >= MIN_NET_DEVICE_FOR_DLS)
1911 {
1912 pEntry->ValidAsCLI = FALSE;
1913 pEntry->ValidAsWDS = FALSE;
1914 pEntry->ValidAsApCli = FALSE;
1915 pEntry->ValidAsMesh = FALSE;
1916 pEntry->ValidAsDls = TRUE;
1917 pEntry->isCached = FALSE;
1918 }
1919 else
1920#endif // QOS_DLS_SUPPORT //
1921#endif // CONFIG_STA_SUPPORT //
1922 {
1923
1924#ifdef CONFIG_STA_SUPPORT
1925 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1926 {
1927 pEntry->ValidAsCLI = TRUE;
1928 pEntry->ValidAsWDS = FALSE;
1929 pEntry->ValidAsApCli = FALSE;
1930 pEntry->ValidAsMesh = FALSE;
1931 pEntry->ValidAsDls = FALSE;
1932 }
1933#endif // CONFIG_STA_SUPPORT //
1934 }
1935
1936 pEntry->bIAmBadAtheros = FALSE;
1937 pEntry->pAd = pAd;
1938 pEntry->CMTimerRunning = FALSE;
1939 pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
1940 pEntry->RSNIE_Len = 0;
1941 NdisZeroMemory(pEntry->R_Counter, sizeof(pEntry->R_Counter));
1942 pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;
1943
1944 if (pEntry->ValidAsMesh)
1945 pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_MESH);
1946 else if (pEntry->ValidAsApCli)
1947 pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_APCLI);
1948 else if (pEntry->ValidAsWDS)
1949 pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_WDS);
1950#ifdef CONFIG_STA_SUPPORT
1951#ifdef QOS_DLS_SUPPORT
1952 else if (pEntry->ValidAsDls)
1953 pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_DLS);
1954#endif // QOS_DLS_SUPPORT //
1955#endif // CONFIG_STA_SUPPORT //
1956 else
1957 pEntry->apidx = apidx;
1958
1959 {
1960
1961#ifdef CONFIG_STA_SUPPORT
1962 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1963 {
1964 pEntry->AuthMode = pAd->StaCfg.AuthMode;
1965 pEntry->WepStatus = pAd->StaCfg.WepStatus;
1966 pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1967 }
1968#endif // CONFIG_STA_SUPPORT //
1969 }
1970
1971 pEntry->GTKState = REKEY_NEGOTIATING;
1972 pEntry->PairwiseKey.KeyLen = 0;
1973 pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
1974#ifdef CONFIG_STA_SUPPORT
1975#ifdef QOS_DLS_SUPPORT
1976 if (pEntry->ValidAsDls == TRUE)
1977 pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
1978 else
1979#endif //QOS_DLS_SUPPORT
1980#endif // CONFIG_STA_SUPPORT //
1981 pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1982 pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND;
1983 COPY_MAC_ADDR(pEntry->Addr, pAddr);
1984 pEntry->Sst = SST_NOT_AUTH;
1985 pEntry->AuthState = AS_NOT_AUTH;
1986 pEntry->Aid = (USHORT)i; //0;
1987 pEntry->CapabilityInfo = 0;
1988 pEntry->PsMode = PWR_ACTIVE;
1989 pEntry->PsQIdleCount = 0;
1990 pEntry->NoDataIdleCount = 0;
1991 pEntry->ContinueTxFailCnt = 0;
1992 InitializeQueueHeader(&pEntry->PsQueue);
1993
1994
1995 pAd->MacTab.Size ++;
1996
1997 // Add this entry into ASIC RX WCID search table
1998 RT28XX_STA_ENTRY_ADD(pAd, pEntry);
1999
2000
2001
2002 DBGPRINT(RT_DEBUG_TRACE, ("MacTableInsertEntry - allocate entry #%d, Total= %d\n",i, pAd->MacTab.Size));
2003 break;
2004 }
2005 }
2006
2007 // add this MAC entry into HASH table
2008 if (pEntry)
2009 {
2010 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
2011 if (pAd->MacTab.Hash[HashIdx] == NULL)
2012 {
2013 pAd->MacTab.Hash[HashIdx] = pEntry;
2014 }
2015 else
2016 {
2017 pCurrEntry = pAd->MacTab.Hash[HashIdx];
2018 while (pCurrEntry->pNext != NULL)
2019 pCurrEntry = pCurrEntry->pNext;
2020 pCurrEntry->pNext = pEntry;
2021 }
2022 }
2023
2024 NdisReleaseSpinLock(&pAd->MacTabLock);
2025 return pEntry;
2026}
2027
2028/*
2029 ==========================================================================
2030 Description:
2031 Delete a specified client from MAC table
2032 ==========================================================================
2033 */
2034BOOLEAN MacTableDeleteEntry(
2035 IN PRTMP_ADAPTER pAd,
2036 IN USHORT wcid,
2037 IN PUCHAR pAddr)
2038{
2039 USHORT HashIdx;
2040 MAC_TABLE_ENTRY *pEntry, *pPrevEntry, *pProbeEntry;
2041 BOOLEAN Cancelled;
2042 //USHORT offset; // unused variable
2043 //UCHAR j; // unused variable
2044
2045 if (wcid >= MAX_LEN_OF_MAC_TABLE)
2046 return FALSE;
2047
2048 NdisAcquireSpinLock(&pAd->MacTabLock);
2049
2050 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
2051 //pEntry = pAd->MacTab.Hash[HashIdx];
2052 pEntry = &pAd->MacTab.Content[wcid];
2053
2054 if (pEntry && (pEntry->ValidAsCLI || pEntry->ValidAsApCli || pEntry->ValidAsWDS || pEntry->ValidAsMesh
2055#ifdef CONFIG_STA_SUPPORT
2056#ifdef QOS_DLS_SUPPORT
2057 || pEntry->ValidAsDls
2058#endif // QOS_DLS_SUPPORT //
2059#endif // CONFIG_STA_SUPPORT //
2060 ))
2061 {
2062 if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
2063 {
2064
2065 // Delete this entry from ASIC on-chip WCID Table
2066 RT28XX_STA_ENTRY_MAC_RESET(pAd, wcid);
2067
2068#ifdef DOT11_N_SUPPORT
2069 // free resources of BA
2070 BASessionTearDownALL(pAd, pEntry->Aid);
2071#endif // DOT11_N_SUPPORT //
2072
2073
2074 pPrevEntry = NULL;
2075 pProbeEntry = pAd->MacTab.Hash[HashIdx];
2076 ASSERT(pProbeEntry);
2077
2078 // update Hash list
2079 do
2080 {
2081 if (pProbeEntry == pEntry)
2082 {
2083 if (pPrevEntry == NULL)
2084 {
2085 pAd->MacTab.Hash[HashIdx] = pEntry->pNext;
2086 }
2087 else
2088 {
2089 pPrevEntry->pNext = pEntry->pNext;
2090 }
2091 break;
2092 }
2093
2094 pPrevEntry = pProbeEntry;
2095 pProbeEntry = pProbeEntry->pNext;
2096 } while (pProbeEntry);
2097
2098 // not found !!!
2099 ASSERT(pProbeEntry != NULL);
2100
2101 RT28XX_STA_ENTRY_KEY_DEL(pAd, BSS0, wcid);
2102
2103
2104 if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE)
2105 {
2106 RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled);
2107 pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
2108 }
2109
2110
2111 NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
2112 pAd->MacTab.Size --;
2113 DBGPRINT(RT_DEBUG_TRACE, ("MacTableDeleteEntry1 - Total= %d\n", pAd->MacTab.Size));
2114 }
2115 else
2116 {
2117 printk("\n%s: Impossible Wcid = %d !!!!!\n", __FUNCTION__, wcid);
2118 }
2119 }
2120
2121 NdisReleaseSpinLock(&pAd->MacTabLock);
2122
2123 //Reset operating mode when no Sta.
2124 if (pAd->MacTab.Size == 0)
2125 {
2126#ifdef DOT11_N_SUPPORT
2127 pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode = 0;
2128#endif // DOT11_N_SUPPORT //
2129 //AsicUpdateProtect(pAd, 0 /*pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode*/, (ALLN_SETPROTECT), TRUE, 0 /*pAd->MacTab.fAnyStationNonGF*/);
2130 RT28XX_UPDATE_PROTECT(pAd); // edit by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
2131 }
2132
2133 return TRUE;
2134}
2135
2136
2137/*
2138 ==========================================================================
2139 Description:
2140 This routine reset the entire MAC table. All packets pending in
2141 the power-saving queues are freed here.
2142 ==========================================================================
2143 */
2144VOID MacTableReset(
2145 IN PRTMP_ADAPTER pAd)
2146{
2147 int i;
2148
2149 DBGPRINT(RT_DEBUG_TRACE, ("MacTableReset\n"));
2150 //NdisAcquireSpinLock(&pAd->MacTabLock);
2151
2152 for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
2153 {
2154 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
2155 {
2156
2157#ifdef DOT11_N_SUPPORT
2158 // free resources of BA
2159 BASessionTearDownALL(pAd, i);
2160#endif // DOT11_N_SUPPORT //
2161
2162 pAd->MacTab.Content[i].ValidAsCLI = FALSE;
2163
2164
2165
2166#ifdef RT2870
2167 NdisZeroMemory(pAd->MacTab.Content[i].Addr, 6);
2168 RT28XX_STA_ENTRY_MAC_RESET(pAd, i);
2169#endif // RT2870 //
2170
2171 //AsicDelWcidTab(pAd, i);
2172 }
2173 }
2174
2175 return;
2176}
2177
2178/*
2179 ==========================================================================
2180 Description:
2181
2182 IRQL = DISPATCH_LEVEL
2183
2184 ==========================================================================
2185*/
2186VOID AssocParmFill(
2187 IN PRTMP_ADAPTER pAd,
2188 IN OUT MLME_ASSOC_REQ_STRUCT *AssocReq,
2189 IN PUCHAR pAddr,
2190 IN USHORT CapabilityInfo,
2191 IN ULONG Timeout,
2192 IN USHORT ListenIntv)
2193{
2194 COPY_MAC_ADDR(AssocReq->Addr, pAddr);
2195 // Add mask to support 802.11b mode only
2196 AssocReq->CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO; // not cf-pollable, not cf-poll-request
2197 AssocReq->Timeout = Timeout;
2198 AssocReq->ListenIntv = ListenIntv;
2199}
2200
2201
2202/*
2203 ==========================================================================
2204 Description:
2205
2206 IRQL = DISPATCH_LEVEL
2207
2208 ==========================================================================
2209*/
2210VOID DisassocParmFill(
2211 IN PRTMP_ADAPTER pAd,
2212 IN OUT MLME_DISASSOC_REQ_STRUCT *DisassocReq,
2213 IN PUCHAR pAddr,
2214 IN USHORT Reason)
2215{
2216 COPY_MAC_ADDR(DisassocReq->Addr, pAddr);
2217 DisassocReq->Reason = Reason;
2218}
2219
2220
2221/*
2222 ========================================================================
2223
2224 Routine Description:
2225 Check the out going frame, if this is an DHCP or ARP datagram
2226 will be duplicate another frame at low data rate transmit.
2227
2228 Arguments:
2229 pAd Pointer to our adapter
2230 pPacket Pointer to outgoing Ndis frame
2231
2232 Return Value:
2233 TRUE To be duplicate at Low data rate transmit. (1mb)
2234 FALSE Do nothing.
2235
2236 IRQL = DISPATCH_LEVEL
2237
2238 Note:
2239
2240 MAC header + IP Header + UDP Header
2241 14 Bytes 20 Bytes
2242
2243 UDP Header
2244 00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|
2245 Source Port
2246 16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|
2247 Destination Port
2248
2249 port 0x43 means Bootstrap Protocol, server.
2250 Port 0x44 means Bootstrap Protocol, client.
2251
2252 ========================================================================
2253*/
2254
2255BOOLEAN RTMPCheckDHCPFrame(
2256 IN PRTMP_ADAPTER pAd,
2257 IN PNDIS_PACKET pPacket)
2258{
2259 PACKET_INFO PacketInfo;
2260 ULONG NumberOfBytesRead = 0;
2261 ULONG CurrentOffset = 0;
2262 PVOID pVirtualAddress = NULL;
2263 UINT NdisBufferLength;
2264 PUCHAR pSrc;
2265 USHORT Protocol;
2266 UCHAR ByteOffset36 = 0;
2267 UCHAR ByteOffset38 = 0;
2268 BOOLEAN ReadFirstParm = TRUE;
2269
2270 RTMP_QueryPacketInfo(pPacket, &PacketInfo, (PUCHAR *)&pVirtualAddress, &NdisBufferLength);
2271
2272 NumberOfBytesRead += NdisBufferLength;
2273 pSrc = (PUCHAR) pVirtualAddress;
2274 Protocol = *(pSrc + 12) * 256 + *(pSrc + 13);
2275
2276 //
2277 // Check DHCP & BOOTP protocol
2278 //
2279 while (NumberOfBytesRead <= PacketInfo.TotalPacketLength)
2280 {
2281 if ((NumberOfBytesRead >= 35) && (ReadFirstParm == TRUE))
2282 {
2283 CurrentOffset = 35 - (NumberOfBytesRead - NdisBufferLength);
2284 ByteOffset36 = *(pSrc + CurrentOffset);
2285 ReadFirstParm = FALSE;
2286 }
2287
2288 if (NumberOfBytesRead >= 37)
2289 {
2290 CurrentOffset = 37 - (NumberOfBytesRead - NdisBufferLength);
2291 ByteOffset38 = *(pSrc + CurrentOffset);
2292 //End of Read
2293 break;
2294 }
2295 return FALSE;
2296 }
2297
2298 // Check for DHCP & BOOTP protocol
2299 if ((ByteOffset36 != 0x44) || (ByteOffset38 != 0x43))
2300 {
2301 //
2302 // 2054 (hex 0806) for ARP datagrams
2303 // if this packet is not ARP datagrams, then do nothing
2304 // ARP datagrams will also be duplicate at 1mb broadcast frames
2305 //
2306 if (Protocol != 0x0806 )
2307 return FALSE;
2308 }
2309
2310 return TRUE;
2311}
2312
2313
2314BOOLEAN RTMPCheckEtherType(
2315 IN PRTMP_ADAPTER pAd,
2316 IN PNDIS_PACKET pPacket)
2317{
2318 USHORT TypeLen;
2319 UCHAR Byte0, Byte1;
2320 PUCHAR pSrcBuf;
2321 UINT32 pktLen;
2322 UINT16 srcPort, dstPort;
2323 BOOLEAN status = TRUE;
2324
2325
2326 pSrcBuf = GET_OS_PKT_DATAPTR(pPacket);
2327 pktLen = GET_OS_PKT_LEN(pPacket);
2328
2329 ASSERT(pSrcBuf);
2330
2331 RTMP_SET_PACKET_SPECIFIC(pPacket, 0);
2332
2333 // get Ethernet protocol field
2334 TypeLen = (pSrcBuf[12] << 8) + pSrcBuf[13];
2335
2336 pSrcBuf += LENGTH_802_3; // Skip the Ethernet Header.
2337
2338 if (TypeLen <= 1500)
2339 { // 802.3, 802.3 LLC
2340 /*
2341 DestMAC(6) + SrcMAC(6) + Lenght(2) +
2342 DSAP(1) + SSAP(1) + Control(1) +
2343 if the DSAP = 0xAA, SSAP=0xAA, Contorl = 0x03, it has a 5-bytes SNAP header.
2344 => + SNAP (5, OriginationID(3) + etherType(2))
2345 */
2346 if (pSrcBuf[0] == 0xAA && pSrcBuf[1] == 0xAA && pSrcBuf[2] == 0x03)
2347 {
2348 Sniff2BytesFromNdisBuffer(pSrcBuf, 6, &Byte0, &Byte1);
2349 RTMP_SET_PACKET_LLCSNAP(pPacket, 1);
2350 TypeLen = (USHORT)((Byte0 << 8) + Byte1);
2351 pSrcBuf += 8; // Skip this LLC/SNAP header
2352 }
2353 else
2354 {
2355 //It just has 3-byte LLC header, maybe a legacy ether type frame. we didn't handle it.
2356 }
2357 }
2358
2359 // If it's a VLAN packet, get the real Type/Length field.
2360 if (TypeLen == 0x8100)
2361 {
2362 /* 0x8100 means VLAN packets */
2363
2364 /* Dest. MAC Address (6-bytes) +
2365 Source MAC Address (6-bytes) +
2366 Length/Type = 802.1Q Tag Type (2-byte) +
2367 Tag Control Information (2-bytes) +
2368 Length / Type (2-bytes) +
2369 data payload (0-n bytes) +
2370 Pad (0-p bytes) +
2371 Frame Check Sequence (4-bytes) */
2372
2373 RTMP_SET_PACKET_VLAN(pPacket, 1);
2374 Sniff2BytesFromNdisBuffer(pSrcBuf, 2, &Byte0, &Byte1);
2375 TypeLen = (USHORT)((Byte0 << 8) + Byte1);
2376
2377 pSrcBuf += 4; // Skip the VLAN Header.
2378 }
2379
2380 switch (TypeLen)
2381 {
2382 case 0x0800:
2383 {
2384 ASSERT((pktLen > 34));
2385 if (*(pSrcBuf + 9) == 0x11)
2386 { // udp packet
2387 ASSERT((pktLen > 34)); // 14 for ethernet header, 20 for IP header
2388
2389 pSrcBuf += 20; // Skip the IP header
2390 srcPort = OS_NTOHS(*((UINT16 *)pSrcBuf));
2391 dstPort = OS_NTOHS(*((UINT16 *)(pSrcBuf +2)));
2392
2393 if ((srcPort==0x44 && dstPort==0x43) || (srcPort==0x43 && dstPort==0x44))
2394 { //It's a BOOTP/DHCP packet
2395 RTMP_SET_PACKET_DHCP(pPacket, 1);
2396 }
2397 }
2398 }
2399 break;
2400 case 0x0806:
2401 {
2402 //ARP Packet.
2403 RTMP_SET_PACKET_DHCP(pPacket, 1);
2404 }
2405 break;
2406 case 0x888e:
2407 {
2408 // EAPOL Packet.
2409 RTMP_SET_PACKET_EAPOL(pPacket, 1);
2410 }
2411 break;
2412 default:
2413 status = FALSE;
2414 break;
2415 }
2416
2417 return status;
2418
2419}
2420
2421
2422
2423VOID Update_Rssi_Sample(
2424 IN PRTMP_ADAPTER pAd,
2425 IN RSSI_SAMPLE *pRssi,
2426 IN PRXWI_STRUC pRxWI)
2427 {
2428 CHAR rssi0 = pRxWI->RSSI0;
2429 CHAR rssi1 = pRxWI->RSSI1;
2430 CHAR rssi2 = pRxWI->RSSI2;
2431
2432 if (rssi0 != 0)
2433 {
2434 pRssi->LastRssi0 = ConvertToRssi(pAd, (CHAR)rssi0, RSSI_0);
2435 pRssi->AvgRssi0X8 = (pRssi->AvgRssi0X8 - pRssi->AvgRssi0) + pRssi->LastRssi0;
2436 pRssi->AvgRssi0 = pRssi->AvgRssi0X8 >> 3;
2437 }
2438
2439 if (rssi1 != 0)
2440 {
2441 pRssi->LastRssi1 = ConvertToRssi(pAd, (CHAR)rssi1, RSSI_1);
2442 pRssi->AvgRssi1X8 = (pRssi->AvgRssi1X8 - pRssi->AvgRssi1) + pRssi->LastRssi1;
2443 pRssi->AvgRssi1 = pRssi->AvgRssi1X8 >> 3;
2444 }
2445
2446 if (rssi2 != 0)
2447 {
2448 pRssi->LastRssi2 = ConvertToRssi(pAd, (CHAR)rssi2, RSSI_2);
2449 pRssi->AvgRssi2X8 = (pRssi->AvgRssi2X8 - pRssi->AvgRssi2) + pRssi->LastRssi2;
2450 pRssi->AvgRssi2 = pRssi->AvgRssi2X8 >> 3;
2451 }
2452}
2453
2454
2455
2456// Normal legacy Rx packet indication
2457VOID Indicate_Legacy_Packet(
2458 IN PRTMP_ADAPTER pAd,
2459 IN RX_BLK *pRxBlk,
2460 IN UCHAR FromWhichBSSID)
2461{
2462 PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
2463 UCHAR Header802_3[LENGTH_802_3];
2464
2465 // 1. get 802.3 Header
2466 // 2. remove LLC
2467 // a. pointer pRxBlk->pData to payload
2468 // b. modify pRxBlk->DataSize
2469#ifdef CONFIG_STA_SUPPORT
2470 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2471 RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
2472#endif // CONFIG_STA_SUPPORT //
2473
2474 if (pRxBlk->DataSize > MAX_RX_PKT_LEN)
2475 {
2476 // release packet
2477 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
2478 return;
2479 }
2480
2481
2482 STATS_INC_RX_PACKETS(pAd, FromWhichBSSID);
2483
2484#ifdef RT2870
2485#ifdef DOT11_N_SUPPORT
2486 if (pAd->CommonCfg.bDisableReordering == 0)
2487 {
2488 PBA_REC_ENTRY pBAEntry;
2489 ULONG Now32;
2490 UCHAR Wcid = pRxBlk->pRxWI->WirelessCliID;
2491 UCHAR TID = pRxBlk->pRxWI->TID;
2492 USHORT Idx;
2493
2494#define REORDERING_PACKET_TIMEOUT ((100 * HZ)/1000) // system ticks -- 100 ms
2495
2496 if (Wcid < MAX_LEN_OF_MAC_TABLE)
2497 {
2498 Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
2499 if (Idx != 0)
2500 {
2501 pBAEntry = &pAd->BATable.BARecEntry[Idx];
2502 // update last rx time
2503 NdisGetSystemUpTime(&Now32);
2504 if ((pBAEntry->list.qlen > 0) &&
2505 RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(REORDERING_PACKET_TIMEOUT)))
2506 )
2507 {
2508 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);
2509 hex_dump("Dump the legacy Packet:", GET_OS_PKT_DATAPTR(pRxBlk->pRxPacket), 64);
2510 ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32);
2511 }
2512 }
2513 }
2514 }
2515#endif // DOT11_N_SUPPORT //
2516#endif // RT2870 //
2517
2518 wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
2519
2520 //
2521 // pass this 802.3 packet to upper layer or forward this packet to WM directly
2522 //
2523#ifdef CONFIG_STA_SUPPORT
2524 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2525 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxPacket, FromWhichBSSID);
2526#endif // CONFIG_STA_SUPPORT //
2527
2528}
2529
2530
2531// Normal, AMPDU or AMSDU
2532VOID CmmRxnonRalinkFrameIndicate(
2533 IN PRTMP_ADAPTER pAd,
2534 IN RX_BLK *pRxBlk,
2535 IN UCHAR FromWhichBSSID)
2536{
2537#ifdef DOT11_N_SUPPORT
2538 if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU) && (pAd->CommonCfg.bDisableReordering == 0))
2539 {
2540 Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID);
2541 }
2542 else
2543#endif // DOT11_N_SUPPORT //
2544 {
2545#ifdef DOT11_N_SUPPORT
2546 if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU))
2547 {
2548 // handle A-MSDU
2549 Indicate_AMSDU_Packet(pAd, pRxBlk, FromWhichBSSID);
2550 }
2551 else
2552#endif // DOT11_N_SUPPORT //
2553 {
2554 Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
2555 }
2556 }
2557}
2558
2559
2560VOID CmmRxRalinkFrameIndicate(
2561 IN PRTMP_ADAPTER pAd,
2562 IN MAC_TABLE_ENTRY *pEntry,
2563 IN RX_BLK *pRxBlk,
2564 IN UCHAR FromWhichBSSID)
2565{
2566 UCHAR Header802_3[LENGTH_802_3];
2567 UINT16 Msdu2Size;
2568 UINT16 Payload1Size, Payload2Size;
2569 PUCHAR pData2;
2570 PNDIS_PACKET pPacket2 = NULL;
2571
2572
2573
2574 Msdu2Size = *(pRxBlk->pData) + (*(pRxBlk->pData+1) << 8);
2575
2576 if ((Msdu2Size <= 1536) && (Msdu2Size < pRxBlk->DataSize))
2577 {
2578 /* skip two byte MSDU2 len */
2579 pRxBlk->pData += 2;
2580 pRxBlk->DataSize -= 2;
2581 }
2582 else
2583 {
2584 // release packet
2585 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
2586 return;
2587 }
2588
2589 // get 802.3 Header and remove LLC
2590#ifdef CONFIG_STA_SUPPORT
2591 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2592 RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
2593#endif // CONFIG_STA_SUPPORT //
2594
2595
2596 ASSERT(pRxBlk->pRxPacket);
2597
2598 // Ralink Aggregation frame
2599 pAd->RalinkCounters.OneSecRxAggregationCount ++;
2600 Payload1Size = pRxBlk->DataSize - Msdu2Size;
2601 Payload2Size = Msdu2Size - LENGTH_802_3;
2602
2603 pData2 = pRxBlk->pData + Payload1Size + LENGTH_802_3;
2604#ifdef CONFIG_STA_SUPPORT
2605 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2606 pPacket2 = duplicate_pkt(pAd, (pData2-LENGTH_802_3), LENGTH_802_3, pData2, Payload2Size, FromWhichBSSID);
2607#endif // CONFIG_STA_SUPPORT //
2608
2609 if (!pPacket2)
2610 {
2611 // release packet
2612 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
2613 return;
2614 }
2615
2616 // update payload size of 1st packet
2617 pRxBlk->DataSize = Payload1Size;
2618 wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
2619
2620#ifdef CONFIG_STA_SUPPORT
2621 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2622 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxBlk->pRxPacket, FromWhichBSSID);
2623#endif // CONFIG_STA_SUPPORT //
2624
2625 if (pPacket2)
2626 {
2627#ifdef CONFIG_STA_SUPPORT
2628 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2629 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket2, FromWhichBSSID);
2630#endif // CONFIG_STA_SUPPORT //
2631 }
2632}
2633
2634
2635#define RESET_FRAGFRAME(_fragFrame) \
2636 { \
2637 _fragFrame.RxSize = 0; \
2638 _fragFrame.Sequence = 0; \
2639 _fragFrame.LastFrag = 0; \
2640 _fragFrame.Flags = 0; \
2641 }
2642
2643
2644PNDIS_PACKET RTMPDeFragmentDataFrame(
2645 IN PRTMP_ADAPTER pAd,
2646 IN RX_BLK *pRxBlk)
2647{
2648 PHEADER_802_11 pHeader = pRxBlk->pHeader;
2649 PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
2650 UCHAR *pData = pRxBlk->pData;
2651 USHORT DataSize = pRxBlk->DataSize;
2652 PNDIS_PACKET pRetPacket = NULL;
2653 UCHAR *pFragBuffer = NULL;
2654 BOOLEAN bReassDone = FALSE;
2655 UCHAR HeaderRoom = 0;
2656
2657
2658 ASSERT(pHeader);
2659
2660 HeaderRoom = pData - (UCHAR *)pHeader;
2661
2662 // Re-assemble the fragmented packets
2663 if (pHeader->Frag == 0) // Frag. Number is 0 : First frag or only one pkt
2664 {
2665 // the first pkt of fragment, record it.
2666 if (pHeader->FC.MoreFrag)
2667 {
2668 ASSERT(pAd->FragFrame.pFragPacket);
2669 pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
2670 pAd->FragFrame.RxSize = DataSize + HeaderRoom;
2671 NdisMoveMemory(pFragBuffer, pHeader, pAd->FragFrame.RxSize);
2672 pAd->FragFrame.Sequence = pHeader->Sequence;
2673 pAd->FragFrame.LastFrag = pHeader->Frag; // Should be 0
2674 ASSERT(pAd->FragFrame.LastFrag == 0);
2675 goto done; // end of processing this frame
2676 }
2677 }
2678 else //Middle & End of fragment
2679 {
2680 if ((pHeader->Sequence != pAd->FragFrame.Sequence) ||
2681 (pHeader->Frag != (pAd->FragFrame.LastFrag + 1)))
2682 {
2683 // Fragment is not the same sequence or out of fragment number order
2684 // Reset Fragment control blk
2685 RESET_FRAGFRAME(pAd->FragFrame);
2686 DBGPRINT(RT_DEBUG_ERROR, ("Fragment is not the same sequence or out of fragment number order.\n"));
2687 goto done; // give up this frame
2688 }
2689 else if ((pAd->FragFrame.RxSize + DataSize) > MAX_FRAME_SIZE)
2690 {
2691 // Fragment frame is too large, it exeeds the maximum frame size.
2692 // Reset Fragment control blk
2693 RESET_FRAGFRAME(pAd->FragFrame);
2694 DBGPRINT(RT_DEBUG_ERROR, ("Fragment frame is too large, it exeeds the maximum frame size.\n"));
2695 goto done; // give up this frame
2696 }
2697
2698 //
2699 // Broadcom AP(BCM94704AGR) will send out LLC in fragment's packet, LLC only can accpet at first fragment.
2700 // In this case, we will dropt it.
2701 //
2702 if (NdisEqualMemory(pData, SNAP_802_1H, sizeof(SNAP_802_1H)))
2703 {
2704 DBGPRINT(RT_DEBUG_ERROR, ("Find another LLC at Middle or End fragment(SN=%d, Frag=%d)\n", pHeader->Sequence, pHeader->Frag));
2705 goto done; // give up this frame
2706 }
2707
2708 pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
2709
2710 // concatenate this fragment into the re-assembly buffer
2711 NdisMoveMemory((pFragBuffer + pAd->FragFrame.RxSize), pData, DataSize);
2712 pAd->FragFrame.RxSize += DataSize;
2713 pAd->FragFrame.LastFrag = pHeader->Frag; // Update fragment number
2714
2715 // Last fragment
2716 if (pHeader->FC.MoreFrag == FALSE)
2717 {
2718 bReassDone = TRUE;
2719 }
2720 }
2721
2722done:
2723 // always release rx fragmented packet
2724 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
2725
2726 // return defragmented packet if packet is reassembled completely
2727 // otherwise return NULL
2728 if (bReassDone)
2729 {
2730 PNDIS_PACKET pNewFragPacket;
2731
2732 // allocate a new packet buffer for fragment
2733 pNewFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
2734 if (pNewFragPacket)
2735 {
2736 // update RxBlk
2737 pRetPacket = pAd->FragFrame.pFragPacket;
2738 pAd->FragFrame.pFragPacket = pNewFragPacket;
2739 pRxBlk->pHeader = (PHEADER_802_11) GET_OS_PKT_DATAPTR(pRetPacket);
2740 pRxBlk->pData = (UCHAR *)pRxBlk->pHeader + HeaderRoom;
2741 pRxBlk->DataSize = pAd->FragFrame.RxSize - HeaderRoom;
2742 pRxBlk->pRxPacket = pRetPacket;
2743 }
2744 else
2745 {
2746 RESET_FRAGFRAME(pAd->FragFrame);
2747 }
2748 }
2749
2750 return pRetPacket;
2751}
2752
2753
2754VOID Indicate_AMSDU_Packet(
2755 IN PRTMP_ADAPTER pAd,
2756 IN RX_BLK *pRxBlk,
2757 IN UCHAR FromWhichBSSID)
2758{
2759 UINT nMSDU;
2760
2761 update_os_packet_info(pAd, pRxBlk, FromWhichBSSID);
2762 RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID);
2763 nMSDU = deaggregate_AMSDU_announce(pAd, pRxBlk->pRxPacket, pRxBlk->pData, pRxBlk->DataSize);
2764}
2765
2766VOID Indicate_EAPOL_Packet(
2767 IN PRTMP_ADAPTER pAd,
2768 IN RX_BLK *pRxBlk,
2769 IN UCHAR FromWhichBSSID)
2770{
2771 MAC_TABLE_ENTRY *pEntry = NULL;
2772
2773
2774#ifdef CONFIG_STA_SUPPORT
2775 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2776 {
2777 pEntry = &pAd->MacTab.Content[BSSID_WCID];
2778 STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
2779 return;
2780 }
2781#endif // CONFIG_STA_SUPPORT //
2782
2783 if (pEntry == NULL)
2784 {
2785 DBGPRINT(RT_DEBUG_WARN, ("Indicate_EAPOL_Packet: drop and release the invalid packet.\n"));
2786 // release packet
2787 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
2788 return;
2789 }
2790}
2791
2792#define BCN_TBTT_OFFSET 64 //defer 64 us
2793VOID ReSyncBeaconTime(
2794 IN PRTMP_ADAPTER pAd)
2795{
2796
2797 UINT32 Offset;
2798
2799
2800 Offset = (pAd->TbttTickCount) % (BCN_TBTT_OFFSET);
2801
2802 pAd->TbttTickCount++;
2803
2804 //
2805 // The updated BeaconInterval Value will affect Beacon Interval after two TBTT
2806 // beacasue the original BeaconInterval had been loaded into next TBTT_TIMER
2807 //
2808 if (Offset == (BCN_TBTT_OFFSET-2))
2809 {
2810 BCN_TIME_CFG_STRUC csr;
2811 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
2812 csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod << 4) - 1 ; // ASIC register in units of 1/16 TU = 64us
2813 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
2814 }
2815 else
2816 {
2817 if (Offset == (BCN_TBTT_OFFSET-1))
2818 {
2819 BCN_TIME_CFG_STRUC csr;
2820
2821 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
2822 csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod) << 4; // ASIC register in units of 1/16 TU
2823 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
2824 }
2825 }
2826}
2827
diff --git a/drivers/staging/rt3070/common/cmm_data_2870.c b/drivers/staging/rt3070/common/cmm_data_2870.c
new file mode 100644
index 000000000000..b1066aa2bb23
--- /dev/null
+++ b/drivers/staging/rt3070/common/cmm_data_2870.c
@@ -0,0 +1,980 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26*/
27/*
28 All functions in this file must be USB-depended, or you should out your function
29 in other files.
30
31*/
32#include "../rt_config.h"
33
34
35/*
36 We can do copy the frame into pTxContext when match following conditions.
37 =>
38 =>
39 =>
40*/
41static inline NDIS_STATUS RtmpUSBCanDoWrite(
42 IN RTMP_ADAPTER *pAd,
43 IN UCHAR QueIdx,
44 IN HT_TX_CONTEXT *pHTTXContext)
45{
46 NDIS_STATUS canWrite = NDIS_STATUS_RESOURCES;
47
48 if (((pHTTXContext->CurWritePosition) < pHTTXContext->NextBulkOutPosition) && (pHTTXContext->CurWritePosition + LOCAL_TXBUF_SIZE) > pHTTXContext->NextBulkOutPosition)
49 {
50 DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c1!\n"));
51 RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
52 }
53 else if ((pHTTXContext->CurWritePosition == 8) && (pHTTXContext->NextBulkOutPosition < LOCAL_TXBUF_SIZE))
54 {
55 DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c2!\n"));
56 RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
57 }
58 else if (pHTTXContext->bCurWriting == TRUE)
59 {
60 DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c3!\n"));
61 }
62 else
63 {
64 canWrite = NDIS_STATUS_SUCCESS;
65 }
66
67
68 return canWrite;
69}
70
71
72USHORT RtmpUSB_WriteSubTxResource(
73 IN PRTMP_ADAPTER pAd,
74 IN TX_BLK *pTxBlk,
75 IN BOOLEAN bIsLast,
76 OUT USHORT *FreeNumber)
77{
78
79 // Dummy function. Should be removed in the future.
80 return 0;
81
82}
83
84USHORT RtmpUSB_WriteFragTxResource(
85 IN PRTMP_ADAPTER pAd,
86 IN TX_BLK *pTxBlk,
87 IN UCHAR fragNum,
88 OUT USHORT *FreeNumber)
89{
90 HT_TX_CONTEXT *pHTTXContext;
91 USHORT hwHdrLen; // The hwHdrLen consist of 802.11 header length plus the header padding length.
92 UINT32 fillOffset;
93 TXINFO_STRUC *pTxInfo;
94 TXWI_STRUC *pTxWI;
95 PUCHAR pWirelessPacket = NULL;
96 UCHAR QueIdx;
97 NDIS_STATUS Status;
98 unsigned long IrqFlags;
99 UINT32 USBDMApktLen = 0, DMAHdrLen, padding;
100 BOOLEAN TxQLastRound = FALSE;
101
102 //
103 // get Tx Ring Resource & Dma Buffer address
104 //
105 QueIdx = pTxBlk->QueIdx;
106 pHTTXContext = &pAd->TxContext[QueIdx];
107
108 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
109
110 pHTTXContext = &pAd->TxContext[QueIdx];
111 fillOffset = pHTTXContext->CurWritePosition;
112
113 if(fragNum == 0)
114 {
115 // Check if we have enough space for this bulk-out batch.
116 Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
117 if (Status == NDIS_STATUS_SUCCESS)
118 {
119 pHTTXContext->bCurWriting = TRUE;
120
121 // Reserve space for 8 bytes padding.
122 if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition))
123 {
124 pHTTXContext->ENextBulkOutPosition += 8;
125 pHTTXContext->CurWritePosition += 8;
126 fillOffset += 8;
127 }
128 pTxBlk->Priv = 0;
129 pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
130 }
131 else
132 {
133 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
134
135 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
136 return(Status);
137 }
138 }
139 else
140 {
141 // For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer.
142 Status = ((pHTTXContext->bCurWriting == TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE);
143 if (Status == NDIS_STATUS_SUCCESS)
144 {
145 fillOffset += pTxBlk->Priv;
146 }
147 else
148 {
149 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
150
151 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
152 return(Status);
153 }
154 }
155
156 NdisZeroMemory((PUCHAR)(&pTxBlk->HeaderBuf[0]), TXINFO_SIZE);
157 pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]);
158 pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]);
159
160 pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
161
162 // copy TXWI + WLAN Header + LLC into DMA Header Buffer
163 //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
164 hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
165
166 // Build our URB for USBD
167 DMAHdrLen = TXWI_SIZE + hwHdrLen;
168 USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen;
169 padding = (4 - (USBDMApktLen % 4)) & 0x03; // round up to 4 byte alignment
170 USBDMApktLen += padding;
171
172 pTxBlk->Priv += (TXINFO_SIZE + USBDMApktLen);
173
174 // For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload
175 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(USBDMApktLen), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE);
176
177 if (fragNum == pTxBlk->TotalFragNum)
178 {
179 pTxInfo->USBDMATxburst = 0;
180 if ((pHTTXContext->CurWritePosition + pTxBlk->Priv + 3906)> MAX_TXBULK_LIMIT)
181 {
182 pTxInfo->SwUseLastRound = 1;
183 TxQLastRound = TRUE;
184 }
185 }
186 else
187 {
188 pTxInfo->USBDMATxburst = 1;
189 }
190
191 NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
192#ifdef RT_BIG_ENDIAN
193 RTMPFrameEndianChange(pAd, (PUCHAR)(pWirelessPacket + TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE);
194#endif // RT_BIG_ENDIAN //
195 pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
196 pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
197
198 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
199
200 NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
201
202 // Zero the last padding.
203 pWirelessPacket += pTxBlk->SrcBufLen;
204 NdisZeroMemory(pWirelessPacket, padding + 8);
205
206 if (fragNum == pTxBlk->TotalFragNum)
207 {
208 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
209
210 // Update the pHTTXContext->CurWritePosition. 3906 used to prevent the NextBulkOut is a A-RALINK/A-MSDU Frame.
211 pHTTXContext->CurWritePosition += pTxBlk->Priv;
212 if (TxQLastRound == TRUE)
213 pHTTXContext->CurWritePosition = 8;
214 pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
215
216
217 // Finally, set bCurWriting as FALSE
218 pHTTXContext->bCurWriting = FALSE;
219
220 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
221
222 // succeed and release the skb buffer
223 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
224 }
225
226
227 return(Status);
228
229}
230
231
232USHORT RtmpUSB_WriteSingleTxResource(
233 IN PRTMP_ADAPTER pAd,
234 IN TX_BLK *pTxBlk,
235 IN BOOLEAN bIsLast,
236 OUT USHORT *FreeNumber)
237{
238 HT_TX_CONTEXT *pHTTXContext;
239 USHORT hwHdrLen;
240 UINT32 fillOffset;
241 TXINFO_STRUC *pTxInfo;
242 TXWI_STRUC *pTxWI;
243 PUCHAR pWirelessPacket;
244 UCHAR QueIdx;
245 unsigned long IrqFlags;
246 NDIS_STATUS Status;
247 UINT32 USBDMApktLen = 0, DMAHdrLen, padding;
248 BOOLEAN bTxQLastRound = FALSE;
249
250 // For USB, didn't need PCI_MAP_SINGLE()
251 //SrcBufPA = PCI_MAP_SINGLE(pAd, (char *) pTxBlk->pSrcBufData, pTxBlk->SrcBufLen, PCI_DMA_TODEVICE);
252
253
254 //
255 // get Tx Ring Resource & Dma Buffer address
256 //
257 QueIdx = pTxBlk->QueIdx;
258
259 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
260 pHTTXContext = &pAd->TxContext[QueIdx];
261 fillOffset = pHTTXContext->CurWritePosition;
262
263
264
265 // Check ring full.
266 Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
267 if(Status == NDIS_STATUS_SUCCESS)
268 {
269 pHTTXContext->bCurWriting = TRUE;
270
271 pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]);
272 pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]);
273
274 // Reserve space for 8 bytes padding.
275 if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition))
276 {
277 pHTTXContext->ENextBulkOutPosition += 8;
278 pHTTXContext->CurWritePosition += 8;
279 fillOffset += 8;
280 }
281 pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
282
283 pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
284
285 // copy TXWI + WLAN Header + LLC into DMA Header Buffer
286 //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
287 hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
288
289 // Build our URB for USBD
290 DMAHdrLen = TXWI_SIZE + hwHdrLen;
291 USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen;
292 padding = (4 - (USBDMApktLen % 4)) & 0x03; // round up to 4 byte alignment
293 USBDMApktLen += padding;
294
295 pTxBlk->Priv = (TXINFO_SIZE + USBDMApktLen);
296
297 // For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload
298 //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
299#ifdef CONFIG_STA_SUPPORT
300 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
301 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(USBDMApktLen), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE);
302#endif // CONFIG_STA_SUPPORT //
303
304 if ((pHTTXContext->CurWritePosition + 3906 + pTxBlk->Priv) > MAX_TXBULK_LIMIT)
305 {
306 pTxInfo->SwUseLastRound = 1;
307 bTxQLastRound = TRUE;
308 }
309 NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
310#ifdef RT_BIG_ENDIAN
311 RTMPFrameEndianChange(pAd, (PUCHAR)(pWirelessPacket + TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE);
312#endif // RT_BIG_ENDIAN //
313 pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
314
315 // We unlock it here to prevent the first 8 bytes maybe over-writed issue.
316 // 1. First we got CurWritePosition but the first 8 bytes still not write to the pTxcontext.
317 // 2. An interrupt break our routine and handle bulk-out complete.
318 // 3. In the bulk-out compllete, it need to do another bulk-out,
319 // if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition,
320 // but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE.
321 // 4. Interrupt complete.
322 // 5. Our interrupted routine go back and fill the first 8 bytes to pTxContext.
323 // 6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition.
324 // and the packet will wrong.
325 pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
326 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
327
328 NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
329 pWirelessPacket += pTxBlk->SrcBufLen;
330 NdisZeroMemory(pWirelessPacket, padding + 8);
331
332 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
333
334 pHTTXContext->CurWritePosition += pTxBlk->Priv;
335 if (bTxQLastRound)
336 pHTTXContext->CurWritePosition = 8;
337 pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
338
339 pHTTXContext->bCurWriting = FALSE;
340 }
341
342
343 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
344
345
346 // succeed and release the skb buffer
347 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
348
349 return(Status);
350
351}
352
353
354USHORT RtmpUSB_WriteMultiTxResource(
355 IN PRTMP_ADAPTER pAd,
356 IN TX_BLK *pTxBlk,
357 IN UCHAR frameNum,
358 OUT USHORT *FreeNumber)
359{
360 HT_TX_CONTEXT *pHTTXContext;
361 USHORT hwHdrLen; // The hwHdrLen consist of 802.11 header length plus the header padding length.
362 UINT32 fillOffset;
363 TXINFO_STRUC *pTxInfo;
364 TXWI_STRUC *pTxWI;
365 PUCHAR pWirelessPacket = NULL;
366 UCHAR QueIdx;
367 NDIS_STATUS Status;
368 unsigned long IrqFlags;
369 //UINT32 USBDMApktLen = 0, DMAHdrLen, padding;
370
371 //
372 // get Tx Ring Resource & Dma Buffer address
373 //
374 QueIdx = pTxBlk->QueIdx;
375 pHTTXContext = &pAd->TxContext[QueIdx];
376
377 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
378
379 if(frameNum == 0)
380 {
381 // Check if we have enough space for this bulk-out batch.
382 Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
383 if (Status == NDIS_STATUS_SUCCESS)
384 {
385 pHTTXContext->bCurWriting = TRUE;
386
387 pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]);
388 pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]);
389
390
391 // Reserve space for 8 bytes padding.
392 if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition))
393 {
394
395 pHTTXContext->CurWritePosition += 8;
396 pHTTXContext->ENextBulkOutPosition += 8;
397 }
398 fillOffset = pHTTXContext->CurWritePosition;
399 pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
400
401 pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
402
403 //
404 // Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
405 //
406 if (pTxBlk->TxFrameType == TX_AMSDU_FRAME)
407 //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD;
408 hwHdrLen = pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD + pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD;
409 else if (pTxBlk->TxFrameType == TX_RALINK_FRAME)
410 //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD;
411 hwHdrLen = pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD + pTxBlk->HdrPadLen + LENGTH_ARALINK_HEADER_FIELD;
412 else
413 //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
414 hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
415
416 // Update the pTxBlk->Priv.
417 pTxBlk->Priv = TXINFO_SIZE + TXWI_SIZE + hwHdrLen;
418
419 // pTxInfo->USBDMApktLen now just a temp value and will to correct latter.
420 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(pTxBlk->Priv), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE);
421
422 // Copy it.
423 NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, pTxBlk->Priv);
424#ifdef RT_BIG_ENDIAN
425 RTMPFrameEndianChange(pAd, (PUCHAR)(pWirelessPacket+ TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE);
426#endif // RT_BIG_ENDIAN //
427 pHTTXContext->CurWriteRealPos += pTxBlk->Priv;
428 pWirelessPacket += pTxBlk->Priv;
429 }
430 }
431 else
432 { // For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer.
433
434 Status = ((pHTTXContext->bCurWriting == TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE);
435 if (Status == NDIS_STATUS_SUCCESS)
436 {
437 fillOffset = (pHTTXContext->CurWritePosition + pTxBlk->Priv);
438 pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
439
440 //hwHdrLen = pTxBlk->MpduHeaderLen;
441 NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, pTxBlk->MpduHeaderLen);
442 pWirelessPacket += (pTxBlk->MpduHeaderLen);
443 pTxBlk->Priv += pTxBlk->MpduHeaderLen;
444 }
445 else
446 { // It should not happened now unless we are going to shutdown.
447 DBGPRINT(RT_DEBUG_ERROR, ("WriteMultiTxResource():bCurWriting is FALSE when handle sub-sequent frames.\n"));
448 Status = NDIS_STATUS_FAILURE;
449 }
450 }
451
452
453 // We unlock it here to prevent the first 8 bytes maybe over-write issue.
454 // 1. First we got CurWritePosition but the first 8 bytes still not write to the pTxContext.
455 // 2. An interrupt break our routine and handle bulk-out complete.
456 // 3. In the bulk-out compllete, it need to do another bulk-out,
457 // if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition,
458 // but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE.
459 // 4. Interrupt complete.
460 // 5. Our interrupted routine go back and fill the first 8 bytes to pTxContext.
461 // 6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition.
462 // and the packet will wrong.
463 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
464
465 if (Status != NDIS_STATUS_SUCCESS)
466 {
467 DBGPRINT(RT_DEBUG_ERROR,("WriteMultiTxResource: CWPos = %ld, NBOutPos = %ld.\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition));
468 goto done;
469 }
470
471 // Copy the frame content into DMA buffer and update the pTxBlk->Priv
472 NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
473 pWirelessPacket += pTxBlk->SrcBufLen;
474 pTxBlk->Priv += pTxBlk->SrcBufLen;
475
476done:
477 // Release the skb buffer here
478 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
479
480 return(Status);
481
482}
483
484
485VOID RtmpUSB_FinalWriteTxResource(
486 IN PRTMP_ADAPTER pAd,
487 IN TX_BLK *pTxBlk,
488 IN USHORT totalMPDUSize,
489 IN USHORT TxIdx)
490{
491 UCHAR QueIdx;
492 HT_TX_CONTEXT *pHTTXContext;
493 UINT32 fillOffset;
494 TXINFO_STRUC *pTxInfo;
495 TXWI_STRUC *pTxWI;
496 UINT32 USBDMApktLen, padding;
497 unsigned long IrqFlags;
498 PUCHAR pWirelessPacket;
499
500 QueIdx = pTxBlk->QueIdx;
501 pHTTXContext = &pAd->TxContext[QueIdx];
502
503 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
504
505 if (pHTTXContext->bCurWriting == TRUE)
506 {
507 fillOffset = pHTTXContext->CurWritePosition;
508 if (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) || ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition))
509 && (pHTTXContext->bCopySavePad == TRUE))
510 pWirelessPacket = (PUCHAR)(&pHTTXContext->SavedPad[0]);
511 else
512 pWirelessPacket = (PUCHAR)(&pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset]);
513
514 //
515 // Update TxInfo->USBDMApktLen ,
516 // the length = TXWI_SIZE + 802.11_hdr + 802.11_hdr_pad + payload_of_all_batch_frames + Bulk-Out-padding
517 //
518 pTxInfo = (PTXINFO_STRUC)(pWirelessPacket);
519
520 // Calculate the bulk-out padding
521 USBDMApktLen = pTxBlk->Priv - TXINFO_SIZE;
522 padding = (4 - (USBDMApktLen % 4)) & 0x03; // round up to 4 byte alignment
523 USBDMApktLen += padding;
524
525 pTxInfo->USBDMATxPktLen = USBDMApktLen;
526
527 //
528 // Update TXWI->MPDUtotalByteCount ,
529 // the length = 802.11 header + payload_of_all_batch_frames
530 pTxWI= (PTXWI_STRUC)(pWirelessPacket + TXINFO_SIZE);
531 pTxWI->MPDUtotalByteCount = totalMPDUSize;
532
533 //
534 // Update the pHTTXContext->CurWritePosition
535 //
536 pHTTXContext->CurWritePosition += (TXINFO_SIZE + USBDMApktLen);
537 if ((pHTTXContext->CurWritePosition + 3906)> MAX_TXBULK_LIMIT)
538 { // Add 3906 for prevent the NextBulkOut packet size is a A-RALINK/A-MSDU Frame.
539 pHTTXContext->CurWritePosition = 8;
540 pTxInfo->SwUseLastRound = 1;
541 }
542 pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
543
544
545 //
546 // Zero the last padding.
547 //
548 pWirelessPacket = (&pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset + pTxBlk->Priv]);
549 NdisZeroMemory(pWirelessPacket, padding + 8);
550
551 // Finally, set bCurWriting as FALSE
552 pHTTXContext->bCurWriting = FALSE;
553
554 }
555 else
556 { // It should not happened now unless we are going to shutdown.
557 DBGPRINT(RT_DEBUG_ERROR, ("FinalWriteTxResource():bCurWriting is FALSE when handle last frames.\n"));
558 }
559
560 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
561
562}
563
564
565VOID RtmpUSBDataLastTxIdx(
566 IN PRTMP_ADAPTER pAd,
567 IN UCHAR QueIdx,
568 IN USHORT TxIdx)
569{
570 // DO nothing for USB.
571}
572
573
574/*
575 When can do bulk-out:
576 1. TxSwFreeIdx < TX_RING_SIZE;
577 It means has at least one Ring entity is ready for bulk-out, kick it out.
578 2. If TxSwFreeIdx == TX_RING_SIZE
579 Check if the CurWriting flag is FALSE, if it's FALSE, we can do kick out.
580
581*/
582VOID RtmpUSBDataKickOut(
583 IN PRTMP_ADAPTER pAd,
584 IN TX_BLK *pTxBlk,
585 IN UCHAR QueIdx)
586{
587 RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
588 RTUSBKickBulkOut(pAd);
589
590}
591
592
593/*
594 Must be run in Interrupt context
595 This function handle RT2870 specific TxDesc and cpu index update and kick the packet out.
596 */
597int RtmpUSBMgmtKickOut(
598 IN RTMP_ADAPTER *pAd,
599 IN UCHAR QueIdx,
600 IN PNDIS_PACKET pPacket,
601 IN PUCHAR pSrcBufVA,
602 IN UINT SrcBufLen)
603{
604 PTXINFO_STRUC pTxInfo;
605 ULONG BulkOutSize;
606 UCHAR padLen;
607 PUCHAR pDest;
608 ULONG SwIdx = pAd->MgmtRing.TxCpuIdx;
609 PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[SwIdx].AllocVa;
610 unsigned long IrqFlags;
611
612
613 pTxInfo = (PTXINFO_STRUC)(pSrcBufVA);
614
615 // Build our URB for USBD
616 BulkOutSize = SrcBufLen;
617 BulkOutSize = (BulkOutSize + 3) & (~3);
618 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(BulkOutSize - TXINFO_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
619
620 BulkOutSize += 4; // Always add 4 extra bytes at every packet.
621
622 // If BulkOutSize is multiple of BulkOutMaxPacketSize, add extra 4 bytes again.
623 if ((BulkOutSize % pAd->BulkOutMaxPacketSize) == 0)
624 BulkOutSize += 4;
625
626 padLen = BulkOutSize - SrcBufLen;
627 ASSERT((padLen <= RTMP_PKT_TAIL_PADDING));
628
629 // Now memzero all extra padding bytes.
630 pDest = (PUCHAR)(pSrcBufVA + SrcBufLen);
631 skb_put(GET_OS_PKT_TYPE(pPacket), padLen);
632 NdisZeroMemory(pDest, padLen);
633
634 RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
635
636 pAd->MgmtRing.Cell[pAd->MgmtRing.TxCpuIdx].pNdisPacket = pPacket;
637 pMLMEContext->TransferBuffer = (PTX_BUFFER)(GET_OS_PKT_DATAPTR(pPacket));
638
639 // Length in TxInfo should be 8 less than bulkout size.
640 pMLMEContext->BulkOutSize = BulkOutSize;
641 pMLMEContext->InUse = TRUE;
642 pMLMEContext->bWaitingBulkOut = TRUE;
643
644
645 //for debug
646 //hex_dump("RtmpUSBMgmtKickOut", &pMLMEContext->TransferBuffer->field.WirelessPacket[0], (pMLMEContext->BulkOutSize > 16 ? 16 : pMLMEContext->BulkOutSize));
647
648 //pAd->RalinkCounters.KickTxCount++;
649 //pAd->RalinkCounters.OneSecTxDoneCount++;
650
651 //if (pAd->MgmtRing.TxSwFreeIdx == MGMT_RING_SIZE)
652 // needKickOut = TRUE;
653
654 // Decrease the TxSwFreeIdx and Increase the TX_CTX_IDX
655 pAd->MgmtRing.TxSwFreeIdx--;
656 INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);
657
658 RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);
659
660 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
661 //if (needKickOut)
662 RTUSBKickBulkOut(pAd);
663
664 return 0;
665}
666
667
668VOID RtmpUSBNullFrameKickOut(
669 IN RTMP_ADAPTER *pAd,
670 IN UCHAR QueIdx,
671 IN UCHAR *pNullFrame,
672 IN UINT32 frameLen)
673{
674 if (pAd->NullContext.InUse == FALSE)
675 {
676 PTX_CONTEXT pNullContext;
677 PTXINFO_STRUC pTxInfo;
678 PTXWI_STRUC pTxWI;
679 PUCHAR pWirelessPkt;
680
681 pNullContext = &(pAd->NullContext);
682
683 // Set the in use bit
684 pNullContext->InUse = TRUE;
685 pWirelessPkt = (PUCHAR)&pNullContext->TransferBuffer->field.WirelessPacket[0];
686
687 RTMPZeroMemory(&pWirelessPkt[0], 100);
688 pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[0];
689 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(HEADER_802_11)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
690 pTxInfo->QSEL = FIFO_EDCA;
691 pTxWI = (PTXWI_STRUC)&pWirelessPkt[TXINFO_SIZE];
692 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(HEADER_802_11)),
693 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
694#ifdef RT_BIG_ENDIAN
695 RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
696#endif // RT_BIG_ENDIAN //
697
698 RTMPMoveMemory(&pWirelessPkt[TXWI_SIZE+TXINFO_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11));
699#ifdef RT_BIG_ENDIAN
700 RTMPFrameEndianChange(pAd, (PUCHAR)&pWirelessPkt[TXINFO_SIZE + TXWI_SIZE], DIR_WRITE, FALSE);
701#endif // RT_BIG_ENDIAN //
702 pAd->NullContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;
703
704 // Fill out frame length information for global Bulk out arbitor
705 //pNullContext->BulkOutSize = TransferBufferLength;
706 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - send NULL Frame @%d Mbps...\n", RateIdToMbps[pAd->CommonCfg.TxRate]));
707 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);
708
709 // Kick bulk out
710 RTUSBKickBulkOut(pAd);
711 }
712
713}
714
715#ifdef CONFIG_STA_SUPPORT
716/*
717 ========================================================================
718
719 Routine Description:
720 Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound
721
722 Arguments:
723 pRxD Pointer to the Rx descriptor
724
725 Return Value:
726 NDIS_STATUS_SUCCESS No err
727 NDIS_STATUS_FAILURE Error
728
729 Note:
730
731 ========================================================================
732*/
733NDIS_STATUS RTMPCheckRxError(
734 IN PRTMP_ADAPTER pAd,
735 IN PHEADER_802_11 pHeader,
736 IN PRXWI_STRUC pRxWI,
737 IN PRT28XX_RXD_STRUC pRxINFO)
738{
739 PCIPHER_KEY pWpaKey;
740 INT dBm;
741
742 if (pAd->bPromiscuous == TRUE)
743 return(NDIS_STATUS_SUCCESS);
744 if(pRxINFO == NULL)
745 return(NDIS_STATUS_FAILURE);
746
747 // Phy errors & CRC errors
748 if (pRxINFO->Crc)
749 {
750 // Check RSSI for Noise Hist statistic collection.
751 dBm = (INT) (pRxWI->RSSI0) - pAd->BbpRssiToDbmDelta;
752 if (dBm <= -87)
753 pAd->StaCfg.RPIDensity[0] += 1;
754 else if (dBm <= -82)
755 pAd->StaCfg.RPIDensity[1] += 1;
756 else if (dBm <= -77)
757 pAd->StaCfg.RPIDensity[2] += 1;
758 else if (dBm <= -72)
759 pAd->StaCfg.RPIDensity[3] += 1;
760 else if (dBm <= -67)
761 pAd->StaCfg.RPIDensity[4] += 1;
762 else if (dBm <= -62)
763 pAd->StaCfg.RPIDensity[5] += 1;
764 else if (dBm <= -57)
765 pAd->StaCfg.RPIDensity[6] += 1;
766 else if (dBm > -57)
767 pAd->StaCfg.RPIDensity[7] += 1;
768
769 return(NDIS_STATUS_FAILURE);
770 }
771
772 // Add Rx size to channel load counter, we should ignore error counts
773 pAd->StaCfg.CLBusyBytes += (pRxWI->MPDUtotalByteCount+ 14);
774
775 // Drop ToDs promiscous frame, it is opened due to CCX 2 channel load statistics
776 if (pHeader->FC.ToDs)
777 {
778 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Err;FC.ToDs\n"));
779 return NDIS_STATUS_FAILURE;
780 }
781
782 // Paul 04-03 for OFDM Rx length issue
783 if (pRxWI->MPDUtotalByteCount > MAX_AGGREGATION_SIZE)
784 {
785 DBGPRINT_RAW(RT_DEBUG_ERROR, ("received packet too long\n"));
786 return NDIS_STATUS_FAILURE;
787 }
788
789 // Drop not U2M frames, cant's drop here because we will drop beacon in this case
790 // I am kind of doubting the U2M bit operation
791 // if (pRxD->U2M == 0)
792 // return(NDIS_STATUS_FAILURE);
793
794 // drop decyption fail frame
795 if (pRxINFO->Decrypted && pRxINFO->CipherErr)
796 {
797
798 //
799 // MIC Error
800 //
801 if ((pRxINFO->CipherErr == 2) && pRxINFO->MyBss)
802 {
803 pWpaKey = &pAd->SharedKey[BSS0][pRxWI->KeyIndex];
804 RTMPReportMicError(pAd, pWpaKey);
805 DBGPRINT_RAW(RT_DEBUG_ERROR,("Rx MIC Value error\n"));
806 }
807
808 if (pRxINFO->Decrypted &&
809 (pAd->SharedKey[BSS0][pRxWI->KeyIndex].CipherAlg == CIPHER_AES) &&
810 (pHeader->Sequence == pAd->FragFrame.Sequence))
811 {
812 //
813 // Acceptable since the First FragFrame no CipherErr problem.
814 //
815 return(NDIS_STATUS_SUCCESS);
816 }
817
818 return(NDIS_STATUS_FAILURE);
819 }
820
821 return(NDIS_STATUS_SUCCESS);
822}
823
824VOID RT28xxUsbStaAsicForceWakeup(
825 IN PRTMP_ADAPTER pAd,
826 IN BOOLEAN bFromTx)
827{
828 AUTO_WAKEUP_STRUC AutoWakeupCfg;
829
830 AutoWakeupCfg.word = 0;
831 RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
832
833 AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
834
835 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
836}
837
838VOID RT28xxUsbStaAsicSleepThenAutoWakeup(
839 IN PRTMP_ADAPTER pAd,
840 IN USHORT TbttNumToNextWakeUp)
841{
842 AUTO_WAKEUP_STRUC AutoWakeupCfg;
843
844 // we have decided to SLEEP, so at least do it for a BEACON period.
845 if (TbttNumToNextWakeUp == 0)
846 TbttNumToNextWakeUp = 1;
847
848 AutoWakeupCfg.word = 0;
849 RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
850
851 AutoWakeupCfg.field.NumofSleepingTbtt = TbttNumToNextWakeUp - 1;
852 AutoWakeupCfg.field.EnableAutoWakeup = 1;
853 AutoWakeupCfg.field.AutoLeadTime = 5;
854 RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
855
856 AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02); // send POWER-SAVE command to MCU. Timeout 40us.
857
858 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE);
859
860}
861#endif // CONFIG_STA_SUPPORT //
862
863VOID RT28xxUsbMlmeRadioOn(
864 IN PRTMP_ADAPTER pAd)
865{
866 DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOn()\n"));
867
868 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
869 return;
870
871#ifdef CONFIG_STA_SUPPORT
872 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
873 {
874 AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
875 RTMPusecDelay(10000);
876 }
877#endif // CONFIG_STA_SUPPORT //
878 NICResetFromError(pAd);
879
880 // Enable Tx/Rx
881 RTMPEnableRxTx(pAd);
882
883#ifdef RT3070
884 if (IS_RT3071(pAd))
885 {
886 RT30xxReverseRFSleepModeSetup(pAd);
887 }
888#endif // RT3070 //
889
890 // Clear Radio off flag
891 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
892
893#ifdef CONFIG_STA_SUPPORT
894 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
895 RTUSBBulkReceive(pAd);
896#endif // CONFIG_STA_SUPPORT //
897
898 // Set LED
899 RTMPSetLED(pAd, LED_RADIO_ON);
900}
901
902VOID RT28xxUsbMlmeRadioOFF(
903 IN PRTMP_ADAPTER pAd)
904{
905 WPDMA_GLO_CFG_STRUC GloCfg;
906 UINT32 Value, i;
907
908 DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOFF()\n"));
909
910 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
911 return;
912
913 // Set LED
914 RTMPSetLED(pAd, LED_RADIO_OFF);
915 // Set Radio off flag
916 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
917
918#ifdef CONFIG_STA_SUPPORT
919 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
920 {
921 // Link down first if any association exists
922 if (INFRA_ON(pAd) || ADHOC_ON(pAd))
923 LinkDown(pAd, FALSE);
924 RTMPusecDelay(10000);
925
926 //==========================================
927 // Clean up old bss table
928 BssTableInit(&pAd->ScanTab);
929 }
930#endif // CONFIG_STA_SUPPORT //
931
932
933 if (pAd->CommonCfg.BBPCurrentBW == BW_40)
934 {
935 // Must using 40MHz.
936 AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel);
937 }
938 else
939 {
940 // Must using 20MHz.
941 AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
942 }
943
944 // Disable Tx/Rx DMA
945 RTUSBReadMACRegister(pAd, WPDMA_GLO_CFG, &GloCfg.word); // disable DMA
946 GloCfg.field.EnableTxDMA = 0;
947 GloCfg.field.EnableRxDMA = 0;
948 RTUSBWriteMACRegister(pAd, WPDMA_GLO_CFG, GloCfg.word); // abort all TX rings
949
950 // Waiting for DMA idle
951 i = 0;
952 do
953 {
954 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
955 if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
956 break;
957
958 RTMPusecDelay(1000);
959 }while (i++ < 100);
960
961 // Disable MAC Tx/Rx
962 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
963 Value &= (0xfffffff3);
964 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
965
966 // MAC_SYS_CTRL => value = 0x0 => 40mA
967 //RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0);
968
969 // PWR_PIN_CFG => value = 0x0 => 40mA
970 //RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0);
971
972 // TX_PIN_CFG => value = 0x0 => 20mA
973 //RTMP_IO_WRITE32(pAd, TX_PIN_CFG, 0);
974
975#ifdef CONFIG_STA_SUPPORT
976 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
977 AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
978#endif // CONFIG_STA_SUPPORT //
979}
980
diff --git a/drivers/staging/rt3070/common/cmm_info.c b/drivers/staging/rt3070/common/cmm_info.c
new file mode 100644
index 000000000000..54cb1a35f7bf
--- /dev/null
+++ b/drivers/staging/rt3070/common/cmm_info.c
@@ -0,0 +1,3395 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26*/
27
28#include "../rt_config.h"
29
30INT Show_SSID_Proc(
31 IN PRTMP_ADAPTER pAd,
32 OUT PUCHAR pBuf);
33
34INT Show_WirelessMode_Proc(
35 IN PRTMP_ADAPTER pAd,
36 OUT PUCHAR pBuf);
37
38INT Show_TxBurst_Proc(
39 IN PRTMP_ADAPTER pAd,
40 OUT PUCHAR pBuf);
41
42INT Show_TxPreamble_Proc(
43 IN PRTMP_ADAPTER pAd,
44 OUT PUCHAR pBuf);
45
46INT Show_TxPower_Proc(
47 IN PRTMP_ADAPTER pAd,
48 OUT PUCHAR pBuf);
49
50INT Show_Channel_Proc(
51 IN PRTMP_ADAPTER pAd,
52 OUT PUCHAR pBuf);
53
54INT Show_BGProtection_Proc(
55 IN PRTMP_ADAPTER pAd,
56 OUT PUCHAR pBuf);
57
58INT Show_RTSThreshold_Proc(
59 IN PRTMP_ADAPTER pAd,
60 OUT PUCHAR pBuf);
61
62INT Show_FragThreshold_Proc(
63 IN PRTMP_ADAPTER pAd,
64 OUT PUCHAR pBuf);
65
66#ifdef DOT11_N_SUPPORT
67INT Show_HtBw_Proc(
68 IN PRTMP_ADAPTER pAd,
69 OUT PUCHAR pBuf);
70
71INT Show_HtMcs_Proc(
72 IN PRTMP_ADAPTER pAd,
73 OUT PUCHAR pBuf);
74
75INT Show_HtGi_Proc(
76 IN PRTMP_ADAPTER pAd,
77 OUT PUCHAR pBuf);
78
79INT Show_HtOpMode_Proc(
80 IN PRTMP_ADAPTER pAd,
81 OUT PUCHAR pBuf);
82
83INT Show_HtExtcha_Proc(
84 IN PRTMP_ADAPTER pAd,
85 OUT PUCHAR pBuf);
86
87INT Show_HtMpduDensity_Proc(
88 IN PRTMP_ADAPTER pAd,
89 OUT PUCHAR pBuf);
90
91INT Show_HtBaWinSize_Proc(
92 IN PRTMP_ADAPTER pAd,
93 OUT PUCHAR pBuf);
94
95INT Show_HtRdg_Proc(
96 IN PRTMP_ADAPTER pAd,
97 OUT PUCHAR pBuf);
98
99INT Show_HtAmsdu_Proc(
100 IN PRTMP_ADAPTER pAd,
101 OUT PUCHAR pBuf);
102
103INT Show_HtAutoBa_Proc(
104 IN PRTMP_ADAPTER pAd,
105 OUT PUCHAR pBuf);
106#endif // DOT11_N_SUPPORT //
107
108INT Show_CountryRegion_Proc(
109 IN PRTMP_ADAPTER pAd,
110 OUT PUCHAR pBuf);
111
112INT Show_CountryRegionABand_Proc(
113 IN PRTMP_ADAPTER pAd,
114 OUT PUCHAR pBuf);
115
116INT Show_CountryCode_Proc(
117 IN PRTMP_ADAPTER pAd,
118 OUT PUCHAR pBuf);
119
120#ifdef AGGREGATION_SUPPORT
121INT Show_PktAggregate_Proc(
122 IN PRTMP_ADAPTER pAd,
123 OUT PUCHAR pBuf);
124#endif // AGGREGATION_SUPPORT //
125
126#ifdef WMM_SUPPORT
127INT Show_WmmCapable_Proc(
128 IN PRTMP_ADAPTER pAd,
129 OUT PUCHAR pBuf);
130#endif // WMM_SUPPORT //
131
132INT Show_IEEE80211H_Proc(
133 IN PRTMP_ADAPTER pAd,
134 OUT PUCHAR pBuf);
135
136#ifdef CONFIG_STA_SUPPORT
137INT Show_NetworkType_Proc(
138 IN PRTMP_ADAPTER pAd,
139 OUT PUCHAR pBuf);
140#endif // CONFIG_STA_SUPPORT //
141
142INT Show_AuthMode_Proc(
143 IN PRTMP_ADAPTER pAd,
144 OUT PUCHAR pBuf);
145
146INT Show_EncrypType_Proc(
147 IN PRTMP_ADAPTER pAd,
148 OUT PUCHAR pBuf);
149
150INT Show_DefaultKeyID_Proc(
151 IN PRTMP_ADAPTER pAd,
152 OUT PUCHAR pBuf);
153
154INT Show_Key1_Proc(
155 IN PRTMP_ADAPTER pAd,
156 OUT PUCHAR pBuf);
157
158INT Show_Key2_Proc(
159 IN PRTMP_ADAPTER pAd,
160 OUT PUCHAR pBuf);
161
162INT Show_Key3_Proc(
163 IN PRTMP_ADAPTER pAd,
164 OUT PUCHAR pBuf);
165
166INT Show_Key4_Proc(
167 IN PRTMP_ADAPTER pAd,
168 OUT PUCHAR pBuf);
169
170INT Show_WPAPSK_Proc(
171 IN PRTMP_ADAPTER pAd,
172 OUT PUCHAR pBuf);
173
174static struct {
175 CHAR *name;
176 INT (*show_proc)(PRTMP_ADAPTER pAdapter, PUCHAR arg);
177} *PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC, RTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC[] = {
178 {"SSID", Show_SSID_Proc},
179 {"WirelessMode", Show_WirelessMode_Proc},
180 {"TxBurst", Show_TxBurst_Proc},
181 {"TxPreamble", Show_TxPreamble_Proc},
182 {"TxPower", Show_TxPower_Proc},
183 {"Channel", Show_Channel_Proc},
184 {"BGProtection", Show_BGProtection_Proc},
185 {"RTSThreshold", Show_RTSThreshold_Proc},
186 {"FragThreshold", Show_FragThreshold_Proc},
187#ifdef DOT11_N_SUPPORT
188 {"HtBw", Show_HtBw_Proc},
189 {"HtMcs", Show_HtMcs_Proc},
190 {"HtGi", Show_HtGi_Proc},
191 {"HtOpMode", Show_HtOpMode_Proc},
192 {"HtExtcha", Show_HtExtcha_Proc},
193 {"HtMpduDensity", Show_HtMpduDensity_Proc},
194 {"HtBaWinSize", Show_HtBaWinSize_Proc},
195 {"HtRdg", Show_HtRdg_Proc},
196 {"HtAmsdu", Show_HtAmsdu_Proc},
197 {"HtAutoBa", Show_HtAutoBa_Proc},
198#endif // DOT11_N_SUPPORT //
199 {"CountryRegion", Show_CountryRegion_Proc},
200 {"CountryRegionABand", Show_CountryRegionABand_Proc},
201 {"CountryCode", Show_CountryCode_Proc},
202#ifdef AGGREGATION_SUPPORT
203 {"PktAggregate", Show_PktAggregate_Proc},
204#endif
205
206#ifdef WMM_SUPPORT
207 {"WmmCapable", Show_WmmCapable_Proc},
208#endif
209 {"IEEE80211H", Show_IEEE80211H_Proc},
210#ifdef CONFIG_STA_SUPPORT
211 {"NetworkType", Show_NetworkType_Proc},
212#endif // CONFIG_STA_SUPPORT //
213 {"AuthMode", Show_AuthMode_Proc},
214 {"EncrypType", Show_EncrypType_Proc},
215 {"DefaultKeyID", Show_DefaultKeyID_Proc},
216 {"Key1", Show_Key1_Proc},
217 {"Key2", Show_Key2_Proc},
218 {"Key3", Show_Key3_Proc},
219 {"Key4", Show_Key4_Proc},
220 {"WPAPSK", Show_WPAPSK_Proc},
221 {NULL, NULL}
222};
223
224/*
225 ==========================================================================
226 Description:
227 Get Driver version.
228
229 Return:
230 ==========================================================================
231*/
232INT Set_DriverVersion_Proc(
233 IN PRTMP_ADAPTER pAd,
234 IN PUCHAR arg)
235{
236
237#ifdef CONFIG_STA_SUPPORT
238 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
239 DBGPRINT(RT_DEBUG_TRACE, ("Driver version-%s\n", STA_DRIVER_VERSION));
240#endif // CONFIG_STA_SUPPORT //
241
242 return TRUE;
243}
244
245/*
246 ==========================================================================
247 Description:
248 Set Country Region.
249 This command will not work, if the field of CountryRegion in eeprom is programmed.
250 Return:
251 TRUE if all parameters are OK, FALSE otherwise
252 ==========================================================================
253*/
254INT Set_CountryRegion_Proc(
255 IN PRTMP_ADAPTER pAd,
256 IN PUCHAR arg)
257{
258 ULONG region;
259
260 region = simple_strtol(arg, 0, 10);
261
262#ifdef EXT_BUILD_CHANNEL_LIST
263 return -EOPNOTSUPP;
264#endif // EXT_BUILD_CHANNEL_LIST //
265
266 // Country can be set only when EEPROM not programmed
267 if (pAd->CommonCfg.CountryRegion & 0x80)
268 {
269 DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegion_Proc::parameter of CountryRegion in eeprom is programmed \n"));
270 return FALSE;
271 }
272
273 if((region >= 0) && (region <= REGION_MAXIMUM_BG_BAND))
274 {
275 pAd->CommonCfg.CountryRegion = (UCHAR) region;
276 }
277 else if (region == REGION_31_BG_BAND)
278 {
279 pAd->CommonCfg.CountryRegion = (UCHAR) region;
280 }
281 else
282 {
283 DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegion_Proc::parameters out of range\n"));
284 return FALSE;
285 }
286
287 // if set country region, driver needs to be reset
288 BuildChannelList(pAd);
289
290 DBGPRINT(RT_DEBUG_TRACE, ("Set_CountryRegion_Proc::(CountryRegion=%d)\n", pAd->CommonCfg.CountryRegion));
291
292 return TRUE;
293}
294
295/*
296 ==========================================================================
297 Description:
298 Set Country Region for A band.
299 This command will not work, if the field of CountryRegion in eeprom is programmed.
300 Return:
301 TRUE if all parameters are OK, FALSE otherwise
302 ==========================================================================
303*/
304INT Set_CountryRegionABand_Proc(
305 IN PRTMP_ADAPTER pAd,
306 IN PUCHAR arg)
307{
308 ULONG region;
309
310 region = simple_strtol(arg, 0, 10);
311
312#ifdef EXT_BUILD_CHANNEL_LIST
313 return -EOPNOTSUPP;
314#endif // EXT_BUILD_CHANNEL_LIST //
315
316 // Country can be set only when EEPROM not programmed
317 if (pAd->CommonCfg.CountryRegionForABand & 0x80)
318 {
319 DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegionABand_Proc::parameter of CountryRegion in eeprom is programmed \n"));
320 return FALSE;
321 }
322
323 if((region >= 0) && (region <= REGION_MAXIMUM_A_BAND))
324 {
325 pAd->CommonCfg.CountryRegionForABand = (UCHAR) region;
326 }
327 else
328 {
329 DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegionABand_Proc::parameters out of range\n"));
330 return FALSE;
331 }
332
333 // if set country region, driver needs to be reset
334 BuildChannelList(pAd);
335
336 DBGPRINT(RT_DEBUG_TRACE, ("Set_CountryRegionABand_Proc::(CountryRegion=%d)\n", pAd->CommonCfg.CountryRegionForABand));
337
338 return TRUE;
339}
340
341/*
342 ==========================================================================
343 Description:
344 Set Wireless Mode
345 Return:
346 TRUE if all parameters are OK, FALSE otherwise
347 ==========================================================================
348*/
349INT Set_WirelessMode_Proc(
350 IN PRTMP_ADAPTER pAd,
351 IN PUCHAR arg)
352{
353 ULONG WirelessMode;
354 INT success = TRUE;
355
356 WirelessMode = simple_strtol(arg, 0, 10);
357
358
359#ifdef CONFIG_STA_SUPPORT
360 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
361 {
362 INT MaxPhyMode = PHY_11G;
363
364#ifdef DOT11_N_SUPPORT
365 MaxPhyMode = PHY_11N_5G;
366#endif // DOT11_N_SUPPORT //
367
368 if (WirelessMode <= MaxPhyMode)
369 {
370 RTMPSetPhyMode(pAd, WirelessMode);
371#ifdef DOT11_N_SUPPORT
372 if (WirelessMode >= PHY_11ABGN_MIXED)
373 {
374 pAd->CommonCfg.BACapability.field.AutoBA = TRUE;
375 pAd->CommonCfg.REGBACapability.field.AutoBA = TRUE;
376 }
377 else
378 {
379 pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
380 pAd->CommonCfg.REGBACapability.field.AutoBA = FALSE;
381 }
382#endif // DOT11_N_SUPPORT //
383 // Set AdhocMode rates
384 if (pAd->StaCfg.BssType == BSS_ADHOC)
385 {
386 MlmeUpdateTxRates(pAd, FALSE, 0);
387 MakeIbssBeacon(pAd); // re-build BEACON frame
388 AsicEnableIbssSync(pAd); // copy to on-chip memory
389 }
390 }
391 else
392 {
393 success = FALSE;
394 }
395 }
396#endif // CONFIG_STA_SUPPORT //
397
398 // it is needed to set SSID to take effect
399 if (success == TRUE)
400 {
401#ifdef DOT11_N_SUPPORT
402 SetCommonHT(pAd);
403#endif // DOT11_N_SUPPORT //
404 DBGPRINT(RT_DEBUG_TRACE, ("Set_WirelessMode_Proc::(=%ld)\n", WirelessMode));
405 }
406 else
407 {
408 DBGPRINT(RT_DEBUG_ERROR, ("Set_WirelessMode_Proc::parameters out of range\n"));
409 }
410
411 return success;
412}
413
414/*
415 ==========================================================================
416 Description:
417 Set Channel
418 Return:
419 TRUE if all parameters are OK, FALSE otherwise
420 ==========================================================================
421*/
422INT Set_Channel_Proc(
423 IN PRTMP_ADAPTER pAd,
424 IN PUCHAR arg)
425{
426 INT success = TRUE;
427 UCHAR Channel;
428
429 Channel = (UCHAR) simple_strtol(arg, 0, 10);
430
431 // check if this channel is valid
432 if (ChannelSanity(pAd, Channel) == TRUE)
433 {
434#ifdef CONFIG_STA_SUPPORT
435 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
436 {
437 pAd->CommonCfg.Channel = Channel;
438
439 if (MONITOR_ON(pAd))
440 {
441#ifdef DOT11_N_SUPPORT
442 N_ChannelCheck(pAd);
443 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
444 pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
445 {
446 N_SetCenCh(pAd);
447 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
448 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
449 DBGPRINT(RT_DEBUG_TRACE, ("BW_40, control_channel(%d), CentralChannel(%d) \n",
450 pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
451 }
452 else
453#endif // DOT11_N_SUPPORT //
454 {
455 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
456 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
457 DBGPRINT(RT_DEBUG_TRACE, ("BW_20, Channel(%d)\n", pAd->CommonCfg.Channel));
458 }
459 }
460 }
461#endif // CONFIG_STA_SUPPORT //
462 success = TRUE;
463 }
464 else
465 {
466
467#ifdef CONFIG_STA_SUPPORT
468 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
469 success = FALSE;
470#endif // CONFIG_STA_SUPPORT //
471 }
472
473
474 if (success == TRUE)
475 DBGPRINT(RT_DEBUG_TRACE, ("Set_Channel_Proc::(Channel=%d)\n", pAd->CommonCfg.Channel));
476
477 return success;
478}
479
480/*
481 ==========================================================================
482 Description:
483 Set Short Slot Time Enable or Disable
484 Return:
485 TRUE if all parameters are OK, FALSE otherwise
486 ==========================================================================
487*/
488INT Set_ShortSlot_Proc(
489 IN PRTMP_ADAPTER pAd,
490 IN PUCHAR arg)
491{
492 ULONG ShortSlot;
493
494 ShortSlot = simple_strtol(arg, 0, 10);
495
496 if (ShortSlot == 1)
497 pAd->CommonCfg.bUseShortSlotTime = TRUE;
498 else if (ShortSlot == 0)
499 pAd->CommonCfg.bUseShortSlotTime = FALSE;
500 else
501 return FALSE; //Invalid argument
502
503 DBGPRINT(RT_DEBUG_TRACE, ("Set_ShortSlot_Proc::(ShortSlot=%d)\n", pAd->CommonCfg.bUseShortSlotTime));
504
505 return TRUE;
506}
507
508/*
509 ==========================================================================
510 Description:
511 Set Tx power
512 Return:
513 TRUE if all parameters are OK, FALSE otherwise
514 ==========================================================================
515*/
516INT Set_TxPower_Proc(
517 IN PRTMP_ADAPTER pAd,
518 IN PUCHAR arg)
519{
520 ULONG TxPower;
521 INT success = FALSE;
522
523 TxPower = (ULONG) simple_strtol(arg, 0, 10);
524 if (TxPower <= 100)
525 {
526
527#ifdef CONFIG_STA_SUPPORT
528 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
529 {
530 pAd->CommonCfg.TxPowerDefault = TxPower;
531 pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
532 }
533#endif // CONFIG_STA_SUPPORT //
534 success = TRUE;
535 }
536 else
537 success = FALSE;
538
539 DBGPRINT(RT_DEBUG_TRACE, ("Set_TxPower_Proc::(TxPowerPercentage=%ld)\n", pAd->CommonCfg.TxPowerPercentage));
540
541 return success;
542}
543
544/*
545 ==========================================================================
546 Description:
547 Set 11B/11G Protection
548 Return:
549 TRUE if all parameters are OK, FALSE otherwise
550 ==========================================================================
551*/
552INT Set_BGProtection_Proc(
553 IN PRTMP_ADAPTER pAd,
554 IN PUCHAR arg)
555{
556 switch (simple_strtol(arg, 0, 10))
557 {
558 case 0: //AUTO
559 pAd->CommonCfg.UseBGProtection = 0;
560 break;
561 case 1: //Always On
562 pAd->CommonCfg.UseBGProtection = 1;
563 break;
564 case 2: //Always OFF
565 pAd->CommonCfg.UseBGProtection = 2;
566 break;
567 default: //Invalid argument
568 return FALSE;
569 }
570
571
572 DBGPRINT(RT_DEBUG_TRACE, ("Set_BGProtection_Proc::(BGProtection=%ld)\n", pAd->CommonCfg.UseBGProtection));
573
574 return TRUE;
575}
576
577/*
578 ==========================================================================
579 Description:
580 Set TxPreamble
581 Return:
582 TRUE if all parameters are OK, FALSE otherwise
583 ==========================================================================
584*/
585INT Set_TxPreamble_Proc(
586 IN PRTMP_ADAPTER pAd,
587 IN PUCHAR arg)
588{
589 RT_802_11_PREAMBLE Preamble;
590
591 Preamble = simple_strtol(arg, 0, 10);
592
593
594 switch (Preamble)
595 {
596 case Rt802_11PreambleShort:
597 pAd->CommonCfg.TxPreamble = Preamble;
598#ifdef CONFIG_STA_SUPPORT
599 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
600 MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
601#endif // CONFIG_STA_SUPPORT //
602 break;
603 case Rt802_11PreambleLong:
604#ifdef CONFIG_STA_SUPPORT
605 case Rt802_11PreambleAuto:
606 // if user wants AUTO, initialize to LONG here, then change according to AP's
607 // capability upon association.
608#endif // CONFIG_STA_SUPPORT //
609 pAd->CommonCfg.TxPreamble = Preamble;
610#ifdef CONFIG_STA_SUPPORT
611 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
612 MlmeSetTxPreamble(pAd, Rt802_11PreambleLong);
613#endif // CONFIG_STA_SUPPORT //
614 break;
615 default: //Invalid argument
616 return FALSE;
617 }
618
619 DBGPRINT(RT_DEBUG_TRACE, ("Set_TxPreamble_Proc::(TxPreamble=%ld)\n", pAd->CommonCfg.TxPreamble));
620
621 return TRUE;
622}
623
624/*
625 ==========================================================================
626 Description:
627 Set RTS Threshold
628 Return:
629 TRUE if all parameters are OK, FALSE otherwise
630 ==========================================================================
631*/
632INT Set_RTSThreshold_Proc(
633 IN PRTMP_ADAPTER pAd,
634 IN PUCHAR arg)
635{
636 NDIS_802_11_RTS_THRESHOLD RtsThresh;
637
638 RtsThresh = simple_strtol(arg, 0, 10);
639
640 if((RtsThresh > 0) && (RtsThresh <= MAX_RTS_THRESHOLD))
641 pAd->CommonCfg.RtsThreshold = (USHORT)RtsThresh;
642#ifdef CONFIG_STA_SUPPORT
643 else if (RtsThresh == 0)
644 pAd->CommonCfg.RtsThreshold = MAX_RTS_THRESHOLD;
645#endif // CONFIG_STA_SUPPORT //
646 else
647 return FALSE; //Invalid argument
648
649 DBGPRINT(RT_DEBUG_TRACE, ("Set_RTSThreshold_Proc::(RTSThreshold=%d)\n", pAd->CommonCfg.RtsThreshold));
650
651 return TRUE;
652}
653
654/*
655 ==========================================================================
656 Description:
657 Set Fragment Threshold
658 Return:
659 TRUE if all parameters are OK, FALSE otherwise
660 ==========================================================================
661*/
662INT Set_FragThreshold_Proc(
663 IN PRTMP_ADAPTER pAd,
664 IN PUCHAR arg)
665{
666 NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh;
667
668 FragThresh = simple_strtol(arg, 0, 10);
669
670 if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD)
671 {
672 //Illegal FragThresh so we set it to default
673 pAd->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD;
674 }
675 else if (FragThresh % 2 == 1)
676 {
677 // The length of each fragment shall always be an even number of octets, except for the last fragment
678 // of an MSDU or MMPDU, which may be either an even or an odd number of octets.
679 pAd->CommonCfg.FragmentThreshold = (USHORT)(FragThresh - 1);
680 }
681 else
682 {
683 pAd->CommonCfg.FragmentThreshold = (USHORT)FragThresh;
684 }
685
686#ifdef CONFIG_STA_SUPPORT
687 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
688 {
689 if (pAd->CommonCfg.FragmentThreshold == MAX_FRAG_THRESHOLD)
690 pAd->CommonCfg.bUseZeroToDisableFragment = TRUE;
691 else
692 pAd->CommonCfg.bUseZeroToDisableFragment = FALSE;
693 }
694#endif // CONFIG_STA_SUPPORT //
695
696 DBGPRINT(RT_DEBUG_TRACE, ("Set_FragThreshold_Proc::(FragThreshold=%d)\n", pAd->CommonCfg.FragmentThreshold));
697
698 return TRUE;
699}
700
701/*
702 ==========================================================================
703 Description:
704 Set TxBurst
705 Return:
706 TRUE if all parameters are OK, FALSE otherwise
707 ==========================================================================
708*/
709INT Set_TxBurst_Proc(
710 IN PRTMP_ADAPTER pAd,
711 IN PUCHAR arg)
712{
713 ULONG TxBurst;
714
715 TxBurst = simple_strtol(arg, 0, 10);
716 if (TxBurst == 1)
717 pAd->CommonCfg.bEnableTxBurst = TRUE;
718 else if (TxBurst == 0)
719 pAd->CommonCfg.bEnableTxBurst = FALSE;
720 else
721 return FALSE; //Invalid argument
722
723 DBGPRINT(RT_DEBUG_TRACE, ("Set_TxBurst_Proc::(TxBurst=%d)\n", pAd->CommonCfg.bEnableTxBurst));
724
725 return TRUE;
726}
727
728#ifdef AGGREGATION_SUPPORT
729/*
730 ==========================================================================
731 Description:
732 Set TxBurst
733 Return:
734 TRUE if all parameters are OK, FALSE otherwise
735 ==========================================================================
736*/
737INT Set_PktAggregate_Proc(
738 IN PRTMP_ADAPTER pAd,
739 IN PUCHAR arg)
740{
741 ULONG aggre;
742
743 aggre = simple_strtol(arg, 0, 10);
744
745 if (aggre == 1)
746 pAd->CommonCfg.bAggregationCapable = TRUE;
747 else if (aggre == 0)
748 pAd->CommonCfg.bAggregationCapable = FALSE;
749 else
750 return FALSE; //Invalid argument
751
752
753 DBGPRINT(RT_DEBUG_TRACE, ("Set_PktAggregate_Proc::(AGGRE=%d)\n", pAd->CommonCfg.bAggregationCapable));
754
755 return TRUE;
756}
757#endif
758
759/*
760 ==========================================================================
761 Description:
762 Set IEEE80211H.
763 This parameter is 1 when needs radar detection, otherwise 0
764 Return:
765 TRUE if all parameters are OK, FALSE otherwise
766 ==========================================================================
767*/
768INT Set_IEEE80211H_Proc(
769 IN PRTMP_ADAPTER pAd,
770 IN PUCHAR arg)
771{
772 ULONG ieee80211h;
773
774 ieee80211h = simple_strtol(arg, 0, 10);
775
776 if (ieee80211h == 1)
777 pAd->CommonCfg.bIEEE80211H = TRUE;
778 else if (ieee80211h == 0)
779 pAd->CommonCfg.bIEEE80211H = FALSE;
780 else
781 return FALSE; //Invalid argument
782
783 DBGPRINT(RT_DEBUG_TRACE, ("Set_IEEE80211H_Proc::(IEEE80211H=%d)\n", pAd->CommonCfg.bIEEE80211H));
784
785 return TRUE;
786}
787
788
789#ifdef DBG
790/*
791 ==========================================================================
792 Description:
793 For Debug information
794 Return:
795 TRUE if all parameters are OK, FALSE otherwise
796 ==========================================================================
797*/
798INT Set_Debug_Proc(
799 IN PRTMP_ADAPTER pAd,
800 IN PUCHAR arg)
801{
802 DBGPRINT(RT_DEBUG_TRACE, ("==> Set_Debug_Proc *******************\n"));
803
804 if(simple_strtol(arg, 0, 10) <= RT_DEBUG_LOUD)
805 RTDebugLevel = simple_strtol(arg, 0, 10);
806
807 DBGPRINT(RT_DEBUG_TRACE, ("<== Set_Debug_Proc(RTDebugLevel = %ld)\n", RTDebugLevel));
808
809 return TRUE;
810}
811#endif
812
813INT Show_DescInfo_Proc(
814 IN PRTMP_ADAPTER pAd,
815 IN PUCHAR arg)
816{
817
818 return TRUE;
819}
820
821/*
822 ==========================================================================
823 Description:
824 Reset statistics counter
825
826 Arguments:
827 pAdapter Pointer to our adapter
828 arg
829
830 Return:
831 TRUE if all parameters are OK, FALSE otherwise
832 ==========================================================================
833*/
834INT Set_ResetStatCounter_Proc(
835 IN PRTMP_ADAPTER pAd,
836 IN PUCHAR arg)
837{
838 //UCHAR i;
839 //MAC_TABLE_ENTRY *pEntry;
840
841 DBGPRINT(RT_DEBUG_TRACE, ("==>Set_ResetStatCounter_Proc\n"));
842
843 // add the most up-to-date h/w raw counters into software counters
844 NICUpdateRawCounters(pAd);
845
846 NdisZeroMemory(&pAd->WlanCounters, sizeof(COUNTER_802_11));
847 NdisZeroMemory(&pAd->Counters8023, sizeof(COUNTER_802_3));
848 NdisZeroMemory(&pAd->RalinkCounters, sizeof(COUNTER_RALINK));
849
850 return TRUE;
851}
852
853BOOLEAN RTMPCheckStrPrintAble(
854 IN CHAR *pInPutStr,
855 IN UCHAR strLen)
856{
857 UCHAR i=0;
858
859 for (i=0; i<strLen; i++)
860 {
861 if ((pInPutStr[i] < 0x21) ||
862 (pInPutStr[i] > 0x7E))
863 return FALSE;
864 }
865
866 return TRUE;
867}
868
869/*
870 ========================================================================
871
872 Routine Description:
873 Remove WPA Key process
874
875 Arguments:
876 pAd Pointer to our adapter
877 pBuf Pointer to the where the key stored
878
879 Return Value:
880 NDIS_SUCCESS Add key successfully
881
882 IRQL = DISPATCH_LEVEL
883
884 Note:
885
886 ========================================================================
887*/
888#ifdef CONFIG_STA_SUPPORT
889VOID RTMPSetDesiredRates(
890 IN PRTMP_ADAPTER pAdapter,
891 IN LONG Rates)
892{
893 NDIS_802_11_RATES aryRates;
894
895 memset(&aryRates, 0x00, sizeof(NDIS_802_11_RATES));
896 switch (pAdapter->CommonCfg.PhyMode)
897 {
898 case PHY_11A: // A only
899 switch (Rates)
900 {
901 case 6000000: //6M
902 aryRates[0] = 0x0c; // 6M
903 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_0;
904 break;
905 case 9000000: //9M
906 aryRates[0] = 0x12; // 9M
907 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_1;
908 break;
909 case 12000000: //12M
910 aryRates[0] = 0x18; // 12M
911 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_2;
912 break;
913 case 18000000: //18M
914 aryRates[0] = 0x24; // 18M
915 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_3;
916 break;
917 case 24000000: //24M
918 aryRates[0] = 0x30; // 24M
919 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_4;
920 break;
921 case 36000000: //36M
922 aryRates[0] = 0x48; // 36M
923 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_5;
924 break;
925 case 48000000: //48M
926 aryRates[0] = 0x60; // 48M
927 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_6;
928 break;
929 case 54000000: //54M
930 aryRates[0] = 0x6c; // 54M
931 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_7;
932 break;
933 case -1: //Auto
934 default:
935 aryRates[0] = 0x6c; // 54Mbps
936 aryRates[1] = 0x60; // 48Mbps
937 aryRates[2] = 0x48; // 36Mbps
938 aryRates[3] = 0x30; // 24Mbps
939 aryRates[4] = 0x24; // 18M
940 aryRates[5] = 0x18; // 12M
941 aryRates[6] = 0x12; // 9M
942 aryRates[7] = 0x0c; // 6M
943 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
944 break;
945 }
946 break;
947 case PHY_11BG_MIXED: // B/G Mixed
948 case PHY_11B: // B only
949 case PHY_11ABG_MIXED: // A/B/G Mixed
950 default:
951 switch (Rates)
952 {
953 case 1000000: //1M
954 aryRates[0] = 0x02;
955 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_0;
956 break;
957 case 2000000: //2M
958 aryRates[0] = 0x04;
959 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_1;
960 break;
961 case 5000000: //5.5M
962 aryRates[0] = 0x0b; // 5.5M
963 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_2;
964 break;
965 case 11000000: //11M
966 aryRates[0] = 0x16; // 11M
967 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_3;
968 break;
969 case 6000000: //6M
970 aryRates[0] = 0x0c; // 6M
971 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_0;
972 break;
973 case 9000000: //9M
974 aryRates[0] = 0x12; // 9M
975 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_1;
976 break;
977 case 12000000: //12M
978 aryRates[0] = 0x18; // 12M
979 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_2;
980 break;
981 case 18000000: //18M
982 aryRates[0] = 0x24; // 18M
983 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_3;
984 break;
985 case 24000000: //24M
986 aryRates[0] = 0x30; // 24M
987 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_4;
988 break;
989 case 36000000: //36M
990 aryRates[0] = 0x48; // 36M
991 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_5;
992 break;
993 case 48000000: //48M
994 aryRates[0] = 0x60; // 48M
995 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_6;
996 break;
997 case 54000000: //54M
998 aryRates[0] = 0x6c; // 54M
999 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_7;
1000 break;
1001 case -1: //Auto
1002 default:
1003 if (pAdapter->CommonCfg.PhyMode == PHY_11B)
1004 { //B Only
1005 aryRates[0] = 0x16; // 11Mbps
1006 aryRates[1] = 0x0b; // 5.5Mbps
1007 aryRates[2] = 0x04; // 2Mbps
1008 aryRates[3] = 0x02; // 1Mbps
1009 }
1010 else
1011 { //(B/G) Mixed or (A/B/G) Mixed
1012 aryRates[0] = 0x6c; // 54Mbps
1013 aryRates[1] = 0x60; // 48Mbps
1014 aryRates[2] = 0x48; // 36Mbps
1015 aryRates[3] = 0x30; // 24Mbps
1016 aryRates[4] = 0x16; // 11Mbps
1017 aryRates[5] = 0x0b; // 5.5Mbps
1018 aryRates[6] = 0x04; // 2Mbps
1019 aryRates[7] = 0x02; // 1Mbps
1020 }
1021 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
1022 break;
1023 }
1024 break;
1025 }
1026
1027 NdisZeroMemory(pAdapter->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
1028 NdisMoveMemory(pAdapter->CommonCfg.DesireRate, &aryRates, sizeof(NDIS_802_11_RATES));
1029 DBGPRINT(RT_DEBUG_TRACE, (" RTMPSetDesiredRates (%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x)\n",
1030 pAdapter->CommonCfg.DesireRate[0],pAdapter->CommonCfg.DesireRate[1],
1031 pAdapter->CommonCfg.DesireRate[2],pAdapter->CommonCfg.DesireRate[3],
1032 pAdapter->CommonCfg.DesireRate[4],pAdapter->CommonCfg.DesireRate[5],
1033 pAdapter->CommonCfg.DesireRate[6],pAdapter->CommonCfg.DesireRate[7] ));
1034 // Changing DesiredRate may affect the MAX TX rate we used to TX frames out
1035 MlmeUpdateTxRates(pAdapter, FALSE, 0);
1036}
1037
1038NDIS_STATUS RTMPWPARemoveKeyProc(
1039 IN PRTMP_ADAPTER pAd,
1040 IN PVOID pBuf)
1041{
1042 PNDIS_802_11_REMOVE_KEY pKey;
1043 ULONG KeyIdx;
1044 NDIS_STATUS Status = NDIS_STATUS_FAILURE;
1045 BOOLEAN bTxKey; // Set the key as transmit key
1046 BOOLEAN bPairwise; // Indicate the key is pairwise key
1047 BOOLEAN bKeyRSC; // indicate the receive SC set by KeyRSC value.
1048 // Otherwise, it will set by the NIC.
1049 BOOLEAN bAuthenticator; // indicate key is set by authenticator.
1050 INT i;
1051
1052 DBGPRINT(RT_DEBUG_TRACE,("---> RTMPWPARemoveKeyProc\n"));
1053
1054 pKey = (PNDIS_802_11_REMOVE_KEY) pBuf;
1055 KeyIdx = pKey->KeyIndex & 0xff;
1056 // Bit 31 of Add-key, Tx Key
1057 bTxKey = (pKey->KeyIndex & 0x80000000) ? TRUE : FALSE;
1058 // Bit 30 of Add-key PairwiseKey
1059 bPairwise = (pKey->KeyIndex & 0x40000000) ? TRUE : FALSE;
1060 // Bit 29 of Add-key KeyRSC
1061 bKeyRSC = (pKey->KeyIndex & 0x20000000) ? TRUE : FALSE;
1062 // Bit 28 of Add-key Authenticator
1063 bAuthenticator = (pKey->KeyIndex & 0x10000000) ? TRUE : FALSE;
1064
1065 // 1. If bTx is TRUE, return failure information
1066 if (bTxKey == TRUE)
1067 return(NDIS_STATUS_INVALID_DATA);
1068
1069 // 2. Check Pairwise Key
1070 if (bPairwise)
1071 {
1072 // a. If BSSID is broadcast, remove all pairwise keys.
1073 // b. If not broadcast, remove the pairwise specified by BSSID
1074 for (i = 0; i < SHARE_KEY_NUM; i++)
1075 {
1076 if (MAC_ADDR_EQUAL(pAd->SharedKey[BSS0][i].BssId, pKey->BSSID))
1077 {
1078 DBGPRINT(RT_DEBUG_TRACE,("RTMPWPARemoveKeyProc(KeyIdx=%d)\n", i));
1079 pAd->SharedKey[BSS0][i].KeyLen = 0;
1080 pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_NONE;
1081 AsicRemoveSharedKeyEntry(pAd, BSS0, (UCHAR)i);
1082 Status = NDIS_STATUS_SUCCESS;
1083 break;
1084 }
1085 }
1086 }
1087 // 3. Group Key
1088 else
1089 {
1090 // a. If BSSID is broadcast, remove all group keys indexed
1091 // b. If BSSID matched, delete the group key indexed.
1092 DBGPRINT(RT_DEBUG_TRACE,("RTMPWPARemoveKeyProc(KeyIdx=%ld)\n", KeyIdx));
1093 pAd->SharedKey[BSS0][KeyIdx].KeyLen = 0;
1094 pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
1095 AsicRemoveSharedKeyEntry(pAd, BSS0, (UCHAR)KeyIdx);
1096 Status = NDIS_STATUS_SUCCESS;
1097 }
1098
1099 return (Status);
1100}
1101#endif // CONFIG_STA_SUPPORT //
1102
1103
1104#ifdef CONFIG_STA_SUPPORT
1105/*
1106 ========================================================================
1107
1108 Routine Description:
1109 Remove All WPA Keys
1110
1111 Arguments:
1112 pAd Pointer to our adapter
1113
1114 Return Value:
1115 None
1116
1117 IRQL = DISPATCH_LEVEL
1118
1119 Note:
1120
1121 ========================================================================
1122*/
1123VOID RTMPWPARemoveAllKeys(
1124 IN PRTMP_ADAPTER pAd)
1125{
1126
1127 UCHAR i;
1128
1129 DBGPRINT(RT_DEBUG_TRACE,("RTMPWPARemoveAllKeys(AuthMode=%d, WepStatus=%d)\n", pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus));
1130
1131 // For WEP/CKIP, there is no need to remove it, since WinXP won't set it again after
1132 // Link up. And it will be replaced if user changed it.
1133 if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
1134 return;
1135
1136 // For WPA-None, there is no need to remove it, since WinXP won't set it again after
1137 // Link up. And it will be replaced if user changed it.
1138 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1139 return;
1140
1141 // set BSSID wcid entry of the Pair-wise Key table as no-security mode
1142 AsicRemovePairwiseKeyEntry(pAd, BSS0, BSSID_WCID);
1143
1144 // set all shared key mode as no-security.
1145 for (i = 0; i < SHARE_KEY_NUM; i++)
1146 {
1147 DBGPRINT(RT_DEBUG_TRACE,("remove %s key #%d\n", CipherName[pAd->SharedKey[BSS0][i].CipherAlg], i));
1148 NdisZeroMemory(&pAd->SharedKey[BSS0][i], sizeof(CIPHER_KEY));
1149
1150 AsicRemoveSharedKeyEntry(pAd, BSS0, i);
1151 }
1152
1153}
1154#endif // CONFIG_STA_SUPPORT //
1155
1156/*
1157 ========================================================================
1158 Routine Description:
1159 Change NIC PHY mode. Re-association may be necessary. possible settings
1160 include - PHY_11B, PHY_11BG_MIXED, PHY_11A, and PHY_11ABG_MIXED
1161
1162 Arguments:
1163 pAd - Pointer to our adapter
1164 phymode -
1165
1166 IRQL = PASSIVE_LEVEL
1167 IRQL = DISPATCH_LEVEL
1168
1169 ========================================================================
1170*/
1171VOID RTMPSetPhyMode(
1172 IN PRTMP_ADAPTER pAd,
1173 IN ULONG phymode)
1174{
1175 INT i;
1176 // the selected phymode must be supported by the RF IC encoded in E2PROM
1177
1178 pAd->CommonCfg.PhyMode = (UCHAR)phymode;
1179
1180 DBGPRINT(RT_DEBUG_TRACE,("RTMPSetPhyMode : PhyMode=%d, channel=%d \n", pAd->CommonCfg.PhyMode, pAd->CommonCfg.Channel));
1181#ifdef EXT_BUILD_CHANNEL_LIST
1182 BuildChannelListEx(pAd);
1183#else
1184 BuildChannelList(pAd);
1185#endif // EXT_BUILD_CHANNEL_LIST //
1186
1187 // sanity check user setting
1188 for (i = 0; i < pAd->ChannelListNum; i++)
1189 {
1190 if (pAd->CommonCfg.Channel == pAd->ChannelList[i].Channel)
1191 break;
1192 }
1193
1194 if (i == pAd->ChannelListNum)
1195 {
1196#ifdef CONFIG_STA_SUPPORT
1197 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1198 pAd->CommonCfg.Channel = FirstChannel(pAd);
1199#endif // CONFIG_STA_SUPPORT //
1200 DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetPhyMode: channel is out of range, use first channel=%d \n", pAd->CommonCfg.Channel));
1201 }
1202
1203 NdisZeroMemory(pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES);
1204 NdisZeroMemory(pAd->CommonCfg.ExtRate, MAX_LEN_OF_SUPPORTED_RATES);
1205 NdisZeroMemory(pAd->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
1206 switch (phymode) {
1207 case PHY_11B:
1208 pAd->CommonCfg.SupRate[0] = 0x82; // 1 mbps, in units of 0.5 Mbps, basic rate
1209 pAd->CommonCfg.SupRate[1] = 0x84; // 2 mbps, in units of 0.5 Mbps, basic rate
1210 pAd->CommonCfg.SupRate[2] = 0x8B; // 5.5 mbps, in units of 0.5 Mbps, basic rate
1211 pAd->CommonCfg.SupRate[3] = 0x96; // 11 mbps, in units of 0.5 Mbps, basic rate
1212 pAd->CommonCfg.SupRateLen = 4;
1213 pAd->CommonCfg.ExtRateLen = 0;
1214 pAd->CommonCfg.DesireRate[0] = 2; // 1 mbps, in units of 0.5 Mbps
1215 pAd->CommonCfg.DesireRate[1] = 4; // 2 mbps, in units of 0.5 Mbps
1216 pAd->CommonCfg.DesireRate[2] = 11; // 5.5 mbps, in units of 0.5 Mbps
1217 pAd->CommonCfg.DesireRate[3] = 22; // 11 mbps, in units of 0.5 Mbps
1218 //pAd->CommonCfg.HTPhyMode.field.MODE = MODE_CCK; // This MODE is only FYI. not use
1219 break;
1220
1221 case PHY_11G:
1222 case PHY_11BG_MIXED:
1223 case PHY_11ABG_MIXED:
1224#ifdef DOT11_N_SUPPORT
1225 case PHY_11N_2_4G:
1226 case PHY_11ABGN_MIXED:
1227 case PHY_11BGN_MIXED:
1228 case PHY_11GN_MIXED:
1229#endif // DOT11_N_SUPPORT //
1230 pAd->CommonCfg.SupRate[0] = 0x82; // 1 mbps, in units of 0.5 Mbps, basic rate
1231 pAd->CommonCfg.SupRate[1] = 0x84; // 2 mbps, in units of 0.5 Mbps, basic rate
1232 pAd->CommonCfg.SupRate[2] = 0x8B; // 5.5 mbps, in units of 0.5 Mbps, basic rate
1233 pAd->CommonCfg.SupRate[3] = 0x96; // 11 mbps, in units of 0.5 Mbps, basic rate
1234 pAd->CommonCfg.SupRate[4] = 0x12; // 9 mbps, in units of 0.5 Mbps
1235 pAd->CommonCfg.SupRate[5] = 0x24; // 18 mbps, in units of 0.5 Mbps
1236 pAd->CommonCfg.SupRate[6] = 0x48; // 36 mbps, in units of 0.5 Mbps
1237 pAd->CommonCfg.SupRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
1238 pAd->CommonCfg.SupRateLen = 8;
1239 pAd->CommonCfg.ExtRate[0] = 0x0C; // 6 mbps, in units of 0.5 Mbps
1240 pAd->CommonCfg.ExtRate[1] = 0x18; // 12 mbps, in units of 0.5 Mbps
1241 pAd->CommonCfg.ExtRate[2] = 0x30; // 24 mbps, in units of 0.5 Mbps
1242 pAd->CommonCfg.ExtRate[3] = 0x60; // 48 mbps, in units of 0.5 Mbps
1243 pAd->CommonCfg.ExtRateLen = 4;
1244 pAd->CommonCfg.DesireRate[0] = 2; // 1 mbps, in units of 0.5 Mbps
1245 pAd->CommonCfg.DesireRate[1] = 4; // 2 mbps, in units of 0.5 Mbps
1246 pAd->CommonCfg.DesireRate[2] = 11; // 5.5 mbps, in units of 0.5 Mbps
1247 pAd->CommonCfg.DesireRate[3] = 22; // 11 mbps, in units of 0.5 Mbps
1248 pAd->CommonCfg.DesireRate[4] = 12; // 6 mbps, in units of 0.5 Mbps
1249 pAd->CommonCfg.DesireRate[5] = 18; // 9 mbps, in units of 0.5 Mbps
1250 pAd->CommonCfg.DesireRate[6] = 24; // 12 mbps, in units of 0.5 Mbps
1251 pAd->CommonCfg.DesireRate[7] = 36; // 18 mbps, in units of 0.5 Mbps
1252 pAd->CommonCfg.DesireRate[8] = 48; // 24 mbps, in units of 0.5 Mbps
1253 pAd->CommonCfg.DesireRate[9] = 72; // 36 mbps, in units of 0.5 Mbps
1254 pAd->CommonCfg.DesireRate[10] = 96; // 48 mbps, in units of 0.5 Mbps
1255 pAd->CommonCfg.DesireRate[11] = 108; // 54 mbps, in units of 0.5 Mbps
1256 break;
1257
1258 case PHY_11A:
1259#ifdef DOT11_N_SUPPORT
1260 case PHY_11AN_MIXED:
1261 case PHY_11AGN_MIXED:
1262 case PHY_11N_5G:
1263#endif // DOT11_N_SUPPORT //
1264 pAd->CommonCfg.SupRate[0] = 0x8C; // 6 mbps, in units of 0.5 Mbps, basic rate
1265 pAd->CommonCfg.SupRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
1266 pAd->CommonCfg.SupRate[2] = 0x98; // 12 mbps, in units of 0.5 Mbps, basic rate
1267 pAd->CommonCfg.SupRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
1268 pAd->CommonCfg.SupRate[4] = 0xb0; // 24 mbps, in units of 0.5 Mbps, basic rate
1269 pAd->CommonCfg.SupRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
1270 pAd->CommonCfg.SupRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
1271 pAd->CommonCfg.SupRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
1272 pAd->CommonCfg.SupRateLen = 8;
1273 pAd->CommonCfg.ExtRateLen = 0;
1274 pAd->CommonCfg.DesireRate[0] = 12; // 6 mbps, in units of 0.5 Mbps
1275 pAd->CommonCfg.DesireRate[1] = 18; // 9 mbps, in units of 0.5 Mbps
1276 pAd->CommonCfg.DesireRate[2] = 24; // 12 mbps, in units of 0.5 Mbps
1277 pAd->CommonCfg.DesireRate[3] = 36; // 18 mbps, in units of 0.5 Mbps
1278 pAd->CommonCfg.DesireRate[4] = 48; // 24 mbps, in units of 0.5 Mbps
1279 pAd->CommonCfg.DesireRate[5] = 72; // 36 mbps, in units of 0.5 Mbps
1280 pAd->CommonCfg.DesireRate[6] = 96; // 48 mbps, in units of 0.5 Mbps
1281 pAd->CommonCfg.DesireRate[7] = 108; // 54 mbps, in units of 0.5 Mbps
1282 //pAd->CommonCfg.HTPhyMode.field.MODE = MODE_OFDM; // This MODE is only FYI. not use
1283 break;
1284
1285 default:
1286 break;
1287 }
1288
1289
1290 pAd->CommonCfg.BandState = UNKNOWN_BAND;
1291}
1292
1293
1294#ifdef DOT11_N_SUPPORT
1295/*
1296 ========================================================================
1297 Routine Description:
1298 Caller ensures we has 802.11n support.
1299 Calls at setting HT from AP/STASetinformation
1300
1301 Arguments:
1302 pAd - Pointer to our adapter
1303 phymode -
1304
1305 ========================================================================
1306*/
1307VOID RTMPSetHT(
1308 IN PRTMP_ADAPTER pAd,
1309 IN OID_SET_HT_PHYMODE *pHTPhyMode)
1310{
1311 //ULONG *pmcs;
1312 UINT32 Value = 0;
1313 UCHAR BBPValue = 0;
1314 UCHAR BBP3Value = 0;
1315 UCHAR RxStream = pAd->CommonCfg.RxStream;
1316
1317 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : HT_mode(%d), ExtOffset(%d), MCS(%d), BW(%d), STBC(%d), SHORTGI(%d)\n",
1318 pHTPhyMode->HtMode, pHTPhyMode->ExtOffset,
1319 pHTPhyMode->MCS, pHTPhyMode->BW,
1320 pHTPhyMode->STBC, pHTPhyMode->SHORTGI));
1321
1322 // Don't zero supportedHyPhy structure.
1323 RTMPZeroMemory(&pAd->CommonCfg.HtCapability, sizeof(pAd->CommonCfg.HtCapability));
1324 RTMPZeroMemory(&pAd->CommonCfg.AddHTInfo, sizeof(pAd->CommonCfg.AddHTInfo));
1325 RTMPZeroMemory(&pAd->CommonCfg.NewExtChanOffset, sizeof(pAd->CommonCfg.NewExtChanOffset));
1326 RTMPZeroMemory(&pAd->CommonCfg.DesiredHtPhy, sizeof(pAd->CommonCfg.DesiredHtPhy));
1327
1328 if (pAd->CommonCfg.bRdg)
1329 {
1330 pAd->CommonCfg.HtCapability.ExtHtCapInfo.PlusHTC = 1;
1331 pAd->CommonCfg.HtCapability.ExtHtCapInfo.RDGSupport = 1;
1332 }
1333 else
1334 {
1335 pAd->CommonCfg.HtCapability.ExtHtCapInfo.PlusHTC = 0;
1336 pAd->CommonCfg.HtCapability.ExtHtCapInfo.RDGSupport = 0;
1337 }
1338
1339 pAd->CommonCfg.HtCapability.HtCapParm.MaxRAmpduFactor = 3;
1340 pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor = 3;
1341
1342 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : RxBAWinLimit = %d\n", pAd->CommonCfg.BACapability.field.RxBAWinLimit));
1343
1344 // Mimo power save, A-MSDU size,
1345 pAd->CommonCfg.DesiredHtPhy.AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable;
1346 pAd->CommonCfg.DesiredHtPhy.AmsduSize = (UCHAR)pAd->CommonCfg.BACapability.field.AmsduSize;
1347 pAd->CommonCfg.DesiredHtPhy.MimoPs = (UCHAR)pAd->CommonCfg.BACapability.field.MMPSmode;
1348 pAd->CommonCfg.DesiredHtPhy.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
1349
1350 pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize;
1351 pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode;
1352 pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
1353
1354 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : AMsduSize = %d, MimoPs = %d, MpduDensity = %d, MaxRAmpduFactor = %d\n",
1355 pAd->CommonCfg.DesiredHtPhy.AmsduSize,
1356 pAd->CommonCfg.DesiredHtPhy.MimoPs,
1357 pAd->CommonCfg.DesiredHtPhy.MpduDensity,
1358 pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor));
1359
1360 if(pHTPhyMode->HtMode == HTMODE_GF)
1361 {
1362 pAd->CommonCfg.HtCapability.HtCapInfo.GF = 1;
1363 pAd->CommonCfg.DesiredHtPhy.GF = 1;
1364 }
1365 else
1366 pAd->CommonCfg.DesiredHtPhy.GF = 0;
1367
1368 // Decide Rx MCSSet
1369 switch (RxStream)
1370 {
1371 case 1:
1372 pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff;
1373 pAd->CommonCfg.HtCapability.MCSSet[1] = 0x00;
1374 break;
1375
1376 case 2:
1377 pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff;
1378 pAd->CommonCfg.HtCapability.MCSSet[1] = 0xff;
1379 break;
1380
1381 case 3: // 3*3
1382 pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff;
1383 pAd->CommonCfg.HtCapability.MCSSet[1] = 0xff;
1384 pAd->CommonCfg.HtCapability.MCSSet[2] = 0xff;
1385 break;
1386 }
1387
1388 if (pAd->CommonCfg.bForty_Mhz_Intolerant && (pAd->CommonCfg.Channel <= 14) && (pHTPhyMode->BW == BW_40) )
1389 {
1390 pHTPhyMode->BW = BW_20;
1391 pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant = 1;
1392 }
1393
1394 if(pHTPhyMode->BW == BW_40)
1395 {
1396 pAd->CommonCfg.HtCapability.MCSSet[4] = 0x1; // MCS 32
1397 pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth = 1;
1398 if (pAd->CommonCfg.Channel <= 14)
1399 pAd->CommonCfg.HtCapability.HtCapInfo.CCKmodein40 = 1;
1400
1401 pAd->CommonCfg.DesiredHtPhy.ChannelWidth = 1;
1402 pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 1;
1403 pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = (pHTPhyMode->ExtOffset == EXTCHA_BELOW)? (EXTCHA_BELOW): EXTCHA_ABOVE;
1404 // Set Regsiter for extension channel position.
1405 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
1406 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBP3Value);
1407 if ((pHTPhyMode->ExtOffset == EXTCHA_BELOW))
1408 {
1409 Value |= 0x1;
1410 BBP3Value |= (0x20);
1411 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
1412 }
1413 else if ((pHTPhyMode->ExtOffset == EXTCHA_ABOVE))
1414 {
1415 Value &= 0xfe;
1416 BBP3Value &= (~0x20);
1417 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
1418 }
1419
1420 // Turn on BBP 40MHz mode now only as AP .
1421 // Sta can turn on BBP 40MHz after connection with 40MHz AP. Sta only broadcast 40MHz capability before connection.
1422 if ((pAd->OpMode == OPMODE_AP) || INFRA_ON(pAd) || ADHOC_ON(pAd)
1423 )
1424 {
1425 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
1426 BBPValue &= (~0x18);
1427 BBPValue |= 0x10;
1428 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
1429
1430 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBP3Value);
1431 pAd->CommonCfg.BBPCurrentBW = BW_40;
1432 }
1433 }
1434 else
1435 {
1436 pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth = 0;
1437 pAd->CommonCfg.DesiredHtPhy.ChannelWidth = 0;
1438 pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 0;
1439 pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = EXTCHA_NONE;
1440 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
1441 // Turn on BBP 20MHz mode by request here.
1442 {
1443 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
1444 BBPValue &= (~0x18);
1445 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
1446 pAd->CommonCfg.BBPCurrentBW = BW_20;
1447 }
1448 }
1449
1450 if(pHTPhyMode->STBC == STBC_USE)
1451 {
1452 pAd->CommonCfg.HtCapability.HtCapInfo.TxSTBC = 1;
1453 pAd->CommonCfg.DesiredHtPhy.TxSTBC = 1;
1454 pAd->CommonCfg.HtCapability.HtCapInfo.RxSTBC = 1;
1455 pAd->CommonCfg.DesiredHtPhy.RxSTBC = 1;
1456 }
1457 else
1458 {
1459 pAd->CommonCfg.DesiredHtPhy.TxSTBC = 0;
1460 pAd->CommonCfg.DesiredHtPhy.RxSTBC = 0;
1461 }
1462
1463 if(pHTPhyMode->SHORTGI == GI_400)
1464 {
1465 pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor20 = 1;
1466 pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor40 = 1;
1467 pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 = 1;
1468 pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 = 1;
1469 }
1470 else
1471 {
1472 pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor20 = 0;
1473 pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor40 = 0;
1474 pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 = 0;
1475 pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 = 0;
1476 }
1477
1478 // We support link adaptation for unsolicit MCS feedback, set to 2.
1479 pAd->CommonCfg.HtCapability.ExtHtCapInfo.MCSFeedback = MCSFBK_NONE; //MCSFBK_UNSOLICIT;
1480 pAd->CommonCfg.AddHTInfo.ControlChan = pAd->CommonCfg.Channel;
1481 // 1, the extension channel above the control channel.
1482
1483 // EDCA parameters used for AP's own transmission
1484 if (pAd->CommonCfg.APEdcaParm.bValid == FALSE)
1485 {
1486 pAd->CommonCfg.APEdcaParm.bValid = TRUE;
1487 pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
1488 pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
1489 pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
1490 pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
1491
1492 pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
1493 pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
1494 pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
1495 pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
1496
1497 pAd->CommonCfg.APEdcaParm.Cwmax[0] = 6;
1498 pAd->CommonCfg.APEdcaParm.Cwmax[1] = 10;
1499 pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
1500 pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
1501
1502 pAd->CommonCfg.APEdcaParm.Txop[0] = 0;
1503 pAd->CommonCfg.APEdcaParm.Txop[1] = 0;
1504 pAd->CommonCfg.APEdcaParm.Txop[2] = 94;
1505 pAd->CommonCfg.APEdcaParm.Txop[3] = 47;
1506 }
1507 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1508
1509
1510#ifdef CONFIG_STA_SUPPORT
1511 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1512 {
1513 RTMPSetIndividualHT(pAd, 0);
1514 }
1515#endif // CONFIG_STA_SUPPORT //
1516
1517}
1518
1519/*
1520 ========================================================================
1521 Routine Description:
1522 Caller ensures we has 802.11n support.
1523 Calls at setting HT from AP/STASetinformation
1524
1525 Arguments:
1526 pAd - Pointer to our adapter
1527 phymode -
1528
1529 ========================================================================
1530*/
1531VOID RTMPSetIndividualHT(
1532 IN PRTMP_ADAPTER pAd,
1533 IN UCHAR apidx)
1534{
1535 PRT_HT_PHY_INFO pDesired_ht_phy = NULL;
1536 UCHAR TxStream = pAd->CommonCfg.TxStream;
1537 UCHAR DesiredMcs = MCS_AUTO;
1538
1539 do
1540 {
1541
1542#ifdef CONFIG_STA_SUPPORT
1543 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1544 {
1545 pDesired_ht_phy = &pAd->StaCfg.DesiredHtPhyInfo;
1546 DesiredMcs = pAd->StaCfg.DesiredTransmitSetting.field.MCS;
1547 //pAd->StaCfg.bAutoTxRateSwitch = (DesiredMcs == MCS_AUTO) ? TRUE : FALSE;
1548 break;
1549 }
1550#endif // CONFIG_STA_SUPPORT //
1551 } while (FALSE);
1552
1553 if (pDesired_ht_phy == NULL)
1554 {
1555 DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetIndividualHT: invalid apidx(%d)\n", apidx));
1556 return;
1557 }
1558 RTMPZeroMemory(pDesired_ht_phy, sizeof(RT_HT_PHY_INFO));
1559
1560 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetIndividualHT : Desired MCS = %d\n", DesiredMcs));
1561 // Check the validity of MCS
1562 if ((TxStream == 1) && ((DesiredMcs >= MCS_8) && (DesiredMcs <= MCS_15)))
1563 {
1564 DBGPRINT(RT_DEBUG_WARN, ("RTMPSetIndividualHT: MCS(%d) is invalid in 1S, reset it as MCS_7\n", DesiredMcs));
1565 DesiredMcs = MCS_7;
1566 }
1567
1568 if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_20) && (DesiredMcs == MCS_32))
1569 {
1570 DBGPRINT(RT_DEBUG_WARN, ("RTMPSetIndividualHT: MCS_32 is only supported in 40-MHz, reset it as MCS_0\n"));
1571 DesiredMcs = MCS_0;
1572 }
1573
1574 pDesired_ht_phy->bHtEnable = TRUE;
1575
1576 // Decide desired Tx MCS
1577 switch (TxStream)
1578 {
1579 case 1:
1580 if (DesiredMcs == MCS_AUTO)
1581 {
1582 pDesired_ht_phy->MCSSet[0]= 0xff;
1583 pDesired_ht_phy->MCSSet[1]= 0x00;
1584 }
1585 else if (DesiredMcs <= MCS_7)
1586 {
1587 pDesired_ht_phy->MCSSet[0]= 1<<DesiredMcs;
1588 pDesired_ht_phy->MCSSet[1]= 0x00;
1589 }
1590 break;
1591
1592 case 2:
1593 if (DesiredMcs == MCS_AUTO)
1594 {
1595 pDesired_ht_phy->MCSSet[0]= 0xff;
1596 pDesired_ht_phy->MCSSet[1]= 0xff;
1597 }
1598 else if (DesiredMcs <= MCS_15)
1599 {
1600 ULONG mode;
1601
1602 mode = DesiredMcs / 8;
1603 if (mode < 2)
1604 pDesired_ht_phy->MCSSet[mode] = (1 << (DesiredMcs - mode * 8));
1605 }
1606 break;
1607
1608 case 3: // 3*3
1609 if (DesiredMcs == MCS_AUTO)
1610 {
1611 /* MCS0 ~ MCS23, 3 bytes */
1612 pDesired_ht_phy->MCSSet[0]= 0xff;
1613 pDesired_ht_phy->MCSSet[1]= 0xff;
1614 pDesired_ht_phy->MCSSet[2]= 0xff;
1615 }
1616 else if (DesiredMcs <= MCS_23)
1617 {
1618 ULONG mode;
1619
1620 mode = DesiredMcs / 8;
1621 if (mode < 3)
1622 pDesired_ht_phy->MCSSet[mode] = (1 << (DesiredMcs - mode * 8));
1623 }
1624 break;
1625 }
1626
1627 if(pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_40)
1628 {
1629 if (DesiredMcs == MCS_AUTO || DesiredMcs == MCS_32)
1630 pDesired_ht_phy->MCSSet[4] = 0x1;
1631 }
1632
1633 // update HT Rate setting
1634 if (pAd->OpMode == OPMODE_STA)
1635 MlmeUpdateHtTxRates(pAd, BSS0);
1636 else
1637 MlmeUpdateHtTxRates(pAd, apidx);
1638}
1639
1640
1641/*
1642 ========================================================================
1643 Routine Description:
1644 Update HT IE from our capability.
1645
1646 Arguments:
1647 Send all HT IE in beacon/probe rsp/assoc rsp/action frame.
1648
1649
1650 ========================================================================
1651*/
1652VOID RTMPUpdateHTIE(
1653 IN RT_HT_CAPABILITY *pRtHt,
1654 IN UCHAR *pMcsSet,
1655 OUT HT_CAPABILITY_IE *pHtCapability,
1656 OUT ADD_HT_INFO_IE *pAddHtInfo)
1657{
1658 RTMPZeroMemory(pHtCapability, sizeof(HT_CAPABILITY_IE));
1659 RTMPZeroMemory(pAddHtInfo, sizeof(ADD_HT_INFO_IE));
1660
1661 pHtCapability->HtCapInfo.ChannelWidth = pRtHt->ChannelWidth;
1662 pHtCapability->HtCapInfo.MimoPs = pRtHt->MimoPs;
1663 pHtCapability->HtCapInfo.GF = pRtHt->GF;
1664 pHtCapability->HtCapInfo.ShortGIfor20 = pRtHt->ShortGIfor20;
1665 pHtCapability->HtCapInfo.ShortGIfor40 = pRtHt->ShortGIfor40;
1666 pHtCapability->HtCapInfo.TxSTBC = pRtHt->TxSTBC;
1667 pHtCapability->HtCapInfo.RxSTBC = pRtHt->RxSTBC;
1668 pHtCapability->HtCapInfo.AMsduSize = pRtHt->AmsduSize;
1669 pHtCapability->HtCapParm.MaxRAmpduFactor = pRtHt->MaxRAmpduFactor;
1670 pHtCapability->HtCapParm.MpduDensity = pRtHt->MpduDensity;
1671
1672 pAddHtInfo->AddHtInfo.ExtChanOffset = pRtHt->ExtChanOffset ;
1673 pAddHtInfo->AddHtInfo.RecomWidth = pRtHt->RecomWidth;
1674 pAddHtInfo->AddHtInfo2.OperaionMode = pRtHt->OperaionMode;
1675 pAddHtInfo->AddHtInfo2.NonGfPresent = pRtHt->NonGfPresent;
1676 RTMPMoveMemory(pAddHtInfo->MCSSet, /*pRtHt->MCSSet*/pMcsSet, 4); // rt2860 only support MCS max=32, no need to copy all 16 uchar.
1677
1678 DBGPRINT(RT_DEBUG_TRACE,("RTMPUpdateHTIE <== \n"));
1679}
1680#endif // DOT11_N_SUPPORT //
1681
1682/*
1683 ========================================================================
1684 Description:
1685 Add Client security information into ASIC WCID table and IVEIV table.
1686 Return:
1687 ========================================================================
1688*/
1689VOID RTMPAddWcidAttributeEntry(
1690 IN PRTMP_ADAPTER pAd,
1691 IN UCHAR BssIdx,
1692 IN UCHAR KeyIdx,
1693 IN UCHAR CipherAlg,
1694 IN MAC_TABLE_ENTRY *pEntry)
1695{
1696 UINT32 WCIDAttri = 0;
1697 USHORT offset;
1698 UCHAR IVEIV = 0;
1699 USHORT Wcid = 0;
1700
1701 {
1702#ifdef CONFIG_STA_SUPPORT
1703 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1704 {
1705 if (BssIdx > BSS0)
1706 {
1707 DBGPRINT(RT_DEBUG_ERROR, ("RTMPAddWcidAttributeEntry: The BSS-index(%d) is out of range for Infra link. \n", BssIdx));
1708 return;
1709 }
1710
1711 // 1. In ADHOC mode, the AID is wcid number. And NO mesh link exists.
1712 // 2. In Infra mode, the AID:1 MUST be wcid of infra STA.
1713 // the AID:2~ assign to mesh link entry.
1714 if (pEntry && ADHOC_ON(pAd))
1715 Wcid = pEntry->Aid;
1716 else if (pEntry && INFRA_ON(pAd))
1717 {
1718#ifdef QOS_DLS_SUPPORT
1719 if (pEntry->ValidAsDls == TRUE)
1720 Wcid = pEntry->Aid;
1721 else
1722#endif // QOS_DLS_SUPPORT //
1723 Wcid = BSSID_WCID;
1724 }
1725 else
1726 Wcid = MCAST_WCID;
1727 }
1728#endif // CONFIG_STA_SUPPORT //
1729 }
1730
1731 // Update WCID attribute table
1732 offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE);
1733
1734#ifdef CONFIG_STA_SUPPORT
1735 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1736 {
1737 if (pEntry && pEntry->ValidAsMesh)
1738 WCIDAttri = (CipherAlg<<1) | PAIRWISEKEYTABLE;
1739#ifdef QOS_DLS_SUPPORT
1740 else if ((pEntry) && (pEntry->ValidAsDls) &&
1741 ((CipherAlg == CIPHER_TKIP) ||
1742 (CipherAlg == CIPHER_TKIP_NO_MIC) ||
1743 (CipherAlg == CIPHER_AES) ||
1744 (CipherAlg == CIPHER_NONE)))
1745 WCIDAttri = (CipherAlg<<1) | PAIRWISEKEYTABLE;
1746#endif // QOS_DLS_SUPPORT //
1747 else
1748 WCIDAttri = (CipherAlg<<1) | SHAREDKEYTABLE;
1749 }
1750#endif // CONFIG_STA_SUPPORT //
1751
1752 RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
1753
1754
1755 // Update IV/EIV table
1756 offset = MAC_IVEIV_TABLE_BASE + (Wcid * HW_IVEIV_ENTRY_SIZE);
1757
1758 // WPA mode
1759 if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) || (CipherAlg == CIPHER_AES))
1760 {
1761 // Eiv bit on. keyid always is 0 for pairwise key
1762 IVEIV = (KeyIdx <<6) | 0x20;
1763 }
1764 else
1765 {
1766 // WEP KeyIdx is default tx key.
1767 IVEIV = (KeyIdx << 6);
1768 }
1769
1770 // For key index and ext IV bit, so only need to update the position(offset+3).
1771#ifdef RT2870
1772 RTUSBMultiWrite_OneByte(pAd, offset+3, &IVEIV);
1773#endif // RT2870 //
1774
1775 DBGPRINT(RT_DEBUG_TRACE,("RTMPAddWcidAttributeEntry: WCID #%d, KeyIndex #%d, Alg=%s\n",Wcid, KeyIdx, CipherName[CipherAlg]));
1776 DBGPRINT(RT_DEBUG_TRACE,(" WCIDAttri = 0x%x \n", WCIDAttri));
1777
1778}
1779
1780/*
1781 ==========================================================================
1782 Description:
1783 Parse encryption type
1784Arguments:
1785 pAdapter Pointer to our adapter
1786 wrq Pointer to the ioctl argument
1787
1788 Return Value:
1789 None
1790
1791 Note:
1792 ==========================================================================
1793*/
1794CHAR *GetEncryptType(CHAR enc)
1795{
1796 if(enc == Ndis802_11WEPDisabled)
1797 return "NONE";
1798 if(enc == Ndis802_11WEPEnabled)
1799 return "WEP";
1800 if(enc == Ndis802_11Encryption2Enabled)
1801 return "TKIP";
1802 if(enc == Ndis802_11Encryption3Enabled)
1803 return "AES";
1804 if(enc == Ndis802_11Encryption4Enabled)
1805 return "TKIPAES";
1806 else
1807 return "UNKNOW";
1808}
1809
1810CHAR *GetAuthMode(CHAR auth)
1811{
1812 if(auth == Ndis802_11AuthModeOpen)
1813 return "OPEN";
1814 if(auth == Ndis802_11AuthModeShared)
1815 return "SHARED";
1816 if(auth == Ndis802_11AuthModeAutoSwitch)
1817 return "AUTOWEP";
1818 if(auth == Ndis802_11AuthModeWPA)
1819 return "WPA";
1820 if(auth == Ndis802_11AuthModeWPAPSK)
1821 return "WPAPSK";
1822 if(auth == Ndis802_11AuthModeWPANone)
1823 return "WPANONE";
1824 if(auth == Ndis802_11AuthModeWPA2)
1825 return "WPA2";
1826 if(auth == Ndis802_11AuthModeWPA2PSK)
1827 return "WPA2PSK";
1828 if(auth == Ndis802_11AuthModeWPA1WPA2)
1829 return "WPA1WPA2";
1830 if(auth == Ndis802_11AuthModeWPA1PSKWPA2PSK)
1831 return "WPA1PSKWPA2PSK";
1832
1833 return "UNKNOW";
1834}
1835
1836#if 1 //#ifndef UCOS
1837/*
1838 ==========================================================================
1839 Description:
1840 Get site survey results
1841 Arguments:
1842 pAdapter Pointer to our adapter
1843 wrq Pointer to the ioctl argument
1844
1845 Return Value:
1846 None
1847
1848 Note:
1849 Usage:
1850 1.) UI needs to wait 4 seconds after issue a site survey command
1851 2.) iwpriv ra0 get_site_survey
1852 3.) UI needs to prepare at least 4096bytes to get the results
1853 ==========================================================================
1854*/
1855#define LINE_LEN (4+33+20+8+10+9+7+3) // Channel+SSID+Bssid+WepStatus+AuthMode+Signal+WiressMode+NetworkType
1856#ifdef CONFIG_STA_SUPPORT
1857#endif // CONFIG_STA_SUPPORT //
1858VOID RTMPIoctlGetSiteSurvey(
1859 IN PRTMP_ADAPTER pAdapter,
1860 IN struct iwreq *wrq)
1861{
1862 CHAR *msg;
1863 INT i=0;
1864 INT WaitCnt;
1865 INT Status=0;
1866 CHAR Ssid[MAX_LEN_OF_SSID +1];
1867 INT Rssi = 0, max_len = LINE_LEN;
1868 UINT Rssi_Quality = 0;
1869 NDIS_802_11_NETWORK_TYPE wireless_mode;
1870
1871 os_alloc_mem(NULL, (PUCHAR *)&msg, sizeof(CHAR)*((MAX_LEN_OF_BSS_TABLE)*max_len));
1872
1873 if (msg == NULL)
1874 {
1875 DBGPRINT(RT_DEBUG_TRACE, ("RTMPIoctlGetSiteSurvey - msg memory alloc fail.\n"));
1876 return;
1877 }
1878
1879 memset(msg, 0 ,(MAX_LEN_OF_BSS_TABLE)*max_len );
1880 memset(Ssid, 0 ,(MAX_LEN_OF_SSID +1));
1881 sprintf(msg,"%s","\n");
1882 sprintf(msg+strlen(msg),"%-4s%-33s%-20s%-8s%-10s%-9s%-7s%-3s\n",
1883 "Ch", "SSID", "BSSID", "Enc", "Auth", "Siganl(%)", "W-Mode", " NT");
1884
1885#ifdef CONFIG_STA_SUPPORT
1886#endif // CONFIG_STA_SUPPORT //
1887
1888 WaitCnt = 0;
1889#ifdef CONFIG_STA_SUPPORT
1890 pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
1891 while ((ScanRunning(pAdapter) == TRUE) && (WaitCnt++ < 200))
1892 OS_WAIT(500);
1893#endif // CONFIG_STA_SUPPORT //
1894
1895 for(i=0; i<pAdapter->ScanTab.BssNr ;i++)
1896 {
1897 if( pAdapter->ScanTab.BssEntry[i].Channel==0)
1898 break;
1899
1900 if((strlen(msg)+max_len ) >= IW_SCAN_MAX_DATA)
1901 break;
1902
1903 //Channel
1904 sprintf(msg+strlen(msg),"%-4d", pAdapter->ScanTab.BssEntry[i].Channel);
1905 //SSID
1906 memcpy(Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen);
1907 Ssid[pAdapter->ScanTab.BssEntry[i].SsidLen] = '\0';
1908 sprintf(msg+strlen(msg),"%-33s", Ssid);
1909 //BSSID
1910 sprintf(msg+strlen(msg),"%02x:%02x:%02x:%02x:%02x:%02x ",
1911 pAdapter->ScanTab.BssEntry[i].Bssid[0],
1912 pAdapter->ScanTab.BssEntry[i].Bssid[1],
1913 pAdapter->ScanTab.BssEntry[i].Bssid[2],
1914 pAdapter->ScanTab.BssEntry[i].Bssid[3],
1915 pAdapter->ScanTab.BssEntry[i].Bssid[4],
1916 pAdapter->ScanTab.BssEntry[i].Bssid[5]);
1917 //Encryption Type
1918 sprintf(msg+strlen(msg),"%-8s",GetEncryptType(pAdapter->ScanTab.BssEntry[i].WepStatus));
1919 //Authentication Mode
1920 if (pAdapter->ScanTab.BssEntry[i].WepStatus == Ndis802_11WEPEnabled)
1921 sprintf(msg+strlen(msg),"%-10s", "UNKNOW");
1922 else
1923 sprintf(msg+strlen(msg),"%-10s",GetAuthMode(pAdapter->ScanTab.BssEntry[i].AuthMode));
1924 // Rssi
1925 Rssi = (INT)pAdapter->ScanTab.BssEntry[i].Rssi;
1926 if (Rssi >= -50)
1927 Rssi_Quality = 100;
1928 else if (Rssi >= -80) // between -50 ~ -80dbm
1929 Rssi_Quality = (UINT)(24 + ((Rssi + 80) * 26)/10);
1930 else if (Rssi >= -90) // between -80 ~ -90dbm
1931 Rssi_Quality = (UINT)(((Rssi + 90) * 26)/10);
1932 else // < -84 dbm
1933 Rssi_Quality = 0;
1934 sprintf(msg+strlen(msg),"%-9d", Rssi_Quality);
1935 // Wireless Mode
1936 wireless_mode = NetworkTypeInUseSanity(&pAdapter->ScanTab.BssEntry[i]);
1937 if (wireless_mode == Ndis802_11FH ||
1938 wireless_mode == Ndis802_11DS)
1939 sprintf(msg+strlen(msg),"%-7s", "11b");
1940 else if (wireless_mode == Ndis802_11OFDM5)
1941 sprintf(msg+strlen(msg),"%-7s", "11a");
1942 else if (wireless_mode == Ndis802_11OFDM5_N)
1943 sprintf(msg+strlen(msg),"%-7s", "11a/n");
1944 else if (wireless_mode == Ndis802_11OFDM24)
1945 sprintf(msg+strlen(msg),"%-7s", "11b/g");
1946 else if (wireless_mode == Ndis802_11OFDM24_N)
1947 sprintf(msg+strlen(msg),"%-7s", "11b/g/n");
1948 else
1949 sprintf(msg+strlen(msg),"%-7s", "unknow");
1950 //Network Type
1951 if (pAdapter->ScanTab.BssEntry[i].BssType == BSS_ADHOC)
1952 sprintf(msg+strlen(msg),"%-3s", " Ad");
1953 else
1954 sprintf(msg+strlen(msg),"%-3s", " In");
1955
1956 sprintf(msg+strlen(msg),"\n");
1957#ifdef CONFIG_STA_SUPPORT
1958#endif // CONFIG_STA_SUPPORT //
1959 }
1960
1961#ifdef CONFIG_STA_SUPPORT
1962 pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
1963#endif // CONFIG_STA_SUPPORT //
1964 wrq->u.data.length = strlen(msg);
1965 Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
1966
1967 DBGPRINT(RT_DEBUG_TRACE, ("RTMPIoctlGetSiteSurvey - wrq->u.data.length = %d\n", wrq->u.data.length));
1968 os_free_mem(NULL, (PUCHAR)msg);
1969}
1970
1971
1972#define MAC_LINE_LEN (14+4+4+10+10+10+6+6) // Addr+aid+psm+datatime+rxbyte+txbyte+current tx rate+last tx rate
1973VOID RTMPIoctlGetMacTable(
1974 IN PRTMP_ADAPTER pAd,
1975 IN struct iwreq *wrq)
1976{
1977 INT i;
1978 RT_802_11_MAC_TABLE MacTab;
1979 char *msg;
1980
1981 MacTab.Num = 0;
1982 for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
1983 {
1984 if (pAd->MacTab.Content[i].ValidAsCLI && (pAd->MacTab.Content[i].Sst == SST_ASSOC))
1985 {
1986 COPY_MAC_ADDR(MacTab.Entry[MacTab.Num].Addr, &pAd->MacTab.Content[i].Addr);
1987 MacTab.Entry[MacTab.Num].Aid = (UCHAR)pAd->MacTab.Content[i].Aid;
1988 MacTab.Entry[MacTab.Num].Psm = pAd->MacTab.Content[i].PsMode;
1989#ifdef DOT11_N_SUPPORT
1990 MacTab.Entry[MacTab.Num].MimoPs = pAd->MacTab.Content[i].MmpsMode;
1991#endif // DOT11_N_SUPPORT //
1992
1993 // Fill in RSSI per entry
1994 MacTab.Entry[MacTab.Num].AvgRssi0 = pAd->MacTab.Content[i].RssiSample.AvgRssi0;
1995 MacTab.Entry[MacTab.Num].AvgRssi1 = pAd->MacTab.Content[i].RssiSample.AvgRssi1;
1996 MacTab.Entry[MacTab.Num].AvgRssi2 = pAd->MacTab.Content[i].RssiSample.AvgRssi2;
1997
1998 // the connected time per entry
1999 MacTab.Entry[MacTab.Num].ConnectedTime = pAd->MacTab.Content[i].StaConnectTime;
2000 MacTab.Entry[MacTab.Num].TxRate.field.MCS = pAd->MacTab.Content[i].HTPhyMode.field.MCS;
2001 MacTab.Entry[MacTab.Num].TxRate.field.BW = pAd->MacTab.Content[i].HTPhyMode.field.BW;
2002 MacTab.Entry[MacTab.Num].TxRate.field.ShortGI = pAd->MacTab.Content[i].HTPhyMode.field.ShortGI;
2003 MacTab.Entry[MacTab.Num].TxRate.field.STBC = pAd->MacTab.Content[i].HTPhyMode.field.STBC;
2004 MacTab.Entry[MacTab.Num].TxRate.field.rsv = pAd->MacTab.Content[i].HTPhyMode.field.rsv;
2005 MacTab.Entry[MacTab.Num].TxRate.field.MODE = pAd->MacTab.Content[i].HTPhyMode.field.MODE;
2006 MacTab.Entry[MacTab.Num].TxRate.word = pAd->MacTab.Content[i].HTPhyMode.word;
2007
2008 MacTab.Num += 1;
2009 }
2010 }
2011 wrq->u.data.length = sizeof(RT_802_11_MAC_TABLE);
2012 if (copy_to_user(wrq->u.data.pointer, &MacTab, wrq->u.data.length))
2013 {
2014 DBGPRINT(RT_DEBUG_TRACE, ("%s: copy_to_user() fail\n", __FUNCTION__));
2015 }
2016
2017 msg = (CHAR *) kmalloc(sizeof(CHAR)*(MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN), MEM_ALLOC_FLAG);
2018 memset(msg, 0 ,MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN );
2019 sprintf(msg,"%s","\n");
2020 sprintf(msg+strlen(msg),"%-14s%-4s%-4s%-10s%-10s%-10s%-6s%-6s\n",
2021 "MAC", "AID", "PSM", "LDT", "RxB", "TxB","CTxR", "LTxR");
2022
2023 for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
2024 {
2025 PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
2026 if (pEntry->ValidAsCLI && (pEntry->Sst == SST_ASSOC))
2027 {
2028 if((strlen(msg)+MAC_LINE_LEN ) >= (MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN) )
2029 break;
2030 sprintf(msg+strlen(msg),"%02x%02x%02x%02x%02x%02x ",
2031 pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
2032 pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
2033 sprintf(msg+strlen(msg),"%-4d", (int)pEntry->Aid);
2034 sprintf(msg+strlen(msg),"%-4d", (int)pEntry->PsMode);
2035 sprintf(msg+strlen(msg),"%-10d",0/*pAd->MacTab.Content[i].HSCounter.LastDataPacketTime*/); // ToDo
2036 sprintf(msg+strlen(msg),"%-10d",0/*pAd->MacTab.Content[i].HSCounter.TotalRxByteCount*/); // ToDo
2037 sprintf(msg+strlen(msg),"%-10d",0/*pAd->MacTab.Content[i].HSCounter.TotalTxByteCount*/); // ToDo
2038 sprintf(msg+strlen(msg),"%-6d",RateIdToMbps[pAd->MacTab.Content[i].CurrTxRate]);
2039 sprintf(msg+strlen(msg),"%-6d\n",0/*RateIdToMbps[pAd->MacTab.Content[i].LastTxRate]*/); // ToDo
2040 }
2041 }
2042 // for compatible with old API just do the printk to console
2043 //wrq->u.data.length = strlen(msg);
2044 //if (copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length))
2045 {
2046 DBGPRINT(RT_DEBUG_TRACE, ("%s", msg));
2047 }
2048
2049 kfree(msg);
2050}
2051#endif // UCOS //
2052
2053#ifdef DOT11_N_SUPPORT
2054INT Set_BASetup_Proc(
2055 IN PRTMP_ADAPTER pAd,
2056 IN PUCHAR arg)
2057{
2058 UCHAR mac[6], tid;
2059 char *token, sepValue[] = ":", DASH = '-';
2060 INT i;
2061 MAC_TABLE_ENTRY *pEntry;
2062
2063/*
2064 The BASetup inupt string format should be xx:xx:xx:xx:xx:xx-d,
2065 =>The six 2 digit hex-decimal number previous are the Mac address,
2066 =>The seventh decimal number is the tid value.
2067*/
2068 //printk("\n%s\n", arg);
2069
2070 if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and tid value in decimal format.
2071 return FALSE;
2072
2073 token = strchr(arg, DASH);
2074 if ((token != NULL) && (strlen(token)>1))
2075 {
2076 tid = simple_strtol((token+1), 0, 10);
2077 if (tid > 15)
2078 return FALSE;
2079
2080 *token = '\0';
2081 for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
2082 {
2083 if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
2084 return FALSE;
2085 AtoH(token, (PUCHAR)(&mac[i]), 1);
2086 }
2087 if(i != 6)
2088 return FALSE;
2089
2090 printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x\n", mac[0], mac[1],
2091 mac[2], mac[3], mac[4], mac[5], tid);
2092
2093 pEntry = MacTableLookup(pAd, mac);
2094
2095 if (pEntry) {
2096 printk("\nSetup BA Session: Tid = %d\n", tid);
2097 BAOriSessionSetUp(pAd, pEntry, tid, 0, 100, TRUE);
2098 }
2099
2100 return TRUE;
2101 }
2102
2103 return FALSE;
2104
2105}
2106
2107INT Set_BADecline_Proc(
2108 IN PRTMP_ADAPTER pAd,
2109 IN PUCHAR arg)
2110{
2111 ULONG bBADecline;
2112
2113 bBADecline = simple_strtol(arg, 0, 10);
2114
2115 if (bBADecline == 0)
2116 {
2117 pAd->CommonCfg.bBADecline = FALSE;
2118 }
2119 else if (bBADecline == 1)
2120 {
2121 pAd->CommonCfg.bBADecline = TRUE;
2122 }
2123 else
2124 {
2125 return FALSE; //Invalid argument
2126 }
2127
2128 DBGPRINT(RT_DEBUG_TRACE, ("Set_BADecline_Proc::(BADecline=%d)\n", pAd->CommonCfg.bBADecline));
2129
2130 return TRUE;
2131}
2132
2133INT Set_BAOriTearDown_Proc(
2134 IN PRTMP_ADAPTER pAd,
2135 IN PUCHAR arg)
2136{
2137 UCHAR mac[6], tid;
2138 char *token, sepValue[] = ":", DASH = '-';
2139 INT i;
2140 MAC_TABLE_ENTRY *pEntry;
2141
2142 //printk("\n%s\n", arg);
2143/*
2144 The BAOriTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d,
2145 =>The six 2 digit hex-decimal number previous are the Mac address,
2146 =>The seventh decimal number is the tid value.
2147*/
2148 if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and tid value in decimal format.
2149 return FALSE;
2150
2151 token = strchr(arg, DASH);
2152 if ((token != NULL) && (strlen(token)>1))
2153 {
2154 tid = simple_strtol((token+1), 0, 10);
2155 if (tid > NUM_OF_TID)
2156 return FALSE;
2157
2158 *token = '\0';
2159 for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
2160 {
2161 if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
2162 return FALSE;
2163 AtoH(token, (PUCHAR)(&mac[i]), 1);
2164 }
2165 if(i != 6)
2166 return FALSE;
2167
2168 printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", mac[0], mac[1],
2169 mac[2], mac[3], mac[4], mac[5], tid);
2170
2171 pEntry = MacTableLookup(pAd, mac);
2172
2173 if (pEntry) {
2174 printk("\nTear down Ori BA Session: Tid = %d\n", tid);
2175 BAOriSessionTearDown(pAd, pEntry->Aid, tid, FALSE, TRUE);
2176 }
2177
2178 return TRUE;
2179 }
2180
2181 return FALSE;
2182
2183}
2184
2185INT Set_BARecTearDown_Proc(
2186 IN PRTMP_ADAPTER pAd,
2187 IN PUCHAR arg)
2188{
2189 UCHAR mac[6], tid;
2190 char *token, sepValue[] = ":", DASH = '-';
2191 INT i;
2192 MAC_TABLE_ENTRY *pEntry;
2193
2194 //printk("\n%s\n", arg);
2195/*
2196 The BARecTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d,
2197 =>The six 2 digit hex-decimal number previous are the Mac address,
2198 =>The seventh decimal number is the tid value.
2199*/
2200 if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and tid value in decimal format.
2201 return FALSE;
2202
2203 token = strchr(arg, DASH);
2204 if ((token != NULL) && (strlen(token)>1))
2205 {
2206 tid = simple_strtol((token+1), 0, 10);
2207 if (tid > NUM_OF_TID)
2208 return FALSE;
2209
2210 *token = '\0';
2211 for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
2212 {
2213 if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
2214 return FALSE;
2215 AtoH(token, (PUCHAR)(&mac[i]), 1);
2216 }
2217 if(i != 6)
2218 return FALSE;
2219
2220 printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", mac[0], mac[1],
2221 mac[2], mac[3], mac[4], mac[5], tid);
2222
2223 pEntry = MacTableLookup(pAd, mac);
2224
2225 if (pEntry) {
2226 printk("\nTear down Rec BA Session: Tid = %d\n", tid);
2227 BARecSessionTearDown(pAd, pEntry->Aid, tid, FALSE);
2228 }
2229
2230 return TRUE;
2231 }
2232
2233 return FALSE;
2234
2235}
2236
2237INT Set_HtBw_Proc(
2238 IN PRTMP_ADAPTER pAd,
2239 IN PUCHAR arg)
2240{
2241 ULONG HtBw;
2242
2243 HtBw = simple_strtol(arg, 0, 10);
2244 if (HtBw == BW_40)
2245 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
2246 else if (HtBw == BW_20)
2247 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
2248 else
2249 return FALSE; //Invalid argument
2250
2251 SetCommonHT(pAd);
2252
2253 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtBw_Proc::(HtBw=%d)\n", pAd->CommonCfg.RegTransmitSetting.field.BW));
2254
2255 return TRUE;
2256}
2257
2258INT Set_HtMcs_Proc(
2259 IN PRTMP_ADAPTER pAd,
2260 IN PUCHAR arg)
2261{
2262 ULONG HtMcs, Mcs_tmp;
2263#ifdef CONFIG_STA_SUPPORT
2264 BOOLEAN bAutoRate = FALSE;
2265#endif // CONFIG_STA_SUPPORT //
2266
2267 Mcs_tmp = simple_strtol(arg, 0, 10);
2268
2269 if (Mcs_tmp <= 15 || Mcs_tmp == 32)
2270 HtMcs = Mcs_tmp;
2271 else
2272 HtMcs = MCS_AUTO;
2273
2274#ifdef CONFIG_STA_SUPPORT
2275 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2276 {
2277 pAd->StaCfg.DesiredTransmitSetting.field.MCS = HtMcs;
2278 pAd->StaCfg.bAutoTxRateSwitch = (HtMcs == MCS_AUTO) ? TRUE:FALSE;
2279 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMcs_Proc::(HtMcs=%d, bAutoTxRateSwitch = %d)\n",
2280 pAd->StaCfg.DesiredTransmitSetting.field.MCS, pAd->StaCfg.bAutoTxRateSwitch));
2281
2282 if ((pAd->CommonCfg.PhyMode < PHY_11ABGN_MIXED) ||
2283 (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE < MODE_HTMIX))
2284 {
2285 if ((pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO) &&
2286 (HtMcs >= 0 && HtMcs <= 3) &&
2287 (pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode == FIXED_TXMODE_CCK))
2288 {
2289 RTMPSetDesiredRates(pAd, (LONG) (RateIdToMbps[HtMcs] * 1000000));
2290 }
2291 else if ((pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO) &&
2292 (HtMcs >= 0 && HtMcs <= 7) &&
2293 (pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode == FIXED_TXMODE_OFDM))
2294 {
2295 RTMPSetDesiredRates(pAd, (LONG) (RateIdToMbps[HtMcs+4] * 1000000));
2296 }
2297 else
2298 bAutoRate = TRUE;
2299
2300 if (bAutoRate)
2301 {
2302 pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
2303 RTMPSetDesiredRates(pAd, -1);
2304 }
2305 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMcs_Proc::(FixedTxMode=%d)\n",pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode));
2306 }
2307 if (ADHOC_ON(pAd))
2308 return TRUE;
2309 }
2310#endif // CONFIG_STA_SUPPORT //
2311
2312 SetCommonHT(pAd);
2313
2314 return TRUE;
2315}
2316
2317INT Set_HtGi_Proc(
2318 IN PRTMP_ADAPTER pAd,
2319 IN PUCHAR arg)
2320{
2321 ULONG HtGi;
2322
2323 HtGi = simple_strtol(arg, 0, 10);
2324
2325 if ( HtGi == GI_400)
2326 pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_400;
2327 else if ( HtGi == GI_800 )
2328 pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_800;
2329 else
2330 return FALSE; //Invalid argument
2331
2332 SetCommonHT(pAd);
2333
2334 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtGi_Proc::(ShortGI=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.ShortGI));
2335
2336 return TRUE;
2337}
2338
2339
2340INT Set_HtTxBASize_Proc(
2341 IN PRTMP_ADAPTER pAd,
2342 IN PUCHAR arg)
2343{
2344 UCHAR Size;
2345
2346 Size = simple_strtol(arg, 0, 10);
2347
2348 if (Size <=0 || Size >=64)
2349 {
2350 Size = 8;
2351 }
2352 pAd->CommonCfg.TxBASize = Size-1;
2353 DBGPRINT(RT_DEBUG_ERROR, ("Set_HtTxBASize ::(TxBASize= %d)\n", Size));
2354
2355 return TRUE;
2356}
2357
2358
2359INT Set_HtOpMode_Proc(
2360 IN PRTMP_ADAPTER pAd,
2361 IN PUCHAR arg)
2362{
2363
2364 ULONG Value;
2365
2366 Value = simple_strtol(arg, 0, 10);
2367
2368 if (Value == HTMODE_GF)
2369 pAd->CommonCfg.RegTransmitSetting.field.HTMODE = HTMODE_GF;
2370 else if ( Value == HTMODE_MM )
2371 pAd->CommonCfg.RegTransmitSetting.field.HTMODE = HTMODE_MM;
2372 else
2373 return FALSE; //Invalid argument
2374
2375 SetCommonHT(pAd);
2376
2377 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtOpMode_Proc::(HtOpMode=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.HTMODE));
2378
2379 return TRUE;
2380
2381}
2382
2383INT Set_HtStbc_Proc(
2384 IN PRTMP_ADAPTER pAd,
2385 IN PUCHAR arg)
2386{
2387
2388 ULONG Value;
2389
2390 Value = simple_strtol(arg, 0, 10);
2391
2392 if (Value == STBC_USE)
2393 pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_USE;
2394 else if ( Value == STBC_NONE )
2395 pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_NONE;
2396 else
2397 return FALSE; //Invalid argument
2398
2399 SetCommonHT(pAd);
2400
2401 DBGPRINT(RT_DEBUG_TRACE, ("Set_Stbc_Proc::(HtStbc=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.STBC));
2402
2403 return TRUE;
2404}
2405
2406INT Set_HtHtc_Proc(
2407 IN PRTMP_ADAPTER pAd,
2408 IN PUCHAR arg)
2409{
2410
2411 ULONG Value;
2412
2413 Value = simple_strtol(arg, 0, 10);
2414 if (Value == 0)
2415 pAd->HTCEnable = FALSE;
2416 else if ( Value ==1 )
2417 pAd->HTCEnable = TRUE;
2418 else
2419 return FALSE; //Invalid argument
2420
2421 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtHtc_Proc::(HtHtc=%d)\n",pAd->HTCEnable));
2422
2423 return TRUE;
2424}
2425
2426INT Set_HtExtcha_Proc(
2427 IN PRTMP_ADAPTER pAd,
2428 IN PUCHAR arg)
2429{
2430
2431 ULONG Value;
2432
2433 Value = simple_strtol(arg, 0, 10);
2434
2435 if (Value == 0)
2436 pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_BELOW;
2437 else if ( Value ==1 )
2438 pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE;
2439 else
2440 return FALSE; //Invalid argument
2441
2442 SetCommonHT(pAd);
2443
2444 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtExtcha_Proc::(HtExtcha=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.EXTCHA));
2445
2446 return TRUE;
2447}
2448
2449INT Set_HtMpduDensity_Proc(
2450 IN PRTMP_ADAPTER pAd,
2451 IN PUCHAR arg)
2452{
2453 ULONG Value;
2454
2455 Value = simple_strtol(arg, 0, 10);
2456
2457 if (Value <=7 && Value >= 0)
2458 pAd->CommonCfg.BACapability.field.MpduDensity = Value;
2459 else
2460 pAd->CommonCfg.BACapability.field.MpduDensity = 4;
2461
2462 SetCommonHT(pAd);
2463
2464 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMpduDensity_Proc::(HtMpduDensity=%d)\n",pAd->CommonCfg.BACapability.field.MpduDensity));
2465
2466 return TRUE;
2467}
2468
2469INT Set_HtBaWinSize_Proc(
2470 IN PRTMP_ADAPTER pAd,
2471 IN PUCHAR arg)
2472{
2473 ULONG Value;
2474
2475 Value = simple_strtol(arg, 0, 10);
2476
2477
2478 if (Value >=1 && Value <= 64)
2479 {
2480 pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = Value;
2481 pAd->CommonCfg.BACapability.field.RxBAWinLimit = Value;
2482 }
2483 else
2484 {
2485 pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = 64;
2486 pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64;
2487 }
2488
2489 SetCommonHT(pAd);
2490
2491 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtBaWinSize_Proc::(HtBaWinSize=%d)\n",pAd->CommonCfg.BACapability.field.RxBAWinLimit));
2492
2493 return TRUE;
2494}
2495
2496INT Set_HtRdg_Proc(
2497 IN PRTMP_ADAPTER pAd,
2498 IN PUCHAR arg)
2499{
2500 ULONG Value;
2501
2502 Value = simple_strtol(arg, 0, 10);
2503
2504 if (Value == 0)
2505 pAd->CommonCfg.bRdg = FALSE;
2506 else if ( Value ==1 )
2507 {
2508 pAd->HTCEnable = TRUE;
2509 pAd->CommonCfg.bRdg = TRUE;
2510 }
2511 else
2512 return FALSE; //Invalid argument
2513
2514 SetCommonHT(pAd);
2515
2516 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtRdg_Proc::(HtRdg=%d)\n",pAd->CommonCfg.bRdg));
2517
2518 return TRUE;
2519}
2520
2521INT Set_HtLinkAdapt_Proc(
2522 IN PRTMP_ADAPTER pAd,
2523 IN PUCHAR arg)
2524{
2525 ULONG Value;
2526
2527 Value = simple_strtol(arg, 0, 10);
2528 if (Value == 0)
2529 pAd->bLinkAdapt = FALSE;
2530 else if ( Value ==1 )
2531 {
2532 pAd->HTCEnable = TRUE;
2533 pAd->bLinkAdapt = TRUE;
2534 }
2535 else
2536 return FALSE; //Invalid argument
2537
2538 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtLinkAdapt_Proc::(HtLinkAdapt=%d)\n",pAd->bLinkAdapt));
2539
2540 return TRUE;
2541}
2542
2543INT Set_HtAmsdu_Proc(
2544 IN PRTMP_ADAPTER pAd,
2545 IN PUCHAR arg)
2546{
2547 ULONG Value;
2548
2549 Value = simple_strtol(arg, 0, 10);
2550 if (Value == 0)
2551 pAd->CommonCfg.BACapability.field.AmsduEnable = FALSE;
2552 else if ( Value == 1 )
2553 pAd->CommonCfg.BACapability.field.AmsduEnable = TRUE;
2554 else
2555 return FALSE; //Invalid argument
2556
2557 SetCommonHT(pAd);
2558
2559 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtAmsdu_Proc::(HtAmsdu=%d)\n",pAd->CommonCfg.BACapability.field.AmsduEnable));
2560
2561 return TRUE;
2562}
2563
2564INT Set_HtAutoBa_Proc(
2565 IN PRTMP_ADAPTER pAd,
2566 IN PUCHAR arg)
2567{
2568 ULONG Value;
2569
2570 Value = simple_strtol(arg, 0, 10);
2571 if (Value == 0)
2572 {
2573 pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
2574 pAd->CommonCfg.BACapability.field.Policy = BA_NOTUSE;
2575 }
2576 else if (Value == 1)
2577 {
2578 pAd->CommonCfg.BACapability.field.AutoBA = TRUE;
2579 pAd->CommonCfg.BACapability.field.Policy = IMMED_BA;
2580 }
2581 else
2582 return FALSE; //Invalid argument
2583
2584 pAd->CommonCfg.REGBACapability.field.AutoBA = pAd->CommonCfg.BACapability.field.AutoBA;
2585 pAd->CommonCfg.REGBACapability.field.Policy = pAd->CommonCfg.BACapability.field.Policy;
2586 SetCommonHT(pAd);
2587
2588 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtAutoBa_Proc::(HtAutoBa=%d)\n",pAd->CommonCfg.BACapability.field.AutoBA));
2589
2590 return TRUE;
2591
2592}
2593
2594INT Set_HtProtect_Proc(
2595 IN PRTMP_ADAPTER pAd,
2596 IN PUCHAR arg)
2597{
2598 ULONG Value;
2599
2600 Value = simple_strtol(arg, 0, 10);
2601 if (Value == 0)
2602 pAd->CommonCfg.bHTProtect = FALSE;
2603 else if (Value == 1)
2604 pAd->CommonCfg.bHTProtect = TRUE;
2605 else
2606 return FALSE; //Invalid argument
2607
2608 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtProtect_Proc::(HtProtect=%d)\n",pAd->CommonCfg.bHTProtect));
2609
2610 return TRUE;
2611}
2612
2613INT Set_SendPSMPAction_Proc(
2614 IN PRTMP_ADAPTER pAd,
2615 IN PUCHAR arg)
2616{
2617 UCHAR mac[6], mode;
2618 char *token, sepValue[] = ":", DASH = '-';
2619 INT i;
2620 MAC_TABLE_ENTRY *pEntry;
2621
2622 //printk("\n%s\n", arg);
2623/*
2624 The BARecTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d,
2625 =>The six 2 digit hex-decimal number previous are the Mac address,
2626 =>The seventh decimal number is the mode value.
2627*/
2628 if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and mode value in decimal format.
2629 return FALSE;
2630
2631 token = strchr(arg, DASH);
2632 if ((token != NULL) && (strlen(token)>1))
2633 {
2634 mode = simple_strtol((token+1), 0, 10);
2635 if (mode > MMPS_ENABLE)
2636 return FALSE;
2637
2638 *token = '\0';
2639 for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
2640 {
2641 if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
2642 return FALSE;
2643 AtoH(token, (PUCHAR)(&mac[i]), 1);
2644 }
2645 if(i != 6)
2646 return FALSE;
2647
2648 printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", mac[0], mac[1],
2649 mac[2], mac[3], mac[4], mac[5], mode);
2650
2651 pEntry = MacTableLookup(pAd, mac);
2652
2653 if (pEntry) {
2654 printk("\nSendPSMPAction MIPS mode = %d\n", mode);
2655 SendPSMPAction(pAd, pEntry->Aid, mode);
2656 }
2657
2658 return TRUE;
2659 }
2660
2661 return FALSE;
2662
2663
2664}
2665
2666INT Set_HtMIMOPSmode_Proc(
2667 IN PRTMP_ADAPTER pAd,
2668 IN PUCHAR arg)
2669{
2670 ULONG Value;
2671
2672 Value = simple_strtol(arg, 0, 10);
2673
2674 if (Value <=3 && Value >= 0)
2675 pAd->CommonCfg.BACapability.field.MMPSmode = Value;
2676 else
2677 pAd->CommonCfg.BACapability.field.MMPSmode = 3;
2678
2679 SetCommonHT(pAd);
2680
2681 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMIMOPSmode_Proc::(MIMOPS mode=%d)\n",pAd->CommonCfg.BACapability.field.MMPSmode));
2682
2683 return TRUE;
2684}
2685
2686
2687INT Set_ForceShortGI_Proc(
2688 IN PRTMP_ADAPTER pAd,
2689 IN PUCHAR arg)
2690{
2691 ULONG Value;
2692
2693 Value = simple_strtol(arg, 0, 10);
2694 if (Value == 0)
2695 pAd->WIFItestbed.bShortGI = FALSE;
2696 else if (Value == 1)
2697 pAd->WIFItestbed.bShortGI = TRUE;
2698 else
2699 return FALSE; //Invalid argument
2700
2701 SetCommonHT(pAd);
2702
2703 DBGPRINT(RT_DEBUG_TRACE, ("Set_ForceShortGI_Proc::(ForceShortGI=%d)\n", pAd->WIFItestbed.bShortGI));
2704
2705 return TRUE;
2706}
2707
2708
2709
2710INT Set_ForceGF_Proc(
2711 IN PRTMP_ADAPTER pAd,
2712 IN PUCHAR arg)
2713{
2714 ULONG Value;
2715
2716 Value = simple_strtol(arg, 0, 10);
2717 if (Value == 0)
2718 pAd->WIFItestbed.bGreenField = FALSE;
2719 else if (Value == 1)
2720 pAd->WIFItestbed.bGreenField = TRUE;
2721 else
2722 return FALSE; //Invalid argument
2723
2724 SetCommonHT(pAd);
2725
2726 DBGPRINT(RT_DEBUG_TRACE, ("Set_ForceGF_Proc::(ForceGF=%d)\n", pAd->WIFItestbed.bGreenField));
2727
2728 return TRUE;
2729}
2730
2731INT Set_HtMimoPs_Proc(
2732 IN PRTMP_ADAPTER pAd,
2733 IN PUCHAR arg)
2734{
2735 ULONG Value;
2736
2737 Value = simple_strtol(arg, 0, 10);
2738 if (Value == 0)
2739 pAd->CommonCfg.bMIMOPSEnable = FALSE;
2740 else if (Value == 1)
2741 pAd->CommonCfg.bMIMOPSEnable = TRUE;
2742 else
2743 return FALSE; //Invalid argument
2744
2745 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMimoPs_Proc::(HtMimoPs=%d)\n",pAd->CommonCfg.bMIMOPSEnable));
2746
2747 return TRUE;
2748}
2749#endif // DOT11_N_SUPPORT //
2750
2751
2752#ifdef DOT11_N_SUPPORT
2753INT SetCommonHT(
2754 IN PRTMP_ADAPTER pAd)
2755{
2756 OID_SET_HT_PHYMODE SetHT;
2757
2758 if (pAd->CommonCfg.PhyMode < PHY_11ABGN_MIXED)
2759 return FALSE;
2760
2761 SetHT.PhyMode = pAd->CommonCfg.PhyMode;
2762 SetHT.TransmitNo = ((UCHAR)pAd->Antenna.field.TxPath);
2763 SetHT.HtMode = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.HTMODE;
2764 SetHT.ExtOffset = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.EXTCHA;
2765 SetHT.MCS = MCS_AUTO;
2766 SetHT.BW = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.BW;
2767 SetHT.STBC = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.STBC;
2768 SetHT.SHORTGI = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.ShortGI;
2769
2770 RTMPSetHT(pAd, &SetHT);
2771
2772 return TRUE;
2773}
2774#endif // DOT11_N_SUPPORT //
2775
2776INT Set_FixedTxMode_Proc(
2777 IN PRTMP_ADAPTER pAd,
2778 IN PUCHAR arg)
2779{
2780 UCHAR fix_tx_mode = FIXED_TXMODE_HT;
2781
2782 if (strcmp(arg, "OFDM") == 0 || strcmp(arg, "ofdm") == 0)
2783 {
2784 fix_tx_mode = FIXED_TXMODE_OFDM;
2785 }
2786 else if (strcmp(arg, "CCK") == 0 || strcmp(arg, "cck") == 0)
2787 {
2788 fix_tx_mode = FIXED_TXMODE_CCK;
2789 }
2790
2791#ifdef CONFIG_STA_SUPPORT
2792 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2793 pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode = fix_tx_mode;
2794#endif // CONFIG_STA_SUPPORT //
2795
2796 DBGPRINT(RT_DEBUG_TRACE, ("Set_FixedTxMode_Proc::(FixedTxMode=%d)\n", fix_tx_mode));
2797
2798 return TRUE;
2799}
2800
2801#ifdef CONFIG_APSTA_MIXED_SUPPORT
2802INT Set_OpMode_Proc(
2803 IN PRTMP_ADAPTER pAd,
2804 IN PUCHAR arg)
2805{
2806 ULONG Value;
2807
2808 Value = simple_strtol(arg, 0, 10);
2809
2810#ifdef RT2870
2811 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
2812#endif // RT2870 //
2813 {
2814 DBGPRINT(RT_DEBUG_ERROR, ("Can not switch operate mode on interface up !! \n"));
2815 return FALSE;
2816 }
2817
2818 if (Value == 0)
2819 pAd->OpMode = OPMODE_STA;
2820 else if (Value == 1)
2821 pAd->OpMode = OPMODE_AP;
2822 else
2823 return FALSE; //Invalid argument
2824
2825 DBGPRINT(RT_DEBUG_TRACE, ("Set_OpMode_Proc::(OpMode=%s)\n", pAd->OpMode == 1 ? "AP Mode" : "STA Mode"));
2826
2827 return TRUE;
2828}
2829#endif // CONFIG_APSTA_MIXED_SUPPORT //
2830
2831
2832/////////////////////////////////////////////////////////////////////////
2833PCHAR RTMPGetRalinkAuthModeStr(
2834 IN NDIS_802_11_AUTHENTICATION_MODE authMode)
2835{
2836 switch(authMode)
2837 {
2838 case Ndis802_11AuthModeOpen:
2839 return "OPEN";
2840 default:
2841 case Ndis802_11AuthModeWPAPSK:
2842 return "WPAPSK";
2843 case Ndis802_11AuthModeShared:
2844 return "SHARED";
2845 case Ndis802_11AuthModeWPA:
2846 return "WPA";
2847 case Ndis802_11AuthModeWPA2:
2848 return "WPA2";
2849 case Ndis802_11AuthModeWPA2PSK:
2850 return "WPA2PSK";
2851 case Ndis802_11AuthModeWPA1PSKWPA2PSK:
2852 return "WPAPSKWPA2PSK";
2853 case Ndis802_11AuthModeWPA1WPA2:
2854 return "WPA1WPA2";
2855 }
2856}
2857
2858PCHAR RTMPGetRalinkEncryModeStr(
2859 IN USHORT encryMode)
2860{
2861 switch(encryMode)
2862 {
2863 default:
2864 case Ndis802_11WEPDisabled:
2865 return "NONE";
2866 case Ndis802_11WEPEnabled:
2867 return "WEP";
2868 case Ndis802_11Encryption2Enabled:
2869 return "TKIP";
2870 case Ndis802_11Encryption3Enabled:
2871 return "AES";
2872 case Ndis802_11Encryption4Enabled:
2873 return "TKIPAES";
2874 }
2875}
2876
2877INT RTMPShowCfgValue(
2878 IN PRTMP_ADAPTER pAd,
2879 IN PUCHAR pName,
2880 IN PUCHAR pBuf)
2881{
2882 INT Status = 0;
2883
2884 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++)
2885 {
2886 if (!strcmp(pName, PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name))
2887 {
2888 if(PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->show_proc(pAd, pBuf))
2889 Status = -EINVAL;
2890 break; //Exit for loop.
2891 }
2892 }
2893
2894 if(PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name == NULL)
2895 {
2896 sprintf(pBuf, "\n");
2897 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++)
2898 sprintf(pBuf, "%s%s\n", pBuf, PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name);
2899 }
2900
2901 return Status;
2902}
2903
2904INT Show_SSID_Proc(
2905 IN PRTMP_ADAPTER pAd,
2906 OUT PUCHAR pBuf)
2907{
2908
2909#ifdef CONFIG_STA_SUPPORT
2910 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2911 sprintf(pBuf, "\t%s", pAd->CommonCfg.Ssid);
2912#endif // CONFIG_STA_SUPPORT //
2913 return 0;
2914}
2915
2916INT Show_WirelessMode_Proc(
2917 IN PRTMP_ADAPTER pAd,
2918 OUT PUCHAR pBuf)
2919{
2920 switch(pAd->CommonCfg.PhyMode)
2921 {
2922 case PHY_11BG_MIXED:
2923 sprintf(pBuf, "\t11B/G");
2924 break;
2925 case PHY_11B:
2926 sprintf(pBuf, "\t11B");
2927 break;
2928 case PHY_11A:
2929 sprintf(pBuf, "\t11A");
2930 break;
2931 case PHY_11ABG_MIXED:
2932 sprintf(pBuf, "\t11A/B/G");
2933 break;
2934 case PHY_11G:
2935 sprintf(pBuf, "\t11G");
2936 break;
2937#ifdef DOT11_N_SUPPORT
2938 case PHY_11ABGN_MIXED:
2939 sprintf(pBuf, "\t11A/B/G/N");
2940 break;
2941 case PHY_11N_2_4G:
2942 sprintf(pBuf, "\t11N only with 2.4G");
2943 break;
2944 case PHY_11GN_MIXED:
2945 sprintf(pBuf, "\t11G/N");
2946 break;
2947 case PHY_11AN_MIXED:
2948 sprintf(pBuf, "\t11A/N");
2949 break;
2950 case PHY_11BGN_MIXED:
2951 sprintf(pBuf, "\t11B/G/N");
2952 break;
2953 case PHY_11AGN_MIXED:
2954 sprintf(pBuf, "\t11A/G/N");
2955 break;
2956 case PHY_11N_5G:
2957 sprintf(pBuf, "\t11N only with 5G");
2958 break;
2959#endif // DOT11_N_SUPPORT //
2960 default:
2961 sprintf(pBuf, "\tUnknow Value(%d)", pAd->CommonCfg.PhyMode);
2962 break;
2963 }
2964 return 0;
2965}
2966
2967
2968INT Show_TxBurst_Proc(
2969 IN PRTMP_ADAPTER pAd,
2970 OUT PUCHAR pBuf)
2971{
2972 sprintf(pBuf, "\t%s", pAd->CommonCfg.bEnableTxBurst ? "TRUE":"FALSE");
2973 return 0;
2974}
2975
2976INT Show_TxPreamble_Proc(
2977 IN PRTMP_ADAPTER pAd,
2978 OUT PUCHAR pBuf)
2979{
2980 switch(pAd->CommonCfg.TxPreamble)
2981 {
2982 case Rt802_11PreambleShort:
2983 sprintf(pBuf, "\tShort");
2984 break;
2985 case Rt802_11PreambleLong:
2986 sprintf(pBuf, "\tLong");
2987 break;
2988 case Rt802_11PreambleAuto:
2989 sprintf(pBuf, "\tAuto");
2990 break;
2991 default:
2992 sprintf(pBuf, "\tUnknow Value(%lu)", pAd->CommonCfg.TxPreamble);
2993 break;
2994 }
2995
2996 return 0;
2997}
2998
2999INT Show_TxPower_Proc(
3000 IN PRTMP_ADAPTER pAd,
3001 OUT PUCHAR pBuf)
3002{
3003 sprintf(pBuf, "\t%lu", pAd->CommonCfg.TxPowerPercentage);
3004 return 0;
3005}
3006
3007INT Show_Channel_Proc(
3008 IN PRTMP_ADAPTER pAd,
3009 OUT PUCHAR pBuf)
3010{
3011 sprintf(pBuf, "\t%d", pAd->CommonCfg.Channel);
3012 return 0;
3013}
3014
3015INT Show_BGProtection_Proc(
3016 IN PRTMP_ADAPTER pAd,
3017 OUT PUCHAR pBuf)
3018{
3019 switch(pAd->CommonCfg.UseBGProtection)
3020 {
3021 case 1: //Always On
3022 sprintf(pBuf, "\tON");
3023 break;
3024 case 2: //Always OFF
3025 sprintf(pBuf, "\tOFF");
3026 break;
3027 case 0: //AUTO
3028 sprintf(pBuf, "\tAuto");
3029 break;
3030 default:
3031 sprintf(pBuf, "\tUnknow Value(%lu)", pAd->CommonCfg.UseBGProtection);
3032 break;
3033 }
3034 return 0;
3035}
3036
3037INT Show_RTSThreshold_Proc(
3038 IN PRTMP_ADAPTER pAd,
3039 OUT PUCHAR pBuf)
3040{
3041 sprintf(pBuf, "\t%u", pAd->CommonCfg.RtsThreshold);
3042 return 0;
3043}
3044
3045INT Show_FragThreshold_Proc(
3046 IN PRTMP_ADAPTER pAd,
3047 OUT PUCHAR pBuf)
3048{
3049 sprintf(pBuf, "\t%u", pAd->CommonCfg.FragmentThreshold);
3050 return 0;
3051}
3052
3053#ifdef DOT11_N_SUPPORT
3054INT Show_HtBw_Proc(
3055 IN PRTMP_ADAPTER pAd,
3056 OUT PUCHAR pBuf)
3057{
3058 if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
3059 {
3060 sprintf(pBuf, "\t40 MHz");
3061 }
3062 else
3063 {
3064 sprintf(pBuf, "\t20 MHz");
3065 }
3066 return 0;
3067}
3068
3069INT Show_HtMcs_Proc(
3070 IN PRTMP_ADAPTER pAd,
3071 OUT PUCHAR pBuf)
3072{
3073
3074#ifdef CONFIG_STA_SUPPORT
3075 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3076 sprintf(pBuf, "\t%u", pAd->StaCfg.DesiredTransmitSetting.field.MCS);
3077#endif // CONFIG_STA_SUPPORT //
3078 return 0;
3079}
3080
3081INT Show_HtGi_Proc(
3082 IN PRTMP_ADAPTER pAd,
3083 OUT PUCHAR pBuf)
3084{
3085 switch(pAd->CommonCfg.RegTransmitSetting.field.ShortGI)
3086 {
3087 case GI_400:
3088 sprintf(pBuf, "\tGI_400");
3089 break;
3090 case GI_800:
3091 sprintf(pBuf, "\tGI_800");
3092 break;
3093 default:
3094 sprintf(pBuf, "\tUnknow Value(%u)", pAd->CommonCfg.RegTransmitSetting.field.ShortGI);
3095 break;
3096 }
3097 return 0;
3098}
3099
3100INT Show_HtOpMode_Proc(
3101 IN PRTMP_ADAPTER pAd,
3102 OUT PUCHAR pBuf)
3103{
3104 switch(pAd->CommonCfg.RegTransmitSetting.field.HTMODE)
3105 {
3106 case HTMODE_GF:
3107 sprintf(pBuf, "\tGF");
3108 break;
3109 case HTMODE_MM:
3110 sprintf(pBuf, "\tMM");
3111 break;
3112 default:
3113 sprintf(pBuf, "\tUnknow Value(%u)", pAd->CommonCfg.RegTransmitSetting.field.HTMODE);
3114 break;
3115 }
3116 return 0;
3117}
3118
3119INT Show_HtExtcha_Proc(
3120 IN PRTMP_ADAPTER pAd,
3121 OUT PUCHAR pBuf)
3122{
3123 switch(pAd->CommonCfg.RegTransmitSetting.field.EXTCHA)
3124 {
3125 case EXTCHA_BELOW:
3126 sprintf(pBuf, "\tBelow");
3127 break;
3128 case EXTCHA_ABOVE:
3129 sprintf(pBuf, "\tAbove");
3130 break;
3131 default:
3132 sprintf(pBuf, "\tUnknow Value(%u)", pAd->CommonCfg.RegTransmitSetting.field.EXTCHA);
3133 break;
3134 }
3135 return 0;
3136}
3137
3138
3139INT Show_HtMpduDensity_Proc(
3140 IN PRTMP_ADAPTER pAd,
3141 OUT PUCHAR pBuf)
3142{
3143 sprintf(pBuf, "\t%u", pAd->CommonCfg.BACapability.field.MpduDensity);
3144 return 0;
3145}
3146
3147INT Show_HtBaWinSize_Proc(
3148 IN PRTMP_ADAPTER pAd,
3149 OUT PUCHAR pBuf)
3150{
3151 sprintf(pBuf, "\t%u", pAd->CommonCfg.BACapability.field.RxBAWinLimit);
3152 return 0;
3153}
3154
3155INT Show_HtRdg_Proc(
3156 IN PRTMP_ADAPTER pAd,
3157 OUT PUCHAR pBuf)
3158{
3159 sprintf(pBuf, "\t%s", pAd->CommonCfg.bRdg ? "TRUE":"FALSE");
3160 return 0;
3161}
3162
3163INT Show_HtAmsdu_Proc(
3164 IN PRTMP_ADAPTER pAd,
3165 OUT PUCHAR pBuf)
3166{
3167 sprintf(pBuf, "\t%s", pAd->CommonCfg.BACapability.field.AmsduEnable ? "TRUE":"FALSE");
3168 return 0;
3169}
3170
3171INT Show_HtAutoBa_Proc(
3172 IN PRTMP_ADAPTER pAd,
3173 OUT PUCHAR pBuf)
3174{
3175 sprintf(pBuf, "\t%s", pAd->CommonCfg.BACapability.field.AutoBA ? "TRUE":"FALSE");
3176 return 0;
3177}
3178#endif // DOT11_N_SUPPORT //
3179
3180INT Show_CountryRegion_Proc(
3181 IN PRTMP_ADAPTER pAd,
3182 OUT PUCHAR pBuf)
3183{
3184 sprintf(pBuf, "\t%d", pAd->CommonCfg.CountryRegion);
3185 return 0;
3186}
3187
3188INT Show_CountryRegionABand_Proc(
3189 IN PRTMP_ADAPTER pAd,
3190 OUT PUCHAR pBuf)
3191{
3192 sprintf(pBuf, "\t%d", pAd->CommonCfg.CountryRegionForABand);
3193 return 0;
3194}
3195
3196INT Show_CountryCode_Proc(
3197 IN PRTMP_ADAPTER pAd,
3198 OUT PUCHAR pBuf)
3199{
3200 sprintf(pBuf, "\t%s", pAd->CommonCfg.CountryCode);
3201 return 0;
3202}
3203
3204#ifdef AGGREGATION_SUPPORT
3205INT Show_PktAggregate_Proc(
3206 IN PRTMP_ADAPTER pAd,
3207 OUT PUCHAR pBuf)
3208{
3209 sprintf(pBuf, "\t%s", pAd->CommonCfg.bAggregationCapable ? "TRUE":"FALSE");
3210 return 0;
3211}
3212#endif // AGGREGATION_SUPPORT //
3213
3214#ifdef WMM_SUPPORT
3215INT Show_WmmCapable_Proc(
3216 IN PRTMP_ADAPTER pAd,
3217 OUT PUCHAR pBuf)
3218{
3219
3220#ifdef CONFIG_STA_SUPPORT
3221 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3222 sprintf(pBuf, "\t%s", pAd->CommonCfg.bWmmCapable ? "TRUE":"FALSE");
3223#endif // CONFIG_STA_SUPPORT //
3224
3225 return 0;
3226}
3227#endif // WMM_SUPPORT //
3228
3229INT Show_IEEE80211H_Proc(
3230 IN PRTMP_ADAPTER pAd,
3231 OUT PUCHAR pBuf)
3232{
3233 sprintf(pBuf, "\t%s", pAd->CommonCfg.bIEEE80211H ? "TRUE":"FALSE");
3234 return 0;
3235}
3236
3237#ifdef CONFIG_STA_SUPPORT
3238INT Show_NetworkType_Proc(
3239 IN PRTMP_ADAPTER pAd,
3240 OUT PUCHAR pBuf)
3241{
3242 switch(pAd->StaCfg.BssType)
3243 {
3244 case BSS_ADHOC:
3245 sprintf(pBuf, "\tAdhoc");
3246 break;
3247 case BSS_INFRA:
3248 sprintf(pBuf, "\tInfra");
3249 break;
3250 case BSS_ANY:
3251 sprintf(pBuf, "\tAny");
3252 break;
3253 case BSS_MONITOR:
3254 sprintf(pBuf, "\tMonitor");
3255 break;
3256 default:
3257 sprintf(pBuf, "\tUnknow Value(%d)", pAd->StaCfg.BssType);
3258 break;
3259 }
3260 return 0;
3261}
3262#endif // CONFIG_STA_SUPPORT //
3263
3264INT Show_AuthMode_Proc(
3265 IN PRTMP_ADAPTER pAd,
3266 OUT PUCHAR pBuf)
3267{
3268 NDIS_802_11_AUTHENTICATION_MODE AuthMode = Ndis802_11AuthModeOpen;
3269
3270#ifdef CONFIG_STA_SUPPORT
3271 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3272 AuthMode = pAd->StaCfg.AuthMode;
3273#endif // CONFIG_STA_SUPPORT //
3274
3275 if ((AuthMode >= Ndis802_11AuthModeOpen) &&
3276 (AuthMode <= Ndis802_11AuthModeWPA1PSKWPA2PSK))
3277 sprintf(pBuf, "\t%s", RTMPGetRalinkAuthModeStr(AuthMode));
3278 else
3279 sprintf(pBuf, "\tUnknow Value(%d)", AuthMode);
3280
3281 return 0;
3282}
3283
3284INT Show_EncrypType_Proc(
3285 IN PRTMP_ADAPTER pAd,
3286 OUT PUCHAR pBuf)
3287{
3288 NDIS_802_11_WEP_STATUS WepStatus = Ndis802_11WEPDisabled;
3289
3290#ifdef CONFIG_STA_SUPPORT
3291 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3292 WepStatus = pAd->StaCfg.WepStatus;
3293#endif // CONFIG_STA_SUPPORT //
3294
3295 if ((WepStatus >= Ndis802_11WEPEnabled) &&
3296 (WepStatus <= Ndis802_11Encryption4KeyAbsent))
3297 sprintf(pBuf, "\t%s", RTMPGetRalinkEncryModeStr(WepStatus));
3298 else
3299 sprintf(pBuf, "\tUnknow Value(%d)", WepStatus);
3300
3301 return 0;
3302}
3303
3304INT Show_DefaultKeyID_Proc(
3305 IN PRTMP_ADAPTER pAd,
3306 OUT PUCHAR pBuf)
3307{
3308 UCHAR DefaultKeyId = 0;
3309
3310#ifdef CONFIG_STA_SUPPORT
3311 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3312 DefaultKeyId = pAd->StaCfg.DefaultKeyId;
3313#endif // CONFIG_STA_SUPPORT //
3314
3315 sprintf(pBuf, "\t%d", DefaultKeyId);
3316
3317 return 0;
3318}
3319
3320INT Show_WepKey_Proc(
3321 IN PRTMP_ADAPTER pAd,
3322 IN INT KeyIdx,
3323 OUT PUCHAR pBuf)
3324{
3325 UCHAR Key[16] = {0}, KeyLength = 0;
3326 INT index = BSS0;
3327
3328 KeyLength = pAd->SharedKey[index][KeyIdx].KeyLen;
3329 NdisMoveMemory(Key, pAd->SharedKey[index][KeyIdx].Key, KeyLength);
3330
3331 //check key string is ASCII or not
3332 if (RTMPCheckStrPrintAble(Key, KeyLength))
3333 sprintf(pBuf, "\t%s", Key);
3334 else
3335 {
3336 int idx;
3337 sprintf(pBuf, "\t");
3338 for (idx = 0; idx < KeyLength; idx++)
3339 sprintf(pBuf+strlen(pBuf), "%02X", Key[idx]);
3340 }
3341 return 0;
3342}
3343
3344INT Show_Key1_Proc(
3345 IN PRTMP_ADAPTER pAd,
3346 OUT PUCHAR pBuf)
3347{
3348 Show_WepKey_Proc(pAd, 0, pBuf);
3349 return 0;
3350}
3351
3352INT Show_Key2_Proc(
3353 IN PRTMP_ADAPTER pAd,
3354 OUT PUCHAR pBuf)
3355{
3356 Show_WepKey_Proc(pAd, 1, pBuf);
3357 return 0;
3358}
3359
3360INT Show_Key3_Proc(
3361 IN PRTMP_ADAPTER pAd,
3362 OUT PUCHAR pBuf)
3363{
3364 Show_WepKey_Proc(pAd, 2, pBuf);
3365 return 0;
3366}
3367
3368INT Show_Key4_Proc(
3369 IN PRTMP_ADAPTER pAd,
3370 OUT PUCHAR pBuf)
3371{
3372 Show_WepKey_Proc(pAd, 3, pBuf);
3373 return 0;
3374}
3375
3376INT Show_WPAPSK_Proc(
3377 IN PRTMP_ADAPTER pAd,
3378 OUT PUCHAR pBuf)
3379{
3380 INT idx;
3381 UCHAR PMK[32] = {0};
3382
3383
3384#ifdef CONFIG_STA_SUPPORT
3385 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3386 NdisMoveMemory(PMK, pAd->StaCfg.PMK, 32);
3387#endif // CONFIG_STA_SUPPORT //
3388
3389 sprintf(pBuf, "\tPMK = ");
3390 for (idx = 0; idx < 32; idx++)
3391 sprintf(pBuf+strlen(pBuf), "%02X", PMK[idx]);
3392
3393 return 0;
3394}
3395
diff --git a/drivers/staging/rt3070/common/cmm_sanity.c b/drivers/staging/rt3070/common/cmm_sanity.c
new file mode 100644
index 000000000000..6118df8de7bb
--- /dev/null
+++ b/drivers/staging/rt3070/common/cmm_sanity.c
@@ -0,0 +1,1669 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 sanity.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 John Chang 2004-09-01 add WMM support
36*/
37#include "../rt_config.h"
38
39
40extern UCHAR CISCO_OUI[];
41
42extern UCHAR WPA_OUI[];
43extern UCHAR RSN_OUI[];
44extern UCHAR WME_INFO_ELEM[];
45extern UCHAR WME_PARM_ELEM[];
46extern UCHAR Ccx2QosInfo[];
47extern UCHAR RALINK_OUI[];
48extern UCHAR BROADCOM_OUI[];
49extern UCHAR WPS_OUI[];
50
51/*
52 ==========================================================================
53 Description:
54 MLME message sanity check
55 Return:
56 TRUE if all parameters are OK, FALSE otherwise
57
58 IRQL = DISPATCH_LEVEL
59
60 ==========================================================================
61 */
62BOOLEAN MlmeAddBAReqSanity(
63 IN PRTMP_ADAPTER pAd,
64 IN VOID *Msg,
65 IN ULONG MsgLen,
66 OUT PUCHAR pAddr2)
67{
68 PMLME_ADDBA_REQ_STRUCT pInfo;
69
70 pInfo = (MLME_ADDBA_REQ_STRUCT *)Msg;
71
72 if ((MsgLen != sizeof(MLME_ADDBA_REQ_STRUCT)))
73 {
74 DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - message lenght not correct.\n"));
75 return FALSE;
76 }
77
78 if ((pInfo->Wcid >= MAX_LEN_OF_MAC_TABLE))
79 {
80 DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - The peer Mac is not associated yet.\n"));
81 return FALSE;
82 }
83
84 /*
85 if ((pInfo->BaBufSize > MAX_RX_REORDERBUF) || (pInfo->BaBufSize < 2))
86 {
87 DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - Rx Reordering buffer too big or too small\n"));
88 return FALSE;
89 }
90 */
91
92 if ((pInfo->pAddr[0]&0x01) == 0x01)
93 {
94 DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - broadcast address not support BA\n"));
95 return FALSE;
96 }
97
98 return TRUE;
99}
100
101/*
102 ==========================================================================
103 Description:
104 MLME message sanity check
105 Return:
106 TRUE if all parameters are OK, FALSE otherwise
107
108 IRQL = DISPATCH_LEVEL
109
110 ==========================================================================
111 */
112BOOLEAN MlmeDelBAReqSanity(
113 IN PRTMP_ADAPTER pAd,
114 IN VOID *Msg,
115 IN ULONG MsgLen)
116{
117 MLME_DELBA_REQ_STRUCT *pInfo;
118 pInfo = (MLME_DELBA_REQ_STRUCT *)Msg;
119
120 if ((MsgLen != sizeof(MLME_DELBA_REQ_STRUCT)))
121 {
122 DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - message lenght not correct.\n"));
123 return FALSE;
124 }
125
126 if ((pInfo->Wcid >= MAX_LEN_OF_MAC_TABLE))
127 {
128 DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - The peer Mac is not associated yet.\n"));
129 return FALSE;
130 }
131
132 if ((pInfo->TID & 0xf0))
133 {
134 DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - The peer TID is incorrect.\n"));
135 return FALSE;
136 }
137
138 if (NdisEqualMemory(pAd->MacTab.Content[pInfo->Wcid].Addr, pInfo->Addr, MAC_ADDR_LEN) == 0)
139 {
140 DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - the peer addr dosen't exist.\n"));
141 return FALSE;
142 }
143
144 return TRUE;
145}
146
147BOOLEAN PeerAddBAReqActionSanity(
148 IN PRTMP_ADAPTER pAd,
149 IN VOID *pMsg,
150 IN ULONG MsgLen,
151 OUT PUCHAR pAddr2)
152{
153 PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
154 PFRAME_ADDBA_REQ pAddFrame;
155 pAddFrame = (PFRAME_ADDBA_REQ)(pMsg);
156 if (MsgLen < (sizeof(FRAME_ADDBA_REQ)))
157 {
158 DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request frame length size = %ld incorrect\n", MsgLen));
159 return FALSE;
160 }
161 // we support immediate BA.
162 *(USHORT *)(&pAddFrame->BaParm) = cpu2le16(*(USHORT *)(&pAddFrame->BaParm));
163 pAddFrame->TimeOutValue = cpu2le16(pAddFrame->TimeOutValue);
164 pAddFrame->BaStartSeq.word = cpu2le16(pAddFrame->BaStartSeq.word);
165
166 if (pAddFrame->BaParm.BAPolicy != IMMED_BA)
167 {
168 DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request Ba Policy[%d] not support\n", pAddFrame->BaParm.BAPolicy));
169 DBGPRINT(RT_DEBUG_ERROR,("ADDBA Request. tid=%x, Bufsize=%x, AMSDUSupported=%x \n", pAddFrame->BaParm.TID, pAddFrame->BaParm.BufSize, pAddFrame->BaParm.AMSDUSupported));
170 return FALSE;
171 }
172
173 // we support immediate BA.
174 if (pAddFrame->BaParm.TID &0xfff0)
175 {
176 DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request incorrect TID = %d\n", pAddFrame->BaParm.TID));
177 return FALSE;
178 }
179 COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
180 return TRUE;
181}
182
183BOOLEAN PeerAddBARspActionSanity(
184 IN PRTMP_ADAPTER pAd,
185 IN VOID *pMsg,
186 IN ULONG MsgLen)
187{
188 //PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
189 PFRAME_ADDBA_RSP pAddFrame;
190
191 pAddFrame = (PFRAME_ADDBA_RSP)(pMsg);
192 if (MsgLen < (sizeof(FRAME_ADDBA_RSP)))
193 {
194 DBGPRINT(RT_DEBUG_ERROR,("PeerAddBARspActionSanity: ADDBA Response frame length size = %ld incorrect\n", MsgLen));
195 return FALSE;
196 }
197 // we support immediate BA.
198 *(USHORT *)(&pAddFrame->BaParm) = cpu2le16(*(USHORT *)(&pAddFrame->BaParm));
199 pAddFrame->StatusCode = cpu2le16(pAddFrame->StatusCode);
200 pAddFrame->TimeOutValue = cpu2le16(pAddFrame->TimeOutValue);
201
202 if (pAddFrame->BaParm.BAPolicy != IMMED_BA)
203 {
204 DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Response Ba Policy[%d] not support\n", pAddFrame->BaParm.BAPolicy));
205 return FALSE;
206 }
207
208 // we support immediate BA.
209 if (pAddFrame->BaParm.TID &0xfff0)
210 {
211 DBGPRINT(RT_DEBUG_ERROR,("PeerAddBARspActionSanity: ADDBA Response incorrect TID = %d\n", pAddFrame->BaParm.TID));
212 return FALSE;
213 }
214 return TRUE;
215
216}
217
218BOOLEAN PeerDelBAActionSanity(
219 IN PRTMP_ADAPTER pAd,
220 IN UCHAR Wcid,
221 IN VOID *pMsg,
222 IN ULONG MsgLen )
223{
224 //PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
225 PFRAME_DELBA_REQ pDelFrame;
226 if (MsgLen != (sizeof(FRAME_DELBA_REQ)))
227 return FALSE;
228
229 if (Wcid >= MAX_LEN_OF_MAC_TABLE)
230 return FALSE;
231
232 pDelFrame = (PFRAME_DELBA_REQ)(pMsg);
233
234 *(USHORT *)(&pDelFrame->DelbaParm) = cpu2le16(*(USHORT *)(&pDelFrame->DelbaParm));
235 pDelFrame->ReasonCode = cpu2le16(pDelFrame->ReasonCode);
236
237 if (pDelFrame->DelbaParm.TID &0xfff0)
238 return FALSE;
239
240 return TRUE;
241}
242
243/*
244 ==========================================================================
245 Description:
246 MLME message sanity check
247 Return:
248 TRUE if all parameters are OK, FALSE otherwise
249
250 IRQL = DISPATCH_LEVEL
251
252 ==========================================================================
253 */
254BOOLEAN PeerBeaconAndProbeRspSanity(
255 IN PRTMP_ADAPTER pAd,
256 IN VOID *Msg,
257 IN ULONG MsgLen,
258 IN UCHAR MsgChannel,
259 OUT PUCHAR pAddr2,
260 OUT PUCHAR pBssid,
261 OUT CHAR Ssid[],
262 OUT UCHAR *pSsidLen,
263 OUT UCHAR *pBssType,
264 OUT USHORT *pBeaconPeriod,
265 OUT UCHAR *pChannel,
266 OUT UCHAR *pNewChannel,
267 OUT LARGE_INTEGER *pTimestamp,
268 OUT CF_PARM *pCfParm,
269 OUT USHORT *pAtimWin,
270 OUT USHORT *pCapabilityInfo,
271 OUT UCHAR *pErp,
272 OUT UCHAR *pDtimCount,
273 OUT UCHAR *pDtimPeriod,
274 OUT UCHAR *pBcastFlag,
275 OUT UCHAR *pMessageToMe,
276 OUT UCHAR SupRate[],
277 OUT UCHAR *pSupRateLen,
278 OUT UCHAR ExtRate[],
279 OUT UCHAR *pExtRateLen,
280 OUT UCHAR *pCkipFlag,
281 OUT UCHAR *pAironetCellPowerLimit,
282 OUT PEDCA_PARM pEdcaParm,
283 OUT PQBSS_LOAD_PARM pQbssLoad,
284 OUT PQOS_CAPABILITY_PARM pQosCapability,
285 OUT ULONG *pRalinkIe,
286 OUT UCHAR *pHtCapabilityLen,
287#ifdef CONFIG_STA_SUPPORT
288 OUT UCHAR *pPreNHtCapabilityLen,
289#endif // CONFIG_STA_SUPPORT //
290 OUT HT_CAPABILITY_IE *pHtCapability,
291 OUT UCHAR *AddHtInfoLen,
292 OUT ADD_HT_INFO_IE *AddHtInfo,
293 OUT UCHAR *NewExtChannelOffset, // Ht extension channel offset(above or below)
294 OUT USHORT *LengthVIE,
295 OUT PNDIS_802_11_VARIABLE_IEs pVIE)
296{
297 CHAR *Ptr;
298#ifdef CONFIG_STA_SUPPORT
299 CHAR TimLen;
300#endif // CONFIG_STA_SUPPORT //
301 PFRAME_802_11 pFrame;
302 PEID_STRUCT pEid;
303 UCHAR SubType;
304 UCHAR Sanity;
305 //UCHAR ECWMin, ECWMax;
306 //MAC_CSR9_STRUC Csr9;
307 ULONG Length = 0;
308
309 // For some 11a AP which didn't have DS_IE, we use two conditions to decide the channel
310 // 1. If the AP is 11n enabled, then check the control channel.
311 // 2. If the AP didn't have any info about channel, use the channel we received this frame as the channel. (May inaccuracy!!)
312 UCHAR CtrlChannel = 0;
313
314 // Add for 3 necessary EID field check
315 Sanity = 0;
316
317 *pAtimWin = 0;
318 *pErp = 0;
319 *pDtimCount = 0;
320 *pDtimPeriod = 0;
321 *pBcastFlag = 0;
322 *pMessageToMe = 0;
323 *pExtRateLen = 0;
324 *pCkipFlag = 0; // Default of CkipFlag is 0
325 *pAironetCellPowerLimit = 0xFF; // Default of AironetCellPowerLimit is 0xFF
326 *LengthVIE = 0; // Set the length of VIE to init value 0
327 *pHtCapabilityLen = 0; // Set the length of VIE to init value 0
328#ifdef CONFIG_STA_SUPPORT
329 if (pAd->OpMode == OPMODE_STA)
330 *pPreNHtCapabilityLen = 0; // Set the length of VIE to init value 0
331#endif // CONFIG_STA_SUPPORT //
332 *AddHtInfoLen = 0; // Set the length of VIE to init value 0
333 *pRalinkIe = 0;
334 *pNewChannel = 0;
335 *NewExtChannelOffset = 0xff; //Default 0xff means no such IE
336 pCfParm->bValid = FALSE; // default: no IE_CF found
337 pQbssLoad->bValid = FALSE; // default: no IE_QBSS_LOAD found
338 pEdcaParm->bValid = FALSE; // default: no IE_EDCA_PARAMETER found
339 pQosCapability->bValid = FALSE; // default: no IE_QOS_CAPABILITY found
340
341 pFrame = (PFRAME_802_11)Msg;
342
343 // get subtype from header
344 SubType = (UCHAR)pFrame->Hdr.FC.SubType;
345
346 // get Addr2 and BSSID from header
347 COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
348 COPY_MAC_ADDR(pBssid, pFrame->Hdr.Addr3);
349
350// hex_dump("Beacon", Msg, MsgLen);
351
352 Ptr = pFrame->Octet;
353 Length += LENGTH_802_11;
354
355 // get timestamp from payload and advance the pointer
356 NdisMoveMemory(pTimestamp, Ptr, TIMESTAMP_LEN);
357
358 pTimestamp->u.LowPart = cpu2le32(pTimestamp->u.LowPart);
359 pTimestamp->u.HighPart = cpu2le32(pTimestamp->u.HighPart);
360
361 Ptr += TIMESTAMP_LEN;
362 Length += TIMESTAMP_LEN;
363
364 // get beacon interval from payload and advance the pointer
365 NdisMoveMemory(pBeaconPeriod, Ptr, 2);
366 Ptr += 2;
367 Length += 2;
368
369 // get capability info from payload and advance the pointer
370 NdisMoveMemory(pCapabilityInfo, Ptr, 2);
371 Ptr += 2;
372 Length += 2;
373
374 if (CAP_IS_ESS_ON(*pCapabilityInfo))
375 *pBssType = BSS_INFRA;
376 else
377 *pBssType = BSS_ADHOC;
378
379 pEid = (PEID_STRUCT) Ptr;
380
381 // get variable fields from payload and advance the pointer
382 while ((Length + 2 + pEid->Len) <= MsgLen)
383 {
384 //
385 // Secure copy VIE to VarIE[MAX_VIE_LEN] didn't overflow.
386 //
387 if ((*LengthVIE + pEid->Len + 2) >= MAX_VIE_LEN)
388 {
389 DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - Variable IEs out of resource [len(=%d) > MAX_VIE_LEN(=%d)]\n",
390 (*LengthVIE + pEid->Len + 2), MAX_VIE_LEN));
391 break;
392 }
393
394 switch(pEid->Eid)
395 {
396 case IE_SSID:
397 // Already has one SSID EID in this beacon, ignore the second one
398 if (Sanity & 0x1)
399 break;
400 if(pEid->Len <= MAX_LEN_OF_SSID)
401 {
402 NdisMoveMemory(Ssid, pEid->Octet, pEid->Len);
403 *pSsidLen = pEid->Len;
404 Sanity |= 0x1;
405 }
406 else
407 {
408 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_SSID (len=%d)\n",pEid->Len));
409 return FALSE;
410 }
411 break;
412
413 case IE_SUPP_RATES:
414 if(pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES)
415 {
416 Sanity |= 0x2;
417 NdisMoveMemory(SupRate, pEid->Octet, pEid->Len);
418 *pSupRateLen = pEid->Len;
419
420 // TODO: 2004-09-14 not a good design here, cause it exclude extra rates
421 // from ScanTab. We should report as is. And filter out unsupported
422 // rates in MlmeAux.
423 // Check against the supported rates
424 // RTMPCheckRates(pAd, SupRate, pSupRateLen);
425 }
426 else
427 {
428 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_SUPP_RATES (len=%d)\n",pEid->Len));
429 return FALSE;
430 }
431 break;
432
433 case IE_HT_CAP:
434 if (pEid->Len >= SIZE_HT_CAP_IE) //Note: allow extension.!!
435 {
436 NdisMoveMemory(pHtCapability, pEid->Octet, sizeof(HT_CAPABILITY_IE));
437 *pHtCapabilityLen = SIZE_HT_CAP_IE; // Nnow we only support 26 bytes.
438
439 *(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo));
440 *(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
441
442#ifdef CONFIG_STA_SUPPORT
443 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
444 {
445 *pPreNHtCapabilityLen = 0; // Nnow we only support 26 bytes.
446
447 Ptr = (PUCHAR) pVIE;
448 NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
449 *LengthVIE += (pEid->Len + 2);
450 }
451#endif // CONFIG_STA_SUPPORT //
452 }
453 else
454 {
455 DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - wrong IE_HT_CAP. pEid->Len = %d\n", pEid->Len));
456 }
457
458 break;
459 case IE_ADD_HT:
460 if (pEid->Len >= sizeof(ADD_HT_INFO_IE))
461 {
462 // This IE allows extension, but we can ignore extra bytes beyond our knowledge , so only
463 // copy first sizeof(ADD_HT_INFO_IE)
464 NdisMoveMemory(AddHtInfo, pEid->Octet, sizeof(ADD_HT_INFO_IE));
465 *AddHtInfoLen = SIZE_ADD_HT_INFO_IE;
466
467 CtrlChannel = AddHtInfo->ControlChan;
468
469 *(USHORT *)(&AddHtInfo->AddHtInfo2) = cpu2le16(*(USHORT *)(&AddHtInfo->AddHtInfo2));
470 *(USHORT *)(&AddHtInfo->AddHtInfo3) = cpu2le16(*(USHORT *)(&AddHtInfo->AddHtInfo3));
471
472#ifdef CONFIG_STA_SUPPORT
473 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
474 {
475 Ptr = (PUCHAR) pVIE;
476 NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
477 *LengthVIE += (pEid->Len + 2);
478 }
479#endif // CONFIG_STA_SUPPORT //
480 }
481 else
482 {
483 DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - wrong IE_ADD_HT. \n"));
484 }
485
486 break;
487 case IE_SECONDARY_CH_OFFSET:
488 if (pEid->Len == 1)
489 {
490 *NewExtChannelOffset = pEid->Octet[0];
491 }
492 else
493 {
494 DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n"));
495 }
496
497 break;
498 case IE_FH_PARM:
499 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity(IE_FH_PARM) \n"));
500 break;
501
502 case IE_DS_PARM:
503 if(pEid->Len == 1)
504 {
505 *pChannel = *pEid->Octet;
506#ifdef CONFIG_STA_SUPPORT
507 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
508 {
509 if (ChannelSanity(pAd, *pChannel) == 0)
510 {
511
512 return FALSE;
513 }
514 }
515#endif // CONFIG_STA_SUPPORT //
516 Sanity |= 0x4;
517 }
518 else
519 {
520 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_DS_PARM (len=%d)\n",pEid->Len));
521 return FALSE;
522 }
523 break;
524
525 case IE_CF_PARM:
526 if(pEid->Len == 6)
527 {
528 pCfParm->bValid = TRUE;
529 pCfParm->CfpCount = pEid->Octet[0];
530 pCfParm->CfpPeriod = pEid->Octet[1];
531 pCfParm->CfpMaxDuration = pEid->Octet[2] + 256 * pEid->Octet[3];
532 pCfParm->CfpDurRemaining = pEid->Octet[4] + 256 * pEid->Octet[5];
533 }
534 else
535 {
536 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_CF_PARM\n"));
537 return FALSE;
538 }
539 break;
540
541 case IE_IBSS_PARM:
542 if(pEid->Len == 2)
543 {
544 NdisMoveMemory(pAtimWin, pEid->Octet, pEid->Len);
545 }
546 else
547 {
548 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_IBSS_PARM\n"));
549 return FALSE;
550 }
551 break;
552
553#ifdef CONFIG_STA_SUPPORT
554 case IE_TIM:
555 if(INFRA_ON(pAd) && SubType == SUBTYPE_BEACON)
556 {
557 GetTimBit((PUCHAR)pEid, pAd->StaActive.Aid, &TimLen, pBcastFlag, pDtimCount, pDtimPeriod, pMessageToMe);
558 }
559 break;
560#endif // CONFIG_STA_SUPPORT //
561 case IE_CHANNEL_SWITCH_ANNOUNCEMENT:
562 if(pEid->Len == 3)
563 {
564 *pNewChannel = pEid->Octet[1]; //extract new channel number
565 }
566 break;
567
568 // New for WPA
569 // CCX v2 has the same IE, we need to parse that too
570 // Wifi WMM use the same IE vale, need to parse that too
571 // case IE_WPA:
572 case IE_VENDOR_SPECIFIC:
573 // Check Broadcom/Atheros 802.11n OUI version, for HT Capability IE.
574 // This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan.
575 /*if (NdisEqualMemory(pEid->Octet, BROADCOM_OUI, 3) && (pEid->Len >= 4))
576 {
577 if ((pEid->Octet[3] == OUI_BROADCOM_HT) && (pEid->Len >= 30))
578 {
579 {
580 NdisMoveMemory(pHtCapability, &pEid->Octet[4], sizeof(HT_CAPABILITY_IE));
581 *pHtCapabilityLen = SIZE_HT_CAP_IE; // Nnow we only support 26 bytes.
582 }
583 }
584 if ((pEid->Octet[3] == OUI_BROADCOM_HT) && (pEid->Len >= 26))
585 {
586 {
587 NdisMoveMemory(AddHtInfo, &pEid->Octet[4], sizeof(ADD_HT_INFO_IE));
588 *AddHtInfoLen = SIZE_ADD_HT_INFO_IE; // Nnow we only support 26 bytes.
589 }
590 }
591 }
592 */
593 // Check the OUI version, filter out non-standard usage
594 if (NdisEqualMemory(pEid->Octet, RALINK_OUI, 3) && (pEid->Len == 7))
595 {
596 //*pRalinkIe = pEid->Octet[3];
597 if (pEid->Octet[3] != 0)
598 *pRalinkIe = pEid->Octet[3];
599 else
600 *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.
601 }
602#ifdef CONFIG_STA_SUPPORT
603#ifdef DOT11_N_SUPPORT
604 // This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan.
605
606 // Other vendors had production before IE_HT_CAP value is assigned. To backward support those old-firmware AP,
607 // Check broadcom-defiend pre-802.11nD1.0 OUI for HT related IE, including HT Capatilities IE and HT Information IE
608 else if ((*pHtCapabilityLen == 0) && NdisEqualMemory(pEid->Octet, PRE_N_HT_OUI, 3) && (pEid->Len >= 4) && (pAd->OpMode == OPMODE_STA))
609 {
610 if ((pEid->Octet[3] == OUI_PREN_HT_CAP) && (pEid->Len >= 30) && (*pHtCapabilityLen == 0))
611 {
612 NdisMoveMemory(pHtCapability, &pEid->Octet[4], sizeof(HT_CAPABILITY_IE));
613 *pPreNHtCapabilityLen = SIZE_HT_CAP_IE;
614 }
615
616 if ((pEid->Octet[3] == OUI_PREN_ADD_HT) && (pEid->Len >= 26))
617 {
618 NdisMoveMemory(AddHtInfo, &pEid->Octet[4], sizeof(ADD_HT_INFO_IE));
619 *AddHtInfoLen = SIZE_ADD_HT_INFO_IE;
620 }
621 }
622#endif // DOT11_N_SUPPORT //
623#endif // CONFIG_STA_SUPPORT //
624 else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
625 {
626 // Copy to pVIE which will report to microsoft bssid list.
627 Ptr = (PUCHAR) pVIE;
628 NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
629 *LengthVIE += (pEid->Len + 2);
630 }
631 else if (NdisEqualMemory(pEid->Octet, WME_PARM_ELEM, 6) && (pEid->Len == 24))
632 {
633 PUCHAR ptr;
634 int i;
635
636 // parsing EDCA parameters
637 pEdcaParm->bValid = TRUE;
638 pEdcaParm->bQAck = FALSE; // pEid->Octet[0] & 0x10;
639 pEdcaParm->bQueueRequest = FALSE; // pEid->Octet[0] & 0x20;
640 pEdcaParm->bTxopRequest = FALSE; // pEid->Octet[0] & 0x40;
641 pEdcaParm->EdcaUpdateCount = pEid->Octet[6] & 0x0f;
642 pEdcaParm->bAPSDCapable = (pEid->Octet[6] & 0x80) ? 1 : 0;
643 ptr = &pEid->Octet[8];
644 for (i=0; i<4; i++)
645 {
646 UCHAR aci = (*ptr & 0x60) >> 5; // b5~6 is AC INDEX
647 pEdcaParm->bACM[aci] = (((*ptr) & 0x10) == 0x10); // b5 is ACM
648 pEdcaParm->Aifsn[aci] = (*ptr) & 0x0f; // b0~3 is AIFSN
649 pEdcaParm->Cwmin[aci] = *(ptr+1) & 0x0f; // b0~4 is Cwmin
650 pEdcaParm->Cwmax[aci] = *(ptr+1) >> 4; // b5~8 is Cwmax
651 pEdcaParm->Txop[aci] = *(ptr+2) + 256 * (*(ptr+3)); // in unit of 32-us
652 ptr += 4; // point to next AC
653 }
654 }
655 else if (NdisEqualMemory(pEid->Octet, WME_INFO_ELEM, 6) && (pEid->Len == 7))
656 {
657 // parsing EDCA parameters
658 pEdcaParm->bValid = TRUE;
659 pEdcaParm->bQAck = FALSE; // pEid->Octet[0] & 0x10;
660 pEdcaParm->bQueueRequest = FALSE; // pEid->Octet[0] & 0x20;
661 pEdcaParm->bTxopRequest = FALSE; // pEid->Octet[0] & 0x40;
662 pEdcaParm->EdcaUpdateCount = pEid->Octet[6] & 0x0f;
663 pEdcaParm->bAPSDCapable = (pEid->Octet[6] & 0x80) ? 1 : 0;
664
665 // use default EDCA parameter
666 pEdcaParm->bACM[QID_AC_BE] = 0;
667 pEdcaParm->Aifsn[QID_AC_BE] = 3;
668 pEdcaParm->Cwmin[QID_AC_BE] = CW_MIN_IN_BITS;
669 pEdcaParm->Cwmax[QID_AC_BE] = CW_MAX_IN_BITS;
670 pEdcaParm->Txop[QID_AC_BE] = 0;
671
672 pEdcaParm->bACM[QID_AC_BK] = 0;
673 pEdcaParm->Aifsn[QID_AC_BK] = 7;
674 pEdcaParm->Cwmin[QID_AC_BK] = CW_MIN_IN_BITS;
675 pEdcaParm->Cwmax[QID_AC_BK] = CW_MAX_IN_BITS;
676 pEdcaParm->Txop[QID_AC_BK] = 0;
677
678 pEdcaParm->bACM[QID_AC_VI] = 0;
679 pEdcaParm->Aifsn[QID_AC_VI] = 2;
680 pEdcaParm->Cwmin[QID_AC_VI] = CW_MIN_IN_BITS-1;
681 pEdcaParm->Cwmax[QID_AC_VI] = CW_MAX_IN_BITS;
682 pEdcaParm->Txop[QID_AC_VI] = 96; // AC_VI: 96*32us ~= 3ms
683
684 pEdcaParm->bACM[QID_AC_VO] = 0;
685 pEdcaParm->Aifsn[QID_AC_VO] = 2;
686 pEdcaParm->Cwmin[QID_AC_VO] = CW_MIN_IN_BITS-2;
687 pEdcaParm->Cwmax[QID_AC_VO] = CW_MAX_IN_BITS-1;
688 pEdcaParm->Txop[QID_AC_VO] = 48; // AC_VO: 48*32us ~= 1.5ms
689 }
690#ifdef CONFIG_STA_SUPPORT
691#endif // CONFIG_STA_SUPPORT //
692 else
693 {
694 }
695
696 break;
697
698 case IE_EXT_SUPP_RATES:
699 if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES)
700 {
701 NdisMoveMemory(ExtRate, pEid->Octet, pEid->Len);
702 *pExtRateLen = pEid->Len;
703
704 // TODO: 2004-09-14 not a good design here, cause it exclude extra rates
705 // from ScanTab. We should report as is. And filter out unsupported
706 // rates in MlmeAux.
707 // Check against the supported rates
708 // RTMPCheckRates(pAd, ExtRate, pExtRateLen);
709 }
710 break;
711
712 case IE_ERP:
713 if (pEid->Len == 1)
714 {
715 *pErp = (UCHAR)pEid->Octet[0];
716 }
717 break;
718
719 case IE_AIRONET_CKIP:
720 // 0. Check Aironet IE length, it must be larger or equal to 28
721 // Cisco AP350 used length as 28
722 // Cisco AP12XX used length as 30
723 if (pEid->Len < (CKIP_NEGOTIATION_LENGTH - 2))
724 break;
725
726 // 1. Copy CKIP flag byte to buffer for process
727 *pCkipFlag = *(pEid->Octet + 8);
728 break;
729
730 case IE_AP_TX_POWER:
731 // AP Control of Client Transmit Power
732 //0. Check Aironet IE length, it must be 6
733 if (pEid->Len != 0x06)
734 break;
735
736 // Get cell power limit in dBm
737 if (NdisEqualMemory(pEid->Octet, CISCO_OUI, 3) == 1)
738 *pAironetCellPowerLimit = *(pEid->Octet + 4);
739 break;
740
741 // WPA2 & 802.11i RSN
742 case IE_RSN:
743 // There is no OUI for version anymore, check the group cipher OUI before copying
744 if (RTMPEqualMemory(pEid->Octet + 2, RSN_OUI, 3))
745 {
746 // Copy to pVIE which will report to microsoft bssid list.
747 Ptr = (PUCHAR) pVIE;
748 NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
749 *LengthVIE += (pEid->Len + 2);
750 }
751 break;
752#ifdef CONFIG_STA_SUPPORT
753#ifdef EXT_BUILD_CHANNEL_LIST
754 case IE_COUNTRY:
755 Ptr = (PUCHAR) pVIE;
756 NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
757 *LengthVIE += (pEid->Len + 2);
758 break;
759#endif // EXT_BUILD_CHANNEL_LIST //
760#endif // CONFIG_STA_SUPPORT //
761 default:
762 break;
763 }
764
765 Length = Length + 2 + pEid->Len; // Eid[1] + Len[1]+ content[Len]
766 pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
767 }
768
769 // For some 11a AP. it did not have the channel EID, patch here
770#ifdef CONFIG_STA_SUPPORT
771 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
772 {
773 UCHAR LatchRfChannel = MsgChannel;
774 if ((pAd->LatchRfRegs.Channel > 14) && ((Sanity & 0x4) == 0))
775 {
776 if (CtrlChannel != 0)
777 *pChannel = CtrlChannel;
778 else
779 *pChannel = LatchRfChannel;
780 Sanity |= 0x4;
781 }
782 }
783#endif // CONFIG_STA_SUPPORT //
784
785 if (Sanity != 0x7)
786 {
787 DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - missing field, Sanity=0x%02x\n", Sanity));
788 return FALSE;
789 }
790 else
791 {
792 return TRUE;
793 }
794
795}
796
797#ifdef DOT11N_DRAFT3
798/*
799 ==========================================================================
800 Description:
801 MLME message sanity check for some IE addressed in 802.11n d3.03.
802 Return:
803 TRUE if all parameters are OK, FALSE otherwise
804
805 IRQL = DISPATCH_LEVEL
806
807 ==========================================================================
808 */
809BOOLEAN PeerBeaconAndProbeRspSanity2(
810 IN PRTMP_ADAPTER pAd,
811 IN VOID *Msg,
812 IN ULONG MsgLen,
813 OUT UCHAR *RegClass)
814{
815 CHAR *Ptr;
816 PFRAME_802_11 pFrame;
817 PEID_STRUCT pEid;
818 ULONG Length = 0;
819
820 pFrame = (PFRAME_802_11)Msg;
821
822 *RegClass = 0;
823 Ptr = pFrame->Octet;
824 Length += LENGTH_802_11;
825
826 // get timestamp from payload and advance the pointer
827 Ptr += TIMESTAMP_LEN;
828 Length += TIMESTAMP_LEN;
829
830 // get beacon interval from payload and advance the pointer
831 Ptr += 2;
832 Length += 2;
833
834 // get capability info from payload and advance the pointer
835 Ptr += 2;
836 Length += 2;
837
838 pEid = (PEID_STRUCT) Ptr;
839
840 // get variable fields from payload and advance the pointer
841 while ((Length + 2 + pEid->Len) <= MsgLen)
842 {
843 switch(pEid->Eid)
844 {
845 case IE_SUPP_REG_CLASS:
846 if(pEid->Len > 0)
847 {
848 *RegClass = *pEid->Octet;
849 }
850 else
851 {
852 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_SSID (len=%d)\n",pEid->Len));
853 return FALSE;
854 }
855 break;
856 }
857
858 Length = Length + 2 + pEid->Len; // Eid[1] + Len[1]+ content[Len]
859 pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
860 }
861
862 return TRUE;
863
864}
865#endif // DOT11N_DRAFT3 //
866
867/*
868 ==========================================================================
869 Description:
870 MLME message sanity check
871 Return:
872 TRUE if all parameters are OK, FALSE otherwise
873 ==========================================================================
874 */
875BOOLEAN MlmeScanReqSanity(
876 IN PRTMP_ADAPTER pAd,
877 IN VOID *Msg,
878 IN ULONG MsgLen,
879 OUT UCHAR *pBssType,
880 OUT CHAR Ssid[],
881 OUT UCHAR *pSsidLen,
882 OUT UCHAR *pScanType)
883{
884 MLME_SCAN_REQ_STRUCT *Info;
885
886 Info = (MLME_SCAN_REQ_STRUCT *)(Msg);
887 *pBssType = Info->BssType;
888 *pSsidLen = Info->SsidLen;
889 NdisMoveMemory(Ssid, Info->Ssid, *pSsidLen);
890 *pScanType = Info->ScanType;
891
892 if ((*pBssType == BSS_INFRA || *pBssType == BSS_ADHOC || *pBssType == BSS_ANY)
893 && (*pScanType == SCAN_ACTIVE || *pScanType == SCAN_PASSIVE
894#ifdef CONFIG_STA_SUPPORT
895 || *pScanType == SCAN_CISCO_PASSIVE || *pScanType == SCAN_CISCO_ACTIVE
896 || *pScanType == SCAN_CISCO_CHANNEL_LOAD || *pScanType == SCAN_CISCO_NOISE
897#endif // CONFIG_STA_SUPPORT //
898 ))
899 {
900 return TRUE;
901 }
902 else
903 {
904 DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqSanity fail - wrong BssType or ScanType\n"));
905 return FALSE;
906 }
907}
908
909// IRQL = DISPATCH_LEVEL
910UCHAR ChannelSanity(
911 IN PRTMP_ADAPTER pAd,
912 IN UCHAR channel)
913{
914 int i;
915
916 for (i = 0; i < pAd->ChannelListNum; i ++)
917 {
918 if (channel == pAd->ChannelList[i].Channel)
919 return 1;
920 }
921 return 0;
922}
923
924/*
925 ==========================================================================
926 Description:
927 MLME message sanity check
928 Return:
929 TRUE if all parameters are OK, FALSE otherwise
930
931 IRQL = DISPATCH_LEVEL
932
933 ==========================================================================
934 */
935BOOLEAN PeerDeauthSanity(
936 IN PRTMP_ADAPTER pAd,
937 IN VOID *Msg,
938 IN ULONG MsgLen,
939 OUT PUCHAR pAddr2,
940 OUT USHORT *pReason)
941{
942 PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
943
944 COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
945 NdisMoveMemory(pReason, &pFrame->Octet[0], 2);
946
947 return TRUE;
948}
949
950/*
951 ==========================================================================
952 Description:
953 MLME message sanity check
954 Return:
955 TRUE if all parameters are OK, FALSE otherwise
956
957 IRQL = DISPATCH_LEVEL
958
959 ==========================================================================
960 */
961BOOLEAN PeerAuthSanity(
962 IN PRTMP_ADAPTER pAd,
963 IN VOID *Msg,
964 IN ULONG MsgLen,
965 OUT PUCHAR pAddr,
966 OUT USHORT *pAlg,
967 OUT USHORT *pSeq,
968 OUT USHORT *pStatus,
969 CHAR *pChlgText)
970{
971 PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
972
973 COPY_MAC_ADDR(pAddr, pFrame->Hdr.Addr2);
974 NdisMoveMemory(pAlg, &pFrame->Octet[0], 2);
975 NdisMoveMemory(pSeq, &pFrame->Octet[2], 2);
976 NdisMoveMemory(pStatus, &pFrame->Octet[4], 2);
977
978 if ((*pAlg == Ndis802_11AuthModeOpen)
979#ifdef LEAP_SUPPORT
980 || (*pAlg == CISCO_AuthModeLEAP)
981#endif // LEAP_SUPPORT //
982 )
983 {
984 if (*pSeq == 1 || *pSeq == 2)
985 {
986 return TRUE;
987 }
988 else
989 {
990 DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong Seg#\n"));
991 return FALSE;
992 }
993 }
994 else if (*pAlg == Ndis802_11AuthModeShared)
995 {
996 if (*pSeq == 1 || *pSeq == 4)
997 {
998 return TRUE;
999 }
1000 else if (*pSeq == 2 || *pSeq == 3)
1001 {
1002 NdisMoveMemory(pChlgText, &pFrame->Octet[8], CIPHER_TEXT_LEN);
1003 return TRUE;
1004 }
1005 else
1006 {
1007 DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong Seg#\n"));
1008 return FALSE;
1009 }
1010 }
1011 else
1012 {
1013 DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong algorithm\n"));
1014 return FALSE;
1015 }
1016}
1017
1018/*
1019 ==========================================================================
1020 Description:
1021 MLME message sanity check
1022 Return:
1023 TRUE if all parameters are OK, FALSE otherwise
1024 ==========================================================================
1025 */
1026BOOLEAN MlmeAuthReqSanity(
1027 IN PRTMP_ADAPTER pAd,
1028 IN VOID *Msg,
1029 IN ULONG MsgLen,
1030 OUT PUCHAR pAddr,
1031 OUT ULONG *pTimeout,
1032 OUT USHORT *pAlg)
1033{
1034 MLME_AUTH_REQ_STRUCT *pInfo;
1035
1036 pInfo = (MLME_AUTH_REQ_STRUCT *)Msg;
1037 COPY_MAC_ADDR(pAddr, pInfo->Addr);
1038 *pTimeout = pInfo->Timeout;
1039 *pAlg = pInfo->Alg;
1040
1041 if (((*pAlg == Ndis802_11AuthModeShared) ||(*pAlg == Ndis802_11AuthModeOpen)
1042#ifdef LEAP_SUPPORT
1043 || (*pAlg == CISCO_AuthModeLEAP)
1044#endif // LEAP_SUPPORT //
1045 ) &&
1046 ((*pAddr & 0x01) == 0))
1047 {
1048 return TRUE;
1049 }
1050 else
1051 {
1052 DBGPRINT(RT_DEBUG_TRACE, ("MlmeAuthReqSanity fail - wrong algorithm\n"));
1053 return FALSE;
1054 }
1055}
1056
1057/*
1058 ==========================================================================
1059 Description:
1060 MLME message sanity check
1061 Return:
1062 TRUE if all parameters are OK, FALSE otherwise
1063
1064 IRQL = DISPATCH_LEVEL
1065
1066 ==========================================================================
1067 */
1068BOOLEAN MlmeAssocReqSanity(
1069 IN PRTMP_ADAPTER pAd,
1070 IN VOID *Msg,
1071 IN ULONG MsgLen,
1072 OUT PUCHAR pApAddr,
1073 OUT USHORT *pCapabilityInfo,
1074 OUT ULONG *pTimeout,
1075 OUT USHORT *pListenIntv)
1076{
1077 MLME_ASSOC_REQ_STRUCT *pInfo;
1078
1079 pInfo = (MLME_ASSOC_REQ_STRUCT *)Msg;
1080 *pTimeout = pInfo->Timeout; // timeout
1081 COPY_MAC_ADDR(pApAddr, pInfo->Addr); // AP address
1082 *pCapabilityInfo = pInfo->CapabilityInfo; // capability info
1083 *pListenIntv = pInfo->ListenIntv;
1084
1085 return TRUE;
1086}
1087
1088/*
1089 ==========================================================================
1090 Description:
1091 MLME message sanity check
1092 Return:
1093 TRUE if all parameters are OK, FALSE otherwise
1094
1095 IRQL = DISPATCH_LEVEL
1096
1097 ==========================================================================
1098 */
1099BOOLEAN PeerDisassocSanity(
1100 IN PRTMP_ADAPTER pAd,
1101 IN VOID *Msg,
1102 IN ULONG MsgLen,
1103 OUT PUCHAR pAddr2,
1104 OUT USHORT *pReason)
1105{
1106 PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
1107
1108 COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
1109 NdisMoveMemory(pReason, &pFrame->Octet[0], 2);
1110
1111 return TRUE;
1112}
1113
1114/*
1115 ========================================================================
1116 Routine Description:
1117 Sanity check NetworkType (11b, 11g or 11a)
1118
1119 Arguments:
1120 pBss - Pointer to BSS table.
1121
1122 Return Value:
1123 Ndis802_11DS .......(11b)
1124 Ndis802_11OFDM24....(11g)
1125 Ndis802_11OFDM5.....(11a)
1126
1127 IRQL = DISPATCH_LEVEL
1128
1129 ========================================================================
1130*/
1131NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity(
1132 IN PBSS_ENTRY pBss)
1133{
1134 NDIS_802_11_NETWORK_TYPE NetWorkType;
1135 UCHAR rate, i;
1136
1137 NetWorkType = Ndis802_11DS;
1138
1139 if (pBss->Channel <= 14)
1140 {
1141 //
1142 // First check support Rate.
1143 //
1144 for (i = 0; i < pBss->SupRateLen; i++)
1145 {
1146 rate = pBss->SupRate[i] & 0x7f; // Mask out basic rate set bit
1147 if ((rate == 2) || (rate == 4) || (rate == 11) || (rate == 22))
1148 {
1149 continue;
1150 }
1151 else
1152 {
1153 //
1154 // Otherwise (even rate > 108) means Ndis802_11OFDM24
1155 //
1156 NetWorkType = Ndis802_11OFDM24;
1157 break;
1158 }
1159 }
1160
1161 //
1162 // Second check Extend Rate.
1163 //
1164 if (NetWorkType != Ndis802_11OFDM24)
1165 {
1166 for (i = 0; i < pBss->ExtRateLen; i++)
1167 {
1168 rate = pBss->SupRate[i] & 0x7f; // Mask out basic rate set bit
1169 if ((rate == 2) || (rate == 4) || (rate == 11) || (rate == 22))
1170 {
1171 continue;
1172 }
1173 else
1174 {
1175 //
1176 // Otherwise (even rate > 108) means Ndis802_11OFDM24
1177 //
1178 NetWorkType = Ndis802_11OFDM24;
1179 break;
1180 }
1181 }
1182 }
1183 }
1184 else
1185 {
1186 NetWorkType = Ndis802_11OFDM5;
1187 }
1188
1189 if (pBss->HtCapabilityLen != 0)
1190 {
1191 if (NetWorkType == Ndis802_11OFDM5)
1192 NetWorkType = Ndis802_11OFDM5_N;
1193 else
1194 NetWorkType = Ndis802_11OFDM24_N;
1195 }
1196
1197 return NetWorkType;
1198}
1199
1200/*
1201 ==========================================================================
1202 Description:
1203 WPA message sanity check
1204 Return:
1205 TRUE if all parameters are OK, FALSE otherwise
1206 ==========================================================================
1207 */
1208BOOLEAN PeerWpaMessageSanity(
1209 IN PRTMP_ADAPTER pAd,
1210 IN PEAPOL_PACKET pMsg,
1211 IN ULONG MsgLen,
1212 IN UCHAR MsgType,
1213 IN MAC_TABLE_ENTRY *pEntry)
1214{
1215 UCHAR mic[LEN_KEY_DESC_MIC], digest[80], KEYDATA[MAX_LEN_OF_RSNIE];
1216 BOOLEAN bReplayDiff = FALSE;
1217 BOOLEAN bWPA2 = FALSE;
1218 KEY_INFO EapolKeyInfo;
1219 UCHAR GroupKeyIndex = 0;
1220
1221
1222 NdisZeroMemory(mic, sizeof(mic));
1223 NdisZeroMemory(digest, sizeof(digest));
1224 NdisZeroMemory(KEYDATA, sizeof(KEYDATA));
1225 NdisZeroMemory((PUCHAR)&EapolKeyInfo, sizeof(EapolKeyInfo));
1226
1227 NdisMoveMemory((PUCHAR)&EapolKeyInfo, (PUCHAR)&pMsg->KeyDesc.KeyInfo, sizeof(KEY_INFO));
1228
1229 *((USHORT *)&EapolKeyInfo) = cpu2le16(*((USHORT *)&EapolKeyInfo));
1230
1231 // Choose WPA2 or not
1232 if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
1233 bWPA2 = TRUE;
1234
1235 // 0. Check MsgType
1236 if ((MsgType > EAPOL_GROUP_MSG_2) || (MsgType < EAPOL_PAIR_MSG_1))
1237 {
1238 DBGPRINT(RT_DEBUG_ERROR, ("The message type is invalid(%d)! \n", MsgType));
1239 return FALSE;
1240 }
1241
1242 // 1. Replay counter check
1243 if (MsgType == EAPOL_PAIR_MSG_1 || MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1) // For supplicant
1244 {
1245 // First validate replay counter, only accept message with larger replay counter.
1246 // Let equal pass, some AP start with all zero replay counter
1247 UCHAR ZeroReplay[LEN_KEY_DESC_REPLAY];
1248
1249 NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY);
1250 if ((RTMPCompareMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY) != 1) &&
1251 (RTMPCompareMemory(pMsg->KeyDesc.ReplayCounter, ZeroReplay, LEN_KEY_DESC_REPLAY) != 0))
1252 {
1253 bReplayDiff = TRUE;
1254 }
1255 }
1256 else if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2) // For authenticator
1257 {
1258 // check Replay Counter coresponds to MSG from authenticator, otherwise discard
1259 if (!NdisEqualMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY))
1260 {
1261 bReplayDiff = TRUE;
1262 }
1263 }
1264
1265 // Replay Counter different condition
1266 if (bReplayDiff)
1267 {
1268 // send wireless event - for replay counter different
1269 if (pAd->CommonCfg.bWirelessEvent)
1270 RTMPSendWirelessEvent(pAd, IW_REPLAY_COUNTER_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
1271
1272 if (MsgType < EAPOL_GROUP_MSG_1)
1273 {
1274 DBGPRINT(RT_DEBUG_ERROR, ("Replay Counter Different in pairwise msg %d of 4-way handshake!\n", MsgType));
1275 }
1276 else
1277 {
1278 DBGPRINT(RT_DEBUG_ERROR, ("Replay Counter Different in group msg %d of 2-way handshake!\n", (MsgType - EAPOL_PAIR_MSG_4)));
1279 }
1280
1281 hex_dump("Receive replay counter ", pMsg->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1282 hex_dump("Current replay counter ", pEntry->R_Counter, LEN_KEY_DESC_REPLAY);
1283 return FALSE;
1284 }
1285
1286 // 2. Verify MIC except Pairwise Msg1
1287 if (MsgType != EAPOL_PAIR_MSG_1)
1288 {
1289 UCHAR rcvd_mic[LEN_KEY_DESC_MIC];
1290
1291 // Record the received MIC for check later
1292 NdisMoveMemory(rcvd_mic, pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
1293 NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
1294
1295 if (pEntry->WepStatus == Ndis802_11Encryption2Enabled) // TKIP
1296 {
1297 hmac_md5(pEntry->PTK, LEN_EAP_MICK, (PUCHAR)pMsg, MsgLen, mic);
1298 }
1299 else if (pEntry->WepStatus == Ndis802_11Encryption3Enabled) // AES
1300 {
1301 HMAC_SHA1((PUCHAR)pMsg, MsgLen, pEntry->PTK, LEN_EAP_MICK, digest);
1302 NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
1303 }
1304
1305 if (!NdisEqualMemory(rcvd_mic, mic, LEN_KEY_DESC_MIC))
1306 {
1307 // send wireless event - for MIC different
1308 if (pAd->CommonCfg.bWirelessEvent)
1309 RTMPSendWirelessEvent(pAd, IW_MIC_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
1310
1311 if (MsgType < EAPOL_GROUP_MSG_1)
1312 {
1313 DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in pairwise msg %d of 4-way handshake!\n", MsgType));
1314 }
1315 else
1316 {
1317 DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in group msg %d of 2-way handshake!\n", (MsgType - EAPOL_PAIR_MSG_4)));
1318 }
1319
1320 hex_dump("Received MIC", rcvd_mic, LEN_KEY_DESC_MIC);
1321 hex_dump("Desired MIC", mic, LEN_KEY_DESC_MIC);
1322
1323 return FALSE;
1324 }
1325 }
1326
1327 // Extract the context of the Key Data field if it exist
1328 // The field in pairwise_msg_2_WPA1(WPA2) & pairwise_msg_3_WPA1 is un-encrypted.
1329 // The field in group_msg_1_WPA1(WPA2) & pairwise_msg_3_WPA2 is encrypted.
1330 if (pMsg->KeyDesc.KeyDataLen[1] > 0)
1331 {
1332 // Decrypt this field
1333 if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2) || (MsgType == EAPOL_GROUP_MSG_1))
1334 {
1335 if(pEntry->WepStatus == Ndis802_11Encryption3Enabled)
1336 {
1337 // AES
1338 AES_GTK_KEY_UNWRAP(&pEntry->PTK[16], KEYDATA, pMsg->KeyDesc.KeyDataLen[1],pMsg->KeyDesc.KeyData);
1339 }
1340 else
1341 {
1342 INT i;
1343 UCHAR Key[32];
1344 // Decrypt TKIP GTK
1345 // Construct 32 bytes RC4 Key
1346 NdisMoveMemory(Key, pMsg->KeyDesc.KeyIv, 16);
1347 NdisMoveMemory(&Key[16], &pEntry->PTK[16], 16);
1348 ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key, 32);
1349 //discard first 256 bytes
1350 for(i = 0; i < 256; i++)
1351 ARCFOUR_BYTE(&pAd->PrivateInfo.WEPCONTEXT);
1352 // Decrypt GTK. Becareful, there is no ICV to check the result is correct or not
1353 ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, KEYDATA, pMsg->KeyDesc.KeyData, pMsg->KeyDesc.KeyDataLen[1]);
1354 }
1355
1356 if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))
1357 GroupKeyIndex = EapolKeyInfo.KeyIndex;
1358
1359 }
1360 else if ((MsgType == EAPOL_PAIR_MSG_2) || (MsgType == EAPOL_PAIR_MSG_3 && !bWPA2))
1361 {
1362 NdisMoveMemory(KEYDATA, pMsg->KeyDesc.KeyData, pMsg->KeyDesc.KeyDataLen[1]);
1363 }
1364 else
1365 {
1366
1367 return TRUE;
1368 }
1369
1370 // Parse Key Data field to
1371 // 1. verify RSN IE for pairwise_msg_2_WPA1(WPA2) ,pairwise_msg_3_WPA1(WPA2)
1372 // 2. verify KDE format for pairwise_msg_3_WPA2, group_msg_1_WPA2
1373 // 3. update shared key for pairwise_msg_3_WPA2, group_msg_1_WPA1(WPA2)
1374 if (!RTMPParseEapolKeyData(pAd, KEYDATA, pMsg->KeyDesc.KeyDataLen[1], GroupKeyIndex, MsgType, bWPA2, pEntry))
1375 {
1376 return FALSE;
1377 }
1378 }
1379
1380 return TRUE;
1381
1382}
1383
1384#ifdef CONFIG_STA_SUPPORT
1385#ifdef QOS_DLS_SUPPORT
1386BOOLEAN MlmeDlsReqSanity(
1387 IN PRTMP_ADAPTER pAd,
1388 IN VOID *Msg,
1389 IN ULONG MsgLen,
1390 OUT PRT_802_11_DLS *pDLS,
1391 OUT PUSHORT pReason)
1392{
1393 MLME_DLS_REQ_STRUCT *pInfo;
1394
1395 pInfo = (MLME_DLS_REQ_STRUCT *)Msg;
1396
1397 *pDLS = pInfo->pDLS;
1398 *pReason = pInfo->Reason;
1399
1400 return TRUE;
1401}
1402#endif // QOS_DLS_SUPPORT //
1403#endif // CONFIG_STA_SUPPORT //
1404
1405#ifdef QOS_DLS_SUPPORT
1406BOOLEAN PeerDlsReqSanity(
1407 IN PRTMP_ADAPTER pAd,
1408 IN VOID *Msg,
1409 IN ULONG MsgLen,
1410 OUT PUCHAR pDA,
1411 OUT PUCHAR pSA,
1412 OUT USHORT *pCapabilityInfo,
1413 OUT USHORT *pDlsTimeout,
1414 OUT UCHAR *pRatesLen,
1415 OUT UCHAR Rates[],
1416 OUT UCHAR *pHtCapabilityLen,
1417 OUT HT_CAPABILITY_IE *pHtCapability)
1418{
1419 CHAR *Ptr;
1420 PFRAME_802_11 Fr = (PFRAME_802_11)Msg;
1421 PEID_STRUCT eid_ptr;
1422
1423 // to prevent caller from using garbage output value
1424 *pCapabilityInfo = 0;
1425 *pDlsTimeout = 0;
1426 *pHtCapabilityLen = 0;
1427
1428 Ptr = Fr->Octet;
1429
1430 // offset to destination MAC address (Category and Action field)
1431 Ptr += 2;
1432
1433 // get DA from payload and advance the pointer
1434 NdisMoveMemory(pDA, Ptr, MAC_ADDR_LEN);
1435 Ptr += MAC_ADDR_LEN;
1436
1437 // get SA from payload and advance the pointer
1438 NdisMoveMemory(pSA, Ptr, MAC_ADDR_LEN);
1439 Ptr += MAC_ADDR_LEN;
1440
1441 // get capability info from payload and advance the pointer
1442 NdisMoveMemory(pCapabilityInfo, Ptr, 2);
1443 Ptr += 2;
1444
1445 // get capability info from payload and advance the pointer
1446 NdisMoveMemory(pDlsTimeout, Ptr, 2);
1447 Ptr += 2;
1448
1449 // Category and Action field + DA + SA + capability + Timeout
1450 eid_ptr = (PEID_STRUCT) &Fr->Octet[18];
1451
1452 while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((UCHAR*)Fr + MsgLen))
1453 {
1454 switch(eid_ptr->Eid)
1455 {
1456 case IE_SUPP_RATES:
1457 if ((eid_ptr->Len <= MAX_LEN_OF_SUPPORTED_RATES) && (eid_ptr->Len > 0))
1458 {
1459 NdisMoveMemory(Rates, eid_ptr->Octet, eid_ptr->Len);
1460 DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - IE_SUPP_RATES., Len=%d. Rates[0]=%x\n",eid_ptr->Len, Rates[0]));
1461 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]));
1462 *pRatesLen = eid_ptr->Len;
1463 }
1464 else
1465 {
1466 *pRatesLen = 8;
1467 Rates[0] = 0x82;
1468 Rates[1] = 0x84;
1469 Rates[2] = 0x8b;
1470 Rates[3] = 0x96;
1471 Rates[4] = 0x12;
1472 Rates[5] = 0x24;
1473 Rates[6] = 0x48;
1474 Rates[7] = 0x6c;
1475 DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - wrong IE_SUPP_RATES., Len=%d\n",eid_ptr->Len));
1476 }
1477 break;
1478
1479 case IE_EXT_SUPP_RATES:
1480 if (eid_ptr->Len + *pRatesLen <= MAX_LEN_OF_SUPPORTED_RATES)
1481 {
1482 NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, eid_ptr->Len);
1483 *pRatesLen = (*pRatesLen) + eid_ptr->Len;
1484 }
1485 else
1486 {
1487 NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, MAX_LEN_OF_SUPPORTED_RATES - (*pRatesLen));
1488 *pRatesLen = MAX_LEN_OF_SUPPORTED_RATES;
1489 }
1490 break;
1491
1492 case IE_HT_CAP:
1493 if (eid_ptr->Len >= sizeof(HT_CAPABILITY_IE))
1494 {
1495 NdisMoveMemory(pHtCapability, eid_ptr->Octet, sizeof(HT_CAPABILITY_IE));
1496
1497 *(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo));
1498 *(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
1499 *pHtCapabilityLen = sizeof(HT_CAPABILITY_IE);
1500
1501 DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - IE_HT_CAP\n"));
1502 }
1503 else
1504 {
1505 DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - wrong IE_HT_CAP.eid_ptr->Len = %d\n", eid_ptr->Len));
1506 }
1507 break;
1508
1509 default:
1510 break;
1511 }
1512
1513 eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
1514 }
1515
1516 return TRUE;
1517}
1518
1519BOOLEAN PeerDlsRspSanity(
1520 IN PRTMP_ADAPTER pAd,
1521 IN VOID *Msg,
1522 IN ULONG MsgLen,
1523 OUT PUCHAR pDA,
1524 OUT PUCHAR pSA,
1525 OUT USHORT *pCapabilityInfo,
1526 OUT USHORT *pStatus,
1527 OUT UCHAR *pRatesLen,
1528 OUT UCHAR Rates[],
1529 OUT UCHAR *pHtCapabilityLen,
1530 OUT HT_CAPABILITY_IE *pHtCapability)
1531{
1532 CHAR *Ptr;
1533 PFRAME_802_11 Fr = (PFRAME_802_11)Msg;
1534 PEID_STRUCT eid_ptr;
1535
1536 // to prevent caller from using garbage output value
1537 *pStatus = 0;
1538 *pCapabilityInfo = 0;
1539 *pHtCapabilityLen = 0;
1540
1541 Ptr = Fr->Octet;
1542
1543 // offset to destination MAC address (Category and Action field)
1544 Ptr += 2;
1545
1546 // get status code from payload and advance the pointer
1547 NdisMoveMemory(pStatus, Ptr, 2);
1548 Ptr += 2;
1549
1550 // get DA from payload and advance the pointer
1551 NdisMoveMemory(pDA, Ptr, MAC_ADDR_LEN);
1552 Ptr += MAC_ADDR_LEN;
1553
1554 // get SA from payload and advance the pointer
1555 NdisMoveMemory(pSA, Ptr, MAC_ADDR_LEN);
1556 Ptr += MAC_ADDR_LEN;
1557
1558 if (pStatus == 0)
1559 {
1560 // get capability info from payload and advance the pointer
1561 NdisMoveMemory(pCapabilityInfo, Ptr, 2);
1562 Ptr += 2;
1563 }
1564
1565 // Category and Action field + status code + DA + SA + capability
1566 eid_ptr = (PEID_STRUCT) &Fr->Octet[18];
1567
1568 while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((UCHAR*)Fr + MsgLen))
1569 {
1570 switch(eid_ptr->Eid)
1571 {
1572 case IE_SUPP_RATES:
1573 if ((eid_ptr->Len <= MAX_LEN_OF_SUPPORTED_RATES) && (eid_ptr->Len > 0))
1574 {
1575 NdisMoveMemory(Rates, eid_ptr->Octet, eid_ptr->Len);
1576 DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - IE_SUPP_RATES., Len=%d. Rates[0]=%x\n",eid_ptr->Len, Rates[0]));
1577 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]));
1578 *pRatesLen = eid_ptr->Len;
1579 }
1580 else
1581 {
1582 *pRatesLen = 8;
1583 Rates[0] = 0x82;
1584 Rates[1] = 0x84;
1585 Rates[2] = 0x8b;
1586 Rates[3] = 0x96;
1587 Rates[4] = 0x12;
1588 Rates[5] = 0x24;
1589 Rates[6] = 0x48;
1590 Rates[7] = 0x6c;
1591 DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - wrong IE_SUPP_RATES., Len=%d\n",eid_ptr->Len));
1592 }
1593 break;
1594
1595 case IE_EXT_SUPP_RATES:
1596 if (eid_ptr->Len + *pRatesLen <= MAX_LEN_OF_SUPPORTED_RATES)
1597 {
1598 NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, eid_ptr->Len);
1599 *pRatesLen = (*pRatesLen) + eid_ptr->Len;
1600 }
1601 else
1602 {
1603 NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, MAX_LEN_OF_SUPPORTED_RATES - (*pRatesLen));
1604 *pRatesLen = MAX_LEN_OF_SUPPORTED_RATES;
1605 }
1606 break;
1607
1608 case IE_HT_CAP:
1609 if (eid_ptr->Len >= sizeof(HT_CAPABILITY_IE))
1610 {
1611 NdisMoveMemory(pHtCapability, eid_ptr->Octet, sizeof(HT_CAPABILITY_IE));
1612
1613 *(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo));
1614 *(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
1615 *pHtCapabilityLen = sizeof(HT_CAPABILITY_IE);
1616
1617 DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - IE_HT_CAP\n"));
1618 }
1619 else
1620 {
1621 DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - wrong IE_HT_CAP.eid_ptr->Len = %d\n", eid_ptr->Len));
1622 }
1623 break;
1624
1625 default:
1626 break;
1627 }
1628
1629 eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
1630 }
1631
1632 return TRUE;
1633}
1634
1635BOOLEAN PeerDlsTearDownSanity(
1636 IN PRTMP_ADAPTER pAd,
1637 IN VOID *Msg,
1638 IN ULONG MsgLen,
1639 OUT PUCHAR pDA,
1640 OUT PUCHAR pSA,
1641 OUT USHORT *pReason)
1642{
1643 CHAR *Ptr;
1644 PFRAME_802_11 Fr = (PFRAME_802_11)Msg;
1645
1646 // to prevent caller from using garbage output value
1647 *pReason = 0;
1648
1649 Ptr = Fr->Octet;
1650
1651 // offset to destination MAC address (Category and Action field)
1652 Ptr += 2;
1653
1654 // get DA from payload and advance the pointer
1655 NdisMoveMemory(pDA, Ptr, MAC_ADDR_LEN);
1656 Ptr += MAC_ADDR_LEN;
1657
1658 // get SA from payload and advance the pointer
1659 NdisMoveMemory(pSA, Ptr, MAC_ADDR_LEN);
1660 Ptr += MAC_ADDR_LEN;
1661
1662 // get reason code from payload and advance the pointer
1663 NdisMoveMemory(pReason, Ptr, 2);
1664 Ptr += 2;
1665
1666 return TRUE;
1667}
1668#endif // QOS_DLS_SUPPORT //
1669
diff --git a/drivers/staging/rt3070/common/cmm_sync.c b/drivers/staging/rt3070/common/cmm_sync.c
new file mode 100644
index 000000000000..2be7c77a384e
--- /dev/null
+++ b/drivers/staging/rt3070/common/cmm_sync.c
@@ -0,0 +1,711 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 sync.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 John Chang 2004-09-01 modified for rt2561/2661
36*/
37#include "../rt_config.h"
38
39// 2.4 Ghz channel plan index in the TxPower arrays.
40#define BG_BAND_REGION_0_START 0 // 1,2,3,4,5,6,7,8,9,10,11
41#define BG_BAND_REGION_0_SIZE 11
42#define BG_BAND_REGION_1_START 0 // 1,2,3,4,5,6,7,8,9,10,11,12,13
43#define BG_BAND_REGION_1_SIZE 13
44#define BG_BAND_REGION_2_START 9 // 10,11
45#define BG_BAND_REGION_2_SIZE 2
46#define BG_BAND_REGION_3_START 9 // 10,11,12,13
47#define BG_BAND_REGION_3_SIZE 4
48#define BG_BAND_REGION_4_START 13 // 14
49#define BG_BAND_REGION_4_SIZE 1
50#define BG_BAND_REGION_5_START 0 // 1,2,3,4,5,6,7,8,9,10,11,12,13,14
51#define BG_BAND_REGION_5_SIZE 14
52#define BG_BAND_REGION_6_START 2 // 3,4,5,6,7,8,9
53#define BG_BAND_REGION_6_SIZE 7
54#define BG_BAND_REGION_7_START 4 // 5,6,7,8,9,10,11,12,13
55#define BG_BAND_REGION_7_SIZE 9
56#define BG_BAND_REGION_31_START 0 // 1,2,3,4,5,6,7,8,9,10,11,12,13,14
57#define BG_BAND_REGION_31_SIZE 14
58
59// 5 Ghz channel plan index in the TxPower arrays.
60UCHAR A_BAND_REGION_0_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165};
61UCHAR 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};
62UCHAR A_BAND_REGION_2_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64};
63UCHAR A_BAND_REGION_3_CHANNEL_LIST[]={52, 56, 60, 64, 149, 153, 157, 161};
64UCHAR A_BAND_REGION_4_CHANNEL_LIST[]={149, 153, 157, 161, 165};
65UCHAR A_BAND_REGION_5_CHANNEL_LIST[]={149, 153, 157, 161};
66UCHAR A_BAND_REGION_6_CHANNEL_LIST[]={36, 40, 44, 48};
67UCHAR 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};
68UCHAR A_BAND_REGION_8_CHANNEL_LIST[]={52, 56, 60, 64};
69UCHAR 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};
70UCHAR A_BAND_REGION_10_CHANNEL_LIST[]={36, 40, 44, 48, 149, 153, 157, 161, 165};
71UCHAR A_BAND_REGION_11_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153, 157, 161};
72
73//BaSizeArray follows the 802.11n definition as MaxRxFactor. 2^(13+factor) bytes. When factor =0, it's about Ba buffer size =8.
74UCHAR BaSizeArray[4] = {8,16,32,64};
75
76/*
77 ==========================================================================
78 Description:
79 Update StaCfg->ChannelList[] according to 1) Country Region 2) RF IC type,
80 and 3) PHY-mode user selected.
81 The outcome is used by driver when doing site survey.
82
83 IRQL = PASSIVE_LEVEL
84 IRQL = DISPATCH_LEVEL
85
86 ==========================================================================
87 */
88VOID BuildChannelList(
89 IN PRTMP_ADAPTER pAd)
90{
91 UCHAR i, j, index=0, num=0;
92 PUCHAR pChannelList = NULL;
93
94 NdisZeroMemory(pAd->ChannelList, MAX_NUM_OF_CHANNELS * sizeof(CHANNEL_TX_POWER));
95
96 // if not 11a-only mode, channel list starts from 2.4Ghz band
97 if ((pAd->CommonCfg.PhyMode != PHY_11A)
98#ifdef DOT11_N_SUPPORT
99 && (pAd->CommonCfg.PhyMode != PHY_11AN_MIXED) && (pAd->CommonCfg.PhyMode != PHY_11N_5G)
100#endif // DOT11_N_SUPPORT //
101 )
102 {
103 switch (pAd->CommonCfg.CountryRegion & 0x7f)
104 {
105 case REGION_0_BG_BAND: // 1 -11
106 NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_0_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_0_SIZE);
107 index += BG_BAND_REGION_0_SIZE;
108 break;
109 case REGION_1_BG_BAND: // 1 - 13
110 NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_1_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_1_SIZE);
111 index += BG_BAND_REGION_1_SIZE;
112 break;
113 case REGION_2_BG_BAND: // 10 - 11
114 NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_2_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_2_SIZE);
115 index += BG_BAND_REGION_2_SIZE;
116 break;
117 case REGION_3_BG_BAND: // 10 - 13
118 NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_3_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_3_SIZE);
119 index += BG_BAND_REGION_3_SIZE;
120 break;
121 case REGION_4_BG_BAND: // 14
122 NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_4_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_4_SIZE);
123 index += BG_BAND_REGION_4_SIZE;
124 break;
125 case REGION_5_BG_BAND: // 1 - 14
126 NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_5_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_5_SIZE);
127 index += BG_BAND_REGION_5_SIZE;
128 break;
129 case REGION_6_BG_BAND: // 3 - 9
130 NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_6_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_6_SIZE);
131 index += BG_BAND_REGION_6_SIZE;
132 break;
133 case REGION_7_BG_BAND: // 5 - 13
134 NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_7_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_7_SIZE);
135 index += BG_BAND_REGION_7_SIZE;
136 break;
137 case REGION_31_BG_BAND: // 1 - 14
138 NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_31_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_31_SIZE);
139 index += BG_BAND_REGION_31_SIZE;
140 break;
141 default: // Error. should never happen
142 break;
143 }
144 for (i=0; i<index; i++)
145 pAd->ChannelList[i].MaxTxPwr = 20;
146 }
147
148 if ((pAd->CommonCfg.PhyMode == PHY_11A) || (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
149#ifdef DOT11_N_SUPPORT
150 || (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11AN_MIXED)
151 || (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)
152#endif // DOT11_N_SUPPORT //
153 )
154 {
155 switch (pAd->CommonCfg.CountryRegionForABand & 0x7f)
156 {
157 case REGION_0_A_BAND:
158 num = sizeof(A_BAND_REGION_0_CHANNEL_LIST)/sizeof(UCHAR);
159 pChannelList = A_BAND_REGION_0_CHANNEL_LIST;
160 break;
161 case REGION_1_A_BAND:
162 num = sizeof(A_BAND_REGION_1_CHANNEL_LIST)/sizeof(UCHAR);
163 pChannelList = A_BAND_REGION_1_CHANNEL_LIST;
164 break;
165 case REGION_2_A_BAND:
166 num = sizeof(A_BAND_REGION_2_CHANNEL_LIST)/sizeof(UCHAR);
167 pChannelList = A_BAND_REGION_2_CHANNEL_LIST;
168 break;
169 case REGION_3_A_BAND:
170 num = sizeof(A_BAND_REGION_3_CHANNEL_LIST)/sizeof(UCHAR);
171 pChannelList = A_BAND_REGION_3_CHANNEL_LIST;
172 break;
173 case REGION_4_A_BAND:
174 num = sizeof(A_BAND_REGION_4_CHANNEL_LIST)/sizeof(UCHAR);
175 pChannelList = A_BAND_REGION_4_CHANNEL_LIST;
176 break;
177 case REGION_5_A_BAND:
178 num = sizeof(A_BAND_REGION_5_CHANNEL_LIST)/sizeof(UCHAR);
179 pChannelList = A_BAND_REGION_5_CHANNEL_LIST;
180 break;
181 case REGION_6_A_BAND:
182 num = sizeof(A_BAND_REGION_6_CHANNEL_LIST)/sizeof(UCHAR);
183 pChannelList = A_BAND_REGION_6_CHANNEL_LIST;
184 break;
185 case REGION_7_A_BAND:
186 num = sizeof(A_BAND_REGION_7_CHANNEL_LIST)/sizeof(UCHAR);
187 pChannelList = A_BAND_REGION_7_CHANNEL_LIST;
188 break;
189 case REGION_8_A_BAND:
190 num = sizeof(A_BAND_REGION_8_CHANNEL_LIST)/sizeof(UCHAR);
191 pChannelList = A_BAND_REGION_8_CHANNEL_LIST;
192 break;
193 case REGION_9_A_BAND:
194 num = sizeof(A_BAND_REGION_9_CHANNEL_LIST)/sizeof(UCHAR);
195 pChannelList = A_BAND_REGION_9_CHANNEL_LIST;
196 break;
197
198 case REGION_10_A_BAND:
199 num = sizeof(A_BAND_REGION_10_CHANNEL_LIST)/sizeof(UCHAR);
200 pChannelList = A_BAND_REGION_10_CHANNEL_LIST;
201 break;
202
203 case REGION_11_A_BAND:
204 num = sizeof(A_BAND_REGION_11_CHANNEL_LIST)/sizeof(UCHAR);
205 pChannelList = A_BAND_REGION_11_CHANNEL_LIST;
206 break;
207
208 default: // Error. should never happen
209 DBGPRINT(RT_DEBUG_WARN,("countryregion=%d not support", pAd->CommonCfg.CountryRegionForABand));
210 break;
211 }
212
213 if (num != 0)
214 {
215 UCHAR RadarCh[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
216 for (i=0; i<num; i++)
217 {
218 for (j=0; j<MAX_NUM_OF_CHANNELS; j++)
219 {
220 if (pChannelList[i] == pAd->TxPower[j].Channel)
221 NdisMoveMemory(&pAd->ChannelList[index+i], &pAd->TxPower[j], sizeof(CHANNEL_TX_POWER));
222 }
223 for (j=0; j<15; j++)
224 {
225 if (pChannelList[i] == RadarCh[j])
226 pAd->ChannelList[index+i].DfsReq = TRUE;
227 }
228 pAd->ChannelList[index+i].MaxTxPwr = 20;
229 }
230 index += num;
231 }
232 }
233
234 pAd->ChannelListNum = index;
235 DBGPRINT(RT_DEBUG_TRACE,("country code=%d/%d, RFIC=%d, PHY mode=%d, support %d channels\n",
236 pAd->CommonCfg.CountryRegion, pAd->CommonCfg.CountryRegionForABand, pAd->RfIcType, pAd->CommonCfg.PhyMode, pAd->ChannelListNum));
237#ifdef DBG
238 for (i=0;i<pAd->ChannelListNum;i++)
239 {
240 DBGPRINT_RAW(RT_DEBUG_TRACE,("BuildChannel # %d :: Pwr0 = %d, Pwr1 =%d, \n ", pAd->ChannelList[i].Channel, pAd->ChannelList[i].Power, pAd->ChannelList[i].Power2));
241 }
242#endif
243}
244
245/*
246 ==========================================================================
247 Description:
248 This routine return the first channel number according to the country
249 code selection and RF IC selection (signal band or dual band). It is called
250 whenever driver need to start a site survey of all supported channels.
251 Return:
252 ch - the first channel number of current country code setting
253
254 IRQL = PASSIVE_LEVEL
255
256 ==========================================================================
257 */
258UCHAR FirstChannel(
259 IN PRTMP_ADAPTER pAd)
260{
261 return pAd->ChannelList[0].Channel;
262}
263
264/*
265 ==========================================================================
266 Description:
267 This routine returns the next channel number. This routine is called
268 during driver need to start a site survey of all supported channels.
269 Return:
270 next_channel - the next channel number valid in current country code setting.
271 Note:
272 return 0 if no more next channel
273 ==========================================================================
274 */
275UCHAR NextChannel(
276 IN PRTMP_ADAPTER pAd,
277 IN UCHAR channel)
278{
279 int i;
280 UCHAR next_channel = 0;
281
282 for (i = 0; i < (pAd->ChannelListNum - 1); i++)
283 if (channel == pAd->ChannelList[i].Channel)
284 {
285 next_channel = pAd->ChannelList[i+1].Channel;
286 break;
287 }
288 return next_channel;
289}
290
291/*
292 ==========================================================================
293 Description:
294 This routine is for Cisco Compatible Extensions 2.X
295 Spec31. AP Control of Client Transmit Power
296 Return:
297 None
298 Note:
299 Required by Aironet dBm(mW)
300 0dBm(1mW), 1dBm(5mW), 13dBm(20mW), 15dBm(30mW),
301 17dBm(50mw), 20dBm(100mW)
302
303 We supported
304 3dBm(Lowest), 6dBm(10%), 9dBm(25%), 12dBm(50%),
305 14dBm(75%), 15dBm(100%)
306
307 The client station's actual transmit power shall be within +/- 5dB of
308 the minimum value or next lower value.
309 ==========================================================================
310 */
311VOID ChangeToCellPowerLimit(
312 IN PRTMP_ADAPTER pAd,
313 IN UCHAR AironetCellPowerLimit)
314{
315 //valud 0xFF means that hasn't found power limit information
316 //from the AP's Beacon/Probe response.
317 if (AironetCellPowerLimit == 0xFF)
318 return;
319
320 if (AironetCellPowerLimit < 6) //Used Lowest Power Percentage.
321 pAd->CommonCfg.TxPowerPercentage = 6;
322 else if (AironetCellPowerLimit < 9)
323 pAd->CommonCfg.TxPowerPercentage = 10;
324 else if (AironetCellPowerLimit < 12)
325 pAd->CommonCfg.TxPowerPercentage = 25;
326 else if (AironetCellPowerLimit < 14)
327 pAd->CommonCfg.TxPowerPercentage = 50;
328 else if (AironetCellPowerLimit < 15)
329 pAd->CommonCfg.TxPowerPercentage = 75;
330 else
331 pAd->CommonCfg.TxPowerPercentage = 100; //else used maximum
332
333 if (pAd->CommonCfg.TxPowerPercentage > pAd->CommonCfg.TxPowerDefault)
334 pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
335
336}
337
338CHAR ConvertToRssi(
339 IN PRTMP_ADAPTER pAd,
340 IN CHAR Rssi,
341 IN UCHAR RssiNumber)
342{
343 UCHAR RssiOffset, LNAGain;
344
345 // Rssi equals to zero should be an invalid value
346 if (Rssi == 0)
347 return -99;
348
349 LNAGain = GET_LNA_GAIN(pAd);
350 if (pAd->LatchRfRegs.Channel > 14)
351 {
352 if (RssiNumber == 0)
353 RssiOffset = pAd->ARssiOffset0;
354 else if (RssiNumber == 1)
355 RssiOffset = pAd->ARssiOffset1;
356 else
357 RssiOffset = pAd->ARssiOffset2;
358 }
359 else
360 {
361 if (RssiNumber == 0)
362 RssiOffset = pAd->BGRssiOffset0;
363 else if (RssiNumber == 1)
364 RssiOffset = pAd->BGRssiOffset1;
365 else
366 RssiOffset = pAd->BGRssiOffset2;
367 }
368
369 return (-12 - RssiOffset - LNAGain - Rssi);
370}
371
372/*
373 ==========================================================================
374 Description:
375 Scan next channel
376 ==========================================================================
377 */
378VOID ScanNextChannel(
379 IN PRTMP_ADAPTER pAd)
380{
381 HEADER_802_11 Hdr80211;
382 PUCHAR pOutBuffer = NULL;
383 NDIS_STATUS NStatus;
384 ULONG FrameLen = 0;
385 UCHAR SsidLen = 0, ScanType = pAd->MlmeAux.ScanType, BBPValue = 0;
386#ifdef CONFIG_STA_SUPPORT
387 USHORT Status;
388 PHEADER_802_11 pHdr80211;
389#endif // CONFIG_STA_SUPPORT //
390 UINT ScanTimeIn5gChannel = SHORT_CHANNEL_TIME;
391
392#ifdef CONFIG_STA_SUPPORT
393 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
394 {
395 if (MONITOR_ON(pAd))
396 return;
397 }
398#endif // CONFIG_STA_SUPPORT //
399
400#ifdef RALINK_ATE
401 // Nothing to do in ATE mode.
402 if (ATE_ON(pAd))
403 return;
404#endif // RALINK_ATE //
405
406 if (pAd->MlmeAux.Channel == 0)
407 {
408 if ((pAd->CommonCfg.BBPCurrentBW == BW_40)
409#ifdef CONFIG_STA_SUPPORT
410 && (INFRA_ON(pAd)
411 || (pAd->OpMode == OPMODE_AP))
412#endif // CONFIG_STA_SUPPORT //
413 )
414 {
415 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
416 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
417 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
418 BBPValue &= (~0x18);
419 BBPValue |= 0x10;
420 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
421 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",pAd->CommonCfg.CentralChannel, pAd->ScanTab.BssNr));
422 }
423 else
424 {
425 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
426 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
427 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to channel %d, Total BSS[%02d]\n",pAd->CommonCfg.Channel, pAd->ScanTab.BssNr));
428 }
429
430#ifdef CONFIG_STA_SUPPORT
431 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
432 {
433 //
434 // To prevent data lost.
435 // Send an NULL data with turned PSM bit on to current associated AP before SCAN progress.
436 // Now, we need to send an NULL data with turned PSM bit off to AP, when scan progress done
437 //
438 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (INFRA_ON(pAd)))
439 {
440 NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);
441 if (NStatus == NDIS_STATUS_SUCCESS)
442 {
443 pHdr80211 = (PHEADER_802_11) pOutBuffer;
444 MgtMacHeaderInit(pAd, pHdr80211, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
445 pHdr80211->Duration = 0;
446 pHdr80211->FC.Type = BTYPE_DATA;
447 pHdr80211->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
448
449 // Send using priority queue
450 MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
451 DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqAction -- Send PSM Data frame\n"));
452 MlmeFreeMemory(pAd, pOutBuffer);
453 RTMPusecDelay(5000);
454 }
455 }
456
457 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
458 Status = MLME_SUCCESS;
459 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
460 }
461#endif // CONFIG_STA_SUPPORT //
462
463
464 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
465 }
466#ifdef RT2870
467#ifdef CONFIG_STA_SUPPORT
468 else if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) && (pAd->OpMode == OPMODE_STA))
469 {
470 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
471 MlmeCntlConfirm(pAd, MT2_SCAN_CONF, MLME_FAIL_NO_RESOURCE);
472 }
473#endif // CONFIG_STA_SUPPORT //
474#endif // RT2870 //
475 else
476 {
477#ifdef CONFIG_STA_SUPPORT
478 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
479 {
480 // BBP and RF are not accessible in PS mode, we has to wake them up first
481 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
482 AsicForceWakeup(pAd, TRUE);
483
484 // leave PSM during scanning. otherwise we may lost ProbeRsp & BEACON
485 if (pAd->StaCfg.Psm == PWR_SAVE)
486 MlmeSetPsmBit(pAd, PWR_ACTIVE);
487 }
488#endif // CONFIG_STA_SUPPORT //
489
490 AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, TRUE);
491 AsicLockChannel(pAd, pAd->MlmeAux.Channel);
492
493#ifdef CONFIG_STA_SUPPORT
494 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
495 {
496 if (pAd->MlmeAux.Channel > 14)
497 {
498 if ((pAd->CommonCfg.bIEEE80211H == 1) && RadarChannelCheck(pAd, pAd->MlmeAux.Channel))
499 {
500 ScanType = SCAN_PASSIVE;
501 ScanTimeIn5gChannel = MIN_CHANNEL_TIME;
502 }
503 }
504
505#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
506 // carrier detection
507 if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
508 {
509 ScanType = SCAN_PASSIVE;
510 ScanTimeIn5gChannel = MIN_CHANNEL_TIME;
511 }
512#endif // CARRIER_DETECTION_SUPPORT //
513 }
514
515#endif // CONFIG_STA_SUPPORT //
516
517 //Global country domain(ch1-11:active scan, ch12-14 passive scan)
518 if ((pAd->MlmeAux.Channel <= 14) && (pAd->MlmeAux.Channel >= 12) && ((pAd->CommonCfg.CountryRegion & 0x7f) == REGION_31_BG_BAND))
519 {
520 ScanType = SCAN_PASSIVE;
521 }
522
523 // We need to shorten active scan time in order for WZC connect issue
524 // Chnage the channel scan time for CISCO stuff based on its IAPP announcement
525 if (ScanType == FAST_SCAN_ACTIVE)
526 RTMPSetTimer(&pAd->MlmeAux.ScanTimer, FAST_ACTIVE_SCAN_TIME);
527#ifdef CONFIG_STA_SUPPORT
528 else if (((ScanType == SCAN_CISCO_ACTIVE) ||
529 (ScanType == SCAN_CISCO_PASSIVE) ||
530 (ScanType == SCAN_CISCO_CHANNEL_LOAD) ||
531 (ScanType == SCAN_CISCO_NOISE)) && (pAd->OpMode == OPMODE_STA))
532 {
533 if (pAd->StaCfg.CCXScanTime < 25)
534 RTMPSetTimer(&pAd->MlmeAux.ScanTimer, pAd->StaCfg.CCXScanTime * 2);
535 else
536 RTMPSetTimer(&pAd->MlmeAux.ScanTimer, pAd->StaCfg.CCXScanTime);
537 }
538#endif // CONFIG_STA_SUPPORT //
539 else // must be SCAN_PASSIVE or SCAN_ACTIVE
540 {
541 if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
542#ifdef DOT11_N_SUPPORT
543 || (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED)
544#endif // DOT11_N_SUPPORT //
545 )
546 {
547 if (pAd->MlmeAux.Channel > 14)
548 RTMPSetTimer(&pAd->MlmeAux.ScanTimer, ScanTimeIn5gChannel);
549 else
550 RTMPSetTimer(&pAd->MlmeAux.ScanTimer, MIN_CHANNEL_TIME);
551 }
552 else
553 RTMPSetTimer(&pAd->MlmeAux.ScanTimer, MAX_CHANNEL_TIME);
554 }
555
556 if ((ScanType == SCAN_ACTIVE) || (ScanType == FAST_SCAN_ACTIVE) ||
557 (ScanType == SCAN_CISCO_ACTIVE))
558 {
559 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
560 if (NStatus != NDIS_STATUS_SUCCESS)
561 {
562 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - ScanNextChannel() allocate memory fail\n"));
563#ifdef CONFIG_STA_SUPPORT
564 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
565 {
566 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
567 Status = MLME_FAIL_NO_RESOURCE;
568 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
569 }
570#endif // CONFIG_STA_SUPPORT //
571
572 return;
573 }
574
575 // There is no need to send broadcast probe request if active scan is in effect.
576 if ((ScanType == SCAN_ACTIVE) || (ScanType == FAST_SCAN_ACTIVE)
577 )
578 SsidLen = pAd->MlmeAux.SsidLen;
579 else
580 SsidLen = 0;
581
582 MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
583 MakeOutgoingFrame(pOutBuffer, &FrameLen,
584 sizeof(HEADER_802_11), &Hdr80211,
585 1, &SsidIe,
586 1, &SsidLen,
587 SsidLen, pAd->MlmeAux.Ssid,
588 1, &SupRateIe,
589 1, &pAd->CommonCfg.SupRateLen,
590 pAd->CommonCfg.SupRateLen, pAd->CommonCfg.SupRate,
591 END_OF_ARGS);
592
593 if (pAd->CommonCfg.ExtRateLen)
594 {
595 ULONG Tmp;
596 MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
597 1, &ExtRateIe,
598 1, &pAd->CommonCfg.ExtRateLen,
599 pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRate,
600 END_OF_ARGS);
601 FrameLen += Tmp;
602 }
603
604#ifdef DOT11_N_SUPPORT
605 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
606 {
607 ULONG Tmp;
608 UCHAR HtLen;
609 UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
610#ifdef RT_BIG_ENDIAN
611 HT_CAPABILITY_IE HtCapabilityTmp;
612#endif
613 if (pAd->bBroadComHT == TRUE)
614 {
615 HtLen = pAd->MlmeAux.HtCapabilityLen + 4;
616#ifdef RT_BIG_ENDIAN
617 NdisMoveMemory(&HtCapabilityTmp, &pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
618 *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
619 *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
620
621 MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
622 1, &WpaIe,
623 1, &HtLen,
624 4, &BROADCOM[0],
625 pAd->MlmeAux.HtCapabilityLen, &HtCapabilityTmp,
626 END_OF_ARGS);
627#else
628 MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
629 1, &WpaIe,
630 1, &HtLen,
631 4, &BROADCOM[0],
632 pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability,
633 END_OF_ARGS);
634#endif // RT_BIG_ENDIAN //
635 }
636 else
637 {
638 HtLen = pAd->MlmeAux.HtCapabilityLen;
639#ifdef RT_BIG_ENDIAN
640 NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, SIZE_HT_CAP_IE);
641 *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
642 *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
643
644 MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
645 1, &HtCapIe,
646 1, &HtLen,
647 HtLen, &HtCapabilityTmp,
648 END_OF_ARGS);
649#else
650 MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
651 1, &HtCapIe,
652 1, &HtLen,
653 HtLen, &pAd->CommonCfg.HtCapability,
654 END_OF_ARGS);
655#endif // RT_BIG_ENDIAN //
656 }
657 FrameLen += Tmp;
658
659#ifdef DOT11N_DRAFT3
660 if (pAd->CommonCfg.BACapability.field.b2040CoexistScanSup == 1)
661 {
662 ULONG Tmp;
663 HtLen = 1;
664 MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
665 1, &ExtHtCapIe,
666 1, &HtLen,
667 1, &pAd->CommonCfg.BSSCoexist2040.word,
668 END_OF_ARGS);
669
670 FrameLen += Tmp;
671 }
672#endif // DOT11N_DRAFT3 //
673 }
674#endif // DOT11_N_SUPPORT //
675
676
677 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
678 MlmeFreeMemory(pAd, pOutBuffer);
679 }
680
681 // For SCAN_CISCO_PASSIVE, do nothing and silently wait for beacon or other probe reponse
682
683#ifdef CONFIG_STA_SUPPORT
684 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
685 pAd->Mlme.SyncMachine.CurrState = SCAN_LISTEN;
686#endif // CONFIG_STA_SUPPORT //
687
688 }
689}
690
691VOID MgtProbReqMacHeaderInit(
692 IN PRTMP_ADAPTER pAd,
693 IN OUT PHEADER_802_11 pHdr80211,
694 IN UCHAR SubType,
695 IN UCHAR ToDs,
696 IN PUCHAR pDA,
697 IN PUCHAR pBssid)
698{
699 NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
700
701 pHdr80211->FC.Type = BTYPE_MGMT;
702 pHdr80211->FC.SubType = SubType;
703 if (SubType == SUBTYPE_ACK)
704 pHdr80211->FC.Type = BTYPE_CNTL;
705 pHdr80211->FC.ToDs = ToDs;
706 COPY_MAC_ADDR(pHdr80211->Addr1, pDA);
707 COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
708 COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
709}
710
711
diff --git a/drivers/staging/rt3070/common/cmm_wpa.c b/drivers/staging/rt3070/common/cmm_wpa.c
new file mode 100644
index 000000000000..81c332ac2524
--- /dev/null
+++ b/drivers/staging/rt3070/common/cmm_wpa.c
@@ -0,0 +1,1606 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 wpa.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Jan Lee 03-07-22 Initial
36 Paul Lin 03-11-28 Modify for supplicant
37*/
38#include "../rt_config.h"
39// WPA OUI
40UCHAR OUI_WPA_NONE_AKM[4] = {0x00, 0x50, 0xF2, 0x00};
41UCHAR OUI_WPA_VERSION[4] = {0x00, 0x50, 0xF2, 0x01};
42UCHAR OUI_WPA_TKIP[4] = {0x00, 0x50, 0xF2, 0x02};
43UCHAR OUI_WPA_CCMP[4] = {0x00, 0x50, 0xF2, 0x04};
44UCHAR OUI_WPA_8021X_AKM[4] = {0x00, 0x50, 0xF2, 0x01};
45UCHAR OUI_WPA_PSK_AKM[4] = {0x00, 0x50, 0xF2, 0x02};
46// WPA2 OUI
47UCHAR OUI_WPA2_WEP40[4] = {0x00, 0x0F, 0xAC, 0x01};
48UCHAR OUI_WPA2_TKIP[4] = {0x00, 0x0F, 0xAC, 0x02};
49UCHAR OUI_WPA2_CCMP[4] = {0x00, 0x0F, 0xAC, 0x04};
50UCHAR OUI_WPA2_8021X_AKM[4] = {0x00, 0x0F, 0xAC, 0x01};
51UCHAR OUI_WPA2_PSK_AKM[4] = {0x00, 0x0F, 0xAC, 0x02};
52// MSA OUI
53UCHAR OUI_MSA_8021X_AKM[4] = {0x00, 0x0F, 0xAC, 0x05}; // Not yet final - IEEE 802.11s-D1.06
54UCHAR OUI_MSA_PSK_AKM[4] = {0x00, 0x0F, 0xAC, 0x06}; // Not yet final - IEEE 802.11s-D1.06
55
56/*
57 ========================================================================
58
59 Routine Description:
60 The pseudo-random function(PRF) that hashes various inputs to
61 derive a pseudo-random value. To add liveness to the pseudo-random
62 value, a nonce should be one of the inputs.
63
64 It is used to generate PTK, GTK or some specific random value.
65
66 Arguments:
67 UCHAR *key, - the key material for HMAC_SHA1 use
68 INT key_len - the length of key
69 UCHAR *prefix - a prefix label
70 INT prefix_len - the length of the label
71 UCHAR *data - a specific data with variable length
72 INT data_len - the length of a specific data
73 INT len - the output lenght
74
75 Return Value:
76 UCHAR *output - the calculated result
77
78 Note:
79 802.11i-2004 Annex H.3
80
81 ========================================================================
82*/
83VOID PRF(
84 IN UCHAR *key,
85 IN INT key_len,
86 IN UCHAR *prefix,
87 IN INT prefix_len,
88 IN UCHAR *data,
89 IN INT data_len,
90 OUT UCHAR *output,
91 IN INT len)
92{
93 INT i;
94 UCHAR *input;
95 INT currentindex = 0;
96 INT total_len;
97
98 // Allocate memory for input
99 os_alloc_mem(NULL, (PUCHAR *)&input, 1024);
100
101 if (input == NULL)
102 {
103 DBGPRINT(RT_DEBUG_ERROR, ("!!!PRF: no memory!!!\n"));
104 return;
105 }
106
107 // Generate concatenation input
108 NdisMoveMemory(input, prefix, prefix_len);
109
110 // Concatenate a single octet containing 0
111 input[prefix_len] = 0;
112
113 // Concatenate specific data
114 NdisMoveMemory(&input[prefix_len + 1], data, data_len);
115 total_len = prefix_len + 1 + data_len;
116
117 // Concatenate a single octet containing 0
118 // This octet shall be update later
119 input[total_len] = 0;
120 total_len++;
121
122 // Iterate to calculate the result by hmac-sha-1
123 // Then concatenate to last result
124 for (i = 0; i < (len + 19) / 20; i++)
125 {
126 HMAC_SHA1(input, total_len, key, key_len, &output[currentindex]);
127 currentindex += 20;
128
129 // update the last octet
130 input[total_len - 1]++;
131 }
132 os_free_mem(NULL, input);
133}
134
135/*
136 ========================================================================
137
138 Routine Description:
139 It utilizes PRF-384 or PRF-512 to derive session-specific keys from a PMK.
140 It shall be called by 4-way handshake processing.
141
142 Arguments:
143 pAd - pointer to our pAdapter context
144 PMK - pointer to PMK
145 ANonce - pointer to ANonce
146 AA - pointer to Authenticator Address
147 SNonce - pointer to SNonce
148 SA - pointer to Supplicant Address
149 len - indicate the length of PTK (octet)
150
151 Return Value:
152 Output pointer to the PTK
153
154 Note:
155 Refer to IEEE 802.11i-2004 8.5.1.2
156
157 ========================================================================
158*/
159VOID WpaCountPTK(
160 IN PRTMP_ADAPTER pAd,
161 IN UCHAR *PMK,
162 IN UCHAR *ANonce,
163 IN UCHAR *AA,
164 IN UCHAR *SNonce,
165 IN UCHAR *SA,
166 OUT UCHAR *output,
167 IN UINT len)
168{
169 UCHAR concatenation[76];
170 UINT CurrPos = 0;
171 UCHAR temp[32];
172 UCHAR Prefix[] = {'P', 'a', 'i', 'r', 'w', 'i', 's', 'e', ' ', 'k', 'e', 'y', ' ',
173 'e', 'x', 'p', 'a', 'n', 's', 'i', 'o', 'n'};
174
175 // initiate the concatenation input
176 NdisZeroMemory(temp, sizeof(temp));
177 NdisZeroMemory(concatenation, 76);
178
179 // Get smaller address
180 if (RTMPCompareMemory(SA, AA, 6) == 1)
181 NdisMoveMemory(concatenation, AA, 6);
182 else
183 NdisMoveMemory(concatenation, SA, 6);
184 CurrPos += 6;
185
186 // Get larger address
187 if (RTMPCompareMemory(SA, AA, 6) == 1)
188 NdisMoveMemory(&concatenation[CurrPos], SA, 6);
189 else
190 NdisMoveMemory(&concatenation[CurrPos], AA, 6);
191
192 // store the larger mac address for backward compatible of
193 // ralink proprietary STA-key issue
194 NdisMoveMemory(temp, &concatenation[CurrPos], MAC_ADDR_LEN);
195 CurrPos += 6;
196
197 // Get smaller Nonce
198 if (RTMPCompareMemory(ANonce, SNonce, 32) == 0)
199 NdisMoveMemory(&concatenation[CurrPos], temp, 32); // patch for ralink proprietary STA-key issue
200 else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
201 NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
202 else
203 NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
204 CurrPos += 32;
205
206 // Get larger Nonce
207 if (RTMPCompareMemory(ANonce, SNonce, 32) == 0)
208 NdisMoveMemory(&concatenation[CurrPos], temp, 32); // patch for ralink proprietary STA-key issue
209 else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
210 NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
211 else
212 NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
213 CurrPos += 32;
214
215 hex_dump("concatenation=", concatenation, 76);
216
217 // Use PRF to generate PTK
218 PRF(PMK, LEN_MASTER_KEY, Prefix, 22, concatenation, 76, output, len);
219
220}
221
222/*
223 ========================================================================
224
225 Routine Description:
226 Generate random number by software.
227
228 Arguments:
229 pAd - pointer to our pAdapter context
230 macAddr - pointer to local MAC address
231
232 Return Value:
233
234 Note:
235 802.1ii-2004 Annex H.5
236
237 ========================================================================
238*/
239VOID GenRandom(
240 IN PRTMP_ADAPTER pAd,
241 IN UCHAR *macAddr,
242 OUT UCHAR *random)
243{
244 INT i, curr;
245 UCHAR local[80], KeyCounter[32];
246 UCHAR result[80];
247 ULONG CurrentTime;
248 UCHAR prefix[] = {'I', 'n', 'i', 't', ' ', 'C', 'o', 'u', 'n', 't', 'e', 'r'};
249
250 // Zero the related information
251 NdisZeroMemory(result, 80);
252 NdisZeroMemory(local, 80);
253 NdisZeroMemory(KeyCounter, 32);
254
255 for (i = 0; i < 32; i++)
256 {
257 // copy the local MAC address
258 COPY_MAC_ADDR(local, macAddr);
259 curr = MAC_ADDR_LEN;
260
261 // concatenate the current time
262 NdisGetSystemUpTime(&CurrentTime);
263 NdisMoveMemory(&local[curr], &CurrentTime, sizeof(CurrentTime));
264 curr += sizeof(CurrentTime);
265
266 // concatenate the last result
267 NdisMoveMemory(&local[curr], result, 32);
268 curr += 32;
269
270 // concatenate a variable
271 NdisMoveMemory(&local[curr], &i, 2);
272 curr += 2;
273
274 // calculate the result
275 PRF(KeyCounter, 32, prefix,12, local, curr, result, 32);
276 }
277
278 NdisMoveMemory(random, result, 32);
279}
280
281/*
282 ========================================================================
283
284 Routine Description:
285 Build cipher suite in RSN-IE.
286 It only shall be called by RTMPMakeRSNIE.
287
288 Arguments:
289 pAd - pointer to our pAdapter context
290 ElementID - indicate the WPA1 or WPA2
291 WepStatus - indicate the encryption type
292 bMixCipher - a boolean to indicate the pairwise cipher and group
293 cipher are the same or not
294
295 Return Value:
296
297 Note:
298
299 ========================================================================
300*/
301static VOID RTMPInsertRsnIeCipher(
302 IN PRTMP_ADAPTER pAd,
303 IN UCHAR ElementID,
304 IN UINT WepStatus,
305 IN BOOLEAN bMixCipher,
306 IN UCHAR FlexibleCipher,
307 OUT PUCHAR pRsnIe,
308 OUT UCHAR *rsn_len)
309{
310 UCHAR PairwiseCnt;
311
312 *rsn_len = 0;
313
314 // decide WPA2 or WPA1
315 if (ElementID == Wpa2Ie)
316 {
317 RSNIE2 *pRsnie_cipher = (RSNIE2*)pRsnIe;
318
319 // Assign the verson as 1
320 pRsnie_cipher->version = 1;
321
322 switch (WepStatus)
323 {
324 // TKIP mode
325 case Ndis802_11Encryption2Enabled:
326 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
327 pRsnie_cipher->ucount = 1;
328 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_TKIP, 4);
329 *rsn_len = sizeof(RSNIE2);
330 break;
331
332 // AES mode
333 case Ndis802_11Encryption3Enabled:
334 if (bMixCipher)
335 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
336 else
337 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_CCMP, 4);
338 pRsnie_cipher->ucount = 1;
339 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_CCMP, 4);
340 *rsn_len = sizeof(RSNIE2);
341 break;
342
343 // TKIP-AES mix mode
344 case Ndis802_11Encryption4Enabled:
345 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
346
347 PairwiseCnt = 1;
348 // Insert WPA2 TKIP as the first pairwise cipher
349 if (MIX_CIPHER_WPA2_TKIP_ON(FlexibleCipher))
350 {
351 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_TKIP, 4);
352 // Insert WPA2 AES as the secondary pairwise cipher
353 if (MIX_CIPHER_WPA2_AES_ON(FlexibleCipher))
354 {
355 NdisMoveMemory(pRsnie_cipher->ucast[0].oui + 4, OUI_WPA2_CCMP, 4);
356 PairwiseCnt = 2;
357 }
358 }
359 else
360 {
361 // Insert WPA2 AES as the first pairwise cipher
362 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_CCMP, 4);
363 }
364
365 pRsnie_cipher->ucount = PairwiseCnt;
366 *rsn_len = sizeof(RSNIE2) + (4 * (PairwiseCnt - 1));
367 break;
368 }
369
370 // swap for big-endian platform
371 pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
372 pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
373 }
374 else
375 {
376 RSNIE *pRsnie_cipher = (RSNIE*)pRsnIe;
377
378 // Assign OUI and version
379 NdisMoveMemory(pRsnie_cipher->oui, OUI_WPA_VERSION, 4);
380 pRsnie_cipher->version = 1;
381
382 switch (WepStatus)
383 {
384 // TKIP mode
385 case Ndis802_11Encryption2Enabled:
386 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
387 pRsnie_cipher->ucount = 1;
388 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_TKIP, 4);
389 *rsn_len = sizeof(RSNIE);
390 break;
391
392 // AES mode
393 case Ndis802_11Encryption3Enabled:
394 if (bMixCipher)
395 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
396 else
397 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_CCMP, 4);
398 pRsnie_cipher->ucount = 1;
399 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_CCMP, 4);
400 *rsn_len = sizeof(RSNIE);
401 break;
402
403 // TKIP-AES mix mode
404 case Ndis802_11Encryption4Enabled:
405 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
406
407 PairwiseCnt = 1;
408 // Insert WPA TKIP as the first pairwise cipher
409 if (MIX_CIPHER_WPA_TKIP_ON(FlexibleCipher))
410 {
411 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_TKIP, 4);
412 // Insert WPA AES as the secondary pairwise cipher
413 if (MIX_CIPHER_WPA_AES_ON(FlexibleCipher))
414 {
415 NdisMoveMemory(pRsnie_cipher->ucast[0].oui + 4, OUI_WPA_CCMP, 4);
416 PairwiseCnt = 2;
417 }
418 }
419 else
420 {
421 // Insert WPA AES as the first pairwise cipher
422 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_CCMP, 4);
423 }
424
425 pRsnie_cipher->ucount = PairwiseCnt;
426 *rsn_len = sizeof(RSNIE) + (4 * (PairwiseCnt - 1));
427 break;
428 }
429
430 // swap for big-endian platform
431 pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
432 pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
433 }
434
435}
436
437/*
438 ========================================================================
439
440 Routine Description:
441 Build AKM suite in RSN-IE.
442 It only shall be called by RTMPMakeRSNIE.
443
444 Arguments:
445 pAd - pointer to our pAdapter context
446 ElementID - indicate the WPA1 or WPA2
447 AuthMode - indicate the authentication mode
448 apidx - indicate the interface index
449
450 Return Value:
451
452 Note:
453
454 ========================================================================
455*/
456static VOID RTMPInsertRsnIeAKM(
457 IN PRTMP_ADAPTER pAd,
458 IN UCHAR ElementID,
459 IN UINT AuthMode,
460 IN UCHAR apidx,
461 OUT PUCHAR pRsnIe,
462 OUT UCHAR *rsn_len)
463{
464 RSNIE_AUTH *pRsnie_auth;
465
466 pRsnie_auth = (RSNIE_AUTH*)(pRsnIe + (*rsn_len));
467
468 // decide WPA2 or WPA1
469 if (ElementID == Wpa2Ie)
470 {
471 switch (AuthMode)
472 {
473 case Ndis802_11AuthModeWPA2:
474 case Ndis802_11AuthModeWPA1WPA2:
475 pRsnie_auth->acount = 1;
476 NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA2_8021X_AKM, 4);
477 break;
478
479 case Ndis802_11AuthModeWPA2PSK:
480 case Ndis802_11AuthModeWPA1PSKWPA2PSK:
481 pRsnie_auth->acount = 1;
482 NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA2_PSK_AKM, 4);
483 break;
484 }
485 }
486 else
487 {
488 switch (AuthMode)
489 {
490 case Ndis802_11AuthModeWPA:
491 case Ndis802_11AuthModeWPA1WPA2:
492 pRsnie_auth->acount = 1;
493 NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_8021X_AKM, 4);
494 break;
495
496 case Ndis802_11AuthModeWPAPSK:
497 case Ndis802_11AuthModeWPA1PSKWPA2PSK:
498 pRsnie_auth->acount = 1;
499 NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_PSK_AKM, 4);
500 break;
501
502 case Ndis802_11AuthModeWPANone:
503 pRsnie_auth->acount = 1;
504 NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_NONE_AKM, 4);
505 break;
506 }
507 }
508
509 pRsnie_auth->acount = cpu2le16(pRsnie_auth->acount);
510
511 (*rsn_len) += sizeof(RSNIE_AUTH); // update current RSNIE length
512
513}
514
515/*
516 ========================================================================
517
518 Routine Description:
519 Build capability in RSN-IE.
520 It only shall be called by RTMPMakeRSNIE.
521
522 Arguments:
523 pAd - pointer to our pAdapter context
524 ElementID - indicate the WPA1 or WPA2
525 apidx - indicate the interface index
526
527 Return Value:
528
529 Note:
530
531 ========================================================================
532*/
533static VOID RTMPInsertRsnIeCap(
534 IN PRTMP_ADAPTER pAd,
535 IN UCHAR ElementID,
536 IN UCHAR apidx,
537 OUT PUCHAR pRsnIe,
538 OUT UCHAR *rsn_len)
539{
540 RSN_CAPABILITIES *pRSN_Cap;
541
542 // it could be ignored in WPA1 mode
543 if (ElementID == WpaIe)
544 return;
545
546 pRSN_Cap = (RSN_CAPABILITIES*)(pRsnIe + (*rsn_len));
547
548
549 pRSN_Cap->word = cpu2le16(pRSN_Cap->word);
550
551 (*rsn_len) += sizeof(RSN_CAPABILITIES); // update current RSNIE length
552
553}
554
555
556/*
557 ========================================================================
558
559 Routine Description:
560 Build RSN IE context. It is not included element-ID and length.
561
562 Arguments:
563 pAd - pointer to our pAdapter context
564 AuthMode - indicate the authentication mode
565 WepStatus - indicate the encryption type
566 apidx - indicate the interface index
567
568 Return Value:
569
570 Note:
571
572 ========================================================================
573*/
574VOID RTMPMakeRSNIE(
575 IN PRTMP_ADAPTER pAd,
576 IN UINT AuthMode,
577 IN UINT WepStatus,
578 IN UCHAR apidx)
579{
580 PUCHAR pRsnIe = NULL; // primary RSNIE
581 UCHAR *rsnielen_cur_p = 0; // the length of the primary RSNIE
582 UCHAR *rsnielen_ex_cur_p = 0; // the length of the secondary RSNIE
583 UCHAR PrimaryRsnie;
584 BOOLEAN bMixCipher = FALSE; // indicate the pairwise and group cipher are different
585 UCHAR p_offset;
586 WPA_MIX_PAIR_CIPHER FlexibleCipher = MIX_CIPHER_NOTUSE; // it provide the more flexible cipher combination in WPA-WPA2 and TKIPAES mode
587
588 rsnielen_cur_p = NULL;
589 rsnielen_ex_cur_p = NULL;
590
591 {
592#ifdef CONFIG_STA_SUPPORT
593 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
594 {
595#ifdef WPA_SUPPLICANT_SUPPORT
596 if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
597 {
598 if (AuthMode < Ndis802_11AuthModeWPA)
599 return;
600 }
601 else
602#endif // WPA_SUPPLICANT_SUPPORT //
603 {
604 // Support WPAPSK or WPA2PSK in STA-Infra mode
605 // Support WPANone in STA-Adhoc mode
606 if ((AuthMode != Ndis802_11AuthModeWPAPSK) &&
607 (AuthMode != Ndis802_11AuthModeWPA2PSK) &&
608 (AuthMode != Ndis802_11AuthModeWPANone)
609 )
610 return;
611 }
612
613 DBGPRINT(RT_DEBUG_TRACE,("==> RTMPMakeRSNIE(STA)\n"));
614
615 // Zero RSNIE context
616 pAd->StaCfg.RSNIE_Len = 0;
617 NdisZeroMemory(pAd->StaCfg.RSN_IE, MAX_LEN_OF_RSNIE);
618
619 // Pointer to RSNIE
620 rsnielen_cur_p = &pAd->StaCfg.RSNIE_Len;
621 pRsnIe = pAd->StaCfg.RSN_IE;
622
623 bMixCipher = pAd->StaCfg.bMixCipher;
624 }
625#endif // CONFIG_STA_SUPPORT //
626 }
627
628 // indicate primary RSNIE as WPA or WPA2
629 if ((AuthMode == Ndis802_11AuthModeWPA) ||
630 (AuthMode == Ndis802_11AuthModeWPAPSK) ||
631 (AuthMode == Ndis802_11AuthModeWPANone) ||
632 (AuthMode == Ndis802_11AuthModeWPA1WPA2) ||
633 (AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK))
634 PrimaryRsnie = WpaIe;
635 else
636 PrimaryRsnie = Wpa2Ie;
637
638 {
639 // Build the primary RSNIE
640 // 1. insert cipher suite
641 RTMPInsertRsnIeCipher(pAd, PrimaryRsnie, WepStatus, bMixCipher, FlexibleCipher, pRsnIe, &p_offset);
642
643 // 2. insert AKM
644 RTMPInsertRsnIeAKM(pAd, PrimaryRsnie, AuthMode, apidx, pRsnIe, &p_offset);
645
646 // 3. insert capability
647 RTMPInsertRsnIeCap(pAd, PrimaryRsnie, apidx, pRsnIe, &p_offset);
648 }
649
650 // 4. update the RSNIE length
651 *rsnielen_cur_p = p_offset;
652
653 hex_dump("The primary RSNIE", pRsnIe, (*rsnielen_cur_p));
654
655
656}
657
658/*
659 ==========================================================================
660 Description:
661 Check whether the received frame is EAP frame.
662
663 Arguments:
664 pAd - pointer to our pAdapter context
665 pEntry - pointer to active entry
666 pData - the received frame
667 DataByteCount - the received frame's length
668 FromWhichBSSID - indicate the interface index
669
670 Return:
671 TRUE - This frame is EAP frame
672 FALSE - otherwise
673 ==========================================================================
674*/
675BOOLEAN RTMPCheckWPAframe(
676 IN PRTMP_ADAPTER pAd,
677 IN PMAC_TABLE_ENTRY pEntry,
678 IN PUCHAR pData,
679 IN ULONG DataByteCount,
680 IN UCHAR FromWhichBSSID)
681{
682 ULONG Body_len;
683 BOOLEAN Cancelled;
684
685
686 if(DataByteCount < (LENGTH_802_1_H + LENGTH_EAPOL_H))
687 return FALSE;
688
689
690 // Skip LLC header
691 if (NdisEqualMemory(SNAP_802_1H, pData, 6) ||
692 // Cisco 1200 AP may send packet with SNAP_BRIDGE_TUNNEL
693 NdisEqualMemory(SNAP_BRIDGE_TUNNEL, pData, 6))
694 {
695 pData += 6;
696 }
697 // Skip 2-bytes EAPoL type
698 if (NdisEqualMemory(EAPOL, pData, 2))
699 {
700 pData += 2;
701 }
702 else
703 return FALSE;
704
705 switch (*(pData+1))
706 {
707 case EAPPacket:
708 Body_len = (*(pData+2)<<8) | (*(pData+3));
709 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAP-Packet frame, TYPE = 0, Length = %ld\n", Body_len));
710 break;
711 case EAPOLStart:
712 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL-Start frame, TYPE = 1 \n"));
713 if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE)
714 {
715 DBGPRINT(RT_DEBUG_TRACE, ("Cancel the EnqueueEapolStartTimerRunning \n"));
716 RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled);
717 pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
718 }
719 break;
720 case EAPOLLogoff:
721 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOLLogoff frame, TYPE = 2 \n"));
722 break;
723 case EAPOLKey:
724 Body_len = (*(pData+2)<<8) | (*(pData+3));
725 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL-Key frame, TYPE = 3, Length = %ld\n", Body_len));
726 break;
727 case EAPOLASFAlert:
728 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOLASFAlert frame, TYPE = 4 \n"));
729 break;
730 default:
731 return FALSE;
732
733 }
734 return TRUE;
735}
736
737
738/*
739 ==========================================================================
740 Description:
741 ENCRYPT AES GTK before sending in EAPOL frame.
742 AES GTK length = 128 bit, so fix blocks for aes-key-wrap as 2 in this function.
743 This function references to RFC 3394 for aes key wrap algorithm.
744 Return:
745 ==========================================================================
746*/
747VOID AES_GTK_KEY_WRAP(
748 IN UCHAR *key,
749 IN UCHAR *plaintext,
750 IN UCHAR p_len,
751 OUT UCHAR *ciphertext)
752{
753 UCHAR A[8], BIN[16], BOUT[16];
754 UCHAR R[512];
755 INT num_blocks = p_len/8; // unit:64bits
756 INT i, j;
757 aes_context aesctx;
758 UCHAR xor;
759
760 rtmp_aes_set_key(&aesctx, key, 128);
761
762 // Init IA
763 for (i = 0; i < 8; i++)
764 A[i] = 0xa6;
765
766 //Input plaintext
767 for (i = 0; i < num_blocks; i++)
768 {
769 for (j = 0 ; j < 8; j++)
770 R[8 * (i + 1) + j] = plaintext[8 * i + j];
771 }
772
773 // Key Mix
774 for (j = 0; j < 6; j++)
775 {
776 for(i = 1; i <= num_blocks; i++)
777 {
778 //phase 1
779 NdisMoveMemory(BIN, A, 8);
780 NdisMoveMemory(&BIN[8], &R[8 * i], 8);
781 rtmp_aes_encrypt(&aesctx, BIN, BOUT);
782
783 NdisMoveMemory(A, &BOUT[0], 8);
784 xor = num_blocks * j + i;
785 A[7] = BOUT[7] ^ xor;
786 NdisMoveMemory(&R[8 * i], &BOUT[8], 8);
787 }
788 }
789
790 // Output ciphertext
791 NdisMoveMemory(ciphertext, A, 8);
792
793 for (i = 1; i <= num_blocks; i++)
794 {
795 for (j = 0 ; j < 8; j++)
796 ciphertext[8 * i + j] = R[8 * i + j];
797 }
798}
799
800
801/*
802 ========================================================================
803
804 Routine Description:
805 Misc function to decrypt AES body
806
807 Arguments:
808
809 Return Value:
810
811 Note:
812 This function references to RFC 3394 for aes key unwrap algorithm.
813
814 ========================================================================
815*/
816VOID AES_GTK_KEY_UNWRAP(
817 IN UCHAR *key,
818 OUT UCHAR *plaintext,
819 IN UCHAR c_len,
820 IN UCHAR *ciphertext)
821
822{
823 UCHAR A[8], BIN[16], BOUT[16];
824 UCHAR xor;
825 INT i, j;
826 aes_context aesctx;
827 UCHAR *R;
828 INT num_blocks = c_len/8; // unit:64bits
829
830
831 os_alloc_mem(NULL, (PUCHAR *)&R, 512);
832
833 if (R == NULL)
834 {
835 DBGPRINT(RT_DEBUG_ERROR, ("!!!AES_GTK_KEY_UNWRAP: no memory!!!\n"));
836 return;
837 } /* End of if */
838
839 // Initialize
840 NdisMoveMemory(A, ciphertext, 8);
841 //Input plaintext
842 for(i = 0; i < (c_len-8); i++)
843 {
844 R[ i] = ciphertext[i + 8];
845 }
846
847 rtmp_aes_set_key(&aesctx, key, 128);
848
849 for(j = 5; j >= 0; j--)
850 {
851 for(i = (num_blocks-1); i > 0; i--)
852 {
853 xor = (num_blocks -1 )* j + i;
854 NdisMoveMemory(BIN, A, 8);
855 BIN[7] = A[7] ^ xor;
856 NdisMoveMemory(&BIN[8], &R[(i-1)*8], 8);
857 rtmp_aes_decrypt(&aesctx, BIN, BOUT);
858 NdisMoveMemory(A, &BOUT[0], 8);
859 NdisMoveMemory(&R[(i-1)*8], &BOUT[8], 8);
860 }
861 }
862
863 // OUTPUT
864 for(i = 0; i < c_len; i++)
865 {
866 plaintext[i] = R[i];
867 }
868
869
870 os_free_mem(NULL, R);
871}
872
873/*
874 ==========================================================================
875 Description:
876 Report the EAP message type
877
878 Arguments:
879 msg - EAPOL_PAIR_MSG_1
880 EAPOL_PAIR_MSG_2
881 EAPOL_PAIR_MSG_3
882 EAPOL_PAIR_MSG_4
883 EAPOL_GROUP_MSG_1
884 EAPOL_GROUP_MSG_2
885
886 Return:
887 message type string
888
889 ==========================================================================
890*/
891CHAR *GetEapolMsgType(CHAR msg)
892{
893 if(msg == EAPOL_PAIR_MSG_1)
894 return "Pairwise Message 1";
895 else if(msg == EAPOL_PAIR_MSG_2)
896 return "Pairwise Message 2";
897 else if(msg == EAPOL_PAIR_MSG_3)
898 return "Pairwise Message 3";
899 else if(msg == EAPOL_PAIR_MSG_4)
900 return "Pairwise Message 4";
901 else if(msg == EAPOL_GROUP_MSG_1)
902 return "Group Message 1";
903 else if(msg == EAPOL_GROUP_MSG_2)
904 return "Group Message 2";
905 else
906 return "Invalid Message";
907}
908
909
910/*
911 ========================================================================
912
913 Routine Description:
914 Check Sanity RSN IE of EAPoL message
915
916 Arguments:
917
918 Return Value:
919
920
921 ========================================================================
922*/
923BOOLEAN RTMPCheckRSNIE(
924 IN PRTMP_ADAPTER pAd,
925 IN PUCHAR pData,
926 IN UCHAR DataLen,
927 IN MAC_TABLE_ENTRY *pEntry,
928 OUT UCHAR *Offset)
929{
930 PUCHAR pVIE;
931 UCHAR len;
932 PEID_STRUCT pEid;
933 BOOLEAN result = FALSE;
934
935 pVIE = pData;
936 len = DataLen;
937 *Offset = 0;
938
939 while (len > sizeof(RSNIE2))
940 {
941 pEid = (PEID_STRUCT) pVIE;
942 // WPA RSN IE
943 if ((pEid->Eid == IE_WPA) && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)))
944 {
945 if ((pEntry->AuthMode == Ndis802_11AuthModeWPA || pEntry->AuthMode == Ndis802_11AuthModeWPAPSK) &&
946 (NdisEqualMemory(pVIE, pEntry->RSN_IE, pEntry->RSNIE_Len)) &&
947 (pEntry->RSNIE_Len == (pEid->Len + 2)))
948 {
949 result = TRUE;
950 }
951
952 *Offset += (pEid->Len + 2);
953 }
954 // WPA2 RSN IE
955 else if ((pEid->Eid == IE_RSN) && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3)))
956 {
957 if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2 || pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) &&
958 (NdisEqualMemory(pVIE, pEntry->RSN_IE, pEntry->RSNIE_Len)) &&
959 (pEntry->RSNIE_Len == (pEid->Len + 2))/* ToDo-AlbertY for mesh*/)
960 {
961 result = TRUE;
962 }
963
964 *Offset += (pEid->Len + 2);
965 }
966 else
967 {
968 break;
969 }
970
971 pVIE += (pEid->Len + 2);
972 len -= (pEid->Len + 2);
973 }
974
975
976 return result;
977
978}
979
980
981/*
982 ========================================================================
983
984 Routine Description:
985 Parse KEYDATA field. KEYDATA[] May contain 2 RSN IE and optionally GTK.
986 GTK is encaptulated in KDE format at p.83 802.11i D10
987
988 Arguments:
989
990 Return Value:
991
992 Note:
993 802.11i D10
994
995 ========================================================================
996*/
997BOOLEAN RTMPParseEapolKeyData(
998 IN PRTMP_ADAPTER pAd,
999 IN PUCHAR pKeyData,
1000 IN UCHAR KeyDataLen,
1001 IN UCHAR GroupKeyIndex,
1002 IN UCHAR MsgType,
1003 IN BOOLEAN bWPA2,
1004 IN MAC_TABLE_ENTRY *pEntry)
1005{
1006 PKDE_ENCAP pKDE = NULL;
1007 PUCHAR pMyKeyData = pKeyData;
1008 UCHAR KeyDataLength = KeyDataLen;
1009 UCHAR GTKLEN = 0;
1010 UCHAR DefaultIdx = 0;
1011 UCHAR skip_offset;
1012
1013 // Verify The RSN IE contained in pairewise_msg_2 && pairewise_msg_3 and skip it
1014 if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_3)
1015 {
1016 // Check RSN IE whether it is WPA2/WPA2PSK
1017 if (!RTMPCheckRSNIE(pAd, pKeyData, KeyDataLen, pEntry, &skip_offset))
1018 {
1019 // send wireless event - for RSN IE different
1020 if (pAd->CommonCfg.bWirelessEvent)
1021 RTMPSendWirelessEvent(pAd, IW_RSNIE_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
1022
1023 DBGPRINT(RT_DEBUG_ERROR, ("RSN_IE Different in msg %d of 4-way handshake!\n", MsgType));
1024 hex_dump("Receive RSN_IE ", pKeyData, KeyDataLen);
1025 hex_dump("Desired RSN_IE ", pEntry->RSN_IE, pEntry->RSNIE_Len);
1026
1027 return FALSE;
1028 }
1029 else
1030 {
1031 if (bWPA2 && MsgType == EAPOL_PAIR_MSG_3)
1032 {
1033 // skip RSN IE
1034 pMyKeyData += skip_offset;
1035 KeyDataLength -= skip_offset;
1036 DBGPRINT(RT_DEBUG_TRACE, ("RTMPParseEapolKeyData ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", skip_offset));
1037 }
1038 else
1039 return TRUE;
1040 }
1041 }
1042
1043 DBGPRINT(RT_DEBUG_TRACE,("RTMPParseEapolKeyData ==> KeyDataLength %d without RSN_IE \n", KeyDataLength));
1044
1045 // Parse EKD format in pairwise_msg_3_WPA2 && group_msg_1_WPA2
1046 if (bWPA2 && (MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1))
1047 {
1048 if (KeyDataLength >= 8) // KDE format exclude GTK length
1049 {
1050 pKDE = (PKDE_ENCAP) pMyKeyData;
1051
1052
1053 DefaultIdx = pKDE->GTKEncap.Kid;
1054
1055 // Sanity check - KED length
1056 if (KeyDataLength < (pKDE->Len + 2))
1057 {
1058 DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The len from KDE is too short \n"));
1059 return FALSE;
1060 }
1061
1062 // Get GTK length - refer to IEEE 802.11i-2004 p.82
1063 GTKLEN = pKDE->Len -6;
1064 if (GTKLEN < LEN_AES_KEY)
1065 {
1066 DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key length is too short (%d) \n", GTKLEN));
1067 return FALSE;
1068 }
1069
1070 }
1071 else
1072 {
1073 DBGPRINT(RT_DEBUG_ERROR, ("ERROR: KDE format length is too short \n"));
1074 return FALSE;
1075 }
1076
1077 DBGPRINT(RT_DEBUG_TRACE, ("GTK in KDE format ,DefaultKeyID=%d, KeyLen=%d \n", DefaultIdx, GTKLEN));
1078 // skip it
1079 pMyKeyData += 8;
1080 KeyDataLength -= 8;
1081
1082 }
1083 else if (!bWPA2 && MsgType == EAPOL_GROUP_MSG_1)
1084 {
1085 DefaultIdx = GroupKeyIndex;
1086 DBGPRINT(RT_DEBUG_TRACE, ("GTK DefaultKeyID=%d \n", DefaultIdx));
1087 }
1088
1089 // Sanity check - shared key index must be 1 ~ 3
1090 if (DefaultIdx < 1 || DefaultIdx > 3)
1091 {
1092 DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key index(%d) is invalid in %s %s \n", DefaultIdx, ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType)));
1093 return FALSE;
1094 }
1095
1096
1097#ifdef CONFIG_STA_SUPPORT
1098 // Todo
1099#endif // CONFIG_STA_SUPPORT //
1100
1101 return TRUE;
1102
1103}
1104
1105
1106/*
1107 ========================================================================
1108
1109 Routine Description:
1110 Construct EAPoL message for WPA handshaking
1111 Its format is below,
1112
1113 +--------------------+
1114 | Protocol Version | 1 octet
1115 +--------------------+
1116 | Protocol Type | 1 octet
1117 +--------------------+
1118 | Body Length | 2 octets
1119 +--------------------+
1120 | Descriptor Type | 1 octet
1121 +--------------------+
1122 | Key Information | 2 octets
1123 +--------------------+
1124 | Key Length | 1 octet
1125 +--------------------+
1126 | Key Repaly Counter | 8 octets
1127 +--------------------+
1128 | Key Nonce | 32 octets
1129 +--------------------+
1130 | Key IV | 16 octets
1131 +--------------------+
1132 | Key RSC | 8 octets
1133 +--------------------+
1134 | Key ID or Reserved | 8 octets
1135 +--------------------+
1136 | Key MIC | 16 octets
1137 +--------------------+
1138 | Key Data Length | 2 octets
1139 +--------------------+
1140 | Key Data | n octets
1141 +--------------------+
1142
1143
1144 Arguments:
1145 pAd Pointer to our adapter
1146
1147 Return Value:
1148 None
1149
1150 Note:
1151
1152 ========================================================================
1153*/
1154VOID ConstructEapolMsg(
1155 IN PRTMP_ADAPTER pAd,
1156 IN UCHAR AuthMode,
1157 IN UCHAR WepStatus,
1158 IN UCHAR GroupKeyWepStatus,
1159 IN UCHAR MsgType,
1160 IN UCHAR DefaultKeyIdx,
1161 IN UCHAR *ReplayCounter,
1162 IN UCHAR *KeyNonce,
1163 IN UCHAR *TxRSC,
1164 IN UCHAR *PTK,
1165 IN UCHAR *GTK,
1166 IN UCHAR *RSNIE,
1167 IN UCHAR RSNIE_Len,
1168 OUT PEAPOL_PACKET pMsg)
1169{
1170 BOOLEAN bWPA2 = FALSE;
1171
1172 // Choose WPA2 or not
1173 if ((AuthMode == Ndis802_11AuthModeWPA2) || (AuthMode == Ndis802_11AuthModeWPA2PSK))
1174 bWPA2 = TRUE;
1175
1176 // Init Packet and Fill header
1177 pMsg->ProVer = EAPOL_VER;
1178 pMsg->ProType = EAPOLKey;
1179
1180 // Default 95 bytes, the EAPoL-Key descriptor exclude Key-data field
1181 pMsg->Body_Len[1] = LEN_EAPOL_KEY_MSG;
1182
1183 // Fill in EAPoL descriptor
1184 if (bWPA2)
1185 pMsg->KeyDesc.Type = WPA2_KEY_DESC;
1186 else
1187 pMsg->KeyDesc.Type = WPA1_KEY_DESC;
1188
1189 // Fill in Key information, refer to IEEE Std 802.11i-2004 page 78
1190 // When either the pairwise or the group cipher is AES, the DESC_TYPE_AES(2) shall be used.
1191 pMsg->KeyDesc.KeyInfo.KeyDescVer =
1192 (((WepStatus == Ndis802_11Encryption3Enabled) || (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
1193
1194 // Specify Key Type as Group(0) or Pairwise(1)
1195 if (MsgType >= EAPOL_GROUP_MSG_1)
1196 pMsg->KeyDesc.KeyInfo.KeyType = GROUPKEY;
1197 else
1198 pMsg->KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
1199
1200 // Specify Key Index, only group_msg1_WPA1
1201 if (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1))
1202 pMsg->KeyDesc.KeyInfo.KeyIndex = DefaultKeyIdx;
1203
1204 if (MsgType == EAPOL_PAIR_MSG_3)
1205 pMsg->KeyDesc.KeyInfo.Install = 1;
1206
1207 if ((MsgType == EAPOL_PAIR_MSG_1) || (MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1))
1208 pMsg->KeyDesc.KeyInfo.KeyAck = 1;
1209
1210 if (MsgType != EAPOL_PAIR_MSG_1)
1211 pMsg->KeyDesc.KeyInfo.KeyMic = 1;
1212
1213 if ((bWPA2 && (MsgType >= EAPOL_PAIR_MSG_3)) || (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1)))
1214 {
1215 pMsg->KeyDesc.KeyInfo.Secure = 1;
1216 }
1217
1218 if (bWPA2 && ((MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1)))
1219 {
1220 pMsg->KeyDesc.KeyInfo.EKD_DL = 1;
1221 }
1222
1223 // key Information element has done.
1224 *(USHORT *)(&pMsg->KeyDesc.KeyInfo) = cpu2le16(*(USHORT *)(&pMsg->KeyDesc.KeyInfo));
1225
1226 // Fill in Key Length
1227 {
1228 if (MsgType >= EAPOL_GROUP_MSG_1)
1229 {
1230 // the length of group key cipher
1231 pMsg->KeyDesc.KeyLength[1] = ((GroupKeyWepStatus == Ndis802_11Encryption2Enabled) ? TKIP_GTK_LENGTH : LEN_AES_KEY);
1232 }
1233 else
1234 {
1235 // the length of pairwise key cipher
1236 pMsg->KeyDesc.KeyLength[1] = ((WepStatus == Ndis802_11Encryption2Enabled) ? LEN_TKIP_KEY : LEN_AES_KEY);
1237 }
1238 }
1239
1240 // Fill in replay counter
1241 NdisMoveMemory(pMsg->KeyDesc.ReplayCounter, ReplayCounter, LEN_KEY_DESC_REPLAY);
1242
1243 // Fill Key Nonce field
1244 // ANonce : pairwise_msg1 & pairwise_msg3
1245 // SNonce : pairwise_msg2
1246 // GNonce : group_msg1_wpa1
1247 if ((MsgType <= EAPOL_PAIR_MSG_3) || ((!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))))
1248 NdisMoveMemory(pMsg->KeyDesc.KeyNonce, KeyNonce, LEN_KEY_DESC_NONCE);
1249
1250 // Fill key IV - WPA2 as 0, WPA1 as random
1251 if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))
1252 {
1253 // Suggest IV be random number plus some number,
1254 NdisMoveMemory(pMsg->KeyDesc.KeyIv, &KeyNonce[16], LEN_KEY_DESC_IV);
1255 pMsg->KeyDesc.KeyIv[15] += 2;
1256 }
1257
1258 // Fill Key RSC field
1259 // It contains the RSC for the GTK being installed.
1260 if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2) || (MsgType == EAPOL_GROUP_MSG_1))
1261 {
1262 NdisMoveMemory(pMsg->KeyDesc.KeyRsc, TxRSC, 6);
1263 }
1264
1265 // Clear Key MIC field for MIC calculation later
1266 NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
1267
1268 ConstructEapolKeyData(pAd,
1269 AuthMode,
1270 WepStatus,
1271 GroupKeyWepStatus,
1272 MsgType,
1273 DefaultKeyIdx,
1274 bWPA2,
1275 PTK,
1276 GTK,
1277 RSNIE,
1278 RSNIE_Len,
1279 pMsg);
1280
1281 // Calculate MIC and fill in KeyMic Field except Pairwise Msg 1.
1282 if (MsgType != EAPOL_PAIR_MSG_1)
1283 {
1284 CalculateMIC(pAd, WepStatus, PTK, pMsg);
1285 }
1286
1287 DBGPRINT(RT_DEBUG_TRACE, ("===> ConstructEapolMsg for %s %s\n", ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType)));
1288 DBGPRINT(RT_DEBUG_TRACE, (" Body length = %d \n", pMsg->Body_Len[1]));
1289 DBGPRINT(RT_DEBUG_TRACE, (" Key length = %d \n", pMsg->KeyDesc.KeyLength[1]));
1290
1291
1292}
1293
1294/*
1295 ========================================================================
1296
1297 Routine Description:
1298 Construct the Key Data field of EAPoL message
1299
1300 Arguments:
1301 pAd Pointer to our adapter
1302 Elem Message body
1303
1304 Return Value:
1305 None
1306
1307 Note:
1308
1309 ========================================================================
1310*/
1311VOID ConstructEapolKeyData(
1312 IN PRTMP_ADAPTER pAd,
1313 IN UCHAR AuthMode,
1314 IN UCHAR WepStatus,
1315 IN UCHAR GroupKeyWepStatus,
1316 IN UCHAR MsgType,
1317 IN UCHAR DefaultKeyIdx,
1318 IN BOOLEAN bWPA2Capable,
1319 IN UCHAR *PTK,
1320 IN UCHAR *GTK,
1321 IN UCHAR *RSNIE,
1322 IN UCHAR RSNIE_LEN,
1323 OUT PEAPOL_PACKET pMsg)
1324{
1325 UCHAR *mpool, *Key_Data, *Rc4GTK;
1326 UCHAR ekey[(LEN_KEY_DESC_IV+LEN_EAP_EK)];
1327 UCHAR data_offset;
1328
1329
1330 if (MsgType == EAPOL_PAIR_MSG_1 || MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2)
1331 return;
1332
1333 // allocate memory pool
1334 os_alloc_mem(pAd, (PUCHAR *)&mpool, 1500);
1335
1336 if (mpool == NULL)
1337 return;
1338
1339 /* Rc4GTK Len = 512 */
1340 Rc4GTK = (UCHAR *) ROUND_UP(mpool, 4);
1341 /* Key_Data Len = 512 */
1342 Key_Data = (UCHAR *) ROUND_UP(Rc4GTK + 512, 4);
1343
1344 NdisZeroMemory(Key_Data, 512);
1345 pMsg->KeyDesc.KeyDataLen[1] = 0;
1346 data_offset = 0;
1347
1348 // Encapsulate RSNIE in pairwise_msg2 & pairwise_msg3
1349 if (RSNIE_LEN && ((MsgType == EAPOL_PAIR_MSG_2) || (MsgType == EAPOL_PAIR_MSG_3)))
1350 {
1351 if (bWPA2Capable)
1352 Key_Data[data_offset + 0] = IE_WPA2;
1353 else
1354 Key_Data[data_offset + 0] = IE_WPA;
1355
1356 Key_Data[data_offset + 1] = RSNIE_LEN;
1357 NdisMoveMemory(&Key_Data[data_offset + 2], RSNIE, RSNIE_LEN);
1358 data_offset += (2 + RSNIE_LEN);
1359 }
1360
1361 // Encapsulate KDE format in pairwise_msg3_WPA2 & group_msg1_WPA2
1362 if (bWPA2Capable && ((MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1)))
1363 {
1364 // Key Data Encapsulation (KDE) format - 802.11i-2004 Figure-43w and Table-20h
1365 Key_Data[data_offset + 0] = 0xDD;
1366
1367 if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)
1368 {
1369 Key_Data[data_offset + 1] = 0x16;// 4+2+16(OUI+DataType+DataField)
1370 }
1371 else
1372 {
1373 Key_Data[data_offset + 1] = 0x26;// 4+2+32(OUI+DataType+DataField)
1374 }
1375
1376 Key_Data[data_offset + 2] = 0x00;
1377 Key_Data[data_offset + 3] = 0x0F;
1378 Key_Data[data_offset + 4] = 0xAC;
1379 Key_Data[data_offset + 5] = 0x01;
1380
1381 // GTK KDE format - 802.11i-2004 Figure-43x
1382 Key_Data[data_offset + 6] = (DefaultKeyIdx & 0x03);
1383 Key_Data[data_offset + 7] = 0x00; // Reserved Byte
1384
1385 data_offset += 8;
1386 }
1387
1388
1389 // Encapsulate GTK and encrypt the key-data field with KEK.
1390 // Only for pairwise_msg3_WPA2 and group_msg1
1391 if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2Capable) || (MsgType == EAPOL_GROUP_MSG_1))
1392 {
1393 // Fill in GTK
1394 if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)
1395 {
1396 NdisMoveMemory(&Key_Data[data_offset], GTK, LEN_AES_KEY);
1397 data_offset += LEN_AES_KEY;
1398 }
1399 else
1400 {
1401 NdisMoveMemory(&Key_Data[data_offset], GTK, TKIP_GTK_LENGTH);
1402 data_offset += TKIP_GTK_LENGTH;
1403 }
1404
1405 // Still dont know why, but if not append will occur "GTK not include in MSG3"
1406 // Patch for compatibility between zero config and funk
1407 if (MsgType == EAPOL_PAIR_MSG_3 && bWPA2Capable)
1408 {
1409 if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)
1410 {
1411 Key_Data[data_offset + 0] = 0xDD;
1412 Key_Data[data_offset + 1] = 0;
1413 data_offset += 2;
1414 }
1415 else
1416 {
1417 Key_Data[data_offset + 0] = 0xDD;
1418 Key_Data[data_offset + 1] = 0;
1419 Key_Data[data_offset + 2] = 0;
1420 Key_Data[data_offset + 3] = 0;
1421 Key_Data[data_offset + 4] = 0;
1422 Key_Data[data_offset + 5] = 0;
1423 data_offset += 6;
1424 }
1425 }
1426
1427 // Encrypt the data material in key data field
1428 if (WepStatus == Ndis802_11Encryption3Enabled)
1429 {
1430 AES_GTK_KEY_WRAP(&PTK[16], Key_Data, data_offset, Rc4GTK);
1431 // AES wrap function will grow 8 bytes in length
1432 data_offset += 8;
1433 }
1434 else
1435 {
1436 // PREPARE Encrypted "Key DATA" field. (Encrypt GTK with RC4, usinf PTK[16]->[31] as Key, IV-field as IV)
1437 // put TxTsc in Key RSC field
1438 pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32; //Init crc32.
1439
1440 // ekey is the contanetion of IV-field, and PTK[16]->PTK[31]
1441 NdisMoveMemory(ekey, pMsg->KeyDesc.KeyIv, LEN_KEY_DESC_IV);
1442 NdisMoveMemory(&ekey[LEN_KEY_DESC_IV], &PTK[16], LEN_EAP_EK);
1443 ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, ekey, sizeof(ekey)); //INIT SBOX, KEYLEN+3(IV)
1444 pAd->PrivateInfo.FCSCRC32 = RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, Key_Data, data_offset);
1445 WPAARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, Rc4GTK, Key_Data, data_offset);
1446 }
1447
1448 NdisMoveMemory(pMsg->KeyDesc.KeyData, Rc4GTK, data_offset);
1449 }
1450 else
1451 {
1452 NdisMoveMemory(pMsg->KeyDesc.KeyData, Key_Data, data_offset);
1453 }
1454
1455 // set key data length field and total length
1456 pMsg->KeyDesc.KeyDataLen[1] = data_offset;
1457 pMsg->Body_Len[1] += data_offset;
1458
1459 os_free_mem(pAd, mpool);
1460
1461}
1462
1463/*
1464 ========================================================================
1465
1466 Routine Description:
1467 Calcaulate MIC. It is used during 4-ways handsharking.
1468
1469 Arguments:
1470 pAd - pointer to our pAdapter context
1471 PeerWepStatus - indicate the encryption type
1472
1473 Return Value:
1474
1475 Note:
1476
1477 ========================================================================
1478*/
1479VOID CalculateMIC(
1480 IN PRTMP_ADAPTER pAd,
1481 IN UCHAR PeerWepStatus,
1482 IN UCHAR *PTK,
1483 OUT PEAPOL_PACKET pMsg)
1484{
1485 UCHAR *OutBuffer;
1486 ULONG FrameLen = 0;
1487 UCHAR mic[LEN_KEY_DESC_MIC];
1488 UCHAR digest[80];
1489
1490 // allocate memory for MIC calculation
1491 os_alloc_mem(pAd, (PUCHAR *)&OutBuffer, 512);
1492
1493 if (OutBuffer == NULL)
1494 {
1495 DBGPRINT(RT_DEBUG_ERROR, ("!!!CalculateMIC: no memory!!!\n"));
1496 return;
1497 }
1498
1499 // make a frame for calculating MIC.
1500 MakeOutgoingFrame(OutBuffer, &FrameLen,
1501 pMsg->Body_Len[1] + 4, pMsg,
1502 END_OF_ARGS);
1503
1504 NdisZeroMemory(mic, sizeof(mic));
1505
1506 // Calculate MIC
1507 if (PeerWepStatus == Ndis802_11Encryption3Enabled)
1508 {
1509 HMAC_SHA1(OutBuffer, FrameLen, PTK, LEN_EAP_MICK, digest);
1510 NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
1511 }
1512 else
1513 {
1514 hmac_md5(PTK, LEN_EAP_MICK, OutBuffer, FrameLen, mic);
1515 }
1516
1517 // store the calculated MIC
1518 NdisMoveMemory(pMsg->KeyDesc.KeyMic, mic, LEN_KEY_DESC_MIC);
1519
1520 os_free_mem(pAd, OutBuffer);
1521}
1522
1523/*
1524 ========================================================================
1525
1526 Routine Description:
1527 Some received frames can't decrypt by Asic, so decrypt them by software.
1528
1529 Arguments:
1530 pAd - pointer to our pAdapter context
1531 PeerWepStatus - indicate the encryption type
1532
1533 Return Value:
1534 NDIS_STATUS_SUCCESS - decryption successful
1535 NDIS_STATUS_FAILURE - decryption failure
1536
1537 ========================================================================
1538*/
1539NDIS_STATUS RTMPSoftDecryptBroadCastData(
1540 IN PRTMP_ADAPTER pAd,
1541 IN RX_BLK *pRxBlk,
1542 IN NDIS_802_11_ENCRYPTION_STATUS GroupCipher,
1543 IN PCIPHER_KEY pShard_key)
1544{
1545 PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
1546
1547
1548
1549 // handle WEP decryption
1550 if (GroupCipher == Ndis802_11Encryption1Enabled)
1551 {
1552 if (RTMPSoftDecryptWEP(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, pShard_key))
1553 {
1554
1555 //Minus IV[4] & ICV[4]
1556 pRxWI->MPDUtotalByteCount -= 8;
1557 }
1558 else
1559 {
1560 DBGPRINT(RT_DEBUG_ERROR, ("ERROR : Software decrypt WEP data fails.\n"));
1561 // give up this frame
1562 return NDIS_STATUS_FAILURE;
1563 }
1564 }
1565 // handle TKIP decryption
1566 else if (GroupCipher == Ndis802_11Encryption2Enabled)
1567 {
1568 if (RTMPSoftDecryptTKIP(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, 0, pShard_key))
1569 {
1570
1571 //Minus 8 bytes MIC, 8 bytes IV/EIV, 4 bytes ICV
1572 pRxWI->MPDUtotalByteCount -= 20;
1573 }
1574 else
1575 {
1576 DBGPRINT(RT_DEBUG_ERROR, ("ERROR : RTMPSoftDecryptTKIP Failed\n"));
1577 // give up this frame
1578 return NDIS_STATUS_FAILURE;
1579 }
1580 }
1581 // handle AES decryption
1582 else if (GroupCipher == Ndis802_11Encryption3Enabled)
1583 {
1584 if (RTMPSoftDecryptAES(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount , pShard_key))
1585 {
1586
1587 //8 bytes MIC, 8 bytes IV/EIV (CCMP Header)
1588 pRxWI->MPDUtotalByteCount -= 16;
1589 }
1590 else
1591 {
1592 DBGPRINT(RT_DEBUG_ERROR, ("ERROR : RTMPSoftDecryptAES Failed\n"));
1593 // give up this frame
1594 return NDIS_STATUS_FAILURE;
1595 }
1596 }
1597 else
1598 {
1599 // give up this frame
1600 return NDIS_STATUS_FAILURE;
1601 }
1602
1603 return NDIS_STATUS_SUCCESS;
1604
1605}
1606
diff --git a/drivers/staging/rt3070/common/dfs.c b/drivers/staging/rt3070/common/dfs.c
new file mode 100644
index 000000000000..28d60145791c
--- /dev/null
+++ b/drivers/staging/rt3070/common/dfs.c
@@ -0,0 +1,441 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 ap_dfs.c
29
30 Abstract:
31 Support DFS function.
32
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36 Fonchi 03-12-2007 created
37*/
38
39#include "../rt_config.h"
40
41typedef struct _RADAR_DURATION_TABLE
42{
43 ULONG RDDurRegion;
44 ULONG RadarSignalDuration;
45 ULONG Tolerance;
46} RADAR_DURATION_TABLE, *PRADAR_DURATION_TABLE;
47
48
49static UCHAR RdIdleTimeTable[MAX_RD_REGION][4] =
50{
51 {9, 250, 250, 250}, // CE
52 {4, 250, 250, 250}, // FCC
53 {4, 250, 250, 250}, // JAP
54 {15, 250, 250, 250}, // JAP_W53
55 {4, 250, 250, 250} // JAP_W56
56};
57
58/*
59 ========================================================================
60
61 Routine Description:
62 Bbp Radar detection routine
63
64 Arguments:
65 pAd Pointer to our adapter
66
67 Return Value:
68
69 ========================================================================
70*/
71VOID BbpRadarDetectionStart(
72 IN PRTMP_ADAPTER pAd)
73{
74 UINT8 RadarPeriod;
75
76 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 114, 0x02);
77 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 121, 0x20);
78 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 122, 0x00);
79 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 123, 0x08/*0x80*/);
80 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 124, 0x28);
81 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 125, 0xff);
82
83 RadarPeriod = ((UINT)RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + (UINT)pAd->CommonCfg.RadarDetect.DfsSessionTime) < 250 ?
84 (RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + pAd->CommonCfg.RadarDetect.DfsSessionTime) : 250;
85
86 RTMP_IO_WRITE8(pAd, 0x7020, 0x1d);
87 RTMP_IO_WRITE8(pAd, 0x7021, 0x40);
88
89 RadarDetectionStart(pAd, 0, RadarPeriod);
90 return;
91}
92
93/*
94 ========================================================================
95
96 Routine Description:
97 Bbp Radar detection routine
98
99 Arguments:
100 pAd Pointer to our adapter
101
102 Return Value:
103
104 ========================================================================
105*/
106VOID BbpRadarDetectionStop(
107 IN PRTMP_ADAPTER pAd)
108{
109 RTMP_IO_WRITE8(pAd, 0x7020, 0x1d);
110 RTMP_IO_WRITE8(pAd, 0x7021, 0x60);
111
112 RadarDetectionStop(pAd);
113 return;
114}
115
116/*
117 ========================================================================
118
119 Routine Description:
120 Radar detection routine
121
122 Arguments:
123 pAd Pointer to our adapter
124
125 Return Value:
126
127 ========================================================================
128*/
129VOID RadarDetectionStart(
130 IN PRTMP_ADAPTER pAd,
131 IN BOOLEAN CTSProtect,
132 IN UINT8 CTSPeriod)
133{
134 UINT8 DfsActiveTime = (pAd->CommonCfg.RadarDetect.DfsSessionTime & 0x1f);
135 UINT8 CtsProtect = (CTSProtect == 1) ? 0x02 : 0x01; // CTS protect.
136
137 if (CTSProtect != 0)
138 {
139 switch(pAd->CommonCfg.RadarDetect.RDDurRegion)
140 {
141 case FCC:
142 case JAP_W56:
143 CtsProtect = 0x03;
144 break;
145
146 case CE:
147 case JAP_W53:
148 default:
149 CtsProtect = 0x02;
150 break;
151 }
152 }
153 else
154 CtsProtect = 0x01;
155
156
157 // send start-RD with CTS protection command to MCU
158 // highbyte [7] reserve
159 // highbyte [6:5] 0x: stop Carrier/Radar detection
160 // highbyte [10]: Start Carrier/Radar detection without CTS protection, 11: Start Carrier/Radar detection with CTS protection
161 // highbyte [4:0] Radar/carrier detection duration. In 1ms.
162
163 // lowbyte [7:0] Radar/carrier detection period, in 1ms.
164 AsicSendCommandToMcu(pAd, 0x60, 0xff, CTSPeriod, DfsActiveTime | (CtsProtect << 5));
165 //AsicSendCommandToMcu(pAd, 0x63, 0xff, 10, 0);
166
167 return;
168}
169
170/*
171 ========================================================================
172
173 Routine Description:
174 Radar detection routine
175
176 Arguments:
177 pAd Pointer to our adapter
178
179 Return Value:
180 TRUE Found radar signal
181 FALSE Not found radar signal
182
183 ========================================================================
184*/
185VOID RadarDetectionStop(
186 IN PRTMP_ADAPTER pAd)
187{
188 DBGPRINT(RT_DEBUG_TRACE,("RadarDetectionStop.\n"));
189 AsicSendCommandToMcu(pAd, 0x60, 0xff, 0x00, 0x00); // send start-RD with CTS protection command to MCU
190
191 return;
192}
193
194/*
195 ========================================================================
196
197 Routine Description:
198 Radar channel check routine
199
200 Arguments:
201 pAd Pointer to our adapter
202
203 Return Value:
204 TRUE need to do radar detect
205 FALSE need not to do radar detect
206
207 ========================================================================
208*/
209BOOLEAN RadarChannelCheck(
210 IN PRTMP_ADAPTER pAd,
211 IN UCHAR Ch)
212{
213#if 1
214 INT i;
215 BOOLEAN result = FALSE;
216
217 for (i=0; i<pAd->ChannelListNum; i++)
218 {
219 if (Ch == pAd->ChannelList[i].Channel)
220 {
221 result = pAd->ChannelList[i].DfsReq;
222 break;
223 }
224 }
225
226 return result;
227#else
228 INT i;
229 UCHAR Channel[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
230
231 for (i=0; i<15; i++)
232 {
233 if (Ch == Channel[i])
234 {
235 break;
236 }
237 }
238
239 if (i != 15)
240 return TRUE;
241 else
242 return FALSE;
243#endif
244}
245
246ULONG JapRadarType(
247 IN PRTMP_ADAPTER pAd)
248{
249 ULONG i;
250 const UCHAR Channel[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
251
252 if (pAd->CommonCfg.RadarDetect.RDDurRegion != JAP)
253 {
254 return pAd->CommonCfg.RadarDetect.RDDurRegion;
255 }
256
257 for (i=0; i<15; i++)
258 {
259 if (pAd->CommonCfg.Channel == Channel[i])
260 {
261 break;
262 }
263 }
264
265 if (i < 4)
266 return JAP_W53;
267 else if (i < 15)
268 return JAP_W56;
269 else
270 return JAP; // W52
271
272}
273
274ULONG RTMPBbpReadRadarDuration(
275 IN PRTMP_ADAPTER pAd)
276{
277 UINT8 byteValue = 0;
278 ULONG result;
279
280 BBP_IO_READ8_BY_REG_ID(pAd, BBP_R115, &byteValue);
281
282 result = 0;
283 switch (byteValue)
284 {
285 case 1: // radar signal detected by pulse mode.
286 case 2: // radar signal detected by width mode.
287 result = RTMPReadRadarDuration(pAd);
288 break;
289
290 case 0: // No radar signal.
291 default:
292
293 result = 0;
294 break;
295 }
296
297 return result;
298}
299
300ULONG RTMPReadRadarDuration(
301 IN PRTMP_ADAPTER pAd)
302{
303 ULONG result = 0;
304
305#ifdef DFS_SUPPORT
306 UINT8 duration1 = 0, duration2 = 0, duration3 = 0;
307
308 BBP_IO_READ8_BY_REG_ID(pAd, BBP_R116, &duration1);
309 BBP_IO_READ8_BY_REG_ID(pAd, BBP_R117, &duration2);
310 BBP_IO_READ8_BY_REG_ID(pAd, BBP_R118, &duration3);
311 result = (duration1 << 16) + (duration2 << 8) + duration3;
312#endif // DFS_SUPPORT //
313
314 return result;
315
316}
317
318VOID RTMPCleanRadarDuration(
319 IN PRTMP_ADAPTER pAd)
320{
321 return;
322}
323
324/*
325 ========================================================================
326 Routine Description:
327 Radar wave detection. The API should be invoke each second.
328
329 Arguments:
330 pAd - Adapter pointer
331
332 Return Value:
333 None
334
335 ========================================================================
336*/
337VOID ApRadarDetectPeriodic(
338 IN PRTMP_ADAPTER pAd)
339{
340 INT i;
341
342 pAd->CommonCfg.RadarDetect.InServiceMonitorCount++;
343
344 for (i=0; i<pAd->ChannelListNum; i++)
345 {
346 if (pAd->ChannelList[i].RemainingTimeForUse > 0)
347 {
348 pAd->ChannelList[i].RemainingTimeForUse --;
349 if ((pAd->Mlme.PeriodicRound%5) == 0)
350 {
351 DBGPRINT(RT_DEBUG_TRACE, ("RadarDetectPeriodic - ch=%d, RemainingTimeForUse=%d\n", pAd->ChannelList[i].Channel, pAd->ChannelList[i].RemainingTimeForUse));
352 }
353 }
354 }
355
356 //radar detect
357 if ((pAd->CommonCfg.Channel > 14)
358 && (pAd->CommonCfg.bIEEE80211H == 1)
359 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
360 {
361 RadarDetectPeriodic(pAd);
362 }
363
364 return;
365}
366
367// Periodic Radar detection, switch channel will occur in RTMPHandleTBTTInterrupt()
368// Before switch channel, driver needs doing channel switch announcement.
369VOID RadarDetectPeriodic(
370 IN PRTMP_ADAPTER pAd)
371{
372 // need to check channel availability, after switch channel
373 if (pAd->CommonCfg.RadarDetect.RDMode != RD_SILENCE_MODE)
374 return;
375
376 // channel availability check time is 60sec, use 65 for assurance
377 if (pAd->CommonCfg.RadarDetect.RDCount++ > pAd->CommonCfg.RadarDetect.ChMovingTime)
378 {
379 DBGPRINT(RT_DEBUG_TRACE, ("Not found radar signal, start send beacon and radar detection in service monitor\n\n"));
380 BbpRadarDetectionStop(pAd);
381 AsicEnableBssSync(pAd);
382 pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
383
384
385 return;
386 }
387
388 return;
389}
390
391
392/*
393 ==========================================================================
394 Description:
395 change channel moving time for DFS testing.
396
397 Arguments:
398 pAdapter Pointer to our adapter
399 wrq Pointer to the ioctl argument
400
401 Return Value:
402 None
403
404 Note:
405 Usage:
406 1.) iwpriv ra0 set ChMovTime=[value]
407 ==========================================================================
408*/
409INT Set_ChMovingTime_Proc(
410 IN PRTMP_ADAPTER pAd,
411 IN PUCHAR arg)
412{
413 UINT8 Value;
414
415 Value = simple_strtol(arg, 0, 10);
416
417 pAd->CommonCfg.RadarDetect.ChMovingTime = Value;
418
419 DBGPRINT(RT_DEBUG_TRACE, ("%s:: %d\n", __FUNCTION__,
420 pAd->CommonCfg.RadarDetect.ChMovingTime));
421
422 return TRUE;
423}
424
425INT Set_LongPulseRadarTh_Proc(
426 IN PRTMP_ADAPTER pAd,
427 IN PUCHAR arg)
428{
429 UINT8 Value;
430
431 Value = simple_strtol(arg, 0, 10) > 10 ? 10 : simple_strtol(arg, 0, 10);
432
433 pAd->CommonCfg.RadarDetect.LongPulseRadarTh = Value;
434
435 DBGPRINT(RT_DEBUG_TRACE, ("%s:: %d\n", __FUNCTION__,
436 pAd->CommonCfg.RadarDetect.LongPulseRadarTh));
437
438 return TRUE;
439}
440
441
diff --git a/drivers/staging/rt3070/common/eeprom.c b/drivers/staging/rt3070/common/eeprom.c
new file mode 100644
index 000000000000..63e1dc14d151
--- /dev/null
+++ b/drivers/staging/rt3070/common/eeprom.c
@@ -0,0 +1,1498 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 eeprom.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Name Date Modification logs
36*/
37#include "../rt_config.h"
38
39// IRQL = PASSIVE_LEVEL
40VOID RaiseClock(
41 IN PRTMP_ADAPTER pAd,
42 IN UINT32 *x)
43{
44 *x = *x | EESK;
45 RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
46 RTMPusecDelay(1); // Max frequency = 1MHz in Spec. definition
47}
48
49// IRQL = PASSIVE_LEVEL
50VOID LowerClock(
51 IN PRTMP_ADAPTER pAd,
52 IN UINT32 *x)
53{
54 *x = *x & ~EESK;
55 RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
56 RTMPusecDelay(1);
57}
58
59// IRQL = PASSIVE_LEVEL
60USHORT ShiftInBits(
61 IN PRTMP_ADAPTER pAd)
62{
63 UINT32 x,i;
64 USHORT data=0;
65
66 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
67
68 x &= ~( EEDO | EEDI);
69
70 for(i=0; i<16; i++)
71 {
72 data = data << 1;
73 RaiseClock(pAd, &x);
74
75 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
76 LowerClock(pAd, &x); //prevent read failed
77
78 x &= ~(EEDI);
79 if(x & EEDO)
80 data |= 1;
81 }
82
83 return data;
84}
85
86// IRQL = PASSIVE_LEVEL
87VOID ShiftOutBits(
88 IN PRTMP_ADAPTER pAd,
89 IN USHORT data,
90 IN USHORT count)
91{
92 UINT32 x,mask;
93
94 mask = 0x01 << (count - 1);
95 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
96
97 x &= ~(EEDO | EEDI);
98
99 do
100 {
101 x &= ~EEDI;
102 if(data & mask) x |= EEDI;
103
104 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
105
106 RaiseClock(pAd, &x);
107 LowerClock(pAd, &x);
108
109 mask = mask >> 1;
110 } while(mask);
111
112 x &= ~EEDI;
113 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
114}
115
116// IRQL = PASSIVE_LEVEL
117VOID EEpromCleanup(
118 IN PRTMP_ADAPTER pAd)
119{
120 UINT32 x;
121
122 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
123
124 x &= ~(EECS | EEDI);
125 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
126
127 RaiseClock(pAd, &x);
128 LowerClock(pAd, &x);
129}
130
131VOID EWEN(
132 IN PRTMP_ADAPTER pAd)
133{
134 UINT32 x;
135
136 // reset bits and set EECS
137 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
138 x &= ~(EEDI | EEDO | EESK);
139 x |= EECS;
140 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
141
142 // kick a pulse
143 RaiseClock(pAd, &x);
144 LowerClock(pAd, &x);
145
146 // output the read_opcode and six pulse in that order
147 ShiftOutBits(pAd, EEPROM_EWEN_OPCODE, 5);
148 ShiftOutBits(pAd, 0, 6);
149
150 EEpromCleanup(pAd);
151}
152
153VOID EWDS(
154 IN PRTMP_ADAPTER pAd)
155{
156 UINT32 x;
157
158 // reset bits and set EECS
159 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
160 x &= ~(EEDI | EEDO | EESK);
161 x |= EECS;
162 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
163
164 // kick a pulse
165 RaiseClock(pAd, &x);
166 LowerClock(pAd, &x);
167
168 // output the read_opcode and six pulse in that order
169 ShiftOutBits(pAd, EEPROM_EWDS_OPCODE, 5);
170 ShiftOutBits(pAd, 0, 6);
171
172 EEpromCleanup(pAd);
173}
174
175// IRQL = PASSIVE_LEVEL
176USHORT RTMP_EEPROM_READ16(
177 IN PRTMP_ADAPTER pAd,
178 IN USHORT Offset)
179{
180 UINT32 x;
181 USHORT data;
182
183 if (pAd->NicConfig2.field.AntDiversity)
184 {
185 pAd->EepromAccess = TRUE;
186 }
187//2008/09/11:KH add to support efuse<--
188//2008/09/11:KH add to support efuse-->
189{
190 Offset /= 2;
191 // reset bits and set EECS
192 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
193 x &= ~(EEDI | EEDO | EESK);
194 x |= EECS;
195 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
196
197 // patch can not access e-Fuse issue
198 if (!IS_RT3090(pAd))
199 {
200 // kick a pulse
201 RaiseClock(pAd, &x);
202 LowerClock(pAd, &x);
203 }
204
205 // output the read_opcode and register number in that order
206 ShiftOutBits(pAd, EEPROM_READ_OPCODE, 3);
207 ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
208
209 // Now read the data (16 bits) in from the selected EEPROM word
210 data = ShiftInBits(pAd);
211
212 EEpromCleanup(pAd);
213
214 // Antenna and EEPROM access are both using EESK pin,
215 // Therefor we should avoid accessing EESK at the same time
216 // Then restore antenna after EEPROM access
217 if ((pAd->NicConfig2.field.AntDiversity) || (pAd->RfIcType == RFIC_3020))
218 {
219 pAd->EepromAccess = FALSE;
220 AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
221 }
222}
223 return data;
224} //ReadEEprom
225
226VOID RTMP_EEPROM_WRITE16(
227 IN PRTMP_ADAPTER pAd,
228 IN USHORT Offset,
229 IN USHORT Data)
230{
231 UINT32 x;
232
233 if (pAd->NicConfig2.field.AntDiversity)
234 {
235 pAd->EepromAccess = TRUE;
236 }
237 //2008/09/11:KH add to support efuse<--
238//2008/09/11:KH add to support efuse-->
239 {
240 Offset /= 2;
241
242 EWEN(pAd);
243
244 // reset bits and set EECS
245 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
246 x &= ~(EEDI | EEDO | EESK);
247 x |= EECS;
248 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
249
250 // patch can not access e-Fuse issue
251 if (!IS_RT3090(pAd))
252 {
253 // kick a pulse
254 RaiseClock(pAd, &x);
255 LowerClock(pAd, &x);
256 }
257
258 // output the read_opcode ,register number and data in that order
259 ShiftOutBits(pAd, EEPROM_WRITE_OPCODE, 3);
260 ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
261 ShiftOutBits(pAd, Data, 16); // 16-bit access
262
263 // read DO status
264 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
265
266 EEpromCleanup(pAd);
267
268 RTMPusecDelay(10000); //delay for twp(MAX)=10ms
269
270 EWDS(pAd);
271
272 EEpromCleanup(pAd);
273
274 // Antenna and EEPROM access are both using EESK pin,
275 // Therefor we should avoid accessing EESK at the same time
276 // Then restore antenna after EEPROM access
277 if ((pAd->NicConfig2.field.AntDiversity) || (pAd->RfIcType == RFIC_3020))
278 {
279 pAd->EepromAccess = FALSE;
280 AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
281 }
282}
283}
284
285//2008/09/11:KH add to support efuse<--
286#ifdef RT30xx
287/*
288 ========================================================================
289
290 Routine Description:
291
292 Arguments:
293
294 Return Value:
295
296 IRQL =
297
298 Note:
299
300 ========================================================================
301*/
302UCHAR eFuseReadRegisters(
303 IN PRTMP_ADAPTER pAd,
304 IN USHORT Offset,
305 IN USHORT Length,
306 OUT USHORT* pData)
307{
308 EFUSE_CTRL_STRUC eFuseCtrlStruc;
309 int i;
310 USHORT efuseDataOffset;
311 UINT32 data;
312
313 RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
314
315 //Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
316 //Use the eeprom logical address and covert to address to block number
317 eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
318
319 //Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 0.
320 eFuseCtrlStruc.field.EFSROM_MODE = 0;
321
322 //Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
323 eFuseCtrlStruc.field.EFSROM_KICK = 1;
324
325 NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
326 RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
327
328 //Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
329 i = 0;
330 while(i < 100)
331 {
332 //rtmp.HwMemoryReadDword(EFUSE_CTRL, (DWORD *) &eFuseCtrlStruc, 4);
333 RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
334 if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
335 {
336 break;
337 }
338 RTMPusecDelay(2);
339 i++;
340 }
341
342 //if EFSROM_AOUT is not found in physical address, write 0xffff
343 if (eFuseCtrlStruc.field.EFSROM_AOUT == 0x3f)
344 {
345 for(i=0; i<Length/2; i++)
346 *(pData+2*i) = 0xffff;
347 }
348 else
349 {
350 //Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x590-0x59C)
351 efuseDataOffset = EFUSE_DATA3 - (Offset & 0xC) ;
352 //data hold 4 bytes data.
353 //In RTMP_IO_READ32 will automatically execute 32-bytes swapping
354 RTMP_IO_READ32(pAd, efuseDataOffset, &data);
355 //Decide the upper 2 bytes or the bottom 2 bytes.
356 // Little-endian S | S Big-endian
357 // addr 3 2 1 0 | 0 1 2 3
358 // Ori-V D C B A | A B C D
359 //After swapping
360 // D C B A | D C B A
361 //Return 2-bytes
362 //The return byte statrs from S. Therefore, the little-endian will return BA, the Big-endian will return DC.
363 //For returning the bottom 2 bytes, the Big-endian should shift right 2-bytes.
364#ifdef RT_BIG_ENDIAN
365 data = data << (8*((Offset & 0x3)^0x2));
366#else
367 data = data >> (8*(Offset & 0x3));
368#endif
369
370 NdisMoveMemory(pData, &data, Length);
371 }
372
373 return (UCHAR) eFuseCtrlStruc.field.EFSROM_AOUT;
374
375}
376
377/*
378 ========================================================================
379
380 Routine Description:
381
382 Arguments:
383
384 Return Value:
385
386 IRQL =
387
388 Note:
389
390 ========================================================================
391*/
392VOID eFusePhysicalReadRegisters(
393 IN PRTMP_ADAPTER pAd,
394 IN USHORT Offset,
395 IN USHORT Length,
396 OUT USHORT* pData)
397{
398 EFUSE_CTRL_STRUC eFuseCtrlStruc;
399 int i;
400 USHORT efuseDataOffset;
401 UINT32 data;
402
403 RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
404
405 //Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
406 eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
407
408 //Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
409 //Read in physical view
410 eFuseCtrlStruc.field.EFSROM_MODE = 1;
411
412 //Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
413 eFuseCtrlStruc.field.EFSROM_KICK = 1;
414
415 NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
416 RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
417
418 //Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
419 i = 0;
420 while(i < 100)
421 {
422 RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
423 if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
424 break;
425 RTMPusecDelay(2);
426 i++;
427 }
428
429 //Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
430 //Because the size of each EFUSE_DATA is 4 Bytes, the size of address of each is 2 bits.
431 //The previous 2 bits is the EFUSE_DATA number, the last 2 bits is used to decide which bytes
432 //Decide which EFUSE_DATA to read
433 //590:F E D C
434 //594:B A 9 8
435 //598:7 6 5 4
436 //59C:3 2 1 0
437 efuseDataOffset = EFUSE_DATA3 - (Offset & 0xC) ;
438
439 RTMP_IO_READ32(pAd, efuseDataOffset, &data);
440
441#ifdef RT_BIG_ENDIAN
442 data = data << (8*((Offset & 0x3)^0x2));
443#else
444 data = data >> (8*(Offset & 0x3));
445#endif
446
447 NdisMoveMemory(pData, &data, Length);
448
449}
450
451/*
452 ========================================================================
453
454 Routine Description:
455
456 Arguments:
457
458 Return Value:
459
460 IRQL =
461
462 Note:
463
464 ========================================================================
465*/
466VOID eFuseReadPhysical(
467 IN PRTMP_ADAPTER pAd,
468 IN PUSHORT lpInBuffer,
469 IN ULONG nInBufferSize,
470 OUT PUSHORT lpOutBuffer,
471 IN ULONG nOutBufferSize
472)
473{
474 USHORT* pInBuf = (USHORT*)lpInBuffer;
475 USHORT* pOutBuf = (USHORT*)lpOutBuffer;
476
477 USHORT Offset = pInBuf[0]; //addr
478 USHORT Length = pInBuf[1]; //length
479 int i;
480
481 for(i=0; i<Length; i+=2)
482 {
483 eFusePhysicalReadRegisters(pAd,Offset+i, 2, &pOutBuf[i/2]);
484 }
485}
486
487/*
488 ========================================================================
489
490 Routine Description:
491
492 Arguments:
493
494 Return Value:
495
496 IRQL =
497
498 Note:
499
500 ========================================================================
501*/
502NTSTATUS eFuseRead(
503 IN PRTMP_ADAPTER pAd,
504 IN USHORT Offset,
505 OUT PUCHAR pData,
506 IN USHORT Length)
507{
508 USHORT* pOutBuf = (USHORT*)pData;
509 NTSTATUS Status = STATUS_SUCCESS;
510 UCHAR EFSROM_AOUT;
511 int i;
512
513 for(i=0; i<Length; i+=2)
514 {
515 EFSROM_AOUT = eFuseReadRegisters(pAd, Offset+i, 2, &pOutBuf[i/2]);
516 }
517 return Status;
518}
519
520/*
521 ========================================================================
522
523 Routine Description:
524
525 Arguments:
526
527 Return Value:
528
529 IRQL =
530
531 Note:
532
533 ========================================================================
534*/
535VOID eFusePhysicalWriteRegisters(
536 IN PRTMP_ADAPTER pAd,
537 IN USHORT Offset,
538 IN USHORT Length,
539 OUT USHORT* pData)
540{
541 EFUSE_CTRL_STRUC eFuseCtrlStruc;
542 int i;
543 USHORT efuseDataOffset;
544 UINT32 data, eFuseDataBuffer[4];
545
546 //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.
547
548 /////////////////////////////////////////////////////////////////
549 //read current values of 16-byte block
550 RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
551
552 //Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
553 eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
554
555 //Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
556 eFuseCtrlStruc.field.EFSROM_MODE = 1;
557
558 //Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
559 eFuseCtrlStruc.field.EFSROM_KICK = 1;
560
561 NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
562 RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
563
564 //Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
565 i = 0;
566 while(i < 100)
567 {
568 RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
569
570 if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
571 break;
572 RTMPusecDelay(2);
573 i++;
574 }
575
576 //Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
577 efuseDataOffset = EFUSE_DATA3;
578 for(i=0; i< 4; i++)
579 {
580 RTMP_IO_READ32(pAd, efuseDataOffset, (PUINT32) &eFuseDataBuffer[i]);
581 efuseDataOffset -= 4;
582 }
583
584 //Update the value, the offset is multiple of 2, length is 2
585 efuseDataOffset = (Offset & 0xc) >> 2;
586 data = pData[0] & 0xffff;
587 //The offset should be 0x***10 or 0x***00
588 if((Offset % 4) != 0)
589 {
590 eFuseDataBuffer[efuseDataOffset] = (eFuseDataBuffer[efuseDataOffset] & 0xffff) | (data << 16);
591 }
592 else
593 {
594 eFuseDataBuffer[efuseDataOffset] = (eFuseDataBuffer[efuseDataOffset] & 0xffff0000) | data;
595 }
596
597 efuseDataOffset = EFUSE_DATA3;
598 for(i=0; i< 4; i++)
599 {
600 RTMP_IO_WRITE32(pAd, efuseDataOffset, eFuseDataBuffer[i]);
601 efuseDataOffset -= 4;
602 }
603 /////////////////////////////////////////////////////////////////
604
605 //Step1. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
606 eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
607
608 //Step2. Write EFSROM_MODE (0x580, bit7:bit6) to 3.
609 eFuseCtrlStruc.field.EFSROM_MODE = 3;
610
611 //Step3. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical write procedure.
612 eFuseCtrlStruc.field.EFSROM_KICK = 1;
613
614 NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
615 RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
616
617 //Step4. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. It¡¦s done.
618 i = 0;
619 while(i < 100)
620 {
621 RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
622
623 if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
624 break;
625
626 RTMPusecDelay(2);
627 i++;
628 }
629}
630
631/*
632 ========================================================================
633
634 Routine Description:
635
636 Arguments:
637
638 Return Value:
639
640 IRQL =
641
642 Note:
643
644 ========================================================================
645*/
646NTSTATUS eFuseWriteRegisters(
647 IN PRTMP_ADAPTER pAd,
648 IN USHORT Offset,
649 IN USHORT Length,
650 IN USHORT* pData)
651{
652 USHORT i;
653 USHORT eFuseData;
654 USHORT LogicalAddress, BlkNum = 0xffff;
655 UCHAR EFSROM_AOUT;
656
657 USHORT addr,tmpaddr, InBuf[3], tmpOffset;
658 USHORT buffer[8];
659 BOOLEAN bWriteSuccess = TRUE;
660
661 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters Offset=%x, pData=%x\n", Offset, *pData));
662
663 //Step 0. find the entry in the mapping table
664 //The address of EEPROM is 2-bytes alignment.
665 //The last bit is used for alignment, so it must be 0.
666 tmpOffset = Offset & 0xfffe;
667 EFSROM_AOUT = eFuseReadRegisters(pAd, tmpOffset, 2, &eFuseData);
668
669 if( EFSROM_AOUT == 0x3f)
670 { //find available logical address pointer
671 //the logical address does not exist, find an empty one
672 //from the first address of block 45=16*45=0x2d0 to the last address of block 47
673 //==>48*16-3(reserved)=2FC
674 for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
675 {
676 //Retrive the logical block nubmer form each logical address pointer
677 //It will access two logical address pointer each time.
678 eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
679 if( (LogicalAddress & 0xff) == 0)
680 {//Not used logical address pointer
681 BlkNum = i-EFUSE_USAGE_MAP_START;
682 break;
683 }
684 else if(( (LogicalAddress >> 8) & 0xff) == 0)
685 {//Not used logical address pointer
686 if (i != EFUSE_USAGE_MAP_END)
687 {
688 BlkNum = i-EFUSE_USAGE_MAP_START+1;
689 }
690 break;
691 }
692 }
693 }
694 else
695 {
696 BlkNum = EFSROM_AOUT;
697 }
698
699 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters BlkNum = %d \n", BlkNum));
700
701 if(BlkNum == 0xffff)
702 {
703 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
704 return FALSE;
705 }
706
707 //Step 1. Save data of this block which is pointed by the avaible logical address pointer
708 // read and save the original block data
709 for(i =0; i<8; i++)
710 {
711 addr = BlkNum * 0x10 ;
712
713 InBuf[0] = addr+2*i;
714 InBuf[1] = 2;
715 InBuf[2] = 0x0;
716
717 eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
718
719 buffer[i] = InBuf[2];
720 }
721
722 //Step 2. Update the data in buffer, and write the data to Efuse
723 buffer[ (Offset >> 1) % 8] = pData[0];
724
725 do
726 {
727 //Step 3. Write the data to Efuse
728 if(!bWriteSuccess)
729 {
730 for(i =0; i<8; i++)
731 {
732 addr = BlkNum * 0x10 ;
733
734 InBuf[0] = addr+2*i;
735 InBuf[1] = 2;
736 InBuf[2] = buffer[i];
737
738 eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
739 }
740 }
741 else
742 {
743 addr = BlkNum * 0x10 ;
744
745 InBuf[0] = addr+(Offset % 16);
746 InBuf[1] = 2;
747 InBuf[2] = pData[0];
748
749 eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
750 }
751
752 //Step 4. Write mapping table
753 addr = EFUSE_USAGE_MAP_START+BlkNum;
754
755 tmpaddr = addr;
756
757 if(addr % 2 != 0)
758 addr = addr -1;
759 InBuf[0] = addr;
760 InBuf[1] = 2;
761
762 //convert the address from 10 to 8 bit ( bit7, 6 = parity and bit5 ~ 0 = bit9~4), and write to logical map entry
763 tmpOffset = Offset;
764 tmpOffset >>= 4;
765 tmpOffset |= ((~((tmpOffset & 0x01) ^ ( tmpOffset >> 1 & 0x01) ^ (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01))) << 6) & 0x40;
766 tmpOffset |= ((~( (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01) ^ (tmpOffset >> 4 & 0x01) ^ ( tmpOffset >> 5 & 0x01))) << 7) & 0x80;
767
768 // write the logical address
769 if(tmpaddr%2 != 0)
770 InBuf[2] = tmpOffset<<8;
771 else
772 InBuf[2] = tmpOffset;
773
774 eFuseWritePhysical(pAd,&InBuf[0], 6, NULL, 0);
775
776 //Step 5. Compare data if not the same, invalidate the mapping entry, then re-write the data until E-fuse is exhausted
777 bWriteSuccess = TRUE;
778 for(i =0; i<8; i++)
779 {
780 addr = BlkNum * 0x10 ;
781
782 InBuf[0] = addr+2*i;
783 InBuf[1] = 2;
784 InBuf[2] = 0x0;
785
786 eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
787
788 if(buffer[i] != InBuf[2])
789 {
790 bWriteSuccess = FALSE;
791 break;
792 }
793 }
794
795 //Step 6. invlidate mapping entry and find a free mapping entry if not succeed
796 if (!bWriteSuccess)
797 {
798 DBGPRINT(RT_DEBUG_TRACE, ("Not bWriteSuccess BlkNum = %d\n", BlkNum));
799
800 // the offset of current mapping entry
801 addr = EFUSE_USAGE_MAP_START+BlkNum;
802
803 //find a new mapping entry
804 BlkNum = 0xffff;
805 for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
806 {
807 eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
808 if( (LogicalAddress & 0xff) == 0)
809 {
810 BlkNum = i-EFUSE_USAGE_MAP_START;
811 break;
812 }
813 else if(( (LogicalAddress >> 8) & 0xff) == 0)
814 {
815 if (i != EFUSE_USAGE_MAP_END)
816 {
817 BlkNum = i+1-EFUSE_USAGE_MAP_START;
818 }
819 break;
820 }
821 }
822 DBGPRINT(RT_DEBUG_TRACE, ("Not bWriteSuccess new BlkNum = %d\n", BlkNum));
823 if(BlkNum == 0xffff)
824 {
825 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
826 return FALSE;
827 }
828
829 //invalidate the original mapping entry if new entry is not found
830 tmpaddr = addr;
831
832 if(addr % 2 != 0)
833 addr = addr -1;
834 InBuf[0] = addr;
835 InBuf[1] = 2;
836
837 eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
838
839 // write the logical address
840 if(tmpaddr%2 != 0)
841 {
842 // Invalidate the high byte
843 for (i=8; i<15; i++)
844 {
845 if( ( (InBuf[2] >> i) & 0x01) == 0)
846 {
847 InBuf[2] |= (0x1 <<i);
848 break;
849 }
850 }
851 }
852 else
853 {
854 // invalidate the low byte
855 for (i=0; i<8; i++)
856 {
857 if( ( (InBuf[2] >> i) & 0x01) == 0)
858 {
859 InBuf[2] |= (0x1 <<i);
860 break;
861 }
862 }
863 }
864 eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 0);
865 }
866 }
867 while(!bWriteSuccess);
868
869 return TRUE;
870}
871
872/*
873 ========================================================================
874
875 Routine Description:
876
877 Arguments:
878
879 Return Value:
880
881 IRQL =
882
883 Note:
884
885 ========================================================================
886*/
887VOID eFuseWritePhysical(
888 IN PRTMP_ADAPTER pAd,
889 PUSHORT lpInBuffer,
890 ULONG nInBufferSize,
891 PUCHAR lpOutBuffer,
892 ULONG nOutBufferSize
893)
894{
895 USHORT* pInBuf = (USHORT*)lpInBuffer;
896 int i;
897 //USHORT* pOutBuf = (USHORT*)ioBuffer;
898
899 USHORT Offset = pInBuf[0]; //addr
900 USHORT Length = pInBuf[1]; //length
901 USHORT* pValueX = &pInBuf[2]; //value ...
902 // Little-endian S | S Big-endian
903 // addr 3 2 1 0 | 0 1 2 3
904 // Ori-V D C B A | A B C D
905 //After swapping
906 // D C B A | D C B A
907 //Both the little and big-endian use the same sequence to write data.
908 //Therefore, we only need swap data when read the data.
909 for(i=0; i<Length; i+=2)
910 {
911 eFusePhysicalWriteRegisters(pAd, Offset+i, 2, &pValueX[i/2]);
912 }
913}
914
915
916/*
917 ========================================================================
918
919 Routine Description:
920
921 Arguments:
922
923 Return Value:
924
925 IRQL =
926
927 Note:
928
929 ========================================================================
930*/
931NTSTATUS eFuseWrite(
932 IN PRTMP_ADAPTER pAd,
933 IN USHORT Offset,
934 IN PUCHAR pData,
935 IN USHORT length)
936{
937 int i;
938
939 USHORT* pValueX = (PUSHORT) pData; //value ...
940 //The input value=3070 will be stored as following
941 // Little-endian S | S Big-endian
942 // addr 1 0 | 0 1
943 // Ori-V 30 70 | 30 70
944 //After swapping
945 // 30 70 | 70 30
946 //Casting
947 // 3070 | 7030 (x)
948 //The swapping should be removed for big-endian
949 for(i=0; i<length; i+=2)
950 {
951 eFuseWriteRegisters(pAd, Offset+i, 2, &pValueX[i/2]);
952 }
953
954 return TRUE;
955}
956
957/*
958 ========================================================================
959
960 Routine Description:
961
962 Arguments:
963
964 Return Value:
965
966 IRQL =
967
968 Note:
969
970 ========================================================================
971*/
972INT set_eFuseGetFreeBlockCount_Proc(
973 IN PRTMP_ADAPTER pAd,
974 IN PUCHAR arg)
975{
976 USHORT i;
977 USHORT LogicalAddress;
978 USHORT efusefreenum=0;
979 if(!pAd->bUseEfuse)
980 return FALSE;
981 for (i = EFUSE_USAGE_MAP_START; i <= EFUSE_USAGE_MAP_END; i+=2)
982 {
983 eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
984 if( (LogicalAddress & 0xff) == 0)
985 {
986 efusefreenum= (UCHAR) (EFUSE_USAGE_MAP_END-i+1);
987 break;
988 }
989 else if(( (LogicalAddress >> 8) & 0xff) == 0)
990 {
991 efusefreenum = (UCHAR) (EFUSE_USAGE_MAP_END-i);
992 break;
993 }
994
995 if(i == EFUSE_USAGE_MAP_END)
996 efusefreenum = 0;
997 }
998 printk("efuseFreeNumber is %d\n",efusefreenum);
999 return TRUE;
1000}
1001INT set_eFusedump_Proc(
1002 IN PRTMP_ADAPTER pAd,
1003 IN PUCHAR arg)
1004{
1005USHORT InBuf[3];
1006 INT i=0;
1007 if(!pAd->bUseEfuse)
1008 return FALSE;
1009 for(i =0; i<EFUSE_USAGE_MAP_END/2; i++)
1010 {
1011 InBuf[0] = 2*i;
1012 InBuf[1] = 2;
1013 InBuf[2] = 0x0;
1014
1015 eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
1016 if(i%4==0)
1017 printk("\nBlock %x:",i/8);
1018 printk("%04x ",InBuf[2]);
1019 }
1020 return TRUE;
1021}
1022INT set_eFuseLoadFromBin_Proc(
1023 IN PRTMP_ADAPTER pAd,
1024 IN PUCHAR arg)
1025{
1026 CHAR *src;
1027 struct file *srcf;
1028 INT retval, orgfsuid, orgfsgid;
1029 mm_segment_t orgfs;
1030 UCHAR *buffer;
1031 UCHAR BinFileSize=0;
1032 INT i = 0,j=0,k=1;
1033 USHORT *PDATA;
1034 USHORT DATA;
1035 BinFileSize=strlen("RT30xxEEPROM.bin");
1036 src = kmalloc(128, MEM_ALLOC_FLAG);
1037 NdisZeroMemory(src, 128);
1038
1039 if(strlen(arg)>0)
1040 {
1041
1042 NdisMoveMemory(src, arg, strlen(arg));
1043 }
1044
1045 else
1046 {
1047
1048 NdisMoveMemory(src, "RT30xxEEPROM.bin", BinFileSize);
1049 }
1050
1051 DBGPRINT(RT_DEBUG_TRACE, ("FileName=%s\n",src));
1052 buffer = kmalloc(MAX_EEPROM_BIN_FILE_SIZE, MEM_ALLOC_FLAG);
1053
1054 if(buffer == NULL)
1055 {
1056 kfree(src);
1057 return FALSE;
1058}
1059 PDATA=kmalloc(sizeof(USHORT)*8,MEM_ALLOC_FLAG);
1060
1061 if(PDATA==NULL)
1062 {
1063 kfree(src);
1064
1065 kfree(buffer);
1066 return FALSE;
1067 }
1068 /* Don't change to uid 0, let the file be opened as the "normal" user */
1069#if 0
1070 orgfsuid = current->fsuid;
1071 orgfsgid = current->fsgid;
1072 current->fsuid=current->fsgid = 0;
1073#endif
1074 orgfs = get_fs();
1075 set_fs(KERNEL_DS);
1076
1077 if (src && *src)
1078 {
1079 srcf = filp_open(src, O_RDONLY, 0);
1080 if (IS_ERR(srcf))
1081 {
1082 DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld opening %s\n", -PTR_ERR(srcf),src));
1083 return FALSE;
1084 }
1085 else
1086 {
1087 // The object must have a read method
1088 if (srcf->f_op && srcf->f_op->read)
1089 {
1090 memset(buffer, 0x00, MAX_EEPROM_BIN_FILE_SIZE);
1091 while(srcf->f_op->read(srcf, &buffer[i], 1, &srcf->f_pos)==1)
1092 {
1093 DBGPRINT(RT_DEBUG_TRACE, ("%02X ",buffer[i]));
1094 if((i+1)%8==0)
1095 DBGPRINT(RT_DEBUG_TRACE, ("\n"));
1096 i++;
1097 if(i>=MAX_EEPROM_BIN_FILE_SIZE)
1098 {
1099 DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld reading %s, The file is too large[1024]\n", -PTR_ERR(srcf),src));
1100 kfree(PDATA);
1101 kfree(buffer);
1102 kfree(src);
1103 return FALSE;
1104 }
1105 }
1106 }
1107 else
1108 {
1109 DBGPRINT(RT_DEBUG_ERROR, ("--> Error!! System doest not support read function\n"));
1110 kfree(PDATA);
1111 kfree(buffer);
1112 kfree(src);
1113 return FALSE;
1114 }
1115 }
1116
1117
1118 }
1119 else
1120 {
1121 DBGPRINT(RT_DEBUG_ERROR, ("--> Error src or srcf is null\n"));
1122 kfree(PDATA);
1123 kfree(buffer);
1124 return FALSE;
1125
1126 }
1127
1128
1129 retval=filp_close(srcf,NULL);
1130
1131 if (retval)
1132 {
1133 DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src));
1134 }
1135 set_fs(orgfs);
1136#if 0
1137 current->fsuid = orgfsuid;
1138 current->fsgid = orgfsgid;
1139#endif
1140 for(j=0;j<i;j++)
1141 {
1142 DBGPRINT(RT_DEBUG_TRACE, ("%02X ",buffer[j]));
1143 if((j+1)%2==0)
1144 PDATA[j/2%8]=((buffer[j]<<8)&0xff00)|(buffer[j-1]&0xff);
1145 if(j%16==0)
1146 {
1147 k=buffer[j];
1148 }
1149 else
1150 {
1151 k&=buffer[j];
1152 if((j+1)%16==0)
1153 {
1154
1155 DBGPRINT(RT_DEBUG_TRACE, (" result=%02X,blk=%02x\n",k,j/16));
1156
1157 if(k!=0xff)
1158 eFuseWriteRegistersFromBin(pAd,(USHORT)j-15, 16, PDATA);
1159 else
1160 {
1161 if(eFuseReadRegisters(pAd,j, 2,(PUSHORT)&DATA)!=0x3f)
1162 eFuseWriteRegistersFromBin(pAd,(USHORT)j-15, 16, PDATA);
1163 }
1164 /*
1165 for(l=0;l<8;l++)
1166 printk("%04x ",PDATA[l]);
1167 printk("\n");
1168 */
1169 NdisZeroMemory(PDATA,16);
1170
1171
1172 }
1173 }
1174
1175
1176 }
1177
1178
1179 kfree(PDATA);
1180 kfree(buffer);
1181 kfree(src);
1182 return TRUE;
1183}
1184NTSTATUS eFuseWriteRegistersFromBin(
1185 IN PRTMP_ADAPTER pAd,
1186 IN USHORT Offset,
1187 IN USHORT Length,
1188 IN USHORT* pData)
1189{
1190 USHORT i;
1191 USHORT eFuseData;
1192 USHORT LogicalAddress, BlkNum = 0xffff;
1193 UCHAR EFSROM_AOUT,Loop=0;
1194 EFUSE_CTRL_STRUC eFuseCtrlStruc;
1195 USHORT efuseDataOffset;
1196 UINT32 data,tempbuffer;
1197 USHORT addr,tmpaddr, InBuf[3], tmpOffset;
1198 UINT32 buffer[4];
1199 BOOLEAN bWriteSuccess = TRUE;
1200 BOOLEAN bNotWrite=TRUE;
1201 BOOLEAN bAllocateNewBlk=TRUE;
1202
1203 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin Offset=%x, pData=%04x:%04x:%04x:%04x\n", Offset, *pData,*(pData+1),*(pData+2),*(pData+3)));
1204
1205 do
1206 {
1207 //Step 0. find the entry in the mapping table
1208 //The address of EEPROM is 2-bytes alignment.
1209 //The last bit is used for alignment, so it must be 0.
1210 Loop++;
1211 tmpOffset = Offset & 0xfffe;
1212 EFSROM_AOUT = eFuseReadRegisters(pAd, tmpOffset, 2, &eFuseData);
1213
1214 if( EFSROM_AOUT == 0x3f)
1215 { //find available logical address pointer
1216 //the logical address does not exist, find an empty one
1217 //from the first address of block 45=16*45=0x2d0 to the last address of block 47
1218 //==>48*16-3(reserved)=2FC
1219 bAllocateNewBlk=TRUE;
1220 for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
1221 {
1222 //Retrive the logical block nubmer form each logical address pointer
1223 //It will access two logical address pointer each time.
1224 eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
1225 if( (LogicalAddress & 0xff) == 0)
1226 {//Not used logical address pointer
1227 BlkNum = i-EFUSE_USAGE_MAP_START;
1228 break;
1229 }
1230 else if(( (LogicalAddress >> 8) & 0xff) == 0)
1231 {//Not used logical address pointer
1232 if (i != EFUSE_USAGE_MAP_END)
1233 {
1234 BlkNum = i-EFUSE_USAGE_MAP_START+1;
1235 }
1236 break;
1237 }
1238 }
1239 }
1240 else
1241 {
1242 bAllocateNewBlk=FALSE;
1243 BlkNum = EFSROM_AOUT;
1244 }
1245
1246 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters BlkNum = %d \n", BlkNum));
1247
1248 if(BlkNum == 0xffff)
1249 {
1250 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
1251 return FALSE;
1252 }
1253 //Step 1.1.0
1254 //If the block is not existing in mapping table, create one
1255 //and write down the 16-bytes data to the new block
1256 if(bAllocateNewBlk)
1257 {
1258 DBGPRINT(RT_DEBUG_TRACE, ("Allocate New Blk\n"));
1259 efuseDataOffset = EFUSE_DATA3;
1260 for(i=0; i< 4; i++)
1261 {
1262 DBGPRINT(RT_DEBUG_TRACE, ("Allocate New Blk, Data%d=%04x%04x\n",3-i,pData[2*i+1],pData[2*i]));
1263 tempbuffer=((pData[2*i+1]<<16)&0xffff0000)|pData[2*i];
1264
1265
1266 RTMP_IO_WRITE32(pAd, efuseDataOffset,tempbuffer);
1267 efuseDataOffset -= 4;
1268
1269 }
1270 /////////////////////////////////////////////////////////////////
1271
1272 //Step1.1.1. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
1273 eFuseCtrlStruc.field.EFSROM_AIN = BlkNum* 0x10 ;
1274
1275 //Step1.1.2. Write EFSROM_MODE (0x580, bit7:bit6) to 3.
1276 eFuseCtrlStruc.field.EFSROM_MODE = 3;
1277
1278 //Step1.1.3. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical write procedure.
1279 eFuseCtrlStruc.field.EFSROM_KICK = 1;
1280
1281 NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
1282
1283 RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
1284
1285 //Step1.1.4. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. It¡¦s done.
1286 i = 0;
1287 while(i < 100)
1288 {
1289 RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
1290
1291 if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
1292 break;
1293
1294 RTMPusecDelay(2);
1295 i++;
1296 }
1297
1298 }
1299 else
1300 { //Step1.2.
1301 //If the same logical number is existing, check if the writting data and the data
1302 //saving in this block are the same.
1303 /////////////////////////////////////////////////////////////////
1304 //read current values of 16-byte block
1305 RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
1306
1307 //Step1.2.0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
1308 eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
1309
1310 //Step1.2.1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
1311 eFuseCtrlStruc.field.EFSROM_MODE = 0;
1312
1313 //Step1.2.2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
1314 eFuseCtrlStruc.field.EFSROM_KICK = 1;
1315
1316 NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
1317 RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
1318
1319 //Step1.2.3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
1320 i = 0;
1321 while(i < 100)
1322 {
1323 RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
1324
1325 if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
1326 break;
1327 RTMPusecDelay(2);
1328 i++;
1329 }
1330
1331 //Step1.2.4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
1332 efuseDataOffset = EFUSE_DATA3;
1333 for(i=0; i< 4; i++)
1334 {
1335 RTMP_IO_READ32(pAd, efuseDataOffset, (PUINT32) &buffer[i]);
1336 efuseDataOffset -= 4;
1337 }
1338 //Step1.2.5. Check if the data of efuse and the writing data are the same.
1339 for(i =0; i<4; i++)
1340 {
1341 tempbuffer=((pData[2*i+1]<<16)&0xffff0000)|pData[2*i];
1342 DBGPRINT(RT_DEBUG_TRACE, ("buffer[%d]=%x,pData[%d]=%x,pData[%d]=%x,tempbuffer=%x\n",i,buffer[i],2*i,pData[2*i],2*i+1,pData[2*i+1],tempbuffer));
1343
1344 if(((buffer[i]&0xffff0000)==(pData[2*i+1]<<16))&&((buffer[i]&0xffff)==pData[2*i]))
1345 bNotWrite&=TRUE;
1346 else
1347 {
1348 bNotWrite&=FALSE;
1349 break;
1350 }
1351 }
1352 if(!bNotWrite)
1353 {
1354 printk("The data is not the same\n");
1355
1356 for(i =0; i<8; i++)
1357 {
1358 addr = BlkNum * 0x10 ;
1359
1360 InBuf[0] = addr+2*i;
1361 InBuf[1] = 2;
1362 InBuf[2] = pData[i];
1363
1364 eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
1365 }
1366
1367 }
1368 else
1369 return TRUE;
1370 }
1371
1372
1373
1374 //Step 2. Write mapping table
1375 addr = EFUSE_USAGE_MAP_START+BlkNum;
1376
1377 tmpaddr = addr;
1378
1379 if(addr % 2 != 0)
1380 addr = addr -1;
1381 InBuf[0] = addr;
1382 InBuf[1] = 2;
1383
1384 //convert the address from 10 to 8 bit ( bit7, 6 = parity and bit5 ~ 0 = bit9~4), and write to logical map entry
1385 tmpOffset = Offset;
1386 tmpOffset >>= 4;
1387 tmpOffset |= ((~((tmpOffset & 0x01) ^ ( tmpOffset >> 1 & 0x01) ^ (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01))) << 6) & 0x40;
1388 tmpOffset |= ((~( (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01) ^ (tmpOffset >> 4 & 0x01) ^ ( tmpOffset >> 5 & 0x01))) << 7) & 0x80;
1389
1390 // write the logical address
1391 if(tmpaddr%2 != 0)
1392 InBuf[2] = tmpOffset<<8;
1393 else
1394 InBuf[2] = tmpOffset;
1395
1396 eFuseWritePhysical(pAd,&InBuf[0], 6, NULL, 0);
1397
1398 //Step 3. Compare data if not the same, invalidate the mapping entry, then re-write the data until E-fuse is exhausted
1399 bWriteSuccess = TRUE;
1400 for(i =0; i<8; i++)
1401 {
1402 addr = BlkNum * 0x10 ;
1403
1404 InBuf[0] = addr+2*i;
1405 InBuf[1] = 2;
1406 InBuf[2] = 0x0;
1407
1408 eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
1409 DBGPRINT(RT_DEBUG_TRACE, ("addr=%x, buffer[i]=%x,InBuf[2]=%x\n",InBuf[0],pData[i],InBuf[2]));
1410 if(pData[i] != InBuf[2])
1411 {
1412 bWriteSuccess = FALSE;
1413 break;
1414 }
1415 }
1416
1417 //Step 4. invlidate mapping entry and find a free mapping entry if not succeed
1418
1419 if (!bWriteSuccess&&Loop<2)
1420 {
1421 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin::Not bWriteSuccess BlkNum = %d\n", BlkNum));
1422
1423 // the offset of current mapping entry
1424 addr = EFUSE_USAGE_MAP_START+BlkNum;
1425
1426 //find a new mapping entry
1427 BlkNum = 0xffff;
1428 for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
1429 {
1430 eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
1431 if( (LogicalAddress & 0xff) == 0)
1432 {
1433 BlkNum = i-EFUSE_USAGE_MAP_START;
1434 break;
1435 }
1436 else if(( (LogicalAddress >> 8) & 0xff) == 0)
1437 {
1438 if (i != EFUSE_USAGE_MAP_END)
1439 {
1440 BlkNum = i+1-EFUSE_USAGE_MAP_START;
1441 }
1442 break;
1443 }
1444 }
1445 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin::Not bWriteSuccess new BlkNum = %d\n", BlkNum));
1446 if(BlkNum == 0xffff)
1447 {
1448 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin: out of free E-fuse space!!!\n"));
1449 return FALSE;
1450 }
1451
1452 //invalidate the original mapping entry if new entry is not found
1453 tmpaddr = addr;
1454
1455 if(addr % 2 != 0)
1456 addr = addr -1;
1457 InBuf[0] = addr;
1458 InBuf[1] = 2;
1459
1460 eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
1461
1462 // write the logical address
1463 if(tmpaddr%2 != 0)
1464 {
1465 // Invalidate the high byte
1466 for (i=8; i<15; i++)
1467 {
1468 if( ( (InBuf[2] >> i) & 0x01) == 0)
1469 {
1470 InBuf[2] |= (0x1 <<i);
1471 break;
1472 }
1473 }
1474 }
1475 else
1476 {
1477 // invalidate the low byte
1478 for (i=0; i<8; i++)
1479 {
1480 if( ( (InBuf[2] >> i) & 0x01) == 0)
1481 {
1482 InBuf[2] |= (0x1 <<i);
1483 break;
1484 }
1485 }
1486 }
1487 eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 0);
1488 }
1489
1490 }
1491 while(!bWriteSuccess&&Loop<2);
1492
1493 return TRUE;
1494}
1495
1496#endif // RT30xx //
1497//2008/09/11:KH add to support efuse-->
1498
diff --git a/drivers/staging/rt3070/common/md5.c b/drivers/staging/rt3070/common/md5.c
new file mode 100644
index 000000000000..774776b4b8c3
--- /dev/null
+++ b/drivers/staging/rt3070/common/md5.c
@@ -0,0 +1,1427 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 md5.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Name Date Modification logs
36 jan 10-28-03 Initial
37 Rita 11-23-04 Modify MD5 and SHA-1
38 Rita 10-14-05 Modify SHA-1 in big-endian platform
39 */
40#include "../rt_config.h"
41
42/**
43 * md5_mac:
44 * @key: pointer to the key used for MAC generation
45 * @key_len: length of the key in bytes
46 * @data: pointer to the data area for which the MAC is generated
47 * @data_len: length of the data in bytes
48 * @mac: pointer to the buffer holding space for the MAC; the buffer should
49 * have space for 128-bit (16 bytes) MD5 hash value
50 *
51 * md5_mac() determines the message authentication code by using secure hash
52 * MD5(key | data | key).
53 */
54void md5_mac(u8 *key, size_t key_len, u8 *data, size_t data_len, u8 *mac)
55{
56 MD5_CTX context;
57
58 MD5Init(&context);
59 MD5Update(&context, key, key_len);
60 MD5Update(&context, data, data_len);
61 MD5Update(&context, key, key_len);
62 MD5Final(mac, &context);
63}
64
65/**
66 * hmac_md5:
67 * @key: pointer to the key used for MAC generation
68 * @key_len: length of the key in bytes
69 * @data: pointer to the data area for which the MAC is generated
70 * @data_len: length of the data in bytes
71 * @mac: pointer to the buffer holding space for the MAC; the buffer should
72 * have space for 128-bit (16 bytes) MD5 hash value
73 *
74 * hmac_md5() determines the message authentication code using HMAC-MD5.
75 * This implementation is based on the sample code presented in RFC 2104.
76 */
77void hmac_md5(u8 *key, size_t key_len, u8 *data, size_t data_len, u8 *mac)
78{
79 MD5_CTX context;
80 u8 k_ipad[65]; /* inner padding - key XORd with ipad */
81 u8 k_opad[65]; /* outer padding - key XORd with opad */
82 u8 tk[16];
83 int i;
84
85 //assert(key != NULL && data != NULL && mac != NULL);
86
87 /* if key is longer than 64 bytes reset it to key = MD5(key) */
88 if (key_len > 64) {
89 MD5_CTX ttcontext;
90
91 MD5Init(&ttcontext);
92 MD5Update(&ttcontext, key, key_len);
93 MD5Final(tk, &ttcontext);
94 //key=(PUCHAR)ttcontext.buf;
95 key = tk;
96 key_len = 16;
97 }
98
99 /* the HMAC_MD5 transform looks like:
100 *
101 * MD5(K XOR opad, MD5(K XOR ipad, text))
102 *
103 * where K is an n byte key
104 * ipad is the byte 0x36 repeated 64 times
105 * opad is the byte 0x5c repeated 64 times
106 * and text is the data being protected */
107
108 /* start out by storing key in pads */
109 NdisZeroMemory(k_ipad, sizeof(k_ipad));
110 NdisZeroMemory(k_opad, sizeof(k_opad));
111 //assert(key_len < sizeof(k_ipad));
112 NdisMoveMemory(k_ipad, key, key_len);
113 NdisMoveMemory(k_opad, key, key_len);
114
115 /* XOR key with ipad and opad values */
116 for (i = 0; i < 64; i++) {
117 k_ipad[i] ^= 0x36;
118 k_opad[i] ^= 0x5c;
119 }
120
121 /* perform inner MD5 */
122 MD5Init(&context); /* init context for 1st pass */
123 MD5Update(&context, k_ipad, 64); /* start with inner pad */
124 MD5Update(&context, data, data_len); /* then text of datagram */
125 MD5Final(mac, &context); /* finish up 1st pass */
126
127 /* perform outer MD5 */
128 MD5Init(&context); /* init context for 2nd pass */
129 MD5Update(&context, k_opad, 64); /* start with outer pad */
130 MD5Update(&context, mac, 16); /* then results of 1st hash */
131 MD5Final(mac, &context); /* finish up 2nd pass */
132}
133
134#ifndef RT_BIG_ENDIAN
135#define byteReverse(buf, len) /* Nothing */
136#else
137void byteReverse(unsigned char *buf, unsigned longs);
138void byteReverse(unsigned char *buf, unsigned longs)
139{
140 do {
141 *(UINT32 *)buf = SWAP32(*(UINT32 *)buf);
142 buf += 4;
143 } while (--longs);
144}
145#endif
146
147
148/* ========================== MD5 implementation =========================== */
149// four base functions for MD5
150#define MD5_F1(x, y, z) (((x) & (y)) | ((~x) & (z)))
151#define MD5_F2(x, y, z) (((x) & (z)) | ((y) & (~z)))
152#define MD5_F3(x, y, z) ((x) ^ (y) ^ (z))
153#define MD5_F4(x, y, z) ((y) ^ ((x) | (~z)))
154#define CYCLIC_LEFT_SHIFT(w, s) (((w) << (s)) | ((w) >> (32-(s))))
155
156#define MD5Step(f, w, x, y, z, data, t, s) \
157 ( w += f(x, y, z) + data + t, w = (CYCLIC_LEFT_SHIFT(w, s)) & 0xffffffff, w += x )
158
159
160/*
161 * Function Description:
162 * Initiate MD5 Context satisfied in RFC 1321
163 *
164 * Arguments:
165 * pCtx Pointer to MD5 context
166 *
167 * Return Value:
168 * None
169 */
170VOID MD5Init(MD5_CTX *pCtx)
171{
172 pCtx->Buf[0]=0x67452301;
173 pCtx->Buf[1]=0xefcdab89;
174 pCtx->Buf[2]=0x98badcfe;
175 pCtx->Buf[3]=0x10325476;
176
177 pCtx->LenInBitCount[0]=0;
178 pCtx->LenInBitCount[1]=0;
179}
180
181
182/*
183 * Function Description:
184 * Update MD5 Context, allow of an arrary of octets as the next portion
185 * of the message
186 *
187 * Arguments:
188 * pCtx Pointer to MD5 context
189 * pData Pointer to input data
190 * LenInBytes The length of input data (unit: byte)
191 *
192 * Return Value:
193 * None
194 *
195 * Note:
196 * Called after MD5Init or MD5Update(itself)
197 */
198VOID MD5Update(MD5_CTX *pCtx, UCHAR *pData, UINT32 LenInBytes)
199{
200
201 UINT32 TfTimes;
202 UINT32 temp;
203 unsigned int i;
204
205 temp = pCtx->LenInBitCount[0];
206
207 pCtx->LenInBitCount[0] = (UINT32) (pCtx->LenInBitCount[0] + (LenInBytes << 3));
208
209 if (pCtx->LenInBitCount[0] < temp)
210 pCtx->LenInBitCount[1]++; //carry in
211
212 pCtx->LenInBitCount[1] += LenInBytes >> 29;
213
214 // mod 64 bytes
215 temp = (temp >> 3) & 0x3f;
216
217 // process lacks of 64-byte data
218 if (temp)
219 {
220 UCHAR *pAds = (UCHAR *) pCtx->Input + temp;
221
222 if ((temp+LenInBytes) < 64)
223 {
224 NdisMoveMemory(pAds, (UCHAR *)pData, LenInBytes);
225 return;
226 }
227
228 NdisMoveMemory(pAds, (UCHAR *)pData, 64-temp);
229 byteReverse(pCtx->Input, 16);
230 MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input);
231
232 pData += 64-temp;
233 LenInBytes -= 64-temp;
234 } // end of if (temp)
235
236
237 TfTimes = (LenInBytes >> 6);
238
239 for (i=TfTimes; i>0; i--)
240 {
241 NdisMoveMemory(pCtx->Input, (UCHAR *)pData, 64);
242 byteReverse(pCtx->Input, 16);
243 MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input);
244 pData += 64;
245 LenInBytes -= 64;
246 } // end of for
247
248 // buffering lacks of 64-byte data
249 if(LenInBytes)
250 NdisMoveMemory(pCtx->Input, (UCHAR *)pData, LenInBytes);
251
252}
253
254
255/*
256 * Function Description:
257 * Append padding bits and length of original message in the tail
258 * The message digest has to be completed in the end
259 *
260 * Arguments:
261 * Digest Output of Digest-Message for MD5
262 * pCtx Pointer to MD5 context
263 *
264 * Return Value:
265 * None
266 *
267 * Note:
268 * Called after MD5Update
269 */
270VOID MD5Final(UCHAR Digest[16], MD5_CTX *pCtx)
271{
272 UCHAR Remainder;
273 UCHAR PadLenInBytes;
274 UCHAR *pAppend=0;
275 unsigned int i;
276
277 Remainder = (UCHAR)((pCtx->LenInBitCount[0] >> 3) & 0x3f);
278
279 PadLenInBytes = (Remainder < 56) ? (56-Remainder) : (120-Remainder);
280
281 pAppend = (UCHAR *)pCtx->Input + Remainder;
282
283 // padding bits without crossing block(64-byte based) boundary
284 if (Remainder < 56)
285 {
286 *pAppend = 0x80;
287 PadLenInBytes --;
288
289 NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, PadLenInBytes);
290
291 // add data-length field, from low to high
292 for (i=0; i<4; i++)
293 {
294 pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[0] >> (i << 3)) & 0xff);
295 pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[1] >> (i << 3)) & 0xff);
296 }
297
298 byteReverse(pCtx->Input, 16);
299 MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input);
300 } // end of if
301
302 // padding bits with crossing block(64-byte based) boundary
303 else
304 {
305 // the first block ===
306 *pAppend = 0x80;
307 PadLenInBytes --;
308
309 NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, (64-Remainder-1));
310 PadLenInBytes -= (64 - Remainder - 1);
311
312 byteReverse(pCtx->Input, 16);
313 MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input);
314
315
316 // the second block ===
317 NdisZeroMemory((UCHAR *)pCtx->Input, PadLenInBytes);
318
319 // add data-length field
320 for (i=0; i<4; i++)
321 {
322 pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[0] >> (i << 3)) & 0xff);
323 pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[1] >> (i << 3)) & 0xff);
324 }
325
326 byteReverse(pCtx->Input, 16);
327 MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input);
328 } // end of else
329
330
331 NdisMoveMemory((UCHAR *)Digest, (UINT32 *)pCtx->Buf, 16); // output
332 byteReverse((UCHAR *)Digest, 4);
333 NdisZeroMemory(pCtx, sizeof(pCtx)); // memory free
334}
335
336
337/*
338 * Function Description:
339 * The central algorithm of MD5, consists of four rounds and sixteen
340 * steps per round
341 *
342 * Arguments:
343 * Buf Buffers of four states (output: 16 bytes)
344 * Mes Input data (input: 64 bytes)
345 *
346 * Return Value:
347 * None
348 *
349 * Note:
350 * Called by MD5Update or MD5Final
351 */
352VOID MD5Transform(UINT32 Buf[4], UINT32 Mes[16])
353{
354 UINT32 Reg[4], Temp;
355 unsigned int i;
356
357 static UCHAR LShiftVal[16] =
358 {
359 7, 12, 17, 22,
360 5, 9 , 14, 20,
361 4, 11, 16, 23,
362 6, 10, 15, 21,
363 };
364
365
366 // [equal to 4294967296*abs(sin(index))]
367 static UINT32 MD5Table[64] =
368 {
369 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
370 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
371 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
372 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
373
374 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
375 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
376 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
377 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
378
379 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
380 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
381 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
382 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
383
384 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
385 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
386 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
387 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
388 };
389
390
391 for (i=0; i<4; i++)
392 Reg[i]=Buf[i];
393
394
395 // 64 steps in MD5 algorithm
396 for (i=0; i<16; i++)
397 {
398 MD5Step(MD5_F1, Reg[0], Reg[1], Reg[2], Reg[3], Mes[i],
399 MD5Table[i], LShiftVal[i & 0x3]);
400
401 // one-word right shift
402 Temp = Reg[3];
403 Reg[3] = Reg[2];
404 Reg[2] = Reg[1];
405 Reg[1] = Reg[0];
406 Reg[0] = Temp;
407 }
408 for (i=16; i<32; i++)
409 {
410 MD5Step(MD5_F2, Reg[0], Reg[1], Reg[2], Reg[3], Mes[(5*(i & 0xf)+1) & 0xf],
411 MD5Table[i], LShiftVal[(0x1 << 2)+(i & 0x3)]);
412
413 // one-word right shift
414 Temp = Reg[3];
415 Reg[3] = Reg[2];
416 Reg[2] = Reg[1];
417 Reg[1] = Reg[0];
418 Reg[0] = Temp;
419 }
420 for (i=32; i<48; i++)
421 {
422 MD5Step(MD5_F3, Reg[0], Reg[1], Reg[2], Reg[3], Mes[(3*(i & 0xf)+5) & 0xf],
423 MD5Table[i], LShiftVal[(0x1 << 3)+(i & 0x3)]);
424
425 // one-word right shift
426 Temp = Reg[3];
427 Reg[3] = Reg[2];
428 Reg[2] = Reg[1];
429 Reg[1] = Reg[0];
430 Reg[0] = Temp;
431 }
432 for (i=48; i<64; i++)
433 {
434 MD5Step(MD5_F4, Reg[0], Reg[1], Reg[2], Reg[3], Mes[(7*(i & 0xf)) & 0xf],
435 MD5Table[i], LShiftVal[(0x3 << 2)+(i & 0x3)]);
436
437 // one-word right shift
438 Temp = Reg[3];
439 Reg[3] = Reg[2];
440 Reg[2] = Reg[1];
441 Reg[1] = Reg[0];
442 Reg[0] = Temp;
443 }
444
445
446 // (temporary)output
447 for (i=0; i<4; i++)
448 Buf[i] += Reg[i];
449
450}
451
452
453
454/* ========================= SHA-1 implementation ========================== */
455// four base functions for SHA-1
456#define SHA1_F1(b, c, d) (((b) & (c)) | ((~b) & (d)))
457#define SHA1_F2(b, c, d) ((b) ^ (c) ^ (d))
458#define SHA1_F3(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
459
460
461#define SHA1Step(f, a, b, c, d, e, w, k) \
462 ( e += ( f(b, c, d) + w + k + CYCLIC_LEFT_SHIFT(a, 5)) & 0xffffffff, \
463 b = CYCLIC_LEFT_SHIFT(b, 30) )
464
465//Initiate SHA-1 Context satisfied in RFC 3174
466VOID SHAInit(SHA_CTX *pCtx)
467{
468 pCtx->Buf[0]=0x67452301;
469 pCtx->Buf[1]=0xefcdab89;
470 pCtx->Buf[2]=0x98badcfe;
471 pCtx->Buf[3]=0x10325476;
472 pCtx->Buf[4]=0xc3d2e1f0;
473
474 pCtx->LenInBitCount[0]=0;
475 pCtx->LenInBitCount[1]=0;
476}
477
478/*
479 * Function Description:
480 * Update SHA-1 Context, allow of an arrary of octets as the next
481 * portion of the message
482 *
483 * Arguments:
484 * pCtx Pointer to SHA-1 context
485 * pData Pointer to input data
486 * LenInBytes The length of input data (unit: byte)
487 *
488 * Return Value:
489 * error indicate more than pow(2,64) bits of data
490 *
491 * Note:
492 * Called after SHAInit or SHAUpdate(itself)
493 */
494UCHAR SHAUpdate(SHA_CTX *pCtx, UCHAR *pData, UINT32 LenInBytes)
495{
496 UINT32 TfTimes;
497 UINT32 temp1,temp2;
498 unsigned int i;
499 UCHAR err=1;
500
501 temp1 = pCtx->LenInBitCount[0];
502 temp2 = pCtx->LenInBitCount[1];
503
504 pCtx->LenInBitCount[0] = (UINT32) (pCtx->LenInBitCount[0] + (LenInBytes << 3));
505 if (pCtx->LenInBitCount[0] < temp1)
506 pCtx->LenInBitCount[1]++; //carry in
507
508
509 pCtx->LenInBitCount[1] = (UINT32) (pCtx->LenInBitCount[1] +(LenInBytes >> 29));
510 if (pCtx->LenInBitCount[1] < temp2)
511 return (err); //check total length of original data
512
513
514 // mod 64 bytes
515 temp1 = (temp1 >> 3) & 0x3f;
516
517 // process lacks of 64-byte data
518 if (temp1)
519 {
520 UCHAR *pAds = (UCHAR *) pCtx->Input + temp1;
521
522 if ((temp1+LenInBytes) < 64)
523 {
524 NdisMoveMemory(pAds, (UCHAR *)pData, LenInBytes);
525 return (0);
526 }
527
528 NdisMoveMemory(pAds, (UCHAR *)pData, 64-temp1);
529 byteReverse((UCHAR *)pCtx->Input, 16);
530
531 NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16);
532 SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input);
533
534 pData += 64-temp1;
535 LenInBytes -= 64-temp1;
536 } // end of if (temp1)
537
538
539 TfTimes = (LenInBytes >> 6);
540
541 for (i=TfTimes; i>0; i--)
542 {
543 NdisMoveMemory(pCtx->Input, (UCHAR *)pData, 64);
544 byteReverse((UCHAR *)pCtx->Input, 16);
545
546 NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16);
547 SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input);
548 pData += 64;
549 LenInBytes -= 64;
550 } // end of for
551
552 // buffering lacks of 64-byte data
553 if(LenInBytes)
554 NdisMoveMemory(pCtx->Input, (UCHAR *)pData, LenInBytes);
555
556 return (0);
557
558}
559
560// Append padding bits and length of original message in the tail
561// The message digest has to be completed in the end
562VOID SHAFinal(SHA_CTX *pCtx, UCHAR Digest[20])
563{
564 UCHAR Remainder;
565 UCHAR PadLenInBytes;
566 UCHAR *pAppend=0;
567 unsigned int i;
568
569 Remainder = (UCHAR)((pCtx->LenInBitCount[0] >> 3) & 0x3f);
570
571 pAppend = (UCHAR *)pCtx->Input + Remainder;
572
573 PadLenInBytes = (Remainder < 56) ? (56-Remainder) : (120-Remainder);
574
575 // padding bits without crossing block(64-byte based) boundary
576 if (Remainder < 56)
577 {
578 *pAppend = 0x80;
579 PadLenInBytes --;
580
581 NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, PadLenInBytes);
582
583 // add data-length field, from high to low
584 for (i=0; i<4; i++)
585 {
586 pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[1] >> ((3-i) << 3)) & 0xff);
587 pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[0] >> ((3-i) << 3)) & 0xff);
588 }
589
590 byteReverse((UCHAR *)pCtx->Input, 16);
591 NdisZeroMemory((UCHAR *)pCtx->Input + 64, 14);
592 SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input);
593 } // end of if
594
595 // padding bits with crossing block(64-byte based) boundary
596 else
597 {
598 // the first block ===
599 *pAppend = 0x80;
600 PadLenInBytes --;
601
602 NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, (64-Remainder-1));
603 PadLenInBytes -= (64 - Remainder - 1);
604
605 byteReverse((UCHAR *)pCtx->Input, 16);
606 NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16);
607 SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input);
608
609
610 // the second block ===
611 NdisZeroMemory((UCHAR *)pCtx->Input, PadLenInBytes);
612
613 // add data-length field
614 for (i=0; i<4; i++)
615 {
616 pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[1] >> ((3-i) << 3)) & 0xff);
617 pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[0] >> ((3-i) << 3)) & 0xff);
618 }
619
620 byteReverse((UCHAR *)pCtx->Input, 16);
621 NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16);
622 SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input);
623 } // end of else
624
625
626 //Output, bytereverse
627 for (i=0; i<20; i++)
628 {
629 Digest [i] = (UCHAR)(pCtx->Buf[i>>2] >> 8*(3-(i & 0x3)));
630 }
631
632 NdisZeroMemory(pCtx, sizeof(pCtx)); // memory free
633}
634
635
636// The central algorithm of SHA-1, consists of four rounds and
637// twenty steps per round
638VOID SHATransform(UINT32 Buf[5], UINT32 Mes[20])
639{
640 UINT32 Reg[5],Temp;
641 unsigned int i;
642 UINT32 W[80];
643
644 static UINT32 SHA1Table[4] = { 0x5a827999, 0x6ed9eba1,
645 0x8f1bbcdc, 0xca62c1d6 };
646
647 Reg[0]=Buf[0];
648 Reg[1]=Buf[1];
649 Reg[2]=Buf[2];
650 Reg[3]=Buf[3];
651 Reg[4]=Buf[4];
652
653 //the first octet of a word is stored in the 0th element, bytereverse
654 for(i = 0; i < 16; i++)
655 {
656 W[i] = (Mes[i] >> 24) & 0xff;
657 W[i] |= (Mes[i] >> 8 ) & 0xff00;
658 W[i] |= (Mes[i] << 8 ) & 0xff0000;
659 W[i] |= (Mes[i] << 24) & 0xff000000;
660 }
661
662
663 for (i = 0; i < 64; i++)
664 W[16+i] = CYCLIC_LEFT_SHIFT(W[i] ^ W[2+i] ^ W[8+i] ^ W[13+i], 1);
665
666
667 // 80 steps in SHA-1 algorithm
668 for (i=0; i<80; i++)
669 {
670 if (i<20)
671 SHA1Step(SHA1_F1, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4],
672 W[i], SHA1Table[0]);
673
674 else if (i>=20 && i<40)
675 SHA1Step(SHA1_F2, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4],
676 W[i], SHA1Table[1]);
677
678 else if (i>=40 && i<60)
679 SHA1Step(SHA1_F3, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4],
680 W[i], SHA1Table[2]);
681
682 else
683 SHA1Step(SHA1_F2, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4],
684 W[i], SHA1Table[3]);
685
686
687 // one-word right shift
688 Temp = Reg[4];
689 Reg[4] = Reg[3];
690 Reg[3] = Reg[2];
691 Reg[2] = Reg[1];
692 Reg[1] = Reg[0];
693 Reg[0] = Temp;
694
695 } // end of for-loop
696
697
698 // (temporary)output
699 for (i=0; i<5; i++)
700 Buf[i] += Reg[i];
701
702}
703
704
705/* ========================= AES En/Decryption ========================== */
706
707/* forward S-box */
708static uint32 FSb[256] =
709{
710 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
711 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
712 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
713 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
714 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
715 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
716 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
717 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
718 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
719 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
720 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
721 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
722 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
723 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
724 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
725 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
726 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
727 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
728 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
729 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
730 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
731 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
732 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
733 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
734 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
735 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
736 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
737 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
738 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
739 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
740 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
741 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
742};
743
744/* forward table */
745#define FT \
746\
747 V(C6,63,63,A5), V(F8,7C,7C,84), V(EE,77,77,99), V(F6,7B,7B,8D), \
748 V(FF,F2,F2,0D), V(D6,6B,6B,BD), V(DE,6F,6F,B1), V(91,C5,C5,54), \
749 V(60,30,30,50), V(02,01,01,03), V(CE,67,67,A9), V(56,2B,2B,7D), \
750 V(E7,FE,FE,19), V(B5,D7,D7,62), V(4D,AB,AB,E6), V(EC,76,76,9A), \
751 V(8F,CA,CA,45), V(1F,82,82,9D), V(89,C9,C9,40), V(FA,7D,7D,87), \
752 V(EF,FA,FA,15), V(B2,59,59,EB), V(8E,47,47,C9), V(FB,F0,F0,0B), \
753 V(41,AD,AD,EC), V(B3,D4,D4,67), V(5F,A2,A2,FD), V(45,AF,AF,EA), \
754 V(23,9C,9C,BF), V(53,A4,A4,F7), V(E4,72,72,96), V(9B,C0,C0,5B), \
755 V(75,B7,B7,C2), V(E1,FD,FD,1C), V(3D,93,93,AE), V(4C,26,26,6A), \
756 V(6C,36,36,5A), V(7E,3F,3F,41), V(F5,F7,F7,02), V(83,CC,CC,4F), \
757 V(68,34,34,5C), V(51,A5,A5,F4), V(D1,E5,E5,34), V(F9,F1,F1,08), \
758 V(E2,71,71,93), V(AB,D8,D8,73), V(62,31,31,53), V(2A,15,15,3F), \
759 V(08,04,04,0C), V(95,C7,C7,52), V(46,23,23,65), V(9D,C3,C3,5E), \
760 V(30,18,18,28), V(37,96,96,A1), V(0A,05,05,0F), V(2F,9A,9A,B5), \
761 V(0E,07,07,09), V(24,12,12,36), V(1B,80,80,9B), V(DF,E2,E2,3D), \
762 V(CD,EB,EB,26), V(4E,27,27,69), V(7F,B2,B2,CD), V(EA,75,75,9F), \
763 V(12,09,09,1B), V(1D,83,83,9E), V(58,2C,2C,74), V(34,1A,1A,2E), \
764 V(36,1B,1B,2D), V(DC,6E,6E,B2), V(B4,5A,5A,EE), V(5B,A0,A0,FB), \
765 V(A4,52,52,F6), V(76,3B,3B,4D), V(B7,D6,D6,61), V(7D,B3,B3,CE), \
766 V(52,29,29,7B), V(DD,E3,E3,3E), V(5E,2F,2F,71), V(13,84,84,97), \
767 V(A6,53,53,F5), V(B9,D1,D1,68), V(00,00,00,00), V(C1,ED,ED,2C), \
768 V(40,20,20,60), V(E3,FC,FC,1F), V(79,B1,B1,C8), V(B6,5B,5B,ED), \
769 V(D4,6A,6A,BE), V(8D,CB,CB,46), V(67,BE,BE,D9), V(72,39,39,4B), \
770 V(94,4A,4A,DE), V(98,4C,4C,D4), V(B0,58,58,E8), V(85,CF,CF,4A), \
771 V(BB,D0,D0,6B), V(C5,EF,EF,2A), V(4F,AA,AA,E5), V(ED,FB,FB,16), \
772 V(86,43,43,C5), V(9A,4D,4D,D7), V(66,33,33,55), V(11,85,85,94), \
773 V(8A,45,45,CF), V(E9,F9,F9,10), V(04,02,02,06), V(FE,7F,7F,81), \
774 V(A0,50,50,F0), V(78,3C,3C,44), V(25,9F,9F,BA), V(4B,A8,A8,E3), \
775 V(A2,51,51,F3), V(5D,A3,A3,FE), V(80,40,40,C0), V(05,8F,8F,8A), \
776 V(3F,92,92,AD), V(21,9D,9D,BC), V(70,38,38,48), V(F1,F5,F5,04), \
777 V(63,BC,BC,DF), V(77,B6,B6,C1), V(AF,DA,DA,75), V(42,21,21,63), \
778 V(20,10,10,30), V(E5,FF,FF,1A), V(FD,F3,F3,0E), V(BF,D2,D2,6D), \
779 V(81,CD,CD,4C), V(18,0C,0C,14), V(26,13,13,35), V(C3,EC,EC,2F), \
780 V(BE,5F,5F,E1), V(35,97,97,A2), V(88,44,44,CC), V(2E,17,17,39), \
781 V(93,C4,C4,57), V(55,A7,A7,F2), V(FC,7E,7E,82), V(7A,3D,3D,47), \
782 V(C8,64,64,AC), V(BA,5D,5D,E7), V(32,19,19,2B), V(E6,73,73,95), \
783 V(C0,60,60,A0), V(19,81,81,98), V(9E,4F,4F,D1), V(A3,DC,DC,7F), \
784 V(44,22,22,66), V(54,2A,2A,7E), V(3B,90,90,AB), V(0B,88,88,83), \
785 V(8C,46,46,CA), V(C7,EE,EE,29), V(6B,B8,B8,D3), V(28,14,14,3C), \
786 V(A7,DE,DE,79), V(BC,5E,5E,E2), V(16,0B,0B,1D), V(AD,DB,DB,76), \
787 V(DB,E0,E0,3B), V(64,32,32,56), V(74,3A,3A,4E), V(14,0A,0A,1E), \
788 V(92,49,49,DB), V(0C,06,06,0A), V(48,24,24,6C), V(B8,5C,5C,E4), \
789 V(9F,C2,C2,5D), V(BD,D3,D3,6E), V(43,AC,AC,EF), V(C4,62,62,A6), \
790 V(39,91,91,A8), V(31,95,95,A4), V(D3,E4,E4,37), V(F2,79,79,8B), \
791 V(D5,E7,E7,32), V(8B,C8,C8,43), V(6E,37,37,59), V(DA,6D,6D,B7), \
792 V(01,8D,8D,8C), V(B1,D5,D5,64), V(9C,4E,4E,D2), V(49,A9,A9,E0), \
793 V(D8,6C,6C,B4), V(AC,56,56,FA), V(F3,F4,F4,07), V(CF,EA,EA,25), \
794 V(CA,65,65,AF), V(F4,7A,7A,8E), V(47,AE,AE,E9), V(10,08,08,18), \
795 V(6F,BA,BA,D5), V(F0,78,78,88), V(4A,25,25,6F), V(5C,2E,2E,72), \
796 V(38,1C,1C,24), V(57,A6,A6,F1), V(73,B4,B4,C7), V(97,C6,C6,51), \
797 V(CB,E8,E8,23), V(A1,DD,DD,7C), V(E8,74,74,9C), V(3E,1F,1F,21), \
798 V(96,4B,4B,DD), V(61,BD,BD,DC), V(0D,8B,8B,86), V(0F,8A,8A,85), \
799 V(E0,70,70,90), V(7C,3E,3E,42), V(71,B5,B5,C4), V(CC,66,66,AA), \
800 V(90,48,48,D8), V(06,03,03,05), V(F7,F6,F6,01), V(1C,0E,0E,12), \
801 V(C2,61,61,A3), V(6A,35,35,5F), V(AE,57,57,F9), V(69,B9,B9,D0), \
802 V(17,86,86,91), V(99,C1,C1,58), V(3A,1D,1D,27), V(27,9E,9E,B9), \
803 V(D9,E1,E1,38), V(EB,F8,F8,13), V(2B,98,98,B3), V(22,11,11,33), \
804 V(D2,69,69,BB), V(A9,D9,D9,70), V(07,8E,8E,89), V(33,94,94,A7), \
805 V(2D,9B,9B,B6), V(3C,1E,1E,22), V(15,87,87,92), V(C9,E9,E9,20), \
806 V(87,CE,CE,49), V(AA,55,55,FF), V(50,28,28,78), V(A5,DF,DF,7A), \
807 V(03,8C,8C,8F), V(59,A1,A1,F8), V(09,89,89,80), V(1A,0D,0D,17), \
808 V(65,BF,BF,DA), V(D7,E6,E6,31), V(84,42,42,C6), V(D0,68,68,B8), \
809 V(82,41,41,C3), V(29,99,99,B0), V(5A,2D,2D,77), V(1E,0F,0F,11), \
810 V(7B,B0,B0,CB), V(A8,54,54,FC), V(6D,BB,BB,D6), V(2C,16,16,3A)
811
812#define V(a,b,c,d) 0x##a##b##c##d
813static uint32 FT0[256] = { FT };
814#undef V
815
816#define V(a,b,c,d) 0x##d##a##b##c
817static uint32 FT1[256] = { FT };
818#undef V
819
820#define V(a,b,c,d) 0x##c##d##a##b
821static uint32 FT2[256] = { FT };
822#undef V
823
824#define V(a,b,c,d) 0x##b##c##d##a
825static uint32 FT3[256] = { FT };
826#undef V
827
828#undef FT
829
830/* reverse S-box */
831
832static uint32 RSb[256] =
833{
834 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
835 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
836 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
837 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
838 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
839 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
840 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
841 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
842 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
843 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
844 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
845 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
846 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
847 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
848 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
849 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
850 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
851 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
852 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
853 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
854 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
855 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
856 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
857 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
858 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
859 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
860 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
861 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
862 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
863 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
864 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
865 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
866};
867
868/* reverse table */
869
870#define RT \
871\
872 V(51,F4,A7,50), V(7E,41,65,53), V(1A,17,A4,C3), V(3A,27,5E,96), \
873 V(3B,AB,6B,CB), V(1F,9D,45,F1), V(AC,FA,58,AB), V(4B,E3,03,93), \
874 V(20,30,FA,55), V(AD,76,6D,F6), V(88,CC,76,91), V(F5,02,4C,25), \
875 V(4F,E5,D7,FC), V(C5,2A,CB,D7), V(26,35,44,80), V(B5,62,A3,8F), \
876 V(DE,B1,5A,49), V(25,BA,1B,67), V(45,EA,0E,98), V(5D,FE,C0,E1), \
877 V(C3,2F,75,02), V(81,4C,F0,12), V(8D,46,97,A3), V(6B,D3,F9,C6), \
878 V(03,8F,5F,E7), V(15,92,9C,95), V(BF,6D,7A,EB), V(95,52,59,DA), \
879 V(D4,BE,83,2D), V(58,74,21,D3), V(49,E0,69,29), V(8E,C9,C8,44), \
880 V(75,C2,89,6A), V(F4,8E,79,78), V(99,58,3E,6B), V(27,B9,71,DD), \
881 V(BE,E1,4F,B6), V(F0,88,AD,17), V(C9,20,AC,66), V(7D,CE,3A,B4), \
882 V(63,DF,4A,18), V(E5,1A,31,82), V(97,51,33,60), V(62,53,7F,45), \
883 V(B1,64,77,E0), V(BB,6B,AE,84), V(FE,81,A0,1C), V(F9,08,2B,94), \
884 V(70,48,68,58), V(8F,45,FD,19), V(94,DE,6C,87), V(52,7B,F8,B7), \
885 V(AB,73,D3,23), V(72,4B,02,E2), V(E3,1F,8F,57), V(66,55,AB,2A), \
886 V(B2,EB,28,07), V(2F,B5,C2,03), V(86,C5,7B,9A), V(D3,37,08,A5), \
887 V(30,28,87,F2), V(23,BF,A5,B2), V(02,03,6A,BA), V(ED,16,82,5C), \
888 V(8A,CF,1C,2B), V(A7,79,B4,92), V(F3,07,F2,F0), V(4E,69,E2,A1), \
889 V(65,DA,F4,CD), V(06,05,BE,D5), V(D1,34,62,1F), V(C4,A6,FE,8A), \
890 V(34,2E,53,9D), V(A2,F3,55,A0), V(05,8A,E1,32), V(A4,F6,EB,75), \
891 V(0B,83,EC,39), V(40,60,EF,AA), V(5E,71,9F,06), V(BD,6E,10,51), \
892 V(3E,21,8A,F9), V(96,DD,06,3D), V(DD,3E,05,AE), V(4D,E6,BD,46), \
893 V(91,54,8D,B5), V(71,C4,5D,05), V(04,06,D4,6F), V(60,50,15,FF), \
894 V(19,98,FB,24), V(D6,BD,E9,97), V(89,40,43,CC), V(67,D9,9E,77), \
895 V(B0,E8,42,BD), V(07,89,8B,88), V(E7,19,5B,38), V(79,C8,EE,DB), \
896 V(A1,7C,0A,47), V(7C,42,0F,E9), V(F8,84,1E,C9), V(00,00,00,00), \
897 V(09,80,86,83), V(32,2B,ED,48), V(1E,11,70,AC), V(6C,5A,72,4E), \
898 V(FD,0E,FF,FB), V(0F,85,38,56), V(3D,AE,D5,1E), V(36,2D,39,27), \
899 V(0A,0F,D9,64), V(68,5C,A6,21), V(9B,5B,54,D1), V(24,36,2E,3A), \
900 V(0C,0A,67,B1), V(93,57,E7,0F), V(B4,EE,96,D2), V(1B,9B,91,9E), \
901 V(80,C0,C5,4F), V(61,DC,20,A2), V(5A,77,4B,69), V(1C,12,1A,16), \
902 V(E2,93,BA,0A), V(C0,A0,2A,E5), V(3C,22,E0,43), V(12,1B,17,1D), \
903 V(0E,09,0D,0B), V(F2,8B,C7,AD), V(2D,B6,A8,B9), V(14,1E,A9,C8), \
904 V(57,F1,19,85), V(AF,75,07,4C), V(EE,99,DD,BB), V(A3,7F,60,FD), \
905 V(F7,01,26,9F), V(5C,72,F5,BC), V(44,66,3B,C5), V(5B,FB,7E,34), \
906 V(8B,43,29,76), V(CB,23,C6,DC), V(B6,ED,FC,68), V(B8,E4,F1,63), \
907 V(D7,31,DC,CA), V(42,63,85,10), V(13,97,22,40), V(84,C6,11,20), \
908 V(85,4A,24,7D), V(D2,BB,3D,F8), V(AE,F9,32,11), V(C7,29,A1,6D), \
909 V(1D,9E,2F,4B), V(DC,B2,30,F3), V(0D,86,52,EC), V(77,C1,E3,D0), \
910 V(2B,B3,16,6C), V(A9,70,B9,99), V(11,94,48,FA), V(47,E9,64,22), \
911 V(A8,FC,8C,C4), V(A0,F0,3F,1A), V(56,7D,2C,D8), V(22,33,90,EF), \
912 V(87,49,4E,C7), V(D9,38,D1,C1), V(8C,CA,A2,FE), V(98,D4,0B,36), \
913 V(A6,F5,81,CF), V(A5,7A,DE,28), V(DA,B7,8E,26), V(3F,AD,BF,A4), \
914 V(2C,3A,9D,E4), V(50,78,92,0D), V(6A,5F,CC,9B), V(54,7E,46,62), \
915 V(F6,8D,13,C2), V(90,D8,B8,E8), V(2E,39,F7,5E), V(82,C3,AF,F5), \
916 V(9F,5D,80,BE), V(69,D0,93,7C), V(6F,D5,2D,A9), V(CF,25,12,B3), \
917 V(C8,AC,99,3B), V(10,18,7D,A7), V(E8,9C,63,6E), V(DB,3B,BB,7B), \
918 V(CD,26,78,09), V(6E,59,18,F4), V(EC,9A,B7,01), V(83,4F,9A,A8), \
919 V(E6,95,6E,65), V(AA,FF,E6,7E), V(21,BC,CF,08), V(EF,15,E8,E6), \
920 V(BA,E7,9B,D9), V(4A,6F,36,CE), V(EA,9F,09,D4), V(29,B0,7C,D6), \
921 V(31,A4,B2,AF), V(2A,3F,23,31), V(C6,A5,94,30), V(35,A2,66,C0), \
922 V(74,4E,BC,37), V(FC,82,CA,A6), V(E0,90,D0,B0), V(33,A7,D8,15), \
923 V(F1,04,98,4A), V(41,EC,DA,F7), V(7F,CD,50,0E), V(17,91,F6,2F), \
924 V(76,4D,D6,8D), V(43,EF,B0,4D), V(CC,AA,4D,54), V(E4,96,04,DF), \
925 V(9E,D1,B5,E3), V(4C,6A,88,1B), V(C1,2C,1F,B8), V(46,65,51,7F), \
926 V(9D,5E,EA,04), V(01,8C,35,5D), V(FA,87,74,73), V(FB,0B,41,2E), \
927 V(B3,67,1D,5A), V(92,DB,D2,52), V(E9,10,56,33), V(6D,D6,47,13), \
928 V(9A,D7,61,8C), V(37,A1,0C,7A), V(59,F8,14,8E), V(EB,13,3C,89), \
929 V(CE,A9,27,EE), V(B7,61,C9,35), V(E1,1C,E5,ED), V(7A,47,B1,3C), \
930 V(9C,D2,DF,59), V(55,F2,73,3F), V(18,14,CE,79), V(73,C7,37,BF), \
931 V(53,F7,CD,EA), V(5F,FD,AA,5B), V(DF,3D,6F,14), V(78,44,DB,86), \
932 V(CA,AF,F3,81), V(B9,68,C4,3E), V(38,24,34,2C), V(C2,A3,40,5F), \
933 V(16,1D,C3,72), V(BC,E2,25,0C), V(28,3C,49,8B), V(FF,0D,95,41), \
934 V(39,A8,01,71), V(08,0C,B3,DE), V(D8,B4,E4,9C), V(64,56,C1,90), \
935 V(7B,CB,84,61), V(D5,32,B6,70), V(48,6C,5C,74), V(D0,B8,57,42)
936
937#define V(a,b,c,d) 0x##a##b##c##d
938static uint32 RT0[256] = { RT };
939#undef V
940
941#define V(a,b,c,d) 0x##d##a##b##c
942static uint32 RT1[256] = { RT };
943#undef V
944
945#define V(a,b,c,d) 0x##c##d##a##b
946static uint32 RT2[256] = { RT };
947#undef V
948
949#define V(a,b,c,d) 0x##b##c##d##a
950static uint32 RT3[256] = { RT };
951#undef V
952
953#undef RT
954
955/* round constants */
956
957static uint32 RCON[10] =
958{
959 0x01000000, 0x02000000, 0x04000000, 0x08000000,
960 0x10000000, 0x20000000, 0x40000000, 0x80000000,
961 0x1B000000, 0x36000000
962};
963
964/* key schedule tables */
965
966static int KT_init = 1;
967
968static uint32 KT0[256];
969static uint32 KT1[256];
970static uint32 KT2[256];
971static uint32 KT3[256];
972
973/* platform-independant 32-bit integer manipulation macros */
974
975#define GET_UINT32(n,b,i) \
976{ \
977 (n) = ( (uint32) (b)[(i) ] << 24 ) \
978 | ( (uint32) (b)[(i) + 1] << 16 ) \
979 | ( (uint32) (b)[(i) + 2] << 8 ) \
980 | ( (uint32) (b)[(i) + 3] ); \
981}
982
983#define PUT_UINT32(n,b,i) \
984{ \
985 (b)[(i) ] = (uint8) ( (n) >> 24 ); \
986 (b)[(i) + 1] = (uint8) ( (n) >> 16 ); \
987 (b)[(i) + 2] = (uint8) ( (n) >> 8 ); \
988 (b)[(i) + 3] = (uint8) ( (n) ); \
989}
990
991/* AES key scheduling routine */
992
993int rtmp_aes_set_key( aes_context *ctx, uint8 *key, int nbits )
994{
995 int i;
996 uint32 *RK, *SK;
997
998 switch( nbits )
999 {
1000 case 128: ctx->nr = 10; break;
1001 case 192: ctx->nr = 12; break;
1002 case 256: ctx->nr = 14; break;
1003 default : return( 1 );
1004 }
1005
1006 RK = ctx->erk;
1007
1008 for( i = 0; i < (nbits >> 5); i++ )
1009 {
1010 GET_UINT32( RK[i], key, i * 4 );
1011 }
1012
1013 /* setup encryption round keys */
1014
1015 switch( nbits )
1016 {
1017 case 128:
1018
1019 for( i = 0; i < 10; i++, RK += 4 )
1020 {
1021 RK[4] = RK[0] ^ RCON[i] ^
1022 ( FSb[ (uint8) ( RK[3] >> 16 ) ] << 24 ) ^
1023 ( FSb[ (uint8) ( RK[3] >> 8 ) ] << 16 ) ^
1024 ( FSb[ (uint8) ( RK[3] ) ] << 8 ) ^
1025 ( FSb[ (uint8) ( RK[3] >> 24 ) ] );
1026
1027 RK[5] = RK[1] ^ RK[4];
1028 RK[6] = RK[2] ^ RK[5];
1029 RK[7] = RK[3] ^ RK[6];
1030 }
1031 break;
1032
1033 case 192:
1034
1035 for( i = 0; i < 8; i++, RK += 6 )
1036 {
1037 RK[6] = RK[0] ^ RCON[i] ^
1038 ( FSb[ (uint8) ( RK[5] >> 16 ) ] << 24 ) ^
1039 ( FSb[ (uint8) ( RK[5] >> 8 ) ] << 16 ) ^
1040 ( FSb[ (uint8) ( RK[5] ) ] << 8 ) ^
1041 ( FSb[ (uint8) ( RK[5] >> 24 ) ] );
1042
1043 RK[7] = RK[1] ^ RK[6];
1044 RK[8] = RK[2] ^ RK[7];
1045 RK[9] = RK[3] ^ RK[8];
1046 RK[10] = RK[4] ^ RK[9];
1047 RK[11] = RK[5] ^ RK[10];
1048 }
1049 break;
1050
1051 case 256:
1052
1053 for( i = 0; i < 7; i++, RK += 8 )
1054 {
1055 RK[8] = RK[0] ^ RCON[i] ^
1056 ( FSb[ (uint8) ( RK[7] >> 16 ) ] << 24 ) ^
1057 ( FSb[ (uint8) ( RK[7] >> 8 ) ] << 16 ) ^
1058 ( FSb[ (uint8) ( RK[7] ) ] << 8 ) ^
1059 ( FSb[ (uint8) ( RK[7] >> 24 ) ] );
1060
1061 RK[9] = RK[1] ^ RK[8];
1062 RK[10] = RK[2] ^ RK[9];
1063 RK[11] = RK[3] ^ RK[10];
1064
1065 RK[12] = RK[4] ^
1066 ( FSb[ (uint8) ( RK[11] >> 24 ) ] << 24 ) ^
1067 ( FSb[ (uint8) ( RK[11] >> 16 ) ] << 16 ) ^
1068 ( FSb[ (uint8) ( RK[11] >> 8 ) ] << 8 ) ^
1069 ( FSb[ (uint8) ( RK[11] ) ] );
1070
1071 RK[13] = RK[5] ^ RK[12];
1072 RK[14] = RK[6] ^ RK[13];
1073 RK[15] = RK[7] ^ RK[14];
1074 }
1075 break;
1076 }
1077
1078 /* setup decryption round keys */
1079
1080 if( KT_init )
1081 {
1082 for( i = 0; i < 256; i++ )
1083 {
1084 KT0[i] = RT0[ FSb[i] ];
1085 KT1[i] = RT1[ FSb[i] ];
1086 KT2[i] = RT2[ FSb[i] ];
1087 KT3[i] = RT3[ FSb[i] ];
1088 }
1089
1090 KT_init = 0;
1091 }
1092
1093 SK = ctx->drk;
1094
1095 *SK++ = *RK++;
1096 *SK++ = *RK++;
1097 *SK++ = *RK++;
1098 *SK++ = *RK++;
1099
1100 for( i = 1; i < ctx->nr; i++ )
1101 {
1102 RK -= 8;
1103
1104 *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^
1105 KT1[ (uint8) ( *RK >> 16 ) ] ^
1106 KT2[ (uint8) ( *RK >> 8 ) ] ^
1107 KT3[ (uint8) ( *RK ) ]; RK++;
1108
1109 *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^
1110 KT1[ (uint8) ( *RK >> 16 ) ] ^
1111 KT2[ (uint8) ( *RK >> 8 ) ] ^
1112 KT3[ (uint8) ( *RK ) ]; RK++;
1113
1114 *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^
1115 KT1[ (uint8) ( *RK >> 16 ) ] ^
1116 KT2[ (uint8) ( *RK >> 8 ) ] ^
1117 KT3[ (uint8) ( *RK ) ]; RK++;
1118
1119 *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^
1120 KT1[ (uint8) ( *RK >> 16 ) ] ^
1121 KT2[ (uint8) ( *RK >> 8 ) ] ^
1122 KT3[ (uint8) ( *RK ) ]; RK++;
1123 }
1124
1125 RK -= 8;
1126
1127 *SK++ = *RK++;
1128 *SK++ = *RK++;
1129 *SK++ = *RK++;
1130 *SK++ = *RK++;
1131
1132 return( 0 );
1133}
1134
1135/* AES 128-bit block encryption routine */
1136
1137void rtmp_aes_encrypt(aes_context *ctx, uint8 input[16], uint8 output[16] )
1138{
1139 uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
1140
1141 RK = ctx->erk;
1142 GET_UINT32( X0, input, 0 ); X0 ^= RK[0];
1143 GET_UINT32( X1, input, 4 ); X1 ^= RK[1];
1144 GET_UINT32( X2, input, 8 ); X2 ^= RK[2];
1145 GET_UINT32( X3, input, 12 ); X3 ^= RK[3];
1146
1147#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
1148{ \
1149 RK += 4; \
1150 \
1151 X0 = RK[0] ^ FT0[ (uint8) ( Y0 >> 24 ) ] ^ \
1152 FT1[ (uint8) ( Y1 >> 16 ) ] ^ \
1153 FT2[ (uint8) ( Y2 >> 8 ) ] ^ \
1154 FT3[ (uint8) ( Y3 ) ]; \
1155 \
1156 X1 = RK[1] ^ FT0[ (uint8) ( Y1 >> 24 ) ] ^ \
1157 FT1[ (uint8) ( Y2 >> 16 ) ] ^ \
1158 FT2[ (uint8) ( Y3 >> 8 ) ] ^ \
1159 FT3[ (uint8) ( Y0 ) ]; \
1160 \
1161 X2 = RK[2] ^ FT0[ (uint8) ( Y2 >> 24 ) ] ^ \
1162 FT1[ (uint8) ( Y3 >> 16 ) ] ^ \
1163 FT2[ (uint8) ( Y0 >> 8 ) ] ^ \
1164 FT3[ (uint8) ( Y1 ) ]; \
1165 \
1166 X3 = RK[3] ^ FT0[ (uint8) ( Y3 >> 24 ) ] ^ \
1167 FT1[ (uint8) ( Y0 >> 16 ) ] ^ \
1168 FT2[ (uint8) ( Y1 >> 8 ) ] ^ \
1169 FT3[ (uint8) ( Y2 ) ]; \
1170}
1171
1172 AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 1 */
1173 AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 2 */
1174 AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 3 */
1175 AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 4 */
1176 AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 5 */
1177 AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 6 */
1178 AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 7 */
1179 AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 8 */
1180 AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 9 */
1181
1182 if( ctx->nr > 10 )
1183 {
1184 AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 10 */
1185 AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 11 */
1186 }
1187
1188 if( ctx->nr > 12 )
1189 {
1190 AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 12 */
1191 AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 13 */
1192 }
1193
1194 /* last round */
1195
1196 RK += 4;
1197
1198 X0 = RK[0] ^ ( FSb[ (uint8) ( Y0 >> 24 ) ] << 24 ) ^
1199 ( FSb[ (uint8) ( Y1 >> 16 ) ] << 16 ) ^
1200 ( FSb[ (uint8) ( Y2 >> 8 ) ] << 8 ) ^
1201 ( FSb[ (uint8) ( Y3 ) ] );
1202
1203 X1 = RK[1] ^ ( FSb[ (uint8) ( Y1 >> 24 ) ] << 24 ) ^
1204 ( FSb[ (uint8) ( Y2 >> 16 ) ] << 16 ) ^
1205 ( FSb[ (uint8) ( Y3 >> 8 ) ] << 8 ) ^
1206 ( FSb[ (uint8) ( Y0 ) ] );
1207
1208 X2 = RK[2] ^ ( FSb[ (uint8) ( Y2 >> 24 ) ] << 24 ) ^
1209 ( FSb[ (uint8) ( Y3 >> 16 ) ] << 16 ) ^
1210 ( FSb[ (uint8) ( Y0 >> 8 ) ] << 8 ) ^
1211 ( FSb[ (uint8) ( Y1 ) ] );
1212
1213 X3 = RK[3] ^ ( FSb[ (uint8) ( Y3 >> 24 ) ] << 24 ) ^
1214 ( FSb[ (uint8) ( Y0 >> 16 ) ] << 16 ) ^
1215 ( FSb[ (uint8) ( Y1 >> 8 ) ] << 8 ) ^
1216 ( FSb[ (uint8) ( Y2 ) ] );
1217
1218 PUT_UINT32( X0, output, 0 );
1219 PUT_UINT32( X1, output, 4 );
1220 PUT_UINT32( X2, output, 8 );
1221 PUT_UINT32( X3, output, 12 );
1222}
1223
1224/* AES 128-bit block decryption routine */
1225
1226void rtmp_aes_decrypt( aes_context *ctx, uint8 input[16], uint8 output[16] )
1227{
1228 uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
1229
1230 RK = ctx->drk;
1231
1232 GET_UINT32( X0, input, 0 ); X0 ^= RK[0];
1233 GET_UINT32( X1, input, 4 ); X1 ^= RK[1];
1234 GET_UINT32( X2, input, 8 ); X2 ^= RK[2];
1235 GET_UINT32( X3, input, 12 ); X3 ^= RK[3];
1236
1237#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
1238{ \
1239 RK += 4; \
1240 \
1241 X0 = RK[0] ^ RT0[ (uint8) ( Y0 >> 24 ) ] ^ \
1242 RT1[ (uint8) ( Y3 >> 16 ) ] ^ \
1243 RT2[ (uint8) ( Y2 >> 8 ) ] ^ \
1244 RT3[ (uint8) ( Y1 ) ]; \
1245 \
1246 X1 = RK[1] ^ RT0[ (uint8) ( Y1 >> 24 ) ] ^ \
1247 RT1[ (uint8) ( Y0 >> 16 ) ] ^ \
1248 RT2[ (uint8) ( Y3 >> 8 ) ] ^ \
1249 RT3[ (uint8) ( Y2 ) ]; \
1250 \
1251 X2 = RK[2] ^ RT0[ (uint8) ( Y2 >> 24 ) ] ^ \
1252 RT1[ (uint8) ( Y1 >> 16 ) ] ^ \
1253 RT2[ (uint8) ( Y0 >> 8 ) ] ^ \
1254 RT3[ (uint8) ( Y3 ) ]; \
1255 \
1256 X3 = RK[3] ^ RT0[ (uint8) ( Y3 >> 24 ) ] ^ \
1257 RT1[ (uint8) ( Y2 >> 16 ) ] ^ \
1258 RT2[ (uint8) ( Y1 >> 8 ) ] ^ \
1259 RT3[ (uint8) ( Y0 ) ]; \
1260}
1261
1262 AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 1 */
1263 AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 2 */
1264 AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 3 */
1265 AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 4 */
1266 AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 5 */
1267 AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 6 */
1268 AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 7 */
1269 AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 8 */
1270 AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 9 */
1271
1272 if( ctx->nr > 10 )
1273 {
1274 AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 10 */
1275 AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 11 */
1276 }
1277
1278 if( ctx->nr > 12 )
1279 {
1280 AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 12 */
1281 AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 13 */
1282 }
1283
1284 /* last round */
1285
1286 RK += 4;
1287
1288 X0 = RK[0] ^ ( RSb[ (uint8) ( Y0 >> 24 ) ] << 24 ) ^
1289 ( RSb[ (uint8) ( Y3 >> 16 ) ] << 16 ) ^
1290 ( RSb[ (uint8) ( Y2 >> 8 ) ] << 8 ) ^
1291 ( RSb[ (uint8) ( Y1 ) ] );
1292
1293 X1 = RK[1] ^ ( RSb[ (uint8) ( Y1 >> 24 ) ] << 24 ) ^
1294 ( RSb[ (uint8) ( Y0 >> 16 ) ] << 16 ) ^
1295 ( RSb[ (uint8) ( Y3 >> 8 ) ] << 8 ) ^
1296 ( RSb[ (uint8) ( Y2 ) ] );
1297
1298 X2 = RK[2] ^ ( RSb[ (uint8) ( Y2 >> 24 ) ] << 24 ) ^
1299 ( RSb[ (uint8) ( Y1 >> 16 ) ] << 16 ) ^
1300 ( RSb[ (uint8) ( Y0 >> 8 ) ] << 8 ) ^
1301 ( RSb[ (uint8) ( Y3 ) ] );
1302
1303 X3 = RK[3] ^ ( RSb[ (uint8) ( Y3 >> 24 ) ] << 24 ) ^
1304 ( RSb[ (uint8) ( Y2 >> 16 ) ] << 16 ) ^
1305 ( RSb[ (uint8) ( Y1 >> 8 ) ] << 8 ) ^
1306 ( RSb[ (uint8) ( Y0 ) ] );
1307
1308 PUT_UINT32( X0, output, 0 );
1309 PUT_UINT32( X1, output, 4 );
1310 PUT_UINT32( X2, output, 8 );
1311 PUT_UINT32( X3, output, 12 );
1312}
1313
1314/*
1315 ========================================================================
1316
1317 Routine Description:
1318 SHA1 function
1319
1320 Arguments:
1321
1322 Return Value:
1323
1324 Note:
1325
1326 ========================================================================
1327*/
1328VOID HMAC_SHA1(
1329 IN UCHAR *text,
1330 IN UINT text_len,
1331 IN UCHAR *key,
1332 IN UINT key_len,
1333 IN UCHAR *digest)
1334{
1335 SHA_CTX context;
1336 UCHAR k_ipad[65]; /* inner padding - key XORd with ipad */
1337 UCHAR k_opad[65]; /* outer padding - key XORd with opad */
1338 INT i;
1339
1340 // if key is longer than 64 bytes reset it to key=SHA1(key)
1341 if (key_len > 64)
1342 {
1343 SHA_CTX tctx;
1344 SHAInit(&tctx);
1345 SHAUpdate(&tctx, key, key_len);
1346 SHAFinal(&tctx, key);
1347 key_len = 20;
1348 }
1349 NdisZeroMemory(k_ipad, sizeof(k_ipad));
1350 NdisZeroMemory(k_opad, sizeof(k_opad));
1351 NdisMoveMemory(k_ipad, key, key_len);
1352 NdisMoveMemory(k_opad, key, key_len);
1353
1354 // XOR key with ipad and opad values
1355 for (i = 0; i < 64; i++)
1356 {
1357 k_ipad[i] ^= 0x36;
1358 k_opad[i] ^= 0x5c;
1359 }
1360
1361 // perform inner SHA1
1362 SHAInit(&context); /* init context for 1st pass */
1363 SHAUpdate(&context, k_ipad, 64); /* start with inner pad */
1364 SHAUpdate(&context, text, text_len); /* then text of datagram */
1365 SHAFinal(&context, digest); /* finish up 1st pass */
1366
1367 //perform outer SHA1
1368 SHAInit(&context); /* init context for 2nd pass */
1369 SHAUpdate(&context, k_opad, 64); /* start with outer pad */
1370 SHAUpdate(&context, digest, 20); /* then results of 1st hash */
1371 SHAFinal(&context, digest); /* finish up 2nd pass */
1372
1373}
1374
1375/*
1376* F(P, S, c, i) = U1 xor U2 xor ... Uc
1377* U1 = PRF(P, S || Int(i))
1378* U2 = PRF(P, U1)
1379* Uc = PRF(P, Uc-1)
1380*/
1381
1382void F(char *password, unsigned char *ssid, int ssidlength, int iterations, int count, unsigned char *output)
1383{
1384 unsigned char digest[36], digest1[SHA_DIGEST_LEN];
1385 int i, j;
1386
1387 /* U1 = PRF(P, S || int(i)) */
1388 memcpy(digest, ssid, ssidlength);
1389 digest[ssidlength] = (unsigned char)((count>>24) & 0xff);
1390 digest[ssidlength+1] = (unsigned char)((count>>16) & 0xff);
1391 digest[ssidlength+2] = (unsigned char)((count>>8) & 0xff);
1392 digest[ssidlength+3] = (unsigned char)(count & 0xff);
1393 HMAC_SHA1(digest, ssidlength+4, (unsigned char*) password, (int) strlen(password), digest1); // for WPA update
1394
1395 /* output = U1 */
1396 memcpy(output, digest1, SHA_DIGEST_LEN);
1397
1398 for (i = 1; i < iterations; i++)
1399 {
1400 /* Un = PRF(P, Un-1) */
1401 HMAC_SHA1(digest1, SHA_DIGEST_LEN, (unsigned char*) password, (int) strlen(password), digest); // for WPA update
1402 memcpy(digest1, digest, SHA_DIGEST_LEN);
1403
1404 /* output = output xor Un */
1405 for (j = 0; j < SHA_DIGEST_LEN; j++)
1406 {
1407 output[j] ^= digest[j];
1408 }
1409 }
1410}
1411/*
1412* password - ascii string up to 63 characters in length
1413* ssid - octet string up to 32 octets
1414* ssidlength - length of ssid in octets
1415* output must be 40 octets in length and outputs 256 bits of key
1416*/
1417int PasswordHash(char *password, unsigned char *ssid, int ssidlength, unsigned char *output)
1418{
1419 if ((strlen(password) > 63) || (ssidlength > 32))
1420 return 0;
1421
1422 F(password, ssid, ssidlength, 4096, 1, output);
1423 F(password, ssid, ssidlength, 4096, 2, &output[SHA_DIGEST_LEN]);
1424 return 1;
1425}
1426
1427
diff --git a/drivers/staging/rt3070/common/mlme.c b/drivers/staging/rt3070/common/mlme.c
new file mode 100644
index 000000000000..0ffbfa36699e
--- /dev/null
+++ b/drivers/staging/rt3070/common/mlme.c
@@ -0,0 +1,9136 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 mlme.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 John Chang 2004-08-25 Modify from RT2500 code base
36 John Chang 2004-09-06 modified for RT2600
37*/
38
39#include "../rt_config.h"
40#include <stdarg.h>
41
42UCHAR CISCO_OUI[] = {0x00, 0x40, 0x96};
43
44UCHAR WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01};
45UCHAR RSN_OUI[] = {0x00, 0x0f, 0xac};
46UCHAR WAPI_OUI[] = {0x00, 0x14, 0x72};
47UCHAR WME_INFO_ELEM[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
48UCHAR WME_PARM_ELEM[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
49UCHAR Ccx2QosInfo[] = {0x00, 0x40, 0x96, 0x04};
50UCHAR RALINK_OUI[] = {0x00, 0x0c, 0x43};
51UCHAR BROADCOM_OUI[] = {0x00, 0x90, 0x4c};
52UCHAR WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04};
53#ifdef CONFIG_STA_SUPPORT
54#ifdef DOT11_N_SUPPORT
55UCHAR PRE_N_HT_OUI[] = {0x00, 0x90, 0x4c};
56#endif // DOT11_N_SUPPORT //
57#endif // CONFIG_STA_SUPPORT //
58
59UCHAR RateSwitchTable[] = {
60// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
61 0x11, 0x00, 0, 0, 0, // Initial used item after association
62 0x00, 0x00, 0, 40, 101,
63 0x01, 0x00, 1, 40, 50,
64 0x02, 0x00, 2, 35, 45,
65 0x03, 0x00, 3, 20, 45,
66 0x04, 0x21, 0, 30, 50,
67 0x05, 0x21, 1, 20, 50,
68 0x06, 0x21, 2, 20, 50,
69 0x07, 0x21, 3, 15, 50,
70 0x08, 0x21, 4, 15, 30,
71 0x09, 0x21, 5, 10, 25,
72 0x0a, 0x21, 6, 8, 25,
73 0x0b, 0x21, 7, 8, 25,
74 0x0c, 0x20, 12, 15, 30,
75 0x0d, 0x20, 13, 8, 20,
76 0x0e, 0x20, 14, 8, 20,
77 0x0f, 0x20, 15, 8, 25,
78 0x10, 0x22, 15, 8, 25,
79 0x11, 0x00, 0, 0, 0,
80 0x12, 0x00, 0, 0, 0,
81 0x13, 0x00, 0, 0, 0,
82 0x14, 0x00, 0, 0, 0,
83 0x15, 0x00, 0, 0, 0,
84 0x16, 0x00, 0, 0, 0,
85 0x17, 0x00, 0, 0, 0,
86 0x18, 0x00, 0, 0, 0,
87 0x19, 0x00, 0, 0, 0,
88 0x1a, 0x00, 0, 0, 0,
89 0x1b, 0x00, 0, 0, 0,
90 0x1c, 0x00, 0, 0, 0,
91 0x1d, 0x00, 0, 0, 0,
92 0x1e, 0x00, 0, 0, 0,
93 0x1f, 0x00, 0, 0, 0,
94};
95
96UCHAR RateSwitchTable11B[] = {
97// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
98 0x04, 0x03, 0, 0, 0, // Initial used item after association
99 0x00, 0x00, 0, 40, 101,
100 0x01, 0x00, 1, 40, 50,
101 0x02, 0x00, 2, 35, 45,
102 0x03, 0x00, 3, 20, 45,
103};
104
105UCHAR RateSwitchTable11BG[] = {
106// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
107 0x0a, 0x00, 0, 0, 0, // Initial used item after association
108 0x00, 0x00, 0, 40, 101,
109 0x01, 0x00, 1, 40, 50,
110 0x02, 0x00, 2, 35, 45,
111 0x03, 0x00, 3, 20, 45,
112 0x04, 0x10, 2, 20, 35,
113 0x05, 0x10, 3, 16, 35,
114 0x06, 0x10, 4, 10, 25,
115 0x07, 0x10, 5, 16, 25,
116 0x08, 0x10, 6, 10, 25,
117 0x09, 0x10, 7, 10, 13,
118};
119
120UCHAR RateSwitchTable11G[] = {
121// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
122 0x08, 0x00, 0, 0, 0, // Initial used item after association
123 0x00, 0x10, 0, 20, 101,
124 0x01, 0x10, 1, 20, 35,
125 0x02, 0x10, 2, 20, 35,
126 0x03, 0x10, 3, 16, 35,
127 0x04, 0x10, 4, 10, 25,
128 0x05, 0x10, 5, 16, 25,
129 0x06, 0x10, 6, 10, 25,
130 0x07, 0x10, 7, 10, 13,
131};
132
133#ifdef DOT11_N_SUPPORT
134UCHAR RateSwitchTable11N1S[] = {
135// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
136 0x09, 0x00, 0, 0, 0, // Initial used item after association
137 0x00, 0x21, 0, 30, 101,
138 0x01, 0x21, 1, 20, 50,
139 0x02, 0x21, 2, 20, 50,
140 0x03, 0x21, 3, 15, 50,
141 0x04, 0x21, 4, 15, 30,
142 0x05, 0x21, 5, 10, 25,
143 0x06, 0x21, 6, 8, 14,
144 0x07, 0x21, 7, 8, 14,
145 0x08, 0x23, 7, 8, 14,
146};
147
148UCHAR RateSwitchTable11N2S[] = {
149// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
150 0x0a, 0x00, 0, 0, 0, // Initial used item after association
151 0x00, 0x21, 0, 30, 101,
152 0x01, 0x21, 1, 20, 50,
153 0x02, 0x21, 2, 20, 50,
154 0x03, 0x21, 3, 15, 50,
155 0x04, 0x21, 4, 15, 30,
156 0x05, 0x20, 12, 15, 30,
157 0x06, 0x20, 13, 8, 20,
158 0x07, 0x20, 14, 8, 20,
159 0x08, 0x20, 15, 8, 25,
160 0x09, 0x22, 15, 8, 25,
161};
162
163UCHAR RateSwitchTable11N3S[] = {
164// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
165 0x0a, 0x00, 0, 0, 0, // Initial used item after association
166 0x00, 0x21, 0, 30, 101,
167 0x01, 0x21, 1, 20, 50,
168 0x02, 0x21, 2, 20, 50,
169 0x03, 0x21, 3, 15, 50,
170 0x04, 0x21, 4, 15, 30,
171 0x05, 0x20, 12, 15, 30,
172 0x06, 0x20, 13, 8, 20,
173 0x07, 0x20, 14, 8, 20,
174 0x08, 0x20, 15, 8, 25,
175 0x09, 0x22, 15, 8, 25,
176};
177
178UCHAR RateSwitchTable11N2SForABand[] = {
179// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
180 0x0b, 0x09, 0, 0, 0, // Initial used item after association
181 0x00, 0x21, 0, 30, 101,
182 0x01, 0x21, 1, 20, 50,
183 0x02, 0x21, 2, 20, 50,
184 0x03, 0x21, 3, 15, 50,
185 0x04, 0x21, 4, 15, 30,
186 0x05, 0x21, 5, 15, 30,
187 0x06, 0x20, 12, 15, 30,
188 0x07, 0x20, 13, 8, 20,
189 0x08, 0x20, 14, 8, 20,
190 0x09, 0x20, 15, 8, 25,
191 0x0a, 0x22, 15, 8, 25,
192};
193
194UCHAR RateSwitchTable11N3SForABand[] = { // 3*3
195// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
196 0x0b, 0x09, 0, 0, 0, // Initial used item after association
197 0x00, 0x21, 0, 30, 101,
198 0x01, 0x21, 1, 20, 50,
199 0x02, 0x21, 2, 20, 50,
200 0x03, 0x21, 3, 15, 50,
201 0x04, 0x21, 4, 15, 30,
202 0x05, 0x21, 5, 15, 30,
203 0x06, 0x20, 12, 15, 30,
204 0x07, 0x20, 13, 8, 20,
205 0x08, 0x20, 14, 8, 20,
206 0x09, 0x20, 15, 8, 25,
207 0x0a, 0x22, 15, 8, 25,
208};
209
210UCHAR RateSwitchTable11BGN1S[] = {
211// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
212 0x0d, 0x00, 0, 0, 0, // Initial used item after association
213 0x00, 0x00, 0, 40, 101,
214 0x01, 0x00, 1, 40, 50,
215 0x02, 0x00, 2, 35, 45,
216 0x03, 0x00, 3, 20, 45,
217 0x04, 0x21, 0, 30,101, //50
218 0x05, 0x21, 1, 20, 50,
219 0x06, 0x21, 2, 20, 50,
220 0x07, 0x21, 3, 15, 50,
221 0x08, 0x21, 4, 15, 30,
222 0x09, 0x21, 5, 10, 25,
223 0x0a, 0x21, 6, 8, 14,
224 0x0b, 0x21, 7, 8, 14,
225 0x0c, 0x23, 7, 8, 14,
226};
227
228UCHAR RateSwitchTable11BGN2S[] = {
229// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
230 0x0a, 0x00, 0, 0, 0, // Initial used item after association
231 0x00, 0x21, 0, 30,101, //50
232 0x01, 0x21, 1, 20, 50,
233 0x02, 0x21, 2, 20, 50,
234 0x03, 0x21, 3, 15, 50,
235 0x04, 0x21, 4, 15, 30,
236 0x05, 0x20, 12, 15, 30,
237 0x06, 0x20, 13, 8, 20,
238 0x07, 0x20, 14, 8, 20,
239 0x08, 0x20, 15, 8, 25,
240 0x09, 0x22, 15, 8, 25,
241};
242
243UCHAR RateSwitchTable11BGN3S[] = { // 3*3
244// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
245 0x0a, 0x00, 0, 0, 0, // Initial used item after association
246 0x00, 0x21, 0, 30,101, //50
247 0x01, 0x21, 1, 20, 50,
248 0x02, 0x21, 2, 20, 50,
249 0x03, 0x21, 3, 20, 50,
250 0x04, 0x21, 4, 15, 50,
251#if 1
252 0x05, 0x20, 20, 15, 30,
253 0x06, 0x20, 21, 8, 20,
254 0x07, 0x20, 22, 8, 20,
255 0x08, 0x20, 23, 8, 25,
256 0x09, 0x22, 23, 8, 25,
257#else // for RT2860 2*3 test
258 0x05, 0x20, 12, 15, 30,
259 0x06, 0x20, 13, 8, 20,
260 0x07, 0x20, 14, 8, 20,
261 0x08, 0x20, 15, 8, 25,
262 0x09, 0x22, 15, 8, 25,
263#endif
264};
265
266UCHAR RateSwitchTable11BGN2SForABand[] = {
267// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
268 0x0b, 0x09, 0, 0, 0, // Initial used item after association
269 0x00, 0x21, 0, 30,101, //50
270 0x01, 0x21, 1, 20, 50,
271 0x02, 0x21, 2, 20, 50,
272 0x03, 0x21, 3, 15, 50,
273 0x04, 0x21, 4, 15, 30,
274 0x05, 0x21, 5, 15, 30,
275 0x06, 0x20, 12, 15, 30,
276 0x07, 0x20, 13, 8, 20,
277 0x08, 0x20, 14, 8, 20,
278 0x09, 0x20, 15, 8, 25,
279 0x0a, 0x22, 15, 8, 25,
280};
281
282UCHAR RateSwitchTable11BGN3SForABand[] = { // 3*3
283// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
284 0x0c, 0x09, 0, 0, 0, // Initial used item after association
285 0x00, 0x21, 0, 30,101, //50
286 0x01, 0x21, 1, 20, 50,
287 0x02, 0x21, 2, 20, 50,
288 0x03, 0x21, 3, 15, 50,
289 0x04, 0x21, 4, 15, 30,
290 0x05, 0x21, 5, 15, 30,
291 0x06, 0x21, 12, 15, 30,
292 0x07, 0x20, 20, 15, 30,
293 0x08, 0x20, 21, 8, 20,
294 0x09, 0x20, 22, 8, 20,
295 0x0a, 0x20, 23, 8, 25,
296 0x0b, 0x22, 23, 8, 25,
297};
298#endif // DOT11_N_SUPPORT //
299
300PUCHAR ReasonString[] = {
301 /* 0 */ "Reserved",
302 /* 1 */ "Unspecified Reason",
303 /* 2 */ "Previous Auth no longer valid",
304 /* 3 */ "STA is leaving / has left",
305 /* 4 */ "DIS-ASSOC due to inactivity",
306 /* 5 */ "AP unable to hanle all associations",
307 /* 6 */ "class 2 error",
308 /* 7 */ "class 3 error",
309 /* 8 */ "STA is leaving / has left",
310 /* 9 */ "require auth before assoc/re-assoc",
311 /* 10 */ "Reserved",
312 /* 11 */ "Reserved",
313 /* 12 */ "Reserved",
314 /* 13 */ "invalid IE",
315 /* 14 */ "MIC error",
316 /* 15 */ "4-way handshake timeout",
317 /* 16 */ "2-way (group key) handshake timeout",
318 /* 17 */ "4-way handshake IE diff among AssosReq/Rsp/Beacon",
319 /* 18 */
320};
321
322extern UCHAR OfdmRateToRxwiMCS[];
323// since RT61 has better RX sensibility, we have to limit TX ACK rate not to exceed our normal data TX rate.
324// otherwise the WLAN peer may not be able to receive the ACK thus downgrade its data TX rate
325ULONG BasicRateMask[12] = {0xfffff001 /* 1-Mbps */, 0xfffff003 /* 2 Mbps */, 0xfffff007 /* 5.5 */, 0xfffff00f /* 11 */,
326 0xfffff01f /* 6 */ , 0xfffff03f /* 9 */ , 0xfffff07f /* 12 */ , 0xfffff0ff /* 18 */,
327 0xfffff1ff /* 24 */ , 0xfffff3ff /* 36 */ , 0xfffff7ff /* 48 */ , 0xffffffff /* 54 */};
328
329UCHAR MULTICAST_ADDR[MAC_ADDR_LEN] = {0x1, 0x00, 0x00, 0x00, 0x00, 0x00};
330UCHAR BROADCAST_ADDR[MAC_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
331UCHAR ZERO_MAC_ADDR[MAC_ADDR_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
332
333// e.g. RssiSafeLevelForTxRate[RATE_36]" means if the current RSSI is greater than
334// this value, then it's quaranteed capable of operating in 36 mbps TX rate in
335// clean environment.
336// TxRate: 1 2 5.5 11 6 9 12 18 24 36 48 54 72 100
337CHAR RssiSafeLevelForTxRate[] ={ -92, -91, -90, -87, -88, -86, -85, -83, -81, -78, -72, -71, -40, -40 };
338
339UCHAR RateIdToMbps[] = { 1, 2, 5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 72, 100};
340USHORT RateIdTo500Kbps[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 144, 200};
341
342UCHAR SsidIe = IE_SSID;
343UCHAR SupRateIe = IE_SUPP_RATES;
344UCHAR ExtRateIe = IE_EXT_SUPP_RATES;
345#ifdef DOT11_N_SUPPORT
346UCHAR HtCapIe = IE_HT_CAP;
347UCHAR AddHtInfoIe = IE_ADD_HT;
348UCHAR NewExtChanIe = IE_SECONDARY_CH_OFFSET;
349#ifdef DOT11N_DRAFT3
350UCHAR ExtHtCapIe = IE_EXT_CAPABILITY;
351#endif // DOT11N_DRAFT3 //
352#endif // DOT11_N_SUPPORT //
353UCHAR ErpIe = IE_ERP;
354UCHAR DsIe = IE_DS_PARM;
355UCHAR TimIe = IE_TIM;
356UCHAR WpaIe = IE_WPA;
357UCHAR Wpa2Ie = IE_WPA2;
358UCHAR IbssIe = IE_IBSS_PARM;
359UCHAR Ccx2Ie = IE_CCX_V2;
360UCHAR WapiIe = IE_WAPI;
361
362extern UCHAR WPA_OUI[];
363
364UCHAR SES_OUI[] = {0x00, 0x90, 0x4c};
365
366UCHAR ZeroSsid[32] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
367 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
368
369// Reset the RFIC setting to new series
370RTMP_RF_REGS RF2850RegTable[] = {
371// ch R1 R2 R3(TX0~4=0) R4
372 {1, 0x98402ecc, 0x984c0786, 0x9816b455, 0x9800510b},
373 {2, 0x98402ecc, 0x984c0786, 0x98168a55, 0x9800519f},
374 {3, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800518b},
375 {4, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800519f},
376 {5, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800518b},
377 {6, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800519f},
378 {7, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800518b},
379 {8, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800519f},
380 {9, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800518b},
381 {10, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800519f},
382 {11, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800518b},
383 {12, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800519f},
384 {13, 0x98402ecc, 0x984c079e, 0x98168a55, 0x9800518b},
385 {14, 0x98402ecc, 0x984c07a2, 0x98168a55, 0x98005193},
386
387 // 802.11 UNI / HyperLan 2
388 {36, 0x98402ecc, 0x984c099a, 0x98158a55, 0x980ed1a3},
389 {38, 0x98402ecc, 0x984c099e, 0x98158a55, 0x980ed193},
390 {40, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed183},
391 {44, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed1a3},
392 {46, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed18b},
393 {48, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed19b},
394 {52, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed193},
395 {54, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed1a3},
396 {56, 0x98402ec8, 0x984c068e, 0x98158a55, 0x980ed18b},
397 {60, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed183},
398 {62, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed193},
399 {64, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed1a3}, // Plugfest#4, Day4, change RFR3 left4th 9->5.
400
401 // 802.11 HyperLan 2
402 {100, 0x98402ec8, 0x984c06b2, 0x98178a55, 0x980ed783},
403
404 // 2008.04.30 modified
405 // The system team has AN to improve the EVM value
406 // for channel 102 to 108 for the RT2850/RT2750 dual band solution.
407 {102, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed793},
408 {104, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed1a3},
409 {108, 0x98402ecc, 0x985c0a32, 0x98578a55, 0x980ed193},
410
411 {110, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed183},
412 {112, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed19b},
413 {116, 0x98402ecc, 0x984c0a3a, 0x98178a55, 0x980ed1a3},
414 {118, 0x98402ecc, 0x984c0a3e, 0x98178a55, 0x980ed193},
415 {120, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed183},
416 {124, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed193},
417 {126, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed15b}, // 0x980ed1bb->0x980ed15b required by Rory 20070927
418 {128, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed1a3},
419 {132, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed18b},
420 {134, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed193},
421 {136, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed19b},
422 {140, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed183},
423
424 // 802.11 UNII
425 {149, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed1a7},
426 {151, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed187},
427 {153, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed18f},
428 {157, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed19f},
429 {159, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed1a7},
430 {161, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed187},
431 {165, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed197},
432
433 // Japan
434 {184, 0x95002ccc, 0x9500491e, 0x9509be55, 0x950c0a0b},
435 {188, 0x95002ccc, 0x95004922, 0x9509be55, 0x950c0a13},
436 {192, 0x95002ccc, 0x95004926, 0x9509be55, 0x950c0a1b},
437 {196, 0x95002ccc, 0x9500492a, 0x9509be55, 0x950c0a23},
438 {208, 0x95002ccc, 0x9500493a, 0x9509be55, 0x950c0a13},
439 {212, 0x95002ccc, 0x9500493e, 0x9509be55, 0x950c0a1b},
440 {216, 0x95002ccc, 0x95004982, 0x9509be55, 0x950c0a23},
441
442 // still lack of MMAC(Japan) ch 34,38,42,46
443};
444UCHAR NUM_OF_2850_CHNL = (sizeof(RF2850RegTable) / sizeof(RTMP_RF_REGS));
445
446FREQUENCY_ITEM FreqItems3020[] =
447{
448 /**************************************************/
449 // ISM : 2.4 to 2.483 GHz //
450 /**************************************************/
451 // 11g
452 /**************************************************/
453 //-CH---N-------R---K-----------
454 {1, 241, 2, 2},
455 {2, 241, 2, 7},
456 {3, 242, 2, 2},
457 {4, 242, 2, 7},
458 {5, 243, 2, 2},
459 {6, 243, 2, 7},
460 {7, 244, 2, 2},
461 {8, 244, 2, 7},
462 {9, 245, 2, 2},
463 {10, 245, 2, 7},
464 {11, 246, 2, 2},
465 {12, 246, 2, 7},
466 {13, 247, 2, 2},
467 {14, 248, 2, 4},
468};
469//2008/07/10:KH Modified to share this variable
470UCHAR NUM_OF_3020_CHNL=(sizeof(FreqItems3020) / sizeof(FREQUENCY_ITEM));
471
472/*
473 ==========================================================================
474 Description:
475 initialize the MLME task and its data structure (queue, spinlock,
476 timer, state machines).
477
478 IRQL = PASSIVE_LEVEL
479
480 Return:
481 always return NDIS_STATUS_SUCCESS
482
483 ==========================================================================
484*/
485NDIS_STATUS MlmeInit(
486 IN PRTMP_ADAPTER pAd)
487{
488 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
489
490 DBGPRINT(RT_DEBUG_TRACE, ("--> MLME Initialize\n"));
491
492 do
493 {
494 Status = MlmeQueueInit(&pAd->Mlme.Queue);
495 if(Status != NDIS_STATUS_SUCCESS)
496 break;
497
498 pAd->Mlme.bRunning = FALSE;
499 NdisAllocateSpinLock(&pAd->Mlme.TaskLock);
500
501#ifdef CONFIG_STA_SUPPORT
502 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
503 {
504 BssTableInit(&pAd->ScanTab);
505
506 // init STA state machines
507 AssocStateMachineInit(pAd, &pAd->Mlme.AssocMachine, pAd->Mlme.AssocFunc);
508 AuthStateMachineInit(pAd, &pAd->Mlme.AuthMachine, pAd->Mlme.AuthFunc);
509 AuthRspStateMachineInit(pAd, &pAd->Mlme.AuthRspMachine, pAd->Mlme.AuthRspFunc);
510 SyncStateMachineInit(pAd, &pAd->Mlme.SyncMachine, pAd->Mlme.SyncFunc);
511 WpaPskStateMachineInit(pAd, &pAd->Mlme.WpaPskMachine, pAd->Mlme.WpaPskFunc);
512 AironetStateMachineInit(pAd, &pAd->Mlme.AironetMachine, pAd->Mlme.AironetFunc);
513
514#ifdef QOS_DLS_SUPPORT
515 DlsStateMachineInit(pAd, &pAd->Mlme.DlsMachine, pAd->Mlme.DlsFunc);
516#endif // QOS_DLS_SUPPORT //
517
518
519 // Since we are using switch/case to implement it, the init is different from the above
520 // state machine init
521 MlmeCntlInit(pAd, &pAd->Mlme.CntlMachine, NULL);
522 }
523#endif // CONFIG_STA_SUPPORT //
524
525
526
527 ActionStateMachineInit(pAd, &pAd->Mlme.ActMachine, pAd->Mlme.ActFunc);
528
529 // Init mlme periodic timer
530 RTMPInitTimer(pAd, &pAd->Mlme.PeriodicTimer, GET_TIMER_FUNCTION(MlmePeriodicExec), pAd, TRUE);
531
532 // Set mlme periodic timer
533 RTMPSetTimer(&pAd->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV);
534
535 // software-based RX Antenna diversity
536 RTMPInitTimer(pAd, &pAd->Mlme.RxAntEvalTimer, GET_TIMER_FUNCTION(AsicRxAntEvalTimeout), pAd, FALSE);
537
538
539#ifdef CONFIG_STA_SUPPORT
540#endif // CONFIG_STA_SUPPORT //
541
542 } while (FALSE);
543
544 DBGPRINT(RT_DEBUG_TRACE, ("<-- MLME Initialize\n"));
545
546 return Status;
547}
548
549/*
550 ==========================================================================
551 Description:
552 main loop of the MLME
553 Pre:
554 Mlme has to be initialized, and there are something inside the queue
555 Note:
556 This function is invoked from MPSetInformation and MPReceive;
557 This task guarantee only one MlmeHandler will run.
558
559 IRQL = DISPATCH_LEVEL
560
561 ==========================================================================
562 */
563VOID MlmeHandler(
564 IN PRTMP_ADAPTER pAd)
565{
566 MLME_QUEUE_ELEM *Elem = NULL;
567
568 // Only accept MLME and Frame from peer side, no other (control/data) frame should
569 // get into this state machine
570
571 NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
572 if(pAd->Mlme.bRunning)
573 {
574 NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
575 return;
576 }
577 else
578 {
579 pAd->Mlme.bRunning = TRUE;
580 }
581 NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
582
583 while (!MlmeQueueEmpty(&pAd->Mlme.Queue))
584 {
585 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MLME_RESET_IN_PROGRESS) ||
586 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) ||
587 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
588 {
589 DBGPRINT(RT_DEBUG_TRACE, ("Device Halted or Removed or MlmeRest, exit MlmeHandler! (queue num = %ld)\n", pAd->Mlme.Queue.Num));
590 break;
591 }
592
593#ifdef RALINK_ATE
594 if(ATE_ON(pAd))
595 {
596 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now in MlmeHandler\n"));
597 break;
598 }
599#endif // RALINK_ATE //
600
601 //From message type, determine which state machine I should drive
602 if (MlmeDequeue(&pAd->Mlme.Queue, &Elem))
603 {
604#ifdef RT2870
605 if (Elem->MsgType == MT2_RESET_CONF)
606 {
607 DBGPRINT_RAW(RT_DEBUG_TRACE, ("!!! reset MLME state machine !!!\n"));
608 MlmeRestartStateMachine(pAd);
609 Elem->Occupied = FALSE;
610 Elem->MsgLen = 0;
611 continue;
612 }
613#endif // RT2870 //
614
615 // if dequeue success
616 switch (Elem->Machine)
617 {
618 // STA state machines
619#ifdef CONFIG_STA_SUPPORT
620 case ASSOC_STATE_MACHINE:
621 StateMachinePerformAction(pAd, &pAd->Mlme.AssocMachine, Elem);
622 break;
623 case AUTH_STATE_MACHINE:
624 StateMachinePerformAction(pAd, &pAd->Mlme.AuthMachine, Elem);
625 break;
626 case AUTH_RSP_STATE_MACHINE:
627 StateMachinePerformAction(pAd, &pAd->Mlme.AuthRspMachine, Elem);
628 break;
629 case SYNC_STATE_MACHINE:
630 StateMachinePerformAction(pAd, &pAd->Mlme.SyncMachine, Elem);
631 break;
632 case MLME_CNTL_STATE_MACHINE:
633 MlmeCntlMachinePerformAction(pAd, &pAd->Mlme.CntlMachine, Elem);
634 break;
635 case WPA_PSK_STATE_MACHINE:
636 StateMachinePerformAction(pAd, &pAd->Mlme.WpaPskMachine, Elem);
637 break;
638#ifdef LEAP_SUPPORT
639 case LEAP_STATE_MACHINE:
640 LeapMachinePerformAction(pAd, &pAd->Mlme.LeapMachine, Elem);
641 break;
642#endif
643 case AIRONET_STATE_MACHINE:
644 StateMachinePerformAction(pAd, &pAd->Mlme.AironetMachine, Elem);
645 break;
646
647#ifdef QOS_DLS_SUPPORT
648 case DLS_STATE_MACHINE:
649 StateMachinePerformAction(pAd, &pAd->Mlme.DlsMachine, Elem);
650 break;
651#endif // QOS_DLS_SUPPORT //
652#endif // CONFIG_STA_SUPPORT //
653
654 case ACTION_STATE_MACHINE:
655 StateMachinePerformAction(pAd, &pAd->Mlme.ActMachine, Elem);
656 break;
657
658
659
660
661 default:
662 DBGPRINT(RT_DEBUG_TRACE, ("ERROR: Illegal machine %ld in MlmeHandler()\n", Elem->Machine));
663 break;
664 } // end of switch
665
666 // free MLME element
667 Elem->Occupied = FALSE;
668 Elem->MsgLen = 0;
669
670 }
671 else {
672 DBGPRINT_ERR(("MlmeHandler: MlmeQueue empty\n"));
673 }
674 }
675
676 NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
677 pAd->Mlme.bRunning = FALSE;
678 NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
679}
680
681/*
682 ==========================================================================
683 Description:
684 Destructor of MLME (Destroy queue, state machine, spin lock and timer)
685 Parameters:
686 Adapter - NIC Adapter pointer
687 Post:
688 The MLME task will no longer work properly
689
690 IRQL = PASSIVE_LEVEL
691
692 ==========================================================================
693 */
694VOID MlmeHalt(
695 IN PRTMP_ADAPTER pAd)
696{
697 BOOLEAN Cancelled;
698#ifdef RT3070
699 UINT32 TxPinCfg = 0x00050F0F;
700#endif // RT3070 //
701
702 DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeHalt\n"));
703
704 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
705 {
706 // disable BEACON generation and other BEACON related hardware timers
707 AsicDisableSync(pAd);
708 }
709
710#ifdef CONFIG_STA_SUPPORT
711 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
712 {
713#ifdef QOS_DLS_SUPPORT
714 UCHAR i;
715#endif // QOS_DLS_SUPPORT //
716 // Cancel pending timers
717 RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled);
718 RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled);
719 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
720 RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled);
721 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled);
722 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
723
724#ifdef QOS_DLS_SUPPORT
725 for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
726 {
727 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &Cancelled);
728 }
729#endif // QOS_DLS_SUPPORT //
730 }
731#endif // CONFIG_STA_SUPPORT //
732
733 RTMPCancelTimer(&pAd->Mlme.PeriodicTimer, &Cancelled);
734 RTMPCancelTimer(&pAd->Mlme.RxAntEvalTimer, &Cancelled);
735
736
737
738 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
739 {
740 // Set LED
741 RTMPSetLED(pAd, LED_HALT);
742 RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, firmware is not done it.
743#ifdef RT2870
744 {
745 LED_CFG_STRUC LedCfg;
746 RTMP_IO_READ32(pAd, LED_CFG, &LedCfg.word);
747 LedCfg.field.LedPolar = 0;
748 LedCfg.field.RLedMode = 0;
749 LedCfg.field.GLedMode = 0;
750 LedCfg.field.YLedMode = 0;
751 RTMP_IO_WRITE32(pAd, LED_CFG, LedCfg.word);
752 }
753#endif // RT2870 //
754#ifdef RT3070
755 //
756 // Turn off LNA_PE
757 //
758 if (IS_RT3070(pAd) || IS_RT3071(pAd))
759 {
760 TxPinCfg &= 0xFFFFF0F0;
761 RTUSBWriteMACRegister(pAd, TX_PIN_CFG, TxPinCfg);
762 }
763#endif // RT3070 //
764 }
765
766 RTMPusecDelay(5000); // 5 msec to gurantee Ant Diversity timer canceled
767
768 MlmeQueueDestroy(&pAd->Mlme.Queue);
769 NdisFreeSpinLock(&pAd->Mlme.TaskLock);
770
771 DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeHalt\n"));
772}
773
774VOID MlmeResetRalinkCounters(
775 IN PRTMP_ADAPTER pAd)
776{
777 pAd->RalinkCounters.LastOneSecRxOkDataCnt = pAd->RalinkCounters.OneSecRxOkDataCnt;
778 // clear all OneSecxxx counters.
779 pAd->RalinkCounters.OneSecBeaconSentCnt = 0;
780 pAd->RalinkCounters.OneSecFalseCCACnt = 0;
781 pAd->RalinkCounters.OneSecRxFcsErrCnt = 0;
782 pAd->RalinkCounters.OneSecRxOkCnt = 0;
783 pAd->RalinkCounters.OneSecTxFailCount = 0;
784 pAd->RalinkCounters.OneSecTxNoRetryOkCount = 0;
785 pAd->RalinkCounters.OneSecTxRetryOkCount = 0;
786 pAd->RalinkCounters.OneSecRxOkDataCnt = 0;
787
788 // TODO: for debug only. to be removed
789 pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BE] = 0;
790 pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BK] = 0;
791 pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VI] = 0;
792 pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VO] = 0;
793 pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_BE] = 0;
794 pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_BK] = 0;
795 pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_VI] = 0;
796 pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_VO] = 0;
797 pAd->RalinkCounters.OneSecTxDoneCount = 0;
798 pAd->RalinkCounters.OneSecRxCount = 0;
799 pAd->RalinkCounters.OneSecTxAggregationCount = 0;
800 pAd->RalinkCounters.OneSecRxAggregationCount = 0;
801
802 return;
803}
804
805unsigned long rx_AMSDU;
806unsigned long rx_Total;
807
808/*
809 ==========================================================================
810 Description:
811 This routine is executed periodically to -
812 1. Decide if it's a right time to turn on PwrMgmt bit of all
813 outgoiing frames
814 2. Calculate ChannelQuality based on statistics of the last
815 period, so that TX rate won't toggling very frequently between a
816 successful TX and a failed TX.
817 3. If the calculated ChannelQuality indicated current connection not
818 healthy, then a ROAMing attempt is tried here.
819
820 IRQL = DISPATCH_LEVEL
821
822 ==========================================================================
823 */
824#define ADHOC_BEACON_LOST_TIME (8*OS_HZ) // 8 sec
825VOID MlmePeriodicExec(
826 IN PVOID SystemSpecific1,
827 IN PVOID FunctionContext,
828 IN PVOID SystemSpecific2,
829 IN PVOID SystemSpecific3)
830{
831 ULONG TxTotalCnt;
832 PRTMP_ADAPTER pAd = (RTMP_ADAPTER *)FunctionContext;
833
834#ifdef CONFIG_STA_SUPPORT
835#endif // CONFIG_STA_SUPPORT //
836
837 // Do nothing if the driver is starting halt state.
838 // This might happen when timer already been fired before cancel timer with mlmehalt
839 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_HALT_IN_PROGRESS |
840 fRTMP_ADAPTER_RADIO_OFF |
841 fRTMP_ADAPTER_RADIO_MEASUREMENT |
842 fRTMP_ADAPTER_RESET_IN_PROGRESS))))
843 return;
844
845 RT28XX_MLME_PRE_SANITY_CHECK(pAd);
846
847#ifdef RALINK_ATE
848 /* Do not show RSSI until "Normal 1 second Mlme PeriodicExec". */
849 if (ATE_ON(pAd))
850 {
851 if (pAd->Mlme.PeriodicRound % MLME_TASK_EXEC_MULTIPLE != (MLME_TASK_EXEC_MULTIPLE - 1))
852 {
853 pAd->Mlme.PeriodicRound ++;
854 return;
855 }
856 }
857#endif // RALINK_ATE //
858
859#ifdef CONFIG_STA_SUPPORT
860 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
861 {
862 // Do nothing if monitor mode is on
863 if (MONITOR_ON(pAd))
864 return;
865
866 if (pAd->Mlme.PeriodicRound & 0x1)
867 {
868 // This is the fix for wifi 11n extension channel overlapping test case. for 2860D
869 if (((pAd->MACVersion & 0xffff) == 0x0101) &&
870 (STA_TGN_WIFI_ON(pAd)) &&
871 (pAd->CommonCfg.IOTestParm.bToggle == FALSE))
872
873 {
874 RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x24Bf);
875 pAd->CommonCfg.IOTestParm.bToggle = TRUE;
876 }
877 else if ((STA_TGN_WIFI_ON(pAd)) &&
878 ((pAd->MACVersion & 0xffff) == 0x0101))
879 {
880 RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x243f);
881 pAd->CommonCfg.IOTestParm.bToggle = FALSE;
882 }
883 }
884 }
885#endif // CONFIG_STA_SUPPORT //
886
887 pAd->bUpdateBcnCntDone = FALSE;
888
889// RECBATimerTimeout(SystemSpecific1,FunctionContext,SystemSpecific2,SystemSpecific3);
890 pAd->Mlme.PeriodicRound ++;
891
892#ifdef RT2870
893 // execute every 100ms, update the Tx FIFO Cnt for update Tx Rate.
894 NICUpdateFifoStaCounters(pAd);
895#endif // RT2870 //
896 // execute every 500ms
897 if ((pAd->Mlme.PeriodicRound % 5 == 0) && RTMPAutoRateSwitchCheck(pAd)/*(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))*/)
898 {
899#ifdef CONFIG_STA_SUPPORT
900 // perform dynamic tx rate switching based on past TX history
901 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
902 {
903 if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
904 )
905 && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)))
906 MlmeDynamicTxRateSwitching(pAd);
907 }
908#endif // CONFIG_STA_SUPPORT //
909 }
910
911 // Normal 1 second Mlme PeriodicExec.
912 if (pAd->Mlme.PeriodicRound %MLME_TASK_EXEC_MULTIPLE == 0)
913 {
914 pAd->Mlme.OneSecPeriodicRound ++;
915
916#ifdef RALINK_ATE
917 if (ATE_ON(pAd))
918 {
919 /* request from Baron : move this routine from later to here */
920 /* for showing Rx error count in ATE RXFRAME */
921 NICUpdateRawCounters(pAd);
922 if (pAd->ate.bRxFer == 1)
923 {
924 pAd->ate.RxTotalCnt += pAd->ate.RxCntPerSec;
925 ate_print(KERN_EMERG "MlmePeriodicExec: Rx packet cnt = %d/%d\n", pAd->ate.RxCntPerSec, pAd->ate.RxTotalCnt);
926 pAd->ate.RxCntPerSec = 0;
927
928 if (pAd->ate.RxAntennaSel == 0)
929 ate_print(KERN_EMERG "MlmePeriodicExec: Rx AvgRssi0=%d, AvgRssi1=%d, AvgRssi2=%d\n\n",
930 pAd->ate.AvgRssi0, pAd->ate.AvgRssi1, pAd->ate.AvgRssi2);
931 else
932 ate_print(KERN_EMERG "MlmePeriodicExec: Rx AvgRssi=%d\n\n", pAd->ate.AvgRssi0);
933 }
934 MlmeResetRalinkCounters(pAd);
935 return;
936 }
937#endif // RALINK_ATE //
938
939
940 if (rx_Total)
941 {
942
943 // reset counters
944 rx_AMSDU = 0;
945 rx_Total = 0;
946 }
947
948 //ORIBATimerTimeout(pAd);
949
950 // Media status changed, report to NDIS
951 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE))
952 {
953 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE);
954 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
955 {
956 pAd->IndicateMediaState = NdisMediaStateConnected;
957 RTMP_IndicateMediaState(pAd);
958
959 }
960 else
961 {
962 pAd->IndicateMediaState = NdisMediaStateDisconnected;
963 RTMP_IndicateMediaState(pAd);
964 }
965 }
966
967 NdisGetSystemUpTime(&pAd->Mlme.Now32);
968
969 // add the most up-to-date h/w raw counters into software variable, so that
970 // the dynamic tuning mechanism below are based on most up-to-date information
971 NICUpdateRawCounters(pAd);
972
973#ifdef RT2870
974 RT2870_WatchDog(pAd);
975#endif // RT2870 //
976
977#ifdef DOT11_N_SUPPORT
978 // Need statistics after read counter. So put after NICUpdateRawCounters
979 ORIBATimerTimeout(pAd);
980#endif // DOT11_N_SUPPORT //
981
982 // The time period for checking antenna is according to traffic
983 {
984 if (pAd->Mlme.bEnableAutoAntennaCheck)
985 {
986 TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
987 pAd->RalinkCounters.OneSecTxRetryOkCount +
988 pAd->RalinkCounters.OneSecTxFailCount;
989
990 // dynamic adjust antenna evaluation period according to the traffic
991 if (TxTotalCnt > 50)
992 {
993 if (pAd->Mlme.OneSecPeriodicRound % 10 == 0)
994 {
995 AsicEvaluateRxAnt(pAd);
996 }
997 }
998 else
999 {
1000 if (pAd->Mlme.OneSecPeriodicRound % 3 == 0)
1001 {
1002 AsicEvaluateRxAnt(pAd);
1003 }
1004 }
1005 }
1006 }
1007
1008#ifdef CONFIG_STA_SUPPORT
1009 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1010 STAMlmePeriodicExec(pAd);
1011#endif // CONFIG_STA_SUPPORT //
1012
1013 MlmeResetRalinkCounters(pAd);
1014
1015#ifdef CONFIG_STA_SUPPORT
1016 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1017 {
1018 {
1019 // When Adhoc beacon is enabled and RTS/CTS is enabled, there is a chance that hardware MAC FSM will run into a deadlock
1020 // and sending CTS-to-self over and over.
1021 // Software Patch Solution:
1022 // 1. Polling debug state register 0x10F4 every one second.
1023 // 2. If in 0x10F4 the ((bit29==1) && (bit7==1)) OR ((bit29==1) && (bit5==1)), it means the deadlock has occurred.
1024 // 3. If the deadlock occurred, reset MAC/BBP by setting 0x1004 to 0x0001 for a while then setting it back to 0x000C again.
1025
1026 UINT32 MacReg = 0;
1027
1028 RTMP_IO_READ32(pAd, 0x10F4, &MacReg);
1029 if (((MacReg & 0x20000000) && (MacReg & 0x80)) || ((MacReg & 0x20000000) && (MacReg & 0x20)))
1030 {
1031 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1);
1032 RTMPusecDelay(1);
1033 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xC);
1034
1035 DBGPRINT(RT_DEBUG_WARN,("Warning, MAC specific condition occurs \n"));
1036 }
1037 }
1038 }
1039#endif // CONFIG_STA_SUPPORT //
1040
1041 RT28XX_MLME_HANDLER(pAd);
1042 }
1043
1044
1045 pAd->bUpdateBcnCntDone = FALSE;
1046}
1047
1048#ifdef CONFIG_STA_SUPPORT
1049VOID STAMlmePeriodicExec(
1050 PRTMP_ADAPTER pAd)
1051{
1052 ULONG TxTotalCnt;
1053 int i;
1054
1055//
1056// We return here in ATE mode, because the statistics
1057// that ATE needs are not collected via this routine.
1058//
1059#ifdef RALINK_ATE
1060 // It is supposed that we will never reach here in ATE mode.
1061 ASSERT(!(ATE_ON(pAd)));
1062 if (ATE_ON(pAd))
1063 return;
1064#endif // RALINK_ATE //
1065
1066#ifdef WPA_SUPPLICANT_SUPPORT
1067 if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)
1068#endif // WPA_SUPPLICANT_SUPPORT //
1069 {
1070 // WPA MIC error should block association attempt for 60 seconds
1071 if (pAd->StaCfg.bBlockAssoc && (pAd->StaCfg.LastMicErrorTime + (60 * OS_HZ) < pAd->Mlme.Now32))
1072 pAd->StaCfg.bBlockAssoc = FALSE;
1073 }
1074
1075 if ((pAd->PreMediaState != pAd->IndicateMediaState) && (pAd->CommonCfg.bWirelessEvent))
1076 {
1077 if (pAd->IndicateMediaState == NdisMediaStateConnected)
1078 {
1079 RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1080 }
1081 pAd->PreMediaState = pAd->IndicateMediaState;
1082 }
1083
1084
1085
1086
1087 AsicStaBbpTuning(pAd);
1088
1089 TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
1090 pAd->RalinkCounters.OneSecTxRetryOkCount +
1091 pAd->RalinkCounters.OneSecTxFailCount;
1092
1093 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1094 {
1095 // update channel quality for Roaming and UI LinkQuality display
1096 MlmeCalculateChannelQuality(pAd, pAd->Mlme.Now32);
1097 }
1098
1099 // must be AFTER MlmeDynamicTxRateSwitching() because it needs to know if
1100 // Radio is currently in noisy environment
1101 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1102 AsicAdjustTxPower(pAd);
1103
1104 if (INFRA_ON(pAd))
1105 {
1106#ifdef QOS_DLS_SUPPORT
1107 // Check DLS time out, then tear down those session
1108 RTMPCheckDLSTimeOut(pAd);
1109#endif // QOS_DLS_SUPPORT //
1110
1111 // Is PSM bit consistent with user power management policy?
1112 // This is the only place that will set PSM bit ON.
1113 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
1114 MlmeCheckPsmChange(pAd, pAd->Mlme.Now32);
1115
1116 pAd->RalinkCounters.LastOneSecTotalTxCount = TxTotalCnt;
1117
1118 if ((pAd->StaCfg.LastBeaconRxTime + 1*OS_HZ < pAd->Mlme.Now32) &&
1119 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) &&
1120 ((TxTotalCnt + pAd->RalinkCounters.OneSecRxOkCnt < 600)))
1121 {
1122 RTMPSetAGCInitValue(pAd, BW_20);
1123 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. restore R66 to the low bound(%d) \n", (0x2E + GET_LNA_GAIN(pAd))));
1124 }
1125
1126 //if ((pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) &&
1127 // (pAd->RalinkCounters.OneSecTxRetryOkCount == 0))
1128 {
1129 if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable)
1130 {
1131 // When APSD is enabled, the period changes as 20 sec
1132 if ((pAd->Mlme.OneSecPeriodicRound % 20) == 8)
1133 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
1134 }
1135 else
1136 {
1137 // Send out a NULL frame every 10 sec to inform AP that STA is still alive (Avoid being age out)
1138 if ((pAd->Mlme.OneSecPeriodicRound % 10) == 8)
1139 {
1140 if (pAd->CommonCfg.bWmmCapable)
1141 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
1142 else
1143 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE);
1144 }
1145 }
1146 }
1147
1148 if (CQI_IS_DEAD(pAd->Mlme.ChannelQuality))
1149 {
1150 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. Dead CQI. Auto Recovery attempt #%ld\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount));
1151 pAd->StaCfg.CCXAdjacentAPReportFlag = TRUE;
1152 pAd->StaCfg.CCXAdjacentAPLinkDownTime = pAd->StaCfg.LastBeaconRxTime;
1153
1154 // Lost AP, send disconnect & link down event
1155 LinkDown(pAd, FALSE);
1156
1157#ifdef WPA_SUPPLICANT_SUPPORT
1158#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
1159 if (pAd->StaCfg.WpaSupplicantUP)
1160 {
1161 union iwreq_data wrqu;
1162 //send disassociate event to wpa_supplicant
1163 memset(&wrqu, 0, sizeof(wrqu));
1164 wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
1165 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
1166 }
1167#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1168#endif // WPA_SUPPLICANT_SUPPORT //
1169
1170#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
1171 {
1172 union iwreq_data wrqu;
1173 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
1174 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
1175 }
1176#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1177
1178 // RTMPPatchMacBbpBug(pAd);
1179 MlmeAutoReconnectLastSSID(pAd);
1180 }
1181 else if (CQI_IS_BAD(pAd->Mlme.ChannelQuality))
1182 {
1183 pAd->RalinkCounters.BadCQIAutoRecoveryCount ++;
1184 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Bad CQI. Auto Recovery attempt #%ld\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount));
1185 MlmeAutoReconnectLastSSID(pAd);
1186 }
1187
1188 // Add auto seamless roaming
1189 if (pAd->StaCfg.bFastRoaming)
1190 {
1191 SHORT dBmToRoam = (SHORT)pAd->StaCfg.dBmToRoam;
1192
1193 DBGPRINT(RT_DEBUG_TRACE, ("Rssi=%d, dBmToRoam=%d\n", RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2), (CHAR)dBmToRoam));
1194
1195 if (RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2) <= (CHAR)dBmToRoam)
1196 {
1197 MlmeCheckForFastRoaming(pAd, pAd->Mlme.Now32);
1198 }
1199 }
1200 }
1201 else if (ADHOC_ON(pAd))
1202 {
1203 //radar detect
1204 if ((pAd->CommonCfg.Channel > 14)
1205 && (pAd->CommonCfg.bIEEE80211H == 1)
1206 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
1207 {
1208 RadarDetectPeriodic(pAd);
1209 }
1210
1211 // If all peers leave, and this STA becomes the last one in this IBSS, then change MediaState
1212 // to DISCONNECTED. But still holding this IBSS (i.e. sending BEACON) so that other STAs can
1213 // join later.
1214 if ((pAd->StaCfg.LastBeaconRxTime + ADHOC_BEACON_LOST_TIME < pAd->Mlme.Now32) &&
1215 OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1216 {
1217 MLME_START_REQ_STRUCT StartReq;
1218
1219 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - excessive BEACON lost, last STA in this IBSS, MediaState=Disconnected\n"));
1220 LinkDown(pAd, FALSE);
1221
1222 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
1223 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
1224 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
1225 }
1226
1227 for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
1228 {
1229 MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[i];
1230
1231 if (pEntry->ValidAsCLI == FALSE)
1232 continue;
1233
1234 if (pEntry->LastBeaconRxTime + ADHOC_BEACON_LOST_TIME < pAd->Mlme.Now32)
1235 MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
1236 }
1237 }
1238 else // no INFRA nor ADHOC connection
1239 {
1240
1241 if (pAd->StaCfg.bScanReqIsFromWebUI &&
1242 ((pAd->StaCfg.LastScanTime + 30 * OS_HZ) > pAd->Mlme.Now32))
1243 goto SKIP_AUTO_SCAN_CONN;
1244 else
1245 pAd->StaCfg.bScanReqIsFromWebUI = FALSE;
1246
1247 if ((pAd->StaCfg.bAutoReconnect == TRUE)
1248 && RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)
1249 && (MlmeValidateSSID(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen) == TRUE))
1250 {
1251 if ((pAd->ScanTab.BssNr==0) && (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE))
1252 {
1253 MLME_SCAN_REQ_STRUCT ScanReq;
1254
1255 if ((pAd->StaCfg.LastScanTime + 10 * OS_HZ) < pAd->Mlme.Now32)
1256 {
1257 DBGPRINT(RT_DEBUG_TRACE, ("STAMlmePeriodicExec():CNTL - ScanTab.BssNr==0, start a new ACTIVE scan SSID[%s]\n", pAd->MlmeAux.AutoReconnectSsid));
1258 ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen, BSS_ANY, SCAN_ACTIVE);
1259 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
1260 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
1261 // Reset Missed scan number
1262 pAd->StaCfg.LastScanTime = pAd->Mlme.Now32;
1263 }
1264 else if (pAd->StaCfg.BssType == BSS_ADHOC) // Quit the forever scan when in a very clean room
1265 MlmeAutoReconnectLastSSID(pAd);
1266 }
1267 else if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
1268 {
1269 if ((pAd->Mlme.OneSecPeriodicRound % 7) == 0)
1270 {
1271 MlmeAutoScan(pAd);
1272 pAd->StaCfg.LastScanTime = pAd->Mlme.Now32;
1273 }
1274 else
1275 {
1276#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
1277 if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
1278 {
1279 if ((pAd->Mlme.OneSecPeriodicRound % 5) == 1)
1280 MlmeAutoReconnectLastSSID(pAd);
1281 }
1282 else
1283#endif // CARRIER_DETECTION_SUPPORT //
1284 MlmeAutoReconnectLastSSID(pAd);
1285 }
1286 }
1287 }
1288 }
1289
1290SKIP_AUTO_SCAN_CONN:
1291
1292#ifdef DOT11_N_SUPPORT
1293 if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap !=0) && (pAd->MacTab.fAnyBASession == FALSE))
1294 {
1295 pAd->MacTab.fAnyBASession = TRUE;
1296 AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, FALSE, FALSE);
1297 }
1298 else if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap ==0) && (pAd->MacTab.fAnyBASession == TRUE))
1299 {
1300 pAd->MacTab.fAnyBASession = FALSE;
1301 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
1302 }
1303#endif // DOT11_N_SUPPORT //
1304
1305
1306#ifdef DOT11_N_SUPPORT
1307#ifdef DOT11N_DRAFT3
1308 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SCAN_2040))
1309 TriEventCounterMaintenance(pAd);
1310#endif // DOT11N_DRAFT3 //
1311#endif // DOT11_N_SUPPORT //
1312
1313 return;
1314}
1315
1316// Link down report
1317VOID LinkDownExec(
1318 IN PVOID SystemSpecific1,
1319 IN PVOID FunctionContext,
1320 IN PVOID SystemSpecific2,
1321 IN PVOID SystemSpecific3)
1322{
1323
1324 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
1325
1326 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1327 RTMP_IndicateMediaState(pAd);
1328 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1329}
1330
1331// IRQL = DISPATCH_LEVEL
1332VOID MlmeAutoScan(
1333 IN PRTMP_ADAPTER pAd)
1334{
1335 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1336 if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
1337 {
1338 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Driver auto scan\n"));
1339 MlmeEnqueue(pAd,
1340 MLME_CNTL_STATE_MACHINE,
1341 OID_802_11_BSSID_LIST_SCAN,
1342 0,
1343 NULL);
1344 RT28XX_MLME_HANDLER(pAd);
1345 }
1346}
1347
1348// IRQL = DISPATCH_LEVEL
1349VOID MlmeAutoReconnectLastSSID(
1350 IN PRTMP_ADAPTER pAd)
1351{
1352
1353
1354 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1355 if ((pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
1356 (MlmeValidateSSID(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen) == TRUE))
1357 {
1358 NDIS_802_11_SSID OidSsid;
1359 OidSsid.SsidLength = pAd->MlmeAux.AutoReconnectSsidLen;
1360 NdisMoveMemory(OidSsid.Ssid, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
1361
1362 DBGPRINT(RT_DEBUG_TRACE, ("Driver auto reconnect to last OID_802_11_SSID setting - %s, len - %d\n", pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen));
1363 MlmeEnqueue(pAd,
1364 MLME_CNTL_STATE_MACHINE,
1365 OID_802_11_SSID,
1366 sizeof(NDIS_802_11_SSID),
1367 &OidSsid);
1368 RT28XX_MLME_HANDLER(pAd);
1369 }
1370}
1371#endif // CONFIG_STA_SUPPORT //
1372
1373/*
1374 ==========================================================================
1375 Validate SSID for connection try and rescan purpose
1376 Valid SSID will have visible chars only.
1377 The valid length is from 0 to 32.
1378 IRQL = DISPATCH_LEVEL
1379 ==========================================================================
1380 */
1381BOOLEAN MlmeValidateSSID(
1382 IN PUCHAR pSsid,
1383 IN UCHAR SsidLen)
1384{
1385 int index;
1386
1387 if (SsidLen > MAX_LEN_OF_SSID)
1388 return (FALSE);
1389
1390 // Check each character value
1391 for (index = 0; index < SsidLen; index++)
1392 {
1393 if (pSsid[index] < 0x20)
1394 return (FALSE);
1395 }
1396
1397 // All checked
1398 return (TRUE);
1399}
1400
1401VOID MlmeSelectTxRateTable(
1402 IN PRTMP_ADAPTER pAd,
1403 IN PMAC_TABLE_ENTRY pEntry,
1404 IN PUCHAR *ppTable,
1405 IN PUCHAR pTableSize,
1406 IN PUCHAR pInitTxRateIdx)
1407{
1408 do
1409 {
1410 // decide the rate table for tuning
1411 if (pAd->CommonCfg.TxRateTableSize > 0)
1412 {
1413 *ppTable = RateSwitchTable;
1414 *pTableSize = RateSwitchTable[0];
1415 *pInitTxRateIdx = RateSwitchTable[1];
1416
1417 break;
1418 }
1419
1420#ifdef CONFIG_STA_SUPPORT
1421 if ((pAd->OpMode == OPMODE_STA) && ADHOC_ON(pAd))
1422 {
1423#ifdef DOT11_N_SUPPORT
1424 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) &&
1425 (pEntry->HTCapability.MCSSet[0] == 0xff) &&
1426 ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
1427 {// 11N 1S Adhoc
1428 *ppTable = RateSwitchTable11N1S;
1429 *pTableSize = RateSwitchTable11N1S[0];
1430 *pInitTxRateIdx = RateSwitchTable11N1S[1];
1431
1432 }
1433 else if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) &&
1434 (pEntry->HTCapability.MCSSet[0] == 0xff) &&
1435 (pEntry->HTCapability.MCSSet[1] == 0xff) &&
1436 (pAd->Antenna.field.TxPath == 2))
1437 {// 11N 2S Adhoc
1438 if (pAd->LatchRfRegs.Channel <= 14)
1439 {
1440 *ppTable = RateSwitchTable11N2S;
1441 *pTableSize = RateSwitchTable11N2S[0];
1442 *pInitTxRateIdx = RateSwitchTable11N2S[1];
1443 }
1444 else
1445 {
1446 *ppTable = RateSwitchTable11N2SForABand;
1447 *pTableSize = RateSwitchTable11N2SForABand[0];
1448 *pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
1449 }
1450
1451 }
1452 else
1453#endif // DOT11_N_SUPPORT //
1454 if ((pEntry->RateLen == 4)
1455#ifdef DOT11_N_SUPPORT
1456 && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
1457#endif // DOT11_N_SUPPORT //
1458 )
1459 {
1460 *ppTable = RateSwitchTable11B;
1461 *pTableSize = RateSwitchTable11B[0];
1462 *pInitTxRateIdx = RateSwitchTable11B[1];
1463
1464 }
1465 else if (pAd->LatchRfRegs.Channel <= 14)
1466 {
1467 *ppTable = RateSwitchTable11BG;
1468 *pTableSize = RateSwitchTable11BG[0];
1469 *pInitTxRateIdx = RateSwitchTable11BG[1];
1470
1471 }
1472 else
1473 {
1474 *ppTable = RateSwitchTable11G;
1475 *pTableSize = RateSwitchTable11G[0];
1476 *pInitTxRateIdx = RateSwitchTable11G[1];
1477
1478 }
1479 break;
1480 }
1481#endif // CONFIG_STA_SUPPORT //
1482
1483#ifdef DOT11_N_SUPPORT
1484 //if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 12) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&
1485 // ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
1486 if ((pEntry->RateLen == 12) && (pEntry->HTCapability.MCSSet[0] == 0xff) &&
1487 ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1)))
1488 {// 11BGN 1S AP
1489 *ppTable = RateSwitchTable11BGN1S;
1490 *pTableSize = RateSwitchTable11BGN1S[0];
1491 *pInitTxRateIdx = RateSwitchTable11BGN1S[1];
1492
1493 break;
1494 }
1495
1496 //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 12) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&
1497 // (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2))
1498 if ((pEntry->RateLen == 12) && (pEntry->HTCapability.MCSSet[0] == 0xff) &&
1499 (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2))
1500 {// 11BGN 2S AP
1501 if (pAd->LatchRfRegs.Channel <= 14)
1502 {
1503 *ppTable = RateSwitchTable11BGN2S;
1504 *pTableSize = RateSwitchTable11BGN2S[0];
1505 *pInitTxRateIdx = RateSwitchTable11BGN2S[1];
1506
1507 }
1508 else
1509 {
1510 *ppTable = RateSwitchTable11BGN2SForABand;
1511 *pTableSize = RateSwitchTable11BGN2SForABand[0];
1512 *pInitTxRateIdx = RateSwitchTable11BGN2SForABand[1];
1513
1514 }
1515 break;
1516 }
1517
1518 //else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
1519 if ((pEntry->HTCapability.MCSSet[0] == 0xff) && ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1)))
1520 {// 11N 1S AP
1521 *ppTable = RateSwitchTable11N1S;
1522 *pTableSize = RateSwitchTable11N1S[0];
1523 *pInitTxRateIdx = RateSwitchTable11N1S[1];
1524
1525 break;
1526 }
1527
1528 //else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2))
1529 if ((pEntry->HTCapability.MCSSet[0] == 0xff) && (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2))
1530 {// 11N 2S AP
1531 if (pAd->LatchRfRegs.Channel <= 14)
1532 {
1533 *ppTable = RateSwitchTable11N2S;
1534 *pTableSize = RateSwitchTable11N2S[0];
1535 *pInitTxRateIdx = RateSwitchTable11N2S[1];
1536 }
1537 else
1538 {
1539 *ppTable = RateSwitchTable11N2SForABand;
1540 *pTableSize = RateSwitchTable11N2SForABand[0];
1541 *pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
1542 }
1543
1544 break;
1545 }
1546#endif // DOT11_N_SUPPORT //
1547 //else if ((pAd->StaActive.SupRateLen == 4) && (pAd->StaActive.ExtRateLen == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
1548 if ((pEntry->RateLen == 4)
1549#ifdef DOT11_N_SUPPORT
1550//Iverson mark for Adhoc b mode,sta will use rate 54 Mbps when connect with sta b/g/n mode
1551// && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
1552#endif // DOT11_N_SUPPORT //
1553 )
1554 {// B only AP
1555 *ppTable = RateSwitchTable11B;
1556 *pTableSize = RateSwitchTable11B[0];
1557 *pInitTxRateIdx = RateSwitchTable11B[1];
1558
1559 break;
1560 }
1561
1562 //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen > 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
1563 if ((pEntry->RateLen > 8)
1564#ifdef DOT11_N_SUPPORT
1565 && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
1566#endif // DOT11_N_SUPPORT //
1567 )
1568 {// B/G mixed AP
1569 *ppTable = RateSwitchTable11BG;
1570 *pTableSize = RateSwitchTable11BG[0];
1571 *pInitTxRateIdx = RateSwitchTable11BG[1];
1572
1573 break;
1574 }
1575
1576 //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
1577 if ((pEntry->RateLen == 8)
1578#ifdef DOT11_N_SUPPORT
1579 && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
1580#endif // DOT11_N_SUPPORT //
1581 )
1582 {// G only AP
1583 *ppTable = RateSwitchTable11G;
1584 *pTableSize = RateSwitchTable11G[0];
1585 *pInitTxRateIdx = RateSwitchTable11G[1];
1586
1587 break;
1588 }
1589#ifdef DOT11_N_SUPPORT
1590#endif // DOT11_N_SUPPORT //
1591
1592#ifdef CONFIG_STA_SUPPORT
1593 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1594 {
1595#ifdef DOT11_N_SUPPORT
1596 //else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
1597 if ((pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0))
1598#endif // DOT11_N_SUPPORT //
1599 { // Legacy mode
1600 if (pAd->CommonCfg.MaxTxRate <= RATE_11)
1601 {
1602 *ppTable = RateSwitchTable11B;
1603 *pTableSize = RateSwitchTable11B[0];
1604 *pInitTxRateIdx = RateSwitchTable11B[1];
1605 }
1606 else if ((pAd->CommonCfg.MaxTxRate > RATE_11) && (pAd->CommonCfg.MinTxRate > RATE_11))
1607 {
1608 *ppTable = RateSwitchTable11G;
1609 *pTableSize = RateSwitchTable11G[0];
1610 *pInitTxRateIdx = RateSwitchTable11G[1];
1611
1612 }
1613 else
1614 {
1615 *ppTable = RateSwitchTable11BG;
1616 *pTableSize = RateSwitchTable11BG[0];
1617 *pInitTxRateIdx = RateSwitchTable11BG[1];
1618 }
1619 break;
1620 }
1621#ifdef DOT11_N_SUPPORT
1622 if (pAd->LatchRfRegs.Channel <= 14)
1623 {
1624 if (pAd->CommonCfg.TxStream == 1)
1625 {
1626 *ppTable = RateSwitchTable11N1S;
1627 *pTableSize = RateSwitchTable11N1S[0];
1628 *pInitTxRateIdx = RateSwitchTable11N1S[1];
1629 DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n"));
1630 }
1631 else
1632 {
1633 *ppTable = RateSwitchTable11N2S;
1634 *pTableSize = RateSwitchTable11N2S[0];
1635 *pInitTxRateIdx = RateSwitchTable11N2S[1];
1636 DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n"));
1637 }
1638 }
1639 else
1640 {
1641 if (pAd->CommonCfg.TxStream == 1)
1642 {
1643 *ppTable = RateSwitchTable11N1S;
1644 *pTableSize = RateSwitchTable11N1S[0];
1645 *pInitTxRateIdx = RateSwitchTable11N1S[1];
1646 DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n"));
1647 }
1648 else
1649 {
1650 *ppTable = RateSwitchTable11N2SForABand;
1651 *pTableSize = RateSwitchTable11N2SForABand[0];
1652 *pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
1653 DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n"));
1654 }
1655 }
1656#endif // DOT11_N_SUPPORT //
1657 DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode (SupRateLen=%d, ExtRateLen=%d, MCSSet[0]=0x%x, MCSSet[1]=0x%x)\n",
1658 pAd->StaActive.SupRateLen, pAd->StaActive.ExtRateLen, pAd->StaActive.SupportedPhyInfo.MCSSet[0], pAd->StaActive.SupportedPhyInfo.MCSSet[1]));
1659 }
1660#endif // CONFIG_STA_SUPPORT //
1661 } while(FALSE);
1662}
1663
1664#ifdef CONFIG_STA_SUPPORT
1665/*
1666 ==========================================================================
1667 Description:
1668 This routine checks if there're other APs out there capable for
1669 roaming. Caller should call this routine only when Link up in INFRA mode
1670 and channel quality is below CQI_GOOD_THRESHOLD.
1671
1672 IRQL = DISPATCH_LEVEL
1673
1674 Output:
1675 ==========================================================================
1676 */
1677VOID MlmeCheckForRoaming(
1678 IN PRTMP_ADAPTER pAd,
1679 IN ULONG Now32)
1680{
1681 USHORT i;
1682 BSS_TABLE *pRoamTab = &pAd->MlmeAux.RoamTab;
1683 BSS_ENTRY *pBss;
1684
1685 DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForRoaming\n"));
1686 // put all roaming candidates into RoamTab, and sort in RSSI order
1687 BssTableInit(pRoamTab);
1688 for (i = 0; i < pAd->ScanTab.BssNr; i++)
1689 {
1690 pBss = &pAd->ScanTab.BssEntry[i];
1691
1692 if ((pBss->LastBeaconRxTime + BEACON_LOST_TIME) < Now32)
1693 continue; // AP disappear
1694 if (pBss->Rssi <= RSSI_THRESHOLD_FOR_ROAMING)
1695 continue; // RSSI too weak. forget it.
1696 if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid))
1697 continue; // skip current AP
1698 if (pBss->Rssi < (pAd->StaCfg.RssiSample.LastRssi0 + RSSI_DELTA))
1699 continue; // only AP with stronger RSSI is eligible for roaming
1700
1701 // AP passing all above rules is put into roaming candidate table
1702 NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY));
1703 pRoamTab->BssNr += 1;
1704 }
1705
1706 if (pRoamTab->BssNr > 0)
1707 {
1708 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1709 if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
1710 {
1711 pAd->RalinkCounters.PoorCQIRoamingCount ++;
1712 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount));
1713 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL);
1714 RT28XX_MLME_HANDLER(pAd);
1715 }
1716 }
1717 DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForRoaming(# of candidate= %d)\n",pRoamTab->BssNr));
1718}
1719
1720/*
1721 ==========================================================================
1722 Description:
1723 This routine checks if there're other APs out there capable for
1724 roaming. Caller should call this routine only when link up in INFRA mode
1725 and channel quality is below CQI_GOOD_THRESHOLD.
1726
1727 IRQL = DISPATCH_LEVEL
1728
1729 Output:
1730 ==========================================================================
1731 */
1732VOID MlmeCheckForFastRoaming(
1733 IN PRTMP_ADAPTER pAd,
1734 IN ULONG Now)
1735{
1736 USHORT i;
1737 BSS_TABLE *pRoamTab = &pAd->MlmeAux.RoamTab;
1738 BSS_ENTRY *pBss;
1739
1740 DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForFastRoaming\n"));
1741 // put all roaming candidates into RoamTab, and sort in RSSI order
1742 BssTableInit(pRoamTab);
1743 for (i = 0; i < pAd->ScanTab.BssNr; i++)
1744 {
1745 pBss = &pAd->ScanTab.BssEntry[i];
1746
1747 if ((pBss->Rssi <= -50) && (pBss->Channel == pAd->CommonCfg.Channel))
1748 continue; // RSSI too weak. forget it.
1749 if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid))
1750 continue; // skip current AP
1751 if (!SSID_EQUAL(pBss->Ssid, pBss->SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen))
1752 continue; // skip different SSID
1753 if (pBss->Rssi < (RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2) + RSSI_DELTA))
1754 continue; // skip AP without better RSSI
1755
1756 DBGPRINT(RT_DEBUG_TRACE, ("LastRssi0 = %d, pBss->Rssi = %d\n", RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2), pBss->Rssi));
1757 // AP passing all above rules is put into roaming candidate table
1758 NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY));
1759 pRoamTab->BssNr += 1;
1760 }
1761
1762 if (pRoamTab->BssNr > 0)
1763 {
1764 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1765 if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
1766 {
1767 pAd->RalinkCounters.PoorCQIRoamingCount ++;
1768 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount));
1769 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL);
1770 RT28XX_MLME_HANDLER(pAd);
1771 }
1772 }
1773 // Maybe site survey required
1774 else
1775 {
1776 if ((pAd->StaCfg.LastScanTime + 10 * 1000) < Now)
1777 {
1778 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1779 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming, No eligable entry, try new scan!\n"));
1780 pAd->StaCfg.ScanCnt = 2;
1781 pAd->StaCfg.LastScanTime = Now;
1782 MlmeAutoScan(pAd);
1783 }
1784 }
1785
1786 DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForFastRoaming (BssNr=%d)\n", pRoamTab->BssNr));
1787}
1788
1789/*
1790 ==========================================================================
1791 Description:
1792 This routine calculates TxPER, RxPER of the past N-sec period. And
1793 according to the calculation result, ChannelQuality is calculated here
1794 to decide if current AP is still doing the job.
1795
1796 If ChannelQuality is not good, a ROAMing attempt may be tried later.
1797 Output:
1798 StaCfg.ChannelQuality - 0..100
1799
1800 IRQL = DISPATCH_LEVEL
1801
1802 NOTE: This routine decide channle quality based on RX CRC error ratio.
1803 Caller should make sure a function call to NICUpdateRawCounters(pAd)
1804 is performed right before this routine, so that this routine can decide
1805 channel quality based on the most up-to-date information
1806 ==========================================================================
1807 */
1808VOID MlmeCalculateChannelQuality(
1809 IN PRTMP_ADAPTER pAd,
1810 IN ULONG Now32)
1811{
1812 ULONG TxOkCnt, TxCnt, TxPER, TxPRR;
1813 ULONG RxCnt, RxPER;
1814 UCHAR NorRssi;
1815 CHAR MaxRssi;
1816 ULONG BeaconLostTime = BEACON_LOST_TIME;
1817
1818#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
1819 // longer beacon lost time when carrier detection enabled
1820 if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
1821 {
1822 BeaconLostTime = BEACON_LOST_TIME + BEACON_LOST_TIME/2;
1823 }
1824#endif // CARRIER_DETECTION_SUPPORT //
1825
1826 MaxRssi = RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2);
1827
1828 //
1829 // calculate TX packet error ratio and TX retry ratio - if too few TX samples, skip TX related statistics
1830 //
1831 TxOkCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount + pAd->RalinkCounters.OneSecTxRetryOkCount;
1832 TxCnt = TxOkCnt + pAd->RalinkCounters.OneSecTxFailCount;
1833 if (TxCnt < 5)
1834 {
1835 TxPER = 0;
1836 TxPRR = 0;
1837 }
1838 else
1839 {
1840 TxPER = (pAd->RalinkCounters.OneSecTxFailCount * 100) / TxCnt;
1841 TxPRR = ((TxCnt - pAd->RalinkCounters.OneSecTxNoRetryOkCount) * 100) / TxCnt;
1842 }
1843
1844 //
1845 // calculate RX PER - don't take RxPER into consideration if too few sample
1846 //
1847 RxCnt = pAd->RalinkCounters.OneSecRxOkCnt + pAd->RalinkCounters.OneSecRxFcsErrCnt;
1848 if (RxCnt < 5)
1849 RxPER = 0;
1850 else
1851 RxPER = (pAd->RalinkCounters.OneSecRxFcsErrCnt * 100) / RxCnt;
1852
1853 //
1854 // decide ChannelQuality based on: 1)last BEACON received time, 2)last RSSI, 3)TxPER, and 4)RxPER
1855 //
1856 if (INFRA_ON(pAd) &&
1857 (pAd->RalinkCounters.OneSecTxNoRetryOkCount < 2) && // no heavy traffic
1858 (pAd->StaCfg.LastBeaconRxTime + BeaconLostTime < Now32))
1859 {
1860 DBGPRINT(RT_DEBUG_TRACE, ("BEACON lost > %ld msec with TxOkCnt=%ld -> CQI=0\n", BeaconLostTime, TxOkCnt));
1861 pAd->Mlme.ChannelQuality = 0;
1862 }
1863 else
1864 {
1865 // Normalize Rssi
1866 if (MaxRssi > -40)
1867 NorRssi = 100;
1868 else if (MaxRssi < -90)
1869 NorRssi = 0;
1870 else
1871 NorRssi = (MaxRssi + 90) * 2;
1872
1873 // ChannelQuality = W1*RSSI + W2*TxPRR + W3*RxPER (RSSI 0..100), (TxPER 100..0), (RxPER 100..0)
1874 pAd->Mlme.ChannelQuality = (RSSI_WEIGHTING * NorRssi +
1875 TX_WEIGHTING * (100 - TxPRR) +
1876 RX_WEIGHTING* (100 - RxPER)) / 100;
1877 if (pAd->Mlme.ChannelQuality >= 100)
1878 pAd->Mlme.ChannelQuality = 100;
1879 }
1880
1881}
1882
1883VOID MlmeSetTxRate(
1884 IN PRTMP_ADAPTER pAd,
1885 IN PMAC_TABLE_ENTRY pEntry,
1886 IN PRTMP_TX_RATE_SWITCH pTxRate)
1887{
1888 UCHAR MaxMode = MODE_OFDM;
1889
1890#ifdef DOT11_N_SUPPORT
1891 MaxMode = MODE_HTGREENFIELD;
1892
1893 if (pTxRate->STBC && (pAd->StaCfg.MaxHTPhyMode.field.STBC) && (pAd->Antenna.field.TxPath == 2))
1894 pAd->StaCfg.HTPhyMode.field.STBC = STBC_USE;
1895 else
1896#endif // DOT11_N_SUPPORT //
1897 pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;
1898
1899 if (pTxRate->CurrMCS < MCS_AUTO)
1900 pAd->StaCfg.HTPhyMode.field.MCS = pTxRate->CurrMCS;
1901
1902 if (pAd->StaCfg.HTPhyMode.field.MCS > 7)
1903 pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;
1904
1905 if (ADHOC_ON(pAd))
1906 {
1907 // If peer adhoc is b-only mode, we can't send 11g rate.
1908 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
1909 pEntry->HTPhyMode.field.STBC = STBC_NONE;
1910
1911 //
1912 // For Adhoc MODE_CCK, driver will use AdhocBOnlyJoined flag to roll back to B only if necessary
1913 //
1914 pEntry->HTPhyMode.field.MODE = pTxRate->Mode;
1915 pEntry->HTPhyMode.field.ShortGI = pAd->StaCfg.HTPhyMode.field.ShortGI;
1916 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
1917
1918 // Patch speed error in status page
1919 pAd->StaCfg.HTPhyMode.field.MODE = pEntry->HTPhyMode.field.MODE;
1920 }
1921 else
1922 {
1923 if (pTxRate->Mode <= MaxMode)
1924 pAd->StaCfg.HTPhyMode.field.MODE = pTxRate->Mode;
1925
1926#ifdef DOT11_N_SUPPORT
1927 if (pTxRate->ShortGI && (pAd->StaCfg.MaxHTPhyMode.field.ShortGI))
1928 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_400;
1929 else
1930#endif // DOT11_N_SUPPORT //
1931 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
1932
1933#ifdef DOT11_N_SUPPORT
1934 // Reexam each bandwidth's SGI support.
1935 if (pAd->StaCfg.HTPhyMode.field.ShortGI == GI_400)
1936 {
1937 if ((pEntry->HTPhyMode.field.BW == BW_20) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE)))
1938 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
1939 if ((pEntry->HTPhyMode.field.BW == BW_40) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE)))
1940 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
1941 }
1942
1943 // Turn RTS/CTS rate to 6Mbps.
1944 if ((pEntry->HTPhyMode.field.MCS == 0) && (pAd->StaCfg.HTPhyMode.field.MCS != 0))
1945 {
1946 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
1947 if (pAd->MacTab.fAnyBASession)
1948 {
1949 AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
1950 }
1951 else
1952 {
1953 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
1954 }
1955 }
1956 else if ((pEntry->HTPhyMode.field.MCS == 8) && (pAd->StaCfg.HTPhyMode.field.MCS != 8))
1957 {
1958 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
1959 if (pAd->MacTab.fAnyBASession)
1960 {
1961 AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
1962 }
1963 else
1964 {
1965 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
1966 }
1967 }
1968 else if ((pEntry->HTPhyMode.field.MCS != 0) && (pAd->StaCfg.HTPhyMode.field.MCS == 0))
1969 {
1970 AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
1971
1972 }
1973 else if ((pEntry->HTPhyMode.field.MCS != 8) && (pAd->StaCfg.HTPhyMode.field.MCS == 8))
1974 {
1975 AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
1976 }
1977#endif // DOT11_N_SUPPORT //
1978
1979 pEntry->HTPhyMode.field.STBC = pAd->StaCfg.HTPhyMode.field.STBC;
1980 pEntry->HTPhyMode.field.ShortGI = pAd->StaCfg.HTPhyMode.field.ShortGI;
1981 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
1982 pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
1983#ifdef DOT11_N_SUPPORT
1984 if ((pAd->StaCfg.MaxHTPhyMode.field.MODE == MODE_HTGREENFIELD) &&
1985 pAd->WIFItestbed.bGreenField)
1986 pEntry->HTPhyMode.field.MODE = MODE_HTGREENFIELD;
1987#endif // DOT11_N_SUPPORT //
1988 }
1989
1990 pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
1991}
1992
1993/*
1994 ==========================================================================
1995 Description:
1996 This routine calculates the acumulated TxPER of eaxh TxRate. And
1997 according to the calculation result, change CommonCfg.TxRate which
1998 is the stable TX Rate we expect the Radio situation could sustained.
1999
2000 CommonCfg.TxRate will change dynamically within {RATE_1/RATE_6, MaxTxRate}
2001 Output:
2002 CommonCfg.TxRate -
2003
2004 IRQL = DISPATCH_LEVEL
2005
2006 NOTE:
2007 call this routine every second
2008 ==========================================================================
2009 */
2010VOID MlmeDynamicTxRateSwitching(
2011 IN PRTMP_ADAPTER pAd)
2012{
2013 UCHAR UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx;
2014 ULONG i, AccuTxTotalCnt = 0, TxTotalCnt;
2015 ULONG TxErrorRatio = 0;
2016 BOOLEAN bTxRateChanged, bUpgradeQuality = FALSE;
2017 PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate = NULL;
2018 PUCHAR pTable;
2019 UCHAR TableSize = 0;
2020 UCHAR InitTxRateIdx = 0, TrainUp, TrainDown;
2021 CHAR Rssi, RssiOffset = 0;
2022 TX_STA_CNT1_STRUC StaTx1;
2023 TX_STA_CNT0_STRUC TxStaCnt0;
2024 ULONG TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
2025 MAC_TABLE_ENTRY *pEntry;
2026
2027#ifdef RALINK_ATE
2028 if (ATE_ON(pAd))
2029 {
2030 return;
2031 }
2032#endif // RALINK_ATE //
2033
2034 //
2035 // walk through MAC table, see if need to change AP's TX rate toward each entry
2036 //
2037 for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
2038 {
2039 pEntry = &pAd->MacTab.Content[i];
2040
2041 // check if this entry need to switch rate automatically
2042 if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
2043 continue;
2044
2045 if ((pAd->MacTab.Size == 1) || (pEntry->ValidAsDls))
2046 {
2047 Rssi = RTMPMaxRssi(pAd,
2048 pAd->StaCfg.RssiSample.AvgRssi0,
2049 pAd->StaCfg.RssiSample.AvgRssi1,
2050 pAd->StaCfg.RssiSample.AvgRssi2);
2051
2052 // Update statistic counter
2053 RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
2054 RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
2055 pAd->bUpdateBcnCntDone = TRUE;
2056 TxRetransmit = StaTx1.field.TxRetransmit;
2057 TxSuccess = StaTx1.field.TxSuccess;
2058 TxFailCount = TxStaCnt0.field.TxFailCount;
2059 TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
2060
2061 pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
2062 pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
2063 pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
2064 pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
2065 pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
2066 pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
2067
2068 // if no traffic in the past 1-sec period, don't change TX rate,
2069 // but clear all bad history. because the bad history may affect the next
2070 // Chariot throughput test
2071 AccuTxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
2072 pAd->RalinkCounters.OneSecTxRetryOkCount +
2073 pAd->RalinkCounters.OneSecTxFailCount;
2074
2075 if (TxTotalCnt)
2076 TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
2077 }
2078 else
2079 {
2080 if (INFRA_ON(pAd) && (i == 1))
2081 Rssi = RTMPMaxRssi(pAd,
2082 pAd->StaCfg.RssiSample.AvgRssi0,
2083 pAd->StaCfg.RssiSample.AvgRssi1,
2084 pAd->StaCfg.RssiSample.AvgRssi2);
2085 else
2086 Rssi = RTMPMaxRssi(pAd,
2087 pEntry->RssiSample.AvgRssi0,
2088 pEntry->RssiSample.AvgRssi1,
2089 pEntry->RssiSample.AvgRssi2);
2090
2091 TxTotalCnt = pEntry->OneSecTxNoRetryOkCount +
2092 pEntry->OneSecTxRetryOkCount +
2093 pEntry->OneSecTxFailCount;
2094
2095 if (TxTotalCnt)
2096 TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt;
2097 }
2098
2099 CurrRateIdx = pEntry->CurrTxRateIndex;
2100
2101 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx);
2102
2103 if (CurrRateIdx >= TableSize)
2104 {
2105 CurrRateIdx = TableSize - 1;
2106 }
2107
2108 // When switch from Fixed rate -> auto rate, the REAL TX rate might be different from pAd->CommonCfg.TxRateIndex.
2109 // So need to sync here.
2110 pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
2111 if ((pEntry->HTPhyMode.field.MCS != pCurrTxRate->CurrMCS)
2112 //&& (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
2113 )
2114 {
2115
2116 // Need to sync Real Tx rate and our record.
2117 // Then return for next DRS.
2118 pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(InitTxRateIdx+1)*5];
2119 pEntry->CurrTxRateIndex = InitTxRateIdx;
2120 MlmeSetTxRate(pAd, pEntry, pCurrTxRate);
2121
2122 // reset all OneSecTx counters
2123 RESET_ONE_SEC_TX_CNT(pEntry);
2124 continue;
2125 }
2126
2127 // decide the next upgrade rate and downgrade rate, if any
2128 if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1)))
2129 {
2130 UpRateIdx = CurrRateIdx + 1;
2131 DownRateIdx = CurrRateIdx -1;
2132 }
2133 else if (CurrRateIdx == 0)
2134 {
2135 UpRateIdx = CurrRateIdx + 1;
2136 DownRateIdx = CurrRateIdx;
2137 }
2138 else if (CurrRateIdx == (TableSize - 1))
2139 {
2140 UpRateIdx = CurrRateIdx;
2141 DownRateIdx = CurrRateIdx - 1;
2142 }
2143
2144 pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
2145
2146#ifdef DOT11_N_SUPPORT
2147 if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX))
2148 {
2149 TrainUp = (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1));
2150 TrainDown = (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1));
2151 }
2152 else
2153#endif // DOT11_N_SUPPORT //
2154 {
2155 TrainUp = pCurrTxRate->TrainUp;
2156 TrainDown = pCurrTxRate->TrainDown;
2157 }
2158
2159 //pAd->DrsCounters.LastTimeTxRateChangeAction = pAd->DrsCounters.LastSecTxRateChangeAction;
2160
2161 //
2162 // Keep the last time TxRateChangeAction status.
2163 //
2164 pEntry->LastTimeTxRateChangeAction = pEntry->LastSecTxRateChangeAction;
2165
2166
2167
2168 //
2169 // CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI
2170 // (criteria copied from RT2500 for Netopia case)
2171 //
2172 if (TxTotalCnt <= 15)
2173 {
2174 CHAR idx = 0;
2175 UCHAR TxRateIdx;
2176 //UCHAR MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0, MCS7 = 0, MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0;
2177 UCHAR MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0, MCS5 =0, MCS6 = 0, MCS7 = 0;
2178 UCHAR MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0;
2179 UCHAR MCS20 = 0, MCS21 = 0, MCS22 = 0, MCS23 = 0; // 3*3
2180
2181 // check the existence and index of each needed MCS
2182 while (idx < pTable[0])
2183 {
2184 pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(idx+1)*5];
2185
2186 if (pCurrTxRate->CurrMCS == MCS_0)
2187 {
2188 MCS0 = idx;
2189 }
2190 else if (pCurrTxRate->CurrMCS == MCS_1)
2191 {
2192 MCS1 = idx;
2193 }
2194 else if (pCurrTxRate->CurrMCS == MCS_2)
2195 {
2196 MCS2 = idx;
2197 }
2198 else if (pCurrTxRate->CurrMCS == MCS_3)
2199 {
2200 MCS3 = idx;
2201 }
2202 else if (pCurrTxRate->CurrMCS == MCS_4)
2203 {
2204 MCS4 = idx;
2205 }
2206 else if (pCurrTxRate->CurrMCS == MCS_5)
2207 {
2208 MCS5 = idx;
2209 }
2210 else if (pCurrTxRate->CurrMCS == MCS_6)
2211 {
2212 MCS6 = idx;
2213 }
2214 //else if (pCurrTxRate->CurrMCS == MCS_7)
2215 else if ((pCurrTxRate->CurrMCS == MCS_7) && (pCurrTxRate->ShortGI == GI_800)) // prevent the highest MCS using short GI when 1T and low throughput
2216 {
2217 MCS7 = idx;
2218 }
2219 else if (pCurrTxRate->CurrMCS == MCS_12)
2220 {
2221 MCS12 = idx;
2222 }
2223 else if (pCurrTxRate->CurrMCS == MCS_13)
2224 {
2225 MCS13 = idx;
2226 }
2227 else if (pCurrTxRate->CurrMCS == MCS_14)
2228 {
2229 MCS14 = idx;
2230 }
2231 else if ((pCurrTxRate->CurrMCS == MCS_15) && (pCurrTxRate->ShortGI == GI_800))
2232 {
2233 MCS15 = idx;
2234 }
2235 else if (pCurrTxRate->CurrMCS == MCS_20) // 3*3
2236 {
2237 MCS20 = idx;
2238 }
2239 else if (pCurrTxRate->CurrMCS == MCS_21)
2240 {
2241 MCS21 = idx;
2242 }
2243 else if (pCurrTxRate->CurrMCS == MCS_22)
2244 {
2245 MCS22 = idx;
2246 }
2247 else if (pCurrTxRate->CurrMCS == MCS_23)
2248 {
2249 MCS23 = idx;
2250 }
2251 idx ++;
2252 }
2253
2254 if (pAd->LatchRfRegs.Channel <= 14)
2255 {
2256 if (pAd->NicConfig2.field.ExternalLNAForG)
2257 {
2258 RssiOffset = 2;
2259 }
2260 else
2261 {
2262 RssiOffset = 5;
2263 }
2264 }
2265 else
2266 {
2267 if (pAd->NicConfig2.field.ExternalLNAForA)
2268 {
2269 RssiOffset = 5;
2270 }
2271 else
2272 {
2273 RssiOffset = 8;
2274 }
2275 }
2276#ifdef DOT11_N_SUPPORT
2277 /*if (MCS15)*/
2278 if ((pTable == RateSwitchTable11BGN3S) ||
2279 (pTable == RateSwitchTable11N3S) ||
2280 (pTable == RateSwitchTable))
2281 {// N mode with 3 stream // 3*3
2282 if (MCS23 && (Rssi >= -70))
2283 TxRateIdx = MCS15;
2284 else if (MCS22 && (Rssi >= -72))
2285 TxRateIdx = MCS14;
2286 else if (MCS21 && (Rssi >= -76))
2287 TxRateIdx = MCS13;
2288 else if (MCS20 && (Rssi >= -78))
2289 TxRateIdx = MCS12;
2290 else if (MCS4 && (Rssi >= -82))
2291 TxRateIdx = MCS4;
2292 else if (MCS3 && (Rssi >= -84))
2293 TxRateIdx = MCS3;
2294 else if (MCS2 && (Rssi >= -86))
2295 TxRateIdx = MCS2;
2296 else if (MCS1 && (Rssi >= -88))
2297 TxRateIdx = MCS1;
2298 else
2299 TxRateIdx = MCS0;
2300 }
2301// else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||(pTable == RateSwitchTable11N2S) ||(pTable == RateSwitchTable11N2SForABand) || (pTable == RateSwitchTable))
2302 else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||(pTable == RateSwitchTable11N2S) ||(pTable == RateSwitchTable11N2SForABand)) // 3*3
2303 {// N mode with 2 stream
2304 if (MCS15 && (Rssi >= (-70+RssiOffset)))
2305 TxRateIdx = MCS15;
2306 else if (MCS14 && (Rssi >= (-72+RssiOffset)))
2307 TxRateIdx = MCS14;
2308 else if (MCS13 && (Rssi >= (-76+RssiOffset)))
2309 TxRateIdx = MCS13;
2310 else if (MCS12 && (Rssi >= (-78+RssiOffset)))
2311 TxRateIdx = MCS12;
2312 else if (MCS4 && (Rssi >= (-82+RssiOffset)))
2313 TxRateIdx = MCS4;
2314 else if (MCS3 && (Rssi >= (-84+RssiOffset)))
2315 TxRateIdx = MCS3;
2316 else if (MCS2 && (Rssi >= (-86+RssiOffset)))
2317 TxRateIdx = MCS2;
2318 else if (MCS1 && (Rssi >= (-88+RssiOffset)))
2319 TxRateIdx = MCS1;
2320 else
2321 TxRateIdx = MCS0;
2322 }
2323 else if ((pTable == RateSwitchTable11BGN1S) || (pTable == RateSwitchTable11N1S))
2324 {// N mode with 1 stream
2325 if (MCS7 && (Rssi > (-72+RssiOffset)))
2326 TxRateIdx = MCS7;
2327 else if (MCS6 && (Rssi > (-74+RssiOffset)))
2328 TxRateIdx = MCS6;
2329 else if (MCS5 && (Rssi > (-77+RssiOffset)))
2330 TxRateIdx = MCS5;
2331 else if (MCS4 && (Rssi > (-79+RssiOffset)))
2332 TxRateIdx = MCS4;
2333 else if (MCS3 && (Rssi > (-81+RssiOffset)))
2334 TxRateIdx = MCS3;
2335 else if (MCS2 && (Rssi > (-83+RssiOffset)))
2336 TxRateIdx = MCS2;
2337 else if (MCS1 && (Rssi > (-86+RssiOffset)))
2338 TxRateIdx = MCS1;
2339 else
2340 TxRateIdx = MCS0;
2341 }
2342 else
2343#endif // DOT11_N_SUPPORT //
2344 {// Legacy mode
2345 if (MCS7 && (Rssi > -70))
2346 TxRateIdx = MCS7;
2347 else if (MCS6 && (Rssi > -74))
2348 TxRateIdx = MCS6;
2349 else if (MCS5 && (Rssi > -78))
2350 TxRateIdx = MCS5;
2351 else if (MCS4 && (Rssi > -82))
2352 TxRateIdx = MCS4;
2353 else if (MCS4 == 0) // for B-only mode
2354 TxRateIdx = MCS3;
2355 else if (MCS3 && (Rssi > -85))
2356 TxRateIdx = MCS3;
2357 else if (MCS2 && (Rssi > -87))
2358 TxRateIdx = MCS2;
2359 else if (MCS1 && (Rssi > -90))
2360 TxRateIdx = MCS1;
2361 else
2362 TxRateIdx = MCS0;
2363 }
2364
2365 // if (TxRateIdx != pAd->CommonCfg.TxRateIndex)
2366 {
2367 pEntry->CurrTxRateIndex = TxRateIdx;
2368 pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5];
2369 MlmeSetTxRate(pAd, pEntry, pNextTxRate);
2370 }
2371
2372 NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
2373 NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
2374 pEntry->fLastSecAccordingRSSI = TRUE;
2375 // reset all OneSecTx counters
2376 RESET_ONE_SEC_TX_CNT(pEntry);
2377
2378 continue;
2379 }
2380
2381 if (pEntry->fLastSecAccordingRSSI == TRUE)
2382 {
2383 pEntry->fLastSecAccordingRSSI = FALSE;
2384 pEntry->LastSecTxRateChangeAction = 0;
2385 // reset all OneSecTx counters
2386 RESET_ONE_SEC_TX_CNT(pEntry);
2387
2388 continue;
2389 }
2390
2391 do
2392 {
2393 BOOLEAN bTrainUpDown = FALSE;
2394
2395 pEntry->CurrTxRateStableTime ++;
2396
2397 // downgrade TX quality if PER >= Rate-Down threshold
2398 if (TxErrorRatio >= TrainDown)
2399 {
2400 bTrainUpDown = TRUE;
2401 pEntry->TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
2402 }
2403 // upgrade TX quality if PER <= Rate-Up threshold
2404 else if (TxErrorRatio <= TrainUp)
2405 {
2406 bTrainUpDown = TRUE;
2407 bUpgradeQuality = TRUE;
2408 if (pEntry->TxQuality[CurrRateIdx])
2409 pEntry->TxQuality[CurrRateIdx] --; // quality very good in CurrRate
2410
2411 if (pEntry->TxRateUpPenalty)
2412 pEntry->TxRateUpPenalty --;
2413 else if (pEntry->TxQuality[UpRateIdx])
2414 pEntry->TxQuality[UpRateIdx] --; // may improve next UP rate's quality
2415 }
2416
2417 pEntry->PER[CurrRateIdx] = (UCHAR)TxErrorRatio;
2418
2419 if (bTrainUpDown)
2420 {
2421 // perform DRS - consider TxRate Down first, then rate up.
2422 if ((CurrRateIdx != DownRateIdx) && (pEntry->TxQuality[CurrRateIdx] >= DRS_TX_QUALITY_WORST_BOUND))
2423 {
2424 pEntry->CurrTxRateIndex = DownRateIdx;
2425 }
2426 else if ((CurrRateIdx != UpRateIdx) && (pEntry->TxQuality[UpRateIdx] <= 0))
2427 {
2428 pEntry->CurrTxRateIndex = UpRateIdx;
2429 }
2430 }
2431 } while (FALSE);
2432
2433 // if rate-up happen, clear all bad history of all TX rates
2434 if (pEntry->CurrTxRateIndex > CurrRateIdx)
2435 {
2436 pEntry->CurrTxRateStableTime = 0;
2437 pEntry->TxRateUpPenalty = 0;
2438 pEntry->LastSecTxRateChangeAction = 1; // rate UP
2439 NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
2440 NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
2441
2442 //
2443 // For TxRate fast train up
2444 //
2445 if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning)
2446 {
2447 RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
2448
2449 pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE;
2450 }
2451 bTxRateChanged = TRUE;
2452 }
2453 // if rate-down happen, only clear DownRate's bad history
2454 else if (pEntry->CurrTxRateIndex < CurrRateIdx)
2455 {
2456 pEntry->CurrTxRateStableTime = 0;
2457 pEntry->TxRateUpPenalty = 0; // no penalty
2458 pEntry->LastSecTxRateChangeAction = 2; // rate DOWN
2459 pEntry->TxQuality[pEntry->CurrTxRateIndex] = 0;
2460 pEntry->PER[pEntry->CurrTxRateIndex] = 0;
2461
2462 //
2463 // For TxRate fast train down
2464 //
2465 if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning)
2466 {
2467 RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
2468
2469 pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE;
2470 }
2471 bTxRateChanged = TRUE;
2472 }
2473 else
2474 {
2475 pEntry->LastSecTxRateChangeAction = 0; // rate no change
2476 bTxRateChanged = FALSE;
2477 }
2478
2479 pEntry->LastTxOkCount = TxSuccess;
2480
2481 // reset all OneSecTx counters
2482 RESET_ONE_SEC_TX_CNT(pEntry);
2483
2484 pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5];
2485 if (bTxRateChanged && pNextTxRate)
2486 {
2487 MlmeSetTxRate(pAd, pEntry, pNextTxRate);
2488 }
2489 }
2490}
2491
2492/*
2493 ========================================================================
2494 Routine Description:
2495 Station side, Auto TxRate faster train up timer call back function.
2496
2497 Arguments:
2498 SystemSpecific1 - Not used.
2499 FunctionContext - Pointer to our Adapter context.
2500 SystemSpecific2 - Not used.
2501 SystemSpecific3 - Not used.
2502
2503 Return Value:
2504 None
2505
2506 ========================================================================
2507*/
2508VOID StaQuickResponeForRateUpExec(
2509 IN PVOID SystemSpecific1,
2510 IN PVOID FunctionContext,
2511 IN PVOID SystemSpecific2,
2512 IN PVOID SystemSpecific3)
2513{
2514 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)FunctionContext;
2515 UCHAR UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx = 0;
2516 ULONG TxTotalCnt;
2517 ULONG TxErrorRatio = 0;
2518 BOOLEAN bTxRateChanged; //, bUpgradeQuality = FALSE;
2519 PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate = NULL;
2520 PUCHAR pTable;
2521 UCHAR TableSize = 0;
2522 UCHAR InitTxRateIdx = 0, TrainUp, TrainDown;
2523 TX_STA_CNT1_STRUC StaTx1;
2524 TX_STA_CNT0_STRUC TxStaCnt0;
2525 CHAR Rssi, ratio;
2526 ULONG TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
2527 MAC_TABLE_ENTRY *pEntry;
2528 ULONG i;
2529
2530 pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE;
2531
2532 //
2533 // walk through MAC table, see if need to change AP's TX rate toward each entry
2534 //
2535 for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
2536 {
2537 pEntry = &pAd->MacTab.Content[i];
2538
2539 // check if this entry need to switch rate automatically
2540 if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
2541 continue;
2542
2543 if (INFRA_ON(pAd) && (i == 1))
2544 Rssi = RTMPMaxRssi(pAd,
2545 pAd->StaCfg.RssiSample.AvgRssi0,
2546 pAd->StaCfg.RssiSample.AvgRssi1,
2547 pAd->StaCfg.RssiSample.AvgRssi2);
2548 else
2549 Rssi = RTMPMaxRssi(pAd,
2550 pEntry->RssiSample.AvgRssi0,
2551 pEntry->RssiSample.AvgRssi1,
2552 pEntry->RssiSample.AvgRssi2);
2553
2554 CurrRateIdx = pAd->CommonCfg.TxRateIndex;
2555
2556 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx);
2557
2558 // decide the next upgrade rate and downgrade rate, if any
2559 if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1)))
2560 {
2561 UpRateIdx = CurrRateIdx + 1;
2562 DownRateIdx = CurrRateIdx -1;
2563 }
2564 else if (CurrRateIdx == 0)
2565 {
2566 UpRateIdx = CurrRateIdx + 1;
2567 DownRateIdx = CurrRateIdx;
2568 }
2569 else if (CurrRateIdx == (TableSize - 1))
2570 {
2571 UpRateIdx = CurrRateIdx;
2572 DownRateIdx = CurrRateIdx - 1;
2573 }
2574
2575 pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
2576
2577#ifdef DOT11_N_SUPPORT
2578 if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX))
2579 {
2580 TrainUp = (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1));
2581 TrainDown = (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1));
2582 }
2583 else
2584#endif // DOT11_N_SUPPORT //
2585 {
2586 TrainUp = pCurrTxRate->TrainUp;
2587 TrainDown = pCurrTxRate->TrainDown;
2588 }
2589
2590 if (pAd->MacTab.Size == 1)
2591 {
2592 // Update statistic counter
2593 RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
2594 RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
2595
2596 TxRetransmit = StaTx1.field.TxRetransmit;
2597 TxSuccess = StaTx1.field.TxSuccess;
2598 TxFailCount = TxStaCnt0.field.TxFailCount;
2599 TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
2600
2601 pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
2602 pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
2603 pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
2604 pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
2605 pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
2606 pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
2607
2608 if (TxTotalCnt)
2609 TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
2610 }
2611 else
2612 {
2613 TxTotalCnt = pEntry->OneSecTxNoRetryOkCount +
2614 pEntry->OneSecTxRetryOkCount +
2615 pEntry->OneSecTxFailCount;
2616
2617 if (TxTotalCnt)
2618 TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt;
2619 }
2620
2621
2622 //
2623 // CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI
2624 // (criteria copied from RT2500 for Netopia case)
2625 //
2626 if (TxTotalCnt <= 12)
2627 {
2628 NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
2629 NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
2630
2631 if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx))
2632 {
2633 pAd->CommonCfg.TxRateIndex = DownRateIdx;
2634 pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
2635 }
2636 else if ((pAd->DrsCounters.LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx))
2637 {
2638 pAd->CommonCfg.TxRateIndex = UpRateIdx;
2639 }
2640
2641 DBGPRINT_RAW(RT_DEBUG_TRACE,("QuickDRS: TxTotalCnt <= 15, train back to original rate \n"));
2642 return;
2643 }
2644
2645 do
2646 {
2647 ULONG OneSecTxNoRetryOKRationCount;
2648
2649 if (pAd->DrsCounters.LastTimeTxRateChangeAction == 0)
2650 ratio = 5;
2651 else
2652 ratio = 4;
2653
2654 // downgrade TX quality if PER >= Rate-Down threshold
2655 if (TxErrorRatio >= TrainDown)
2656 {
2657 pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
2658 }
2659
2660 pAd->DrsCounters.PER[CurrRateIdx] = (UCHAR)TxErrorRatio;
2661
2662 OneSecTxNoRetryOKRationCount = (TxSuccess * ratio);
2663
2664 // perform DRS - consider TxRate Down first, then rate up.
2665 if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx))
2666 {
2667 if ((pAd->DrsCounters.LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount)
2668 {
2669 pAd->CommonCfg.TxRateIndex = DownRateIdx;
2670 pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
2671
2672 }
2673
2674 }
2675 else if ((pAd->DrsCounters.LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx))
2676 {
2677 if ((TxErrorRatio >= 50) || (TxErrorRatio >= TrainDown))
2678 {
2679
2680 }
2681 else if ((pAd->DrsCounters.LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount)
2682 {
2683 pAd->CommonCfg.TxRateIndex = UpRateIdx;
2684 }
2685 }
2686 }while (FALSE);
2687
2688 // if rate-up happen, clear all bad history of all TX rates
2689 if (pAd->CommonCfg.TxRateIndex > CurrRateIdx)
2690 {
2691 pAd->DrsCounters.TxRateUpPenalty = 0;
2692 NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
2693 NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
2694 bTxRateChanged = TRUE;
2695 }
2696 // if rate-down happen, only clear DownRate's bad history
2697 else if (pAd->CommonCfg.TxRateIndex < CurrRateIdx)
2698 {
2699 DBGPRINT_RAW(RT_DEBUG_TRACE,("QuickDRS: --TX rate from %d to %d \n", CurrRateIdx, pAd->CommonCfg.TxRateIndex));
2700
2701 pAd->DrsCounters.TxRateUpPenalty = 0; // no penalty
2702 pAd->DrsCounters.TxQuality[pAd->CommonCfg.TxRateIndex] = 0;
2703 pAd->DrsCounters.PER[pAd->CommonCfg.TxRateIndex] = 0;
2704 bTxRateChanged = TRUE;
2705 }
2706 else
2707 {
2708 bTxRateChanged = FALSE;
2709 }
2710
2711 pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pAd->CommonCfg.TxRateIndex+1)*5];
2712 if (bTxRateChanged && pNextTxRate)
2713 {
2714 MlmeSetTxRate(pAd, pEntry, pNextTxRate);
2715 }
2716 }
2717}
2718
2719/*
2720 ==========================================================================
2721 Description:
2722 This routine is executed periodically inside MlmePeriodicExec() after
2723 association with an AP.
2724 It checks if StaCfg.Psm is consistent with user policy (recorded in
2725 StaCfg.WindowsPowerMode). If not, enforce user policy. However,
2726 there're some conditions to consider:
2727 1. we don't support power-saving in ADHOC mode, so Psm=PWR_ACTIVE all
2728 the time when Mibss==TRUE
2729 2. When link up in INFRA mode, Psm should not be switch to PWR_SAVE
2730 if outgoing traffic available in TxRing or MgmtRing.
2731 Output:
2732 1. change pAd->StaCfg.Psm to PWR_SAVE or leave it untouched
2733
2734 IRQL = DISPATCH_LEVEL
2735
2736 ==========================================================================
2737 */
2738VOID MlmeCheckPsmChange(
2739 IN PRTMP_ADAPTER pAd,
2740 IN ULONG Now32)
2741{
2742 ULONG PowerMode;
2743
2744 // condition -
2745 // 1. Psm maybe ON only happen in INFRASTRUCTURE mode
2746 // 2. user wants either MAX_PSP or FAST_PSP
2747 // 3. but current psm is not in PWR_SAVE
2748 // 4. CNTL state machine is not doing SCANning
2749 // 5. no TX SUCCESS event for the past 1-sec period
2750#ifdef NDIS51_MINIPORT
2751 if (pAd->StaCfg.WindowsPowerProfile == NdisPowerProfileBattery)
2752 PowerMode = pAd->StaCfg.WindowsBatteryPowerMode;
2753 else
2754#endif
2755 PowerMode = pAd->StaCfg.WindowsPowerMode;
2756
2757 if (INFRA_ON(pAd) &&
2758 (PowerMode != Ndis802_11PowerModeCAM) &&
2759 (pAd->StaCfg.Psm == PWR_ACTIVE) &&
2760// (! RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
2761 (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) /*&&
2762 (pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) &&
2763 (pAd->RalinkCounters.OneSecTxRetryOkCount == 0)*/)
2764 {
2765 // add by johnli, use Rx OK data count per second to calculate throughput
2766 // If Ttraffic is too high ( > 400 Rx per second), don't go to sleep mode. If tx rate is low, use low criteria
2767 // Mode=CCK/MCS=3 => 11 Mbps, Mode=OFDM/MCS=3 => 18 Mbps
2768 if (((pAd->StaCfg.HTPhyMode.field.MCS <= 3) &&
2769/* Iverson mark
2770 (pAd->StaCfg.HTPhyMode.field.MODE <= MODE_OFDM) &&
2771*/
2772 (pAd->RalinkCounters.OneSecRxOkDataCnt < (ULONG)100)) ||
2773 ((pAd->StaCfg.HTPhyMode.field.MCS > 3) &&
2774/* Iverson mark
2775 (pAd->StaCfg.HTPhyMode.field.MODE > MODE_OFDM) &&
2776*/
2777 (pAd->RalinkCounters.OneSecRxOkDataCnt < (ULONG)400)))
2778 {
2779 // Get this time
2780 NdisGetSystemUpTime(&pAd->Mlme.LastSendNULLpsmTime);
2781 pAd->RalinkCounters.RxCountSinceLastNULL = 0;
2782 MlmeSetPsmBit(pAd, PWR_SAVE);
2783 if (!(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable))
2784 {
2785 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE);
2786 }
2787 else
2788 {
2789 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
2790 }
2791 }
2792 }
2793}
2794
2795// IRQL = PASSIVE_LEVEL
2796// IRQL = DISPATCH_LEVEL
2797VOID MlmeSetPsmBit(
2798 IN PRTMP_ADAPTER pAd,
2799 IN USHORT psm)
2800{
2801 AUTO_RSP_CFG_STRUC csr4;
2802
2803 pAd->StaCfg.Psm = psm;
2804 RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word);
2805 csr4.field.AckCtsPsmBit = (psm == PWR_SAVE)? 1:0;
2806 RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word);
2807}
2808#endif // CONFIG_STA_SUPPORT //
2809
2810
2811// IRQL = DISPATCH_LEVEL
2812VOID MlmeSetTxPreamble(
2813 IN PRTMP_ADAPTER pAd,
2814 IN USHORT TxPreamble)
2815{
2816 AUTO_RSP_CFG_STRUC csr4;
2817
2818 //
2819 // Always use Long preamble before verifiation short preamble functionality works well.
2820 // Todo: remove the following line if short preamble functionality works
2821 //
2822 //TxPreamble = Rt802_11PreambleLong;
2823
2824 RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word);
2825 if (TxPreamble == Rt802_11PreambleLong)
2826 {
2827 DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetTxPreamble (= LONG PREAMBLE)\n"));
2828 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
2829 csr4.field.AutoResponderPreamble = 0;
2830 }
2831 else
2832 {
2833 // NOTE: 1Mbps should always use long preamble
2834 DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetTxPreamble (= SHORT PREAMBLE)\n"));
2835 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
2836 csr4.field.AutoResponderPreamble = 1;
2837 }
2838
2839 RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word);
2840}
2841
2842/*
2843 ==========================================================================
2844 Description:
2845 Update basic rate bitmap
2846 ==========================================================================
2847 */
2848
2849VOID UpdateBasicRateBitmap(
2850 IN PRTMP_ADAPTER pAdapter)
2851{
2852 INT i, j;
2853 /* 1 2 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54 */
2854 UCHAR rate[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
2855 UCHAR *sup_p = pAdapter->CommonCfg.SupRate;
2856 UCHAR *ext_p = pAdapter->CommonCfg.ExtRate;
2857 ULONG bitmap = pAdapter->CommonCfg.BasicRateBitmap;
2858
2859
2860 /* if A mode, always use fix BasicRateBitMap */
2861 //if (pAdapter->CommonCfg.Channel == PHY_11A)
2862 if (pAdapter->CommonCfg.Channel > 14)
2863 pAdapter->CommonCfg.BasicRateBitmap = 0x150; /* 6, 12, 24M */
2864 /* End of if */
2865
2866 if (pAdapter->CommonCfg.BasicRateBitmap > 4095)
2867 {
2868 /* (2 ^ MAX_LEN_OF_SUPPORTED_RATES) -1 */
2869 return;
2870 } /* End of if */
2871
2872 for(i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
2873 {
2874 sup_p[i] &= 0x7f;
2875 ext_p[i] &= 0x7f;
2876 } /* End of for */
2877
2878 for(i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
2879 {
2880 if (bitmap & (1 << i))
2881 {
2882 for(j=0; j<MAX_LEN_OF_SUPPORTED_RATES; j++)
2883 {
2884 if (sup_p[j] == rate[i])
2885 sup_p[j] |= 0x80;
2886 /* End of if */
2887 } /* End of for */
2888
2889 for(j=0; j<MAX_LEN_OF_SUPPORTED_RATES; j++)
2890 {
2891 if (ext_p[j] == rate[i])
2892 ext_p[j] |= 0x80;
2893 /* End of if */
2894 } /* End of for */
2895 } /* End of if */
2896 } /* End of for */
2897} /* End of UpdateBasicRateBitmap */
2898
2899// IRQL = PASSIVE_LEVEL
2900// IRQL = DISPATCH_LEVEL
2901// bLinkUp is to identify the inital link speed.
2902// TRUE indicates the rate update at linkup, we should not try to set the rate at 54Mbps.
2903VOID MlmeUpdateTxRates(
2904 IN PRTMP_ADAPTER pAd,
2905 IN BOOLEAN bLinkUp,
2906 IN UCHAR apidx)
2907{
2908 int i, num;
2909 UCHAR Rate = RATE_6, MaxDesire = RATE_1, MaxSupport = RATE_1;
2910 UCHAR MinSupport = RATE_54;
2911 ULONG BasicRateBitmap = 0;
2912 UCHAR CurrBasicRate = RATE_1;
2913 UCHAR *pSupRate, SupRateLen, *pExtRate, ExtRateLen;
2914 PHTTRANSMIT_SETTING pHtPhy = NULL;
2915 PHTTRANSMIT_SETTING pMaxHtPhy = NULL;
2916 PHTTRANSMIT_SETTING pMinHtPhy = NULL;
2917 BOOLEAN *auto_rate_cur_p;
2918 UCHAR HtMcs = MCS_AUTO;
2919
2920 // find max desired rate
2921 UpdateBasicRateBitmap(pAd);
2922
2923 num = 0;
2924 auto_rate_cur_p = NULL;
2925 for (i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
2926 {
2927 switch (pAd->CommonCfg.DesireRate[i] & 0x7f)
2928 {
2929 case 2: Rate = RATE_1; num++; break;
2930 case 4: Rate = RATE_2; num++; break;
2931 case 11: Rate = RATE_5_5; num++; break;
2932 case 22: Rate = RATE_11; num++; break;
2933 case 12: Rate = RATE_6; num++; break;
2934 case 18: Rate = RATE_9; num++; break;
2935 case 24: Rate = RATE_12; num++; break;
2936 case 36: Rate = RATE_18; num++; break;
2937 case 48: Rate = RATE_24; num++; break;
2938 case 72: Rate = RATE_36; num++; break;
2939 case 96: Rate = RATE_48; num++; break;
2940 case 108: Rate = RATE_54; num++; break;
2941 //default: Rate = RATE_1; break;
2942 }
2943 if (MaxDesire < Rate) MaxDesire = Rate;
2944 }
2945
2946//===========================================================================
2947//===========================================================================
2948
2949#ifdef CONFIG_STA_SUPPORT
2950 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2951 {
2952 pHtPhy = &pAd->StaCfg.HTPhyMode;
2953 pMaxHtPhy = &pAd->StaCfg.MaxHTPhyMode;
2954 pMinHtPhy = &pAd->StaCfg.MinHTPhyMode;
2955
2956 auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch;
2957 HtMcs = pAd->StaCfg.DesiredTransmitSetting.field.MCS;
2958
2959 if ((pAd->StaCfg.BssType == BSS_ADHOC) &&
2960 (pAd->CommonCfg.PhyMode == PHY_11B) &&
2961 (MaxDesire > RATE_11))
2962 {
2963 MaxDesire = RATE_11;
2964 }
2965 }
2966#endif // CONFIG_STA_SUPPORT //
2967
2968 pAd->CommonCfg.MaxDesiredRate = MaxDesire;
2969 pMinHtPhy->word = 0;
2970 pMaxHtPhy->word = 0;
2971 pHtPhy->word = 0;
2972
2973 // Auto rate switching is enabled only if more than one DESIRED RATES are
2974 // specified; otherwise disabled
2975 if (num <= 1)
2976 {
2977 //OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
2978 //pAd->CommonCfg.bAutoTxRateSwitch = FALSE;
2979 *auto_rate_cur_p = FALSE;
2980 }
2981 else
2982 {
2983 //OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
2984 //pAd->CommonCfg.bAutoTxRateSwitch = TRUE;
2985 *auto_rate_cur_p = TRUE;
2986 }
2987
2988#if 1
2989 if (HtMcs != MCS_AUTO)
2990 {
2991 //OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
2992 //pAd->CommonCfg.bAutoTxRateSwitch = FALSE;
2993 *auto_rate_cur_p = FALSE;
2994 }
2995 else
2996 {
2997 //OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
2998 //pAd->CommonCfg.bAutoTxRateSwitch = TRUE;
2999 *auto_rate_cur_p = TRUE;
3000 }
3001#endif
3002
3003#ifdef CONFIG_STA_SUPPORT
3004 if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA))
3005 {
3006 pSupRate = &pAd->StaActive.SupRate[0];
3007 pExtRate = &pAd->StaActive.ExtRate[0];
3008 SupRateLen = pAd->StaActive.SupRateLen;
3009 ExtRateLen = pAd->StaActive.ExtRateLen;
3010 }
3011 else
3012#endif // CONFIG_STA_SUPPORT //
3013 {
3014 pSupRate = &pAd->CommonCfg.SupRate[0];
3015 pExtRate = &pAd->CommonCfg.ExtRate[0];
3016 SupRateLen = pAd->CommonCfg.SupRateLen;
3017 ExtRateLen = pAd->CommonCfg.ExtRateLen;
3018 }
3019
3020 // find max supported rate
3021 for (i=0; i<SupRateLen; i++)
3022 {
3023 switch (pSupRate[i] & 0x7f)
3024 {
3025 case 2: Rate = RATE_1; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0001; break;
3026 case 4: Rate = RATE_2; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0002; break;
3027 case 11: Rate = RATE_5_5; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0004; break;
3028 case 22: Rate = RATE_11; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0008; break;
3029 case 12: Rate = RATE_6; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap |= 0x0010; break;
3030 case 18: Rate = RATE_9; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0020; break;
3031 case 24: Rate = RATE_12; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap |= 0x0040; break;
3032 case 36: Rate = RATE_18; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0080; break;
3033 case 48: Rate = RATE_24; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap |= 0x0100; break;
3034 case 72: Rate = RATE_36; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0200; break;
3035 case 96: Rate = RATE_48; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0400; break;
3036 case 108: Rate = RATE_54; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0800; break;
3037 default: Rate = RATE_1; break;
3038 }
3039 if (MaxSupport < Rate) MaxSupport = Rate;
3040
3041 if (MinSupport > Rate) MinSupport = Rate;
3042 }
3043
3044 for (i=0; i<ExtRateLen; i++)
3045 {
3046 switch (pExtRate[i] & 0x7f)
3047 {
3048 case 2: Rate = RATE_1; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0001; break;
3049 case 4: Rate = RATE_2; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0002; break;
3050 case 11: Rate = RATE_5_5; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0004; break;
3051 case 22: Rate = RATE_11; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0008; break;
3052 case 12: Rate = RATE_6; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap |= 0x0010; break;
3053 case 18: Rate = RATE_9; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0020; break;
3054 case 24: Rate = RATE_12; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap |= 0x0040; break;
3055 case 36: Rate = RATE_18; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0080; break;
3056 case 48: Rate = RATE_24; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap |= 0x0100; break;
3057 case 72: Rate = RATE_36; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0200; break;
3058 case 96: Rate = RATE_48; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0400; break;
3059 case 108: Rate = RATE_54; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0800; break;
3060 default: Rate = RATE_1; break;
3061 }
3062 if (MaxSupport < Rate) MaxSupport = Rate;
3063
3064 if (MinSupport > Rate) MinSupport = Rate;
3065 }
3066
3067 RTMP_IO_WRITE32(pAd, LEGACY_BASIC_RATE, BasicRateBitmap);
3068
3069 // calculate the exptected ACK rate for each TX rate. This info is used to caculate
3070 // the DURATION field of outgoing uniicast DATA/MGMT frame
3071 for (i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
3072 {
3073 if (BasicRateBitmap & (0x01 << i))
3074 CurrBasicRate = (UCHAR)i;
3075 pAd->CommonCfg.ExpectedACKRate[i] = CurrBasicRate;
3076 }
3077
3078 DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateTxRates[MaxSupport = %d] = MaxDesire %d Mbps\n", RateIdToMbps[MaxSupport], RateIdToMbps[MaxDesire]));
3079 // max tx rate = min {max desire rate, max supported rate}
3080 if (MaxSupport < MaxDesire)
3081 pAd->CommonCfg.MaxTxRate = MaxSupport;
3082 else
3083 pAd->CommonCfg.MaxTxRate = MaxDesire;
3084
3085 pAd->CommonCfg.MinTxRate = MinSupport;
3086 // 2003-07-31 john - 2500 doesn't have good sensitivity at high OFDM rates. to increase the success
3087 // ratio of initial DHCP packet exchange, TX rate starts from a lower rate depending
3088 // on average RSSI
3089 // 1. RSSI >= -70db, start at 54 Mbps (short distance)
3090 // 2. -70 > RSSI >= -75, start at 24 Mbps (mid distance)
3091 // 3. -75 > RSSI, start at 11 Mbps (long distance)
3092 //if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)/* &&
3093 // OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)*/)
3094 if (*auto_rate_cur_p)
3095 {
3096 short dbm = 0;
3097#ifdef CONFIG_STA_SUPPORT
3098 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3099 dbm = pAd->StaCfg.RssiSample.AvgRssi0 - pAd->BbpRssiToDbmDelta;
3100#endif // CONFIG_STA_SUPPORT //
3101 if (bLinkUp == TRUE)
3102 pAd->CommonCfg.TxRate = RATE_24;
3103 else
3104 pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
3105
3106 if (dbm < -75)
3107 pAd->CommonCfg.TxRate = RATE_11;
3108 else if (dbm < -70)
3109 pAd->CommonCfg.TxRate = RATE_24;
3110
3111 // should never exceed MaxTxRate (consider 11B-only mode)
3112 if (pAd->CommonCfg.TxRate > pAd->CommonCfg.MaxTxRate)
3113 pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
3114
3115 pAd->CommonCfg.TxRateIndex = 0;
3116 }
3117 else
3118 {
3119 pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
3120 pHtPhy->field.MCS = (pAd->CommonCfg.MaxTxRate > 3) ? (pAd->CommonCfg.MaxTxRate - 4) : pAd->CommonCfg.MaxTxRate;
3121 pHtPhy->field.MODE = (pAd->CommonCfg.MaxTxRate > 3) ? MODE_OFDM : MODE_CCK;
3122
3123 pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC = pHtPhy->field.STBC;
3124 pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI = pHtPhy->field.ShortGI;
3125 pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS = pHtPhy->field.MCS;
3126 pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE = pHtPhy->field.MODE;
3127 }
3128
3129 if (pAd->CommonCfg.TxRate <= RATE_11)
3130 {
3131 pMaxHtPhy->field.MODE = MODE_CCK;
3132 pMaxHtPhy->field.MCS = pAd->CommonCfg.TxRate;
3133 pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;
3134 }
3135 else
3136 {
3137 pMaxHtPhy->field.MODE = MODE_OFDM;
3138 pMaxHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.TxRate];
3139 if (pAd->CommonCfg.MinTxRate >= RATE_6 && (pAd->CommonCfg.MinTxRate <= RATE_54))
3140 {pMinHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MinTxRate];}
3141 else
3142 {pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;}
3143 }
3144
3145 pHtPhy->word = (pMaxHtPhy->word);
3146 if (bLinkUp && (pAd->OpMode == OPMODE_STA))
3147 {
3148 pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word = pHtPhy->word;
3149 pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word = pMaxHtPhy->word;
3150 pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word = pMinHtPhy->word;
3151 }
3152 else
3153 {
3154 switch (pAd->CommonCfg.PhyMode)
3155 {
3156 case PHY_11BG_MIXED:
3157 case PHY_11B:
3158#ifdef DOT11_N_SUPPORT
3159 case PHY_11BGN_MIXED:
3160#endif // DOT11_N_SUPPORT //
3161 pAd->CommonCfg.MlmeRate = RATE_1;
3162 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
3163 pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
3164
3165//#ifdef WIFI_TEST
3166 pAd->CommonCfg.RtsRate = RATE_11;
3167//#else
3168// pAd->CommonCfg.RtsRate = RATE_1;
3169//#endif
3170 break;
3171 case PHY_11G:
3172 case PHY_11A:
3173#ifdef DOT11_N_SUPPORT
3174 case PHY_11AGN_MIXED:
3175 case PHY_11GN_MIXED:
3176 case PHY_11N_2_4G:
3177 case PHY_11AN_MIXED:
3178 case PHY_11N_5G:
3179#endif // DOT11_N_SUPPORT //
3180 pAd->CommonCfg.MlmeRate = RATE_6;
3181 pAd->CommonCfg.RtsRate = RATE_6;
3182 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
3183 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
3184 break;
3185 case PHY_11ABG_MIXED:
3186#ifdef DOT11_N_SUPPORT
3187 case PHY_11ABGN_MIXED:
3188#endif // DOT11_N_SUPPORT //
3189 if (pAd->CommonCfg.Channel <= 14)
3190 {
3191 pAd->CommonCfg.MlmeRate = RATE_1;
3192 pAd->CommonCfg.RtsRate = RATE_1;
3193 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
3194 pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
3195 }
3196 else
3197 {
3198 pAd->CommonCfg.MlmeRate = RATE_6;
3199 pAd->CommonCfg.RtsRate = RATE_6;
3200 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
3201 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
3202 }
3203 break;
3204 default: // error
3205 pAd->CommonCfg.MlmeRate = RATE_6;
3206 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
3207 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
3208 pAd->CommonCfg.RtsRate = RATE_1;
3209 break;
3210 }
3211 //
3212 // Keep Basic Mlme Rate.
3213 //
3214 pAd->MacTab.Content[MCAST_WCID].HTPhyMode.word = pAd->CommonCfg.MlmeTransmit.word;
3215 if (pAd->CommonCfg.MlmeTransmit.field.MODE == MODE_OFDM)
3216 pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[RATE_24];
3217 else
3218 pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS = RATE_1;
3219 pAd->CommonCfg.BasicMlmeRate = pAd->CommonCfg.MlmeRate;
3220 }
3221
3222 DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (MaxDesire=%d, MaxSupport=%d, MaxTxRate=%d, MinRate=%d, Rate Switching =%d)\n",
3223 RateIdToMbps[MaxDesire], RateIdToMbps[MaxSupport], RateIdToMbps[pAd->CommonCfg.MaxTxRate], RateIdToMbps[pAd->CommonCfg.MinTxRate],
3224 /*OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)*/*auto_rate_cur_p));
3225 DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (TxRate=%d, RtsRate=%d, BasicRateBitmap=0x%04lx)\n",
3226 RateIdToMbps[pAd->CommonCfg.TxRate], RateIdToMbps[pAd->CommonCfg.RtsRate], BasicRateBitmap));
3227 DBGPRINT(RT_DEBUG_TRACE, ("MlmeUpdateTxRates (MlmeTransmit=0x%x, MinHTPhyMode=%x, MaxHTPhyMode=0x%x, HTPhyMode=0x%x)\n",
3228 pAd->CommonCfg.MlmeTransmit.word, pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word ,pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word ,pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word ));
3229}
3230
3231#ifdef DOT11_N_SUPPORT
3232/*
3233 ==========================================================================
3234 Description:
3235 This function update HT Rate setting.
3236 Input Wcid value is valid for 2 case :
3237 1. it's used for Station in infra mode that copy AP rate to Mactable.
3238 2. OR Station in adhoc mode to copy peer's HT rate to Mactable.
3239
3240 IRQL = DISPATCH_LEVEL
3241
3242 ==========================================================================
3243 */
3244VOID MlmeUpdateHtTxRates(
3245 IN PRTMP_ADAPTER pAd,
3246 IN UCHAR apidx)
3247{
3248 UCHAR StbcMcs; //j, StbcMcs, bitmask;
3249 CHAR i; // 3*3
3250 RT_HT_CAPABILITY *pRtHtCap = NULL;
3251 RT_HT_PHY_INFO *pActiveHtPhy = NULL;
3252 ULONG BasicMCS;
3253 UCHAR j, bitmask;
3254 PRT_HT_PHY_INFO pDesireHtPhy = NULL;
3255 PHTTRANSMIT_SETTING pHtPhy = NULL;
3256 PHTTRANSMIT_SETTING pMaxHtPhy = NULL;
3257 PHTTRANSMIT_SETTING pMinHtPhy = NULL;
3258 BOOLEAN *auto_rate_cur_p;
3259
3260 DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates===> \n"));
3261
3262 auto_rate_cur_p = NULL;
3263
3264#ifdef CONFIG_STA_SUPPORT
3265 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3266 {
3267 pDesireHtPhy = &pAd->StaCfg.DesiredHtPhyInfo;
3268 pActiveHtPhy = &pAd->StaCfg.DesiredHtPhyInfo;
3269 pHtPhy = &pAd->StaCfg.HTPhyMode;
3270 pMaxHtPhy = &pAd->StaCfg.MaxHTPhyMode;
3271 pMinHtPhy = &pAd->StaCfg.MinHTPhyMode;
3272
3273 auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch;
3274 }
3275#endif // CONFIG_STA_SUPPORT //
3276
3277#ifdef CONFIG_STA_SUPPORT
3278 if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA))
3279 {
3280 if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
3281 return;
3282
3283 pRtHtCap = &pAd->StaActive.SupportedHtPhy;
3284 pActiveHtPhy = &pAd->StaActive.SupportedPhyInfo;
3285 StbcMcs = (UCHAR)pAd->MlmeAux.AddHtInfo.AddHtInfo3.StbcMcs;
3286 BasicMCS =pAd->MlmeAux.AddHtInfo.MCSSet[0]+(pAd->MlmeAux.AddHtInfo.MCSSet[1]<<8)+(StbcMcs<<16);
3287 if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC) && (pAd->Antenna.field.TxPath == 2))
3288 pMaxHtPhy->field.STBC = STBC_USE;
3289 else
3290 pMaxHtPhy->field.STBC = STBC_NONE;
3291 }
3292 else
3293#endif // CONFIG_STA_SUPPORT //
3294 {
3295 if (pDesireHtPhy->bHtEnable == FALSE)
3296 return;
3297
3298 pRtHtCap = &pAd->CommonCfg.DesiredHtPhy;
3299 StbcMcs = (UCHAR)pAd->CommonCfg.AddHTInfo.AddHtInfo3.StbcMcs;
3300 BasicMCS = pAd->CommonCfg.AddHTInfo.MCSSet[0]+(pAd->CommonCfg.AddHTInfo.MCSSet[1]<<8)+(StbcMcs<<16);
3301 if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC) && (pAd->Antenna.field.TxPath == 2))
3302 pMaxHtPhy->field.STBC = STBC_USE;
3303 else
3304 pMaxHtPhy->field.STBC = STBC_NONE;
3305 }
3306
3307 // Decide MAX ht rate.
3308 if ((pRtHtCap->GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
3309 pMaxHtPhy->field.MODE = MODE_HTGREENFIELD;
3310 else
3311 pMaxHtPhy->field.MODE = MODE_HTMIX;
3312
3313 if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth) && (pRtHtCap->ChannelWidth))
3314 pMaxHtPhy->field.BW = BW_40;
3315 else
3316 pMaxHtPhy->field.BW = BW_20;
3317
3318 if (pMaxHtPhy->field.BW == BW_20)
3319 pMaxHtPhy->field.ShortGI = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 & pRtHtCap->ShortGIfor20);
3320 else
3321 pMaxHtPhy->field.ShortGI = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 & pRtHtCap->ShortGIfor40);
3322
3323 for (i=23; i>=0; i--) // 3*3
3324 {
3325 j = i/8;
3326 bitmask = (1<<(i-(j*8)));
3327
3328 if ((pActiveHtPhy->MCSSet[j] & bitmask) && (pDesireHtPhy->MCSSet[j] & bitmask))
3329 {
3330 pMaxHtPhy->field.MCS = i;
3331 break;
3332 }
3333
3334 if (i==0)
3335 break;
3336 }
3337
3338 // Copy MIN ht rate. rt2860???
3339 pMinHtPhy->field.BW = BW_20;
3340 pMinHtPhy->field.MCS = 0;
3341 pMinHtPhy->field.STBC = 0;
3342 pMinHtPhy->field.ShortGI = 0;
3343 //If STA assigns fixed rate. update to fixed here.
3344#ifdef CONFIG_STA_SUPPORT
3345 if ( (pAd->OpMode == OPMODE_STA) && (pDesireHtPhy->MCSSet[0] != 0xff))
3346 {
3347 if (pDesireHtPhy->MCSSet[4] != 0)
3348 {
3349 pMaxHtPhy->field.MCS = 32;
3350 pMinHtPhy->field.MCS = 32;
3351 DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== Use Fixed MCS = %d\n",pMinHtPhy->field.MCS));
3352 }
3353
3354 for (i=23; (CHAR)i >= 0; i--) // 3*3
3355 {
3356 j = i/8;
3357 bitmask = (1<<(i-(j*8)));
3358 if ( (pDesireHtPhy->MCSSet[j] & bitmask) && (pActiveHtPhy->MCSSet[j] & bitmask))
3359 {
3360 pMaxHtPhy->field.MCS = i;
3361 pMinHtPhy->field.MCS = i;
3362 break;
3363 }
3364 if (i==0)
3365 break;
3366 }
3367 }
3368#endif // CONFIG_STA_SUPPORT //
3369
3370
3371 // Decide ht rate
3372 pHtPhy->field.STBC = pMaxHtPhy->field.STBC;
3373 pHtPhy->field.BW = pMaxHtPhy->field.BW;
3374 pHtPhy->field.MODE = pMaxHtPhy->field.MODE;
3375 pHtPhy->field.MCS = pMaxHtPhy->field.MCS;
3376 pHtPhy->field.ShortGI = pMaxHtPhy->field.ShortGI;
3377
3378 // use default now. rt2860
3379 if (pDesireHtPhy->MCSSet[0] != 0xff)
3380 *auto_rate_cur_p = FALSE;
3381 else
3382 *auto_rate_cur_p = TRUE;
3383
3384 DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateHtTxRates<---.AMsduSize = %d \n", pAd->CommonCfg.DesiredHtPhy.AmsduSize ));
3385 DBGPRINT(RT_DEBUG_TRACE,("TX: MCS[0] = %x (choose %d), BW = %d, ShortGI = %d, MODE = %d, \n", pActiveHtPhy->MCSSet[0],pHtPhy->field.MCS,
3386 pHtPhy->field.BW, pHtPhy->field.ShortGI, pHtPhy->field.MODE));
3387 DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== \n"));
3388}
3389#endif // DOT11_N_SUPPORT //
3390
3391// IRQL = DISPATCH_LEVEL
3392VOID MlmeRadioOff(
3393 IN PRTMP_ADAPTER pAd)
3394{
3395 RT28XX_MLME_RADIO_OFF(pAd);
3396}
3397
3398// IRQL = DISPATCH_LEVEL
3399VOID MlmeRadioOn(
3400 IN PRTMP_ADAPTER pAd)
3401{
3402 RT28XX_MLME_RADIO_ON(pAd);
3403}
3404
3405// ===========================================================================================
3406// bss_table.c
3407// ===========================================================================================
3408
3409
3410/*! \brief initialize BSS table
3411 * \param p_tab pointer to the table
3412 * \return none
3413 * \pre
3414 * \post
3415
3416 IRQL = PASSIVE_LEVEL
3417 IRQL = DISPATCH_LEVEL
3418
3419 */
3420VOID BssTableInit(
3421 IN BSS_TABLE *Tab)
3422{
3423 int i;
3424
3425 Tab->BssNr = 0;
3426 Tab->BssOverlapNr = 0;
3427 for (i = 0; i < MAX_LEN_OF_BSS_TABLE; i++)
3428 {
3429 NdisZeroMemory(&Tab->BssEntry[i], sizeof(BSS_ENTRY));
3430 Tab->BssEntry[i].Rssi = -127; // initial the rssi as a minimum value
3431 }
3432}
3433
3434#ifdef DOT11_N_SUPPORT
3435VOID BATableInit(
3436 IN PRTMP_ADAPTER pAd,
3437 IN BA_TABLE *Tab)
3438{
3439 int i;
3440
3441 Tab->numAsOriginator = 0;
3442 Tab->numAsRecipient = 0;
3443 NdisAllocateSpinLock(&pAd->BATabLock);
3444 for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++)
3445 {
3446 Tab->BARecEntry[i].REC_BA_Status = Recipient_NONE;
3447 NdisAllocateSpinLock(&(Tab->BARecEntry[i].RxReRingLock));
3448 }
3449 for (i = 0; i < MAX_LEN_OF_BA_ORI_TABLE; i++)
3450 {
3451 Tab->BAOriEntry[i].ORI_BA_Status = Originator_NONE;
3452 }
3453}
3454#endif // DOT11_N_SUPPORT //
3455
3456/*! \brief search the BSS table by SSID
3457 * \param p_tab pointer to the bss table
3458 * \param ssid SSID string
3459 * \return index of the table, BSS_NOT_FOUND if not in the table
3460 * \pre
3461 * \post
3462 * \note search by sequential search
3463
3464 IRQL = DISPATCH_LEVEL
3465
3466 */
3467ULONG BssTableSearch(
3468 IN BSS_TABLE *Tab,
3469 IN PUCHAR pBssid,
3470 IN UCHAR Channel)
3471{
3472 UCHAR i;
3473
3474 for (i = 0; i < Tab->BssNr; i++)
3475 {
3476 //
3477 // Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G.
3478 // We should distinguish this case.
3479 //
3480 if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
3481 ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
3482 MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid))
3483 {
3484 return i;
3485 }
3486 }
3487 return (ULONG)BSS_NOT_FOUND;
3488}
3489
3490ULONG BssSsidTableSearch(
3491 IN BSS_TABLE *Tab,
3492 IN PUCHAR pBssid,
3493 IN PUCHAR pSsid,
3494 IN UCHAR SsidLen,
3495 IN UCHAR Channel)
3496{
3497 UCHAR i;
3498
3499 for (i = 0; i < Tab->BssNr; i++)
3500 {
3501 //
3502 // Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G.
3503 // We should distinguish this case.
3504 //
3505 if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
3506 ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
3507 MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid) &&
3508 SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen))
3509 {
3510 return i;
3511 }
3512 }
3513 return (ULONG)BSS_NOT_FOUND;
3514}
3515
3516ULONG BssTableSearchWithSSID(
3517 IN BSS_TABLE *Tab,
3518 IN PUCHAR Bssid,
3519 IN PUCHAR pSsid,
3520 IN UCHAR SsidLen,
3521 IN UCHAR Channel)
3522{
3523 UCHAR i;
3524
3525 for (i = 0; i < Tab->BssNr; i++)
3526 {
3527 if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
3528 ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
3529 MAC_ADDR_EQUAL(&(Tab->BssEntry[i].Bssid), Bssid) &&
3530 (SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen) ||
3531 (NdisEqualMemory(pSsid, ZeroSsid, SsidLen)) ||
3532 (NdisEqualMemory(Tab->BssEntry[i].Ssid, ZeroSsid, Tab->BssEntry[i].SsidLen))))
3533 {
3534 return i;
3535 }
3536 }
3537 return (ULONG)BSS_NOT_FOUND;
3538}
3539
3540// IRQL = DISPATCH_LEVEL
3541VOID BssTableDeleteEntry(
3542 IN OUT BSS_TABLE *Tab,
3543 IN PUCHAR pBssid,
3544 IN UCHAR Channel)
3545{
3546 UCHAR i, j;
3547
3548 for (i = 0; i < Tab->BssNr; i++)
3549 {
3550 if ((Tab->BssEntry[i].Channel == Channel) &&
3551 (MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid)))
3552 {
3553 for (j = i; j < Tab->BssNr - 1; j++)
3554 {
3555 NdisMoveMemory(&(Tab->BssEntry[j]), &(Tab->BssEntry[j + 1]), sizeof(BSS_ENTRY));
3556 }
3557 NdisZeroMemory(&(Tab->BssEntry[Tab->BssNr - 1]), sizeof(BSS_ENTRY));
3558 Tab->BssNr -= 1;
3559 return;
3560 }
3561 }
3562}
3563
3564#ifdef DOT11_N_SUPPORT
3565/*
3566 ========================================================================
3567 Routine Description:
3568 Delete the Originator Entry in BAtable. Or decrease numAs Originator by 1 if needed.
3569
3570 Arguments:
3571 // IRQL = DISPATCH_LEVEL
3572 ========================================================================
3573*/
3574VOID BATableDeleteORIEntry(
3575 IN OUT PRTMP_ADAPTER pAd,
3576 IN BA_ORI_ENTRY *pBAORIEntry)
3577{
3578
3579 if (pBAORIEntry->ORI_BA_Status != Originator_NONE)
3580 {
3581 NdisAcquireSpinLock(&pAd->BATabLock);
3582 if (pBAORIEntry->ORI_BA_Status == Originator_Done)
3583 {
3584 pAd->BATable.numAsOriginator -= 1;
3585 DBGPRINT(RT_DEBUG_TRACE, ("BATableDeleteORIEntry numAsOriginator= %ld\n", pAd->BATable.numAsRecipient));
3586 // Erase Bitmap flag.
3587 }
3588 pAd->MacTab.Content[pBAORIEntry->Wcid].TXBAbitmap &= (~(1<<(pBAORIEntry->TID) )); // If STA mode, erase flag here
3589 pAd->MacTab.Content[pBAORIEntry->Wcid].BAOriWcidArray[pBAORIEntry->TID] = 0; // If STA mode, erase flag here
3590 pBAORIEntry->ORI_BA_Status = Originator_NONE;
3591 pBAORIEntry->Token = 1;
3592 // Not clear Sequence here.
3593 NdisReleaseSpinLock(&pAd->BATabLock);
3594 }
3595}
3596#endif // DOT11_N_SUPPORT //
3597
3598/*! \brief
3599 * \param
3600 * \return
3601 * \pre
3602 * \post
3603
3604 IRQL = DISPATCH_LEVEL
3605
3606 */
3607VOID BssEntrySet(
3608 IN PRTMP_ADAPTER pAd,
3609 OUT BSS_ENTRY *pBss,
3610 IN PUCHAR pBssid,
3611 IN CHAR Ssid[],
3612 IN UCHAR SsidLen,
3613 IN UCHAR BssType,
3614 IN USHORT BeaconPeriod,
3615 IN PCF_PARM pCfParm,
3616 IN USHORT AtimWin,
3617 IN USHORT CapabilityInfo,
3618 IN UCHAR SupRate[],
3619 IN UCHAR SupRateLen,
3620 IN UCHAR ExtRate[],
3621 IN UCHAR ExtRateLen,
3622 IN HT_CAPABILITY_IE *pHtCapability,
3623 IN ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
3624 IN UCHAR HtCapabilityLen,
3625 IN UCHAR AddHtInfoLen,
3626 IN UCHAR NewExtChanOffset,
3627 IN UCHAR Channel,
3628 IN CHAR Rssi,
3629 IN LARGE_INTEGER TimeStamp,
3630 IN UCHAR CkipFlag,
3631 IN PEDCA_PARM pEdcaParm,
3632 IN PQOS_CAPABILITY_PARM pQosCapability,
3633 IN PQBSS_LOAD_PARM pQbssLoad,
3634 IN USHORT LengthVIE,
3635 IN PNDIS_802_11_VARIABLE_IEs pVIE)
3636{
3637 COPY_MAC_ADDR(pBss->Bssid, pBssid);
3638 // Default Hidden SSID to be TRUE, it will be turned to FALSE after coping SSID
3639 pBss->Hidden = 1;
3640 if (SsidLen > 0)
3641 {
3642 // For hidden SSID AP, it might send beacon with SSID len equal to 0
3643 // Or send beacon /probe response with SSID len matching real SSID length,
3644 // but SSID is all zero. such as "00-00-00-00" with length 4.
3645 // We have to prevent this case overwrite correct table
3646 if (NdisEqualMemory(Ssid, ZeroSsid, SsidLen) == 0)
3647 {
3648 NdisZeroMemory(pBss->Ssid, MAX_LEN_OF_SSID);
3649 NdisMoveMemory(pBss->Ssid, Ssid, SsidLen);
3650 pBss->SsidLen = SsidLen;
3651 pBss->Hidden = 0;
3652 }
3653 }
3654 else
3655 pBss->SsidLen = 0;
3656 pBss->BssType = BssType;
3657 pBss->BeaconPeriod = BeaconPeriod;
3658 if (BssType == BSS_INFRA)
3659 {
3660 if (pCfParm->bValid)
3661 {
3662 pBss->CfpCount = pCfParm->CfpCount;
3663 pBss->CfpPeriod = pCfParm->CfpPeriod;
3664 pBss->CfpMaxDuration = pCfParm->CfpMaxDuration;
3665 pBss->CfpDurRemaining = pCfParm->CfpDurRemaining;
3666 }
3667 }
3668 else
3669 {
3670 pBss->AtimWin = AtimWin;
3671 }
3672
3673 pBss->CapabilityInfo = CapabilityInfo;
3674 // The privacy bit indicate security is ON, it maight be WEP, TKIP or AES
3675 // Combine with AuthMode, they will decide the connection methods.
3676 pBss->Privacy = CAP_IS_PRIVACY_ON(pBss->CapabilityInfo);
3677 ASSERT(SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
3678 if (SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES)
3679 NdisMoveMemory(pBss->SupRate, SupRate, SupRateLen);
3680 else
3681 NdisMoveMemory(pBss->SupRate, SupRate, MAX_LEN_OF_SUPPORTED_RATES);
3682 pBss->SupRateLen = SupRateLen;
3683 ASSERT(ExtRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
3684 NdisMoveMemory(pBss->ExtRate, ExtRate, ExtRateLen);
3685 NdisMoveMemory(&pBss->HtCapability, pHtCapability, HtCapabilityLen);
3686 NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo, AddHtInfoLen);
3687 pBss->NewExtChanOffset = NewExtChanOffset;
3688 pBss->ExtRateLen = ExtRateLen;
3689 pBss->Channel = Channel;
3690 pBss->CentralChannel = Channel;
3691 pBss->Rssi = Rssi;
3692 // Update CkipFlag. if not exists, the value is 0x0
3693 pBss->CkipFlag = CkipFlag;
3694
3695 // New for microsoft Fixed IEs
3696 NdisMoveMemory(pBss->FixIEs.Timestamp, &TimeStamp, 8);
3697 pBss->FixIEs.BeaconInterval = BeaconPeriod;
3698 pBss->FixIEs.Capabilities = CapabilityInfo;
3699
3700 // New for microsoft Variable IEs
3701 if (LengthVIE != 0)
3702 {
3703 pBss->VarIELen = LengthVIE;
3704 NdisMoveMemory(pBss->VarIEs, pVIE, pBss->VarIELen);
3705 }
3706 else
3707 {
3708 pBss->VarIELen = 0;
3709 }
3710
3711 pBss->AddHtInfoLen = 0;
3712 pBss->HtCapabilityLen = 0;
3713#ifdef DOT11_N_SUPPORT
3714 if (HtCapabilityLen> 0)
3715 {
3716 pBss->HtCapabilityLen = HtCapabilityLen;
3717 NdisMoveMemory(&pBss->HtCapability, pHtCapability, HtCapabilityLen);
3718 if (AddHtInfoLen > 0)
3719 {
3720 pBss->AddHtInfoLen = AddHtInfoLen;
3721 NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo, AddHtInfoLen);
3722
3723 if ((pAddHtInfo->ControlChan > 2)&& (pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_BELOW) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40))
3724 {
3725 pBss->CentralChannel = pAddHtInfo->ControlChan - 2;
3726 }
3727 else if ((pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40))
3728 {
3729 pBss->CentralChannel = pAddHtInfo->ControlChan + 2;
3730 }
3731 }
3732 }
3733#endif // DOT11_N_SUPPORT //
3734
3735 BssCipherParse(pBss);
3736
3737 // new for QOS
3738 if (pEdcaParm)
3739 NdisMoveMemory(&pBss->EdcaParm, pEdcaParm, sizeof(EDCA_PARM));
3740 else
3741 pBss->EdcaParm.bValid = FALSE;
3742 if (pQosCapability)
3743 NdisMoveMemory(&pBss->QosCapability, pQosCapability, sizeof(QOS_CAPABILITY_PARM));
3744 else
3745 pBss->QosCapability.bValid = FALSE;
3746 if (pQbssLoad)
3747 NdisMoveMemory(&pBss->QbssLoad, pQbssLoad, sizeof(QBSS_LOAD_PARM));
3748 else
3749 pBss->QbssLoad.bValid = FALSE;
3750
3751#ifdef CONFIG_STA_SUPPORT
3752 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3753 {
3754 PEID_STRUCT pEid;
3755 USHORT Length = 0;
3756
3757
3758 NdisZeroMemory(&pBss->WpaIE.IE[0], MAX_CUSTOM_LEN);
3759 NdisZeroMemory(&pBss->RsnIE.IE[0], MAX_CUSTOM_LEN);
3760#ifdef EXT_BUILD_CHANNEL_LIST
3761 NdisZeroMemory(&pBss->CountryString[0], 3);
3762 pBss->bHasCountryIE = FALSE;
3763#endif // EXT_BUILD_CHANNEL_LIST //
3764 pEid = (PEID_STRUCT) pVIE;
3765 while ((Length + 2 + (USHORT)pEid->Len) <= LengthVIE)
3766 {
3767 switch(pEid->Eid)
3768 {
3769 case IE_WPA:
3770 if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
3771 {
3772 if ((pEid->Len + 2) > MAX_CUSTOM_LEN)
3773 {
3774 pBss->WpaIE.IELen = 0;
3775 break;
3776 }
3777 pBss->WpaIE.IELen = pEid->Len + 2;
3778 NdisMoveMemory(pBss->WpaIE.IE, pEid, pBss->WpaIE.IELen);
3779 }
3780 break;
3781 case IE_RSN:
3782 if (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))
3783 {
3784 if ((pEid->Len + 2) > MAX_CUSTOM_LEN)
3785 {
3786 pBss->RsnIE.IELen = 0;
3787 break;
3788 }
3789 pBss->RsnIE.IELen = pEid->Len + 2;
3790 NdisMoveMemory(pBss->RsnIE.IE, pEid, pBss->RsnIE.IELen);
3791 }
3792 break;
3793#ifdef EXT_BUILD_CHANNEL_LIST
3794 case IE_COUNTRY:
3795 NdisMoveMemory(&pBss->CountryString[0], pEid->Octet, 3);
3796 pBss->bHasCountryIE = TRUE;
3797 break;
3798#endif // EXT_BUILD_CHANNEL_LIST //
3799 }
3800 Length = Length + 2 + (USHORT)pEid->Len; // Eid[1] + Len[1]+ content[Len]
3801 pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
3802 }
3803 }
3804#endif // CONFIG_STA_SUPPORT //
3805}
3806
3807/*!
3808 * \brief insert an entry into the bss table
3809 * \param p_tab The BSS table
3810 * \param Bssid BSSID
3811 * \param ssid SSID
3812 * \param ssid_len Length of SSID
3813 * \param bss_type
3814 * \param beacon_period
3815 * \param timestamp
3816 * \param p_cf
3817 * \param atim_win
3818 * \param cap
3819 * \param rates
3820 * \param rates_len
3821 * \param channel_idx
3822 * \return none
3823 * \pre
3824 * \post
3825 * \note If SSID is identical, the old entry will be replaced by the new one
3826
3827 IRQL = DISPATCH_LEVEL
3828
3829 */
3830ULONG BssTableSetEntry(
3831 IN PRTMP_ADAPTER pAd,
3832 OUT BSS_TABLE *Tab,
3833 IN PUCHAR pBssid,
3834 IN CHAR Ssid[],
3835 IN UCHAR SsidLen,
3836 IN UCHAR BssType,
3837 IN USHORT BeaconPeriod,
3838 IN CF_PARM *CfParm,
3839 IN USHORT AtimWin,
3840 IN USHORT CapabilityInfo,
3841 IN UCHAR SupRate[],
3842 IN UCHAR SupRateLen,
3843 IN UCHAR ExtRate[],
3844 IN UCHAR ExtRateLen,
3845 IN HT_CAPABILITY_IE *pHtCapability,
3846 IN ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
3847 IN UCHAR HtCapabilityLen,
3848 IN UCHAR AddHtInfoLen,
3849 IN UCHAR NewExtChanOffset,
3850 IN UCHAR ChannelNo,
3851 IN CHAR Rssi,
3852 IN LARGE_INTEGER TimeStamp,
3853 IN UCHAR CkipFlag,
3854 IN PEDCA_PARM pEdcaParm,
3855 IN PQOS_CAPABILITY_PARM pQosCapability,
3856 IN PQBSS_LOAD_PARM pQbssLoad,
3857 IN USHORT LengthVIE,
3858 IN PNDIS_802_11_VARIABLE_IEs pVIE)
3859{
3860 ULONG Idx;
3861
3862 Idx = BssTableSearchWithSSID(Tab, pBssid, Ssid, SsidLen, ChannelNo);
3863 if (Idx == BSS_NOT_FOUND)
3864 {
3865 if (Tab->BssNr >= MAX_LEN_OF_BSS_TABLE)
3866 {
3867 //
3868 // It may happen when BSS Table was full.
3869 // The desired AP will not be added into BSS Table
3870 // In this case, if we found the desired AP then overwrite BSS Table.
3871 //
3872 if(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
3873 {
3874 if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, pBssid) ||
3875 SSID_EQUAL(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Ssid, SsidLen))
3876 {
3877 Idx = Tab->BssOverlapNr;
3878 BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin,
3879 CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
3880 NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
3881 Tab->BssOverlapNr = (Tab->BssOverlapNr++) % MAX_LEN_OF_BSS_TABLE;
3882 }
3883 return Idx;
3884 }
3885 else
3886 {
3887 return BSS_NOT_FOUND;
3888 }
3889 }
3890 Idx = Tab->BssNr;
3891 BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin,
3892 CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
3893 NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
3894 Tab->BssNr++;
3895 }
3896 else
3897 {
3898 /* avoid Hidden SSID form beacon to overwirite correct SSID from probe response */
3899 if ((SSID_EQUAL(Ssid, SsidLen, Tab->BssEntry[Idx].Ssid, Tab->BssEntry[Idx].SsidLen)) ||
3900 (NdisEqualMemory(Tab->BssEntry[Idx].Ssid, ZeroSsid, Tab->BssEntry[Idx].SsidLen)))
3901 {
3902 BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod,CfParm, AtimWin,
3903 CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
3904 NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
3905 }
3906 }
3907
3908 return Idx;
3909}
3910
3911#ifdef CONFIG_STA_SUPPORT
3912#ifdef DOT11_N_SUPPORT
3913#ifdef DOT11N_DRAFT3
3914VOID TriEventInit(
3915 IN PRTMP_ADAPTER pAd)
3916{
3917 UCHAR i;
3918
3919 for (i = 0;i < MAX_TRIGGER_EVENT;i++)
3920 pAd->CommonCfg.TriggerEventTab.EventA[i].bValid = FALSE;
3921
3922 pAd->CommonCfg.TriggerEventTab.EventANo = 0;
3923 pAd->CommonCfg.TriggerEventTab.EventBCountDown = 0;
3924}
3925
3926ULONG TriEventTableSetEntry(
3927 IN PRTMP_ADAPTER pAd,
3928 OUT TRIGGER_EVENT_TAB *Tab,
3929 IN PUCHAR pBssid,
3930 IN HT_CAPABILITY_IE *pHtCapability,
3931 IN UCHAR HtCapabilityLen,
3932 IN UCHAR RegClass,
3933 IN UCHAR ChannelNo)
3934{
3935 // Event A
3936 if (HtCapabilityLen == 0)
3937 {
3938 if (Tab->EventANo < MAX_TRIGGER_EVENT)
3939 {
3940 RTMPMoveMemory(Tab->EventA[Tab->EventANo].BSSID, pBssid, 6);
3941 Tab->EventA[Tab->EventANo].bValid = TRUE;
3942 Tab->EventA[Tab->EventANo].Channel = ChannelNo;
3943 Tab->EventA[Tab->EventANo].CDCounter = pAd->CommonCfg.Dot11BssWidthChanTranDelay;
3944 if (RegClass != 0)
3945 {
3946 // Beacon has Regulatory class IE. So use beacon's
3947 Tab->EventA[Tab->EventANo].RegClass = RegClass;
3948 }
3949 else
3950 {
3951 // Use Station's Regulatory class instead.
3952 if (pAd->StaActive.SupportedHtPhy.bHtEnable == TRUE)
3953 {
3954 if (pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel)
3955 {
3956 Tab->EventA[Tab->EventANo].RegClass = 32;
3957 }
3958 else if (pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel)
3959 Tab->EventA[Tab->EventANo].RegClass = 33;
3960 }
3961 else
3962 Tab->EventA[Tab->EventANo].RegClass = ??;
3963
3964 }
3965
3966 Tab->EventANo ++;
3967 }
3968 }
3969 else if (pHtCapability->HtCapInfo.Intolerant40)
3970 {
3971 Tab->EventBCountDown = pAd->CommonCfg.Dot11BssWidthChanTranDelay;
3972 }
3973
3974}
3975
3976/*
3977 ========================================================================
3978 Routine Description:
3979 Trigger Event table Maintainence called once every second.
3980
3981 Arguments:
3982 // IRQL = DISPATCH_LEVEL
3983 ========================================================================
3984*/
3985VOID TriEventCounterMaintenance(
3986 IN PRTMP_ADAPTER pAd)
3987{
3988 UCHAR i;
3989 BOOLEAN bNotify = FALSE;
3990 for (i = 0;i < MAX_TRIGGER_EVENT;i++)
3991 {
3992 if (pAd->CommonCfg.TriggerEventTab.EventA[i].bValid && (pAd->CommonCfg.TriggerEventTab.EventA[i].CDCounter > 0))
3993 {
3994 pAd->CommonCfg.TriggerEventTab.EventA[i].CDCounter--;
3995 if (pAd->CommonCfg.TriggerEventTab.EventA[i].CDCounter == 0)
3996 {
3997 pAd->CommonCfg.TriggerEventTab.EventA[i].bValid = FALSE;
3998 pAd->CommonCfg.TriggerEventTab.EventANo --;
3999 // Need to send 20/40 Coexistence Notify frame if has status change.
4000 bNotify = TRUE;
4001 }
4002 }
4003 }
4004 if (pAd->CommonCfg.TriggerEventTab.EventBCountDown > 0)
4005 {
4006 pAd->CommonCfg.TriggerEventTab.EventBCountDown--;
4007 if (pAd->CommonCfg.TriggerEventTab.EventBCountDown == 0)
4008 bNotify = TRUE;
4009 }
4010
4011 if (bNotify == TRUE)
4012 Update2040CoexistFrameAndNotify(pAd, BSSID_WCID, TRUE);
4013}
4014#endif // DOT11N_DRAFT3 //
4015#endif // DOT11_N_SUPPORT //
4016
4017// IRQL = DISPATCH_LEVEL
4018VOID BssTableSsidSort(
4019 IN PRTMP_ADAPTER pAd,
4020 OUT BSS_TABLE *OutTab,
4021 IN CHAR Ssid[],
4022 IN UCHAR SsidLen)
4023{
4024 INT i;
4025 BssTableInit(OutTab);
4026
4027 for (i = 0; i < pAd->ScanTab.BssNr; i++)
4028 {
4029 BSS_ENTRY *pInBss = &pAd->ScanTab.BssEntry[i];
4030 BOOLEAN bIsHiddenApIncluded = FALSE;
4031
4032 if (((pAd->CommonCfg.bIEEE80211H == 1) &&
4033 (pAd->MlmeAux.Channel > 14) &&
4034 RadarChannelCheck(pAd, pInBss->Channel))
4035#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
4036 || (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
4037#endif // CARRIER_DETECTION_SUPPORT //
4038 )
4039 {
4040 if (pInBss->Hidden)
4041 bIsHiddenApIncluded = TRUE;
4042 }
4043
4044 if ((pInBss->BssType == pAd->StaCfg.BssType) &&
4045 (SSID_EQUAL(Ssid, SsidLen, pInBss->Ssid, pInBss->SsidLen) || bIsHiddenApIncluded))
4046 {
4047 BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
4048
4049
4050#ifdef EXT_BUILD_CHANNEL_LIST
4051 // If no Country IE exists no Connection will be established when IEEE80211dClientMode is strict.
4052 if ((pAd->StaCfg.IEEE80211dClientMode == Rt802_11_D_Strict) &&
4053 (pInBss->bHasCountryIE == FALSE))
4054 {
4055 DBGPRINT(RT_DEBUG_TRACE,("StaCfg.IEEE80211dClientMode == Rt802_11_D_Strict, but this AP doesn't have country IE.\n"));
4056 continue;
4057 }
4058#endif // EXT_BUILD_CHANNEL_LIST //
4059
4060#ifdef DOT11_N_SUPPORT
4061 // 2.4G/5G N only mode
4062 if ((pInBss->HtCapabilityLen == 0) &&
4063 ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)))
4064 {
4065 DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
4066 continue;
4067 }
4068#endif // DOT11_N_SUPPORT //
4069
4070 // New for WPA2
4071 // Check the Authmode first
4072 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
4073 {
4074 // Check AuthMode and AuthModeAux for matching, in case AP support dual-mode
4075 if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) && (pAd->StaCfg.AuthMode != pInBss->AuthModeAux))
4076 // None matched
4077 continue;
4078
4079 // Check cipher suite, AP must have more secured cipher than station setting
4080 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
4081 {
4082 // If it's not mixed mode, we should only let BSS pass with the same encryption
4083 if (pInBss->WPA.bMixMode == FALSE)
4084 if (pAd->StaCfg.WepStatus != pInBss->WPA.GroupCipher)
4085 continue;
4086
4087 // check group cipher
4088 if (pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher)
4089 continue;
4090
4091 // check pairwise cipher, skip if none matched
4092 // If profile set to AES, let it pass without question.
4093 // If profile set to TKIP, we must find one mateched
4094 if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
4095 (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipher) &&
4096 (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipherAux))
4097 continue;
4098 }
4099 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
4100 {
4101 // If it's not mixed mode, we should only let BSS pass with the same encryption
4102 if (pInBss->WPA2.bMixMode == FALSE)
4103 if (pAd->StaCfg.WepStatus != pInBss->WPA2.GroupCipher)
4104 continue;
4105
4106 // check group cipher
4107 if (pAd->StaCfg.WepStatus < pInBss->WPA2.GroupCipher)
4108 continue;
4109
4110 // check pairwise cipher, skip if none matched
4111 // If profile set to AES, let it pass without question.
4112 // If profile set to TKIP, we must find one mateched
4113 if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
4114 (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipher) &&
4115 (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipherAux))
4116 continue;
4117 }
4118 }
4119 // Bss Type matched, SSID matched.
4120 // We will check wepstatus for qualification Bss
4121 else if (pAd->StaCfg.WepStatus != pInBss->WepStatus)
4122 {
4123 DBGPRINT(RT_DEBUG_TRACE,("StaCfg.WepStatus=%d, while pInBss->WepStatus=%d\n", pAd->StaCfg.WepStatus, pInBss->WepStatus));
4124 //
4125 // For the SESv2 case, we will not qualify WepStatus.
4126 //
4127 if (!pInBss->bSES)
4128 continue;
4129 }
4130
4131 // Since the AP is using hidden SSID, and we are trying to connect to ANY
4132 // It definitely will fail. So, skip it.
4133 // CCX also require not even try to connect it!!
4134 if (SsidLen == 0)
4135 continue;
4136
4137#ifdef DOT11_N_SUPPORT
4138 // If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region
4139 // If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead,
4140 if ((pInBss->CentralChannel != pInBss->Channel) &&
4141 (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40))
4142 {
4143 if (RTMPCheckChannel(pAd, pInBss->CentralChannel, pInBss->Channel) == FALSE)
4144 {
4145 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
4146 SetCommonHT(pAd);
4147 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
4148 }
4149 else
4150 {
4151 if (pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BAND_WIDTH_20)
4152 {
4153 SetCommonHT(pAd);
4154 }
4155 }
4156 }
4157#endif // DOT11_N_SUPPORT //
4158
4159 // copy matching BSS from InTab to OutTab
4160 NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY));
4161
4162 OutTab->BssNr++;
4163 }
4164 else if ((pInBss->BssType == pAd->StaCfg.BssType) && (SsidLen == 0))
4165 {
4166 BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
4167
4168
4169#ifdef DOT11_N_SUPPORT
4170 // 2.4G/5G N only mode
4171 if ((pInBss->HtCapabilityLen == 0) &&
4172 ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)))
4173 {
4174 DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
4175 continue;
4176 }
4177#endif // DOT11_N_SUPPORT //
4178
4179 // New for WPA2
4180 // Check the Authmode first
4181 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
4182 {
4183 // Check AuthMode and AuthModeAux for matching, in case AP support dual-mode
4184 if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) && (pAd->StaCfg.AuthMode != pInBss->AuthModeAux))
4185 // None matched
4186 continue;
4187
4188 // Check cipher suite, AP must have more secured cipher than station setting
4189 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
4190 {
4191 // If it's not mixed mode, we should only let BSS pass with the same encryption
4192 if (pInBss->WPA.bMixMode == FALSE)
4193 if (pAd->StaCfg.WepStatus != pInBss->WPA.GroupCipher)
4194 continue;
4195
4196 // check group cipher
4197 if (pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher)
4198 continue;
4199
4200 // check pairwise cipher, skip if none matched
4201 // If profile set to AES, let it pass without question.
4202 // If profile set to TKIP, we must find one mateched
4203 if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
4204 (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipher) &&
4205 (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipherAux))
4206 continue;
4207 }
4208 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
4209 {
4210 // If it's not mixed mode, we should only let BSS pass with the same encryption
4211 if (pInBss->WPA2.bMixMode == FALSE)
4212 if (pAd->StaCfg.WepStatus != pInBss->WPA2.GroupCipher)
4213 continue;
4214
4215 // check group cipher
4216 if (pAd->StaCfg.WepStatus < pInBss->WPA2.GroupCipher)
4217 continue;
4218
4219 // check pairwise cipher, skip if none matched
4220 // If profile set to AES, let it pass without question.
4221 // If profile set to TKIP, we must find one mateched
4222 if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
4223 (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipher) &&
4224 (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipherAux))
4225 continue;
4226 }
4227 }
4228 // Bss Type matched, SSID matched.
4229 // We will check wepstatus for qualification Bss
4230 else if (pAd->StaCfg.WepStatus != pInBss->WepStatus)
4231 continue;
4232
4233#ifdef DOT11_N_SUPPORT
4234 // If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region
4235 // If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead,
4236 if ((pInBss->CentralChannel != pInBss->Channel) &&
4237 (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40))
4238 {
4239 if (RTMPCheckChannel(pAd, pInBss->CentralChannel, pInBss->Channel) == FALSE)
4240 {
4241 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
4242 SetCommonHT(pAd);
4243 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
4244 }
4245 }
4246#endif // DOT11_N_SUPPORT //
4247
4248 // copy matching BSS from InTab to OutTab
4249 NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY));
4250
4251 OutTab->BssNr++;
4252 }
4253
4254 if (OutTab->BssNr >= MAX_LEN_OF_BSS_TABLE)
4255 break;
4256 }
4257
4258 BssTableSortByRssi(OutTab);
4259}
4260
4261
4262// IRQL = DISPATCH_LEVEL
4263VOID BssTableSortByRssi(
4264 IN OUT BSS_TABLE *OutTab)
4265{
4266 INT i, j;
4267 BSS_ENTRY TmpBss;
4268
4269 for (i = 0; i < OutTab->BssNr - 1; i++)
4270 {
4271 for (j = i+1; j < OutTab->BssNr; j++)
4272 {
4273 if (OutTab->BssEntry[j].Rssi > OutTab->BssEntry[i].Rssi)
4274 {
4275 NdisMoveMemory(&TmpBss, &OutTab->BssEntry[j], sizeof(BSS_ENTRY));
4276 NdisMoveMemory(&OutTab->BssEntry[j], &OutTab->BssEntry[i], sizeof(BSS_ENTRY));
4277 NdisMoveMemory(&OutTab->BssEntry[i], &TmpBss, sizeof(BSS_ENTRY));
4278 }
4279 }
4280 }
4281}
4282#endif // CONFIG_STA_SUPPORT //
4283
4284
4285VOID BssCipherParse(
4286 IN OUT PBSS_ENTRY pBss)
4287{
4288 PEID_STRUCT pEid;
4289 PUCHAR pTmp;
4290 PRSN_IE_HEADER_STRUCT pRsnHeader;
4291 PCIPHER_SUITE_STRUCT pCipher;
4292 PAKM_SUITE_STRUCT pAKM;
4293 USHORT Count;
4294 INT Length;
4295 NDIS_802_11_ENCRYPTION_STATUS TmpCipher;
4296
4297 //
4298 // WepStatus will be reset later, if AP announce TKIP or AES on the beacon frame.
4299 //
4300 if (pBss->Privacy)
4301 {
4302 pBss->WepStatus = Ndis802_11WEPEnabled;
4303 }
4304 else
4305 {
4306 pBss->WepStatus = Ndis802_11WEPDisabled;
4307 }
4308 // Set default to disable & open authentication before parsing variable IE
4309 pBss->AuthMode = Ndis802_11AuthModeOpen;
4310 pBss->AuthModeAux = Ndis802_11AuthModeOpen;
4311
4312 // Init WPA setting
4313 pBss->WPA.PairCipher = Ndis802_11WEPDisabled;
4314 pBss->WPA.PairCipherAux = Ndis802_11WEPDisabled;
4315 pBss->WPA.GroupCipher = Ndis802_11WEPDisabled;
4316 pBss->WPA.RsnCapability = 0;
4317 pBss->WPA.bMixMode = FALSE;
4318
4319 // Init WPA2 setting
4320 pBss->WPA2.PairCipher = Ndis802_11WEPDisabled;
4321 pBss->WPA2.PairCipherAux = Ndis802_11WEPDisabled;
4322 pBss->WPA2.GroupCipher = Ndis802_11WEPDisabled;
4323 pBss->WPA2.RsnCapability = 0;
4324 pBss->WPA2.bMixMode = FALSE;
4325
4326
4327 Length = (INT) pBss->VarIELen;
4328
4329 while (Length > 0)
4330 {
4331 // Parse cipher suite base on WPA1 & WPA2, they should be parsed differently
4332 pTmp = ((PUCHAR) pBss->VarIEs) + pBss->VarIELen - Length;
4333 pEid = (PEID_STRUCT) pTmp;
4334 switch (pEid->Eid)
4335 {
4336 case IE_WPA:
4337 //Parse Cisco IE_WPA (LEAP, CCKM, etc.)
4338 if ( NdisEqualMemory((pTmp+8), CISCO_OUI, 3))
4339 {
4340 pTmp += 11;
4341 switch (*pTmp)
4342 {
4343 case 1:
4344 case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
4345 pBss->WepStatus = Ndis802_11Encryption1Enabled;
4346 pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
4347 pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
4348 break;
4349 case 2:
4350 pBss->WepStatus = Ndis802_11Encryption2Enabled;
4351 pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
4352 pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
4353 break;
4354 case 4:
4355 pBss->WepStatus = Ndis802_11Encryption3Enabled;
4356 pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
4357 pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
4358 break;
4359 default:
4360 break;
4361 }
4362
4363 // if Cisco IE_WPA, break
4364 break;
4365 }
4366 else if (NdisEqualMemory(pEid->Octet, SES_OUI, 3) && (pEid->Len == 7))
4367 {
4368 pBss->bSES = TRUE;
4369 break;
4370 }
4371 else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4) != 1)
4372 {
4373 // if unsupported vendor specific IE
4374 break;
4375 }
4376 // Skip OUI, version, and multicast suite
4377 // This part should be improved in the future when AP supported multiple cipher suite.
4378 // For now, it's OK since almost all APs have fixed cipher suite supported.
4379 // pTmp = (PUCHAR) pEid->Octet;
4380 pTmp += 11;
4381
4382 // Cipher Suite Selectors from Spec P802.11i/D3.2 P26.
4383 // Value Meaning
4384 // 0 None
4385 // 1 WEP-40
4386 // 2 Tkip
4387 // 3 WRAP
4388 // 4 AES
4389 // 5 WEP-104
4390 // Parse group cipher
4391 switch (*pTmp)
4392 {
4393 case 1:
4394 case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
4395 pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
4396 break;
4397 case 2:
4398 pBss->WPA.GroupCipher = Ndis802_11Encryption2Enabled;
4399 break;
4400 case 4:
4401 pBss->WPA.GroupCipher = Ndis802_11Encryption3Enabled;
4402 break;
4403 default:
4404 break;
4405 }
4406 // number of unicast suite
4407 pTmp += 1;
4408
4409 // skip all unicast cipher suites
4410 //Count = *(PUSHORT) pTmp;
4411 Count = (pTmp[1]<<8) + pTmp[0];
4412 pTmp += sizeof(USHORT);
4413
4414 // Parsing all unicast cipher suite
4415 while (Count > 0)
4416 {
4417 // Skip OUI
4418 pTmp += 3;
4419 TmpCipher = Ndis802_11WEPDisabled;
4420 switch (*pTmp)
4421 {
4422 case 1:
4423 case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
4424 TmpCipher = Ndis802_11Encryption1Enabled;
4425 break;
4426 case 2:
4427 TmpCipher = Ndis802_11Encryption2Enabled;
4428 break;
4429 case 4:
4430 TmpCipher = Ndis802_11Encryption3Enabled;
4431 break;
4432 default:
4433 break;
4434 }
4435 if (TmpCipher > pBss->WPA.PairCipher)
4436 {
4437 // Move the lower cipher suite to PairCipherAux
4438 pBss->WPA.PairCipherAux = pBss->WPA.PairCipher;
4439 pBss->WPA.PairCipher = TmpCipher;
4440 }
4441 else
4442 {
4443 pBss->WPA.PairCipherAux = TmpCipher;
4444 }
4445 pTmp++;
4446 Count--;
4447 }
4448
4449 // 4. get AKM suite counts
4450 //Count = *(PUSHORT) pTmp;
4451 Count = (pTmp[1]<<8) + pTmp[0];
4452 pTmp += sizeof(USHORT);
4453 pTmp += 3;
4454
4455 switch (*pTmp)
4456 {
4457 case 1:
4458 // Set AP support WPA mode
4459 if (pBss->AuthMode == Ndis802_11AuthModeOpen)
4460 pBss->AuthMode = Ndis802_11AuthModeWPA;
4461 else
4462 pBss->AuthModeAux = Ndis802_11AuthModeWPA;
4463 break;
4464 case 2:
4465 // Set AP support WPA mode
4466 if (pBss->AuthMode == Ndis802_11AuthModeOpen)
4467 pBss->AuthMode = Ndis802_11AuthModeWPAPSK;
4468 else
4469 pBss->AuthModeAux = Ndis802_11AuthModeWPAPSK;
4470 break;
4471 default:
4472 break;
4473 }
4474 pTmp += 1;
4475
4476 // Fixed for WPA-None
4477 if (pBss->BssType == BSS_ADHOC)
4478 {
4479 pBss->AuthMode = Ndis802_11AuthModeWPANone;
4480 pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
4481 pBss->WepStatus = pBss->WPA.GroupCipher;
4482 if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
4483 pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher;
4484 }
4485 else
4486 pBss->WepStatus = pBss->WPA.PairCipher;
4487
4488 // Check the Pair & Group, if different, turn on mixed mode flag
4489 if (pBss->WPA.GroupCipher != pBss->WPA.PairCipher)
4490 pBss->WPA.bMixMode = TRUE;
4491
4492 break;
4493
4494 case IE_RSN:
4495 pRsnHeader = (PRSN_IE_HEADER_STRUCT) pTmp;
4496
4497 // 0. Version must be 1
4498 if (le2cpu16(pRsnHeader->Version) != 1)
4499 break;
4500 pTmp += sizeof(RSN_IE_HEADER_STRUCT);
4501
4502 // 1. Check group cipher
4503 pCipher = (PCIPHER_SUITE_STRUCT) pTmp;
4504 if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
4505 break;
4506
4507 // Parse group cipher
4508 switch (pCipher->Type)
4509 {
4510 case 1:
4511 case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
4512 pBss->WPA2.GroupCipher = Ndis802_11Encryption1Enabled;
4513 break;
4514 case 2:
4515 pBss->WPA2.GroupCipher = Ndis802_11Encryption2Enabled;
4516 break;
4517 case 4:
4518 pBss->WPA2.GroupCipher = Ndis802_11Encryption3Enabled;
4519 break;
4520 default:
4521 break;
4522 }
4523 // set to correct offset for next parsing
4524 pTmp += sizeof(CIPHER_SUITE_STRUCT);
4525
4526 // 2. Get pairwise cipher counts
4527 //Count = *(PUSHORT) pTmp;
4528 Count = (pTmp[1]<<8) + pTmp[0];
4529 pTmp += sizeof(USHORT);
4530
4531 // 3. Get pairwise cipher
4532 // Parsing all unicast cipher suite
4533 while (Count > 0)
4534 {
4535 // Skip OUI
4536 pCipher = (PCIPHER_SUITE_STRUCT) pTmp;
4537 TmpCipher = Ndis802_11WEPDisabled;
4538 switch (pCipher->Type)
4539 {
4540 case 1:
4541 case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
4542 TmpCipher = Ndis802_11Encryption1Enabled;
4543 break;
4544 case 2:
4545 TmpCipher = Ndis802_11Encryption2Enabled;
4546 break;
4547 case 4:
4548 TmpCipher = Ndis802_11Encryption3Enabled;
4549 break;
4550 default:
4551 break;
4552 }
4553 if (TmpCipher > pBss->WPA2.PairCipher)
4554 {
4555 // Move the lower cipher suite to PairCipherAux
4556 pBss->WPA2.PairCipherAux = pBss->WPA2.PairCipher;
4557 pBss->WPA2.PairCipher = TmpCipher;
4558 }
4559 else
4560 {
4561 pBss->WPA2.PairCipherAux = TmpCipher;
4562 }
4563 pTmp += sizeof(CIPHER_SUITE_STRUCT);
4564 Count--;
4565 }
4566
4567 // 4. get AKM suite counts
4568 //Count = *(PUSHORT) pTmp;
4569 Count = (pTmp[1]<<8) + pTmp[0];
4570 pTmp += sizeof(USHORT);
4571
4572 // 5. Get AKM ciphers
4573 pAKM = (PAKM_SUITE_STRUCT) pTmp;
4574 if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
4575 break;
4576
4577 switch (pAKM->Type)
4578 {
4579 case 1:
4580 // Set AP support WPA mode
4581 if (pBss->AuthMode == Ndis802_11AuthModeOpen)
4582 pBss->AuthMode = Ndis802_11AuthModeWPA2;
4583 else
4584 pBss->AuthModeAux = Ndis802_11AuthModeWPA2;
4585 break;
4586 case 2:
4587 // Set AP support WPA mode
4588 if (pBss->AuthMode == Ndis802_11AuthModeOpen)
4589 pBss->AuthMode = Ndis802_11AuthModeWPA2PSK;
4590 else
4591 pBss->AuthModeAux = Ndis802_11AuthModeWPA2PSK;
4592 break;
4593 default:
4594 break;
4595 }
4596 pTmp += (Count * sizeof(AKM_SUITE_STRUCT));
4597
4598 // Fixed for WPA-None
4599 if (pBss->BssType == BSS_ADHOC)
4600 {
4601 pBss->AuthMode = Ndis802_11AuthModeWPANone;
4602 pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
4603 pBss->WPA.PairCipherAux = pBss->WPA2.PairCipherAux;
4604 pBss->WPA.GroupCipher = pBss->WPA2.GroupCipher;
4605 pBss->WepStatus = pBss->WPA.GroupCipher;
4606 if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
4607 pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher;
4608 }
4609 pBss->WepStatus = pBss->WPA2.PairCipher;
4610
4611 // 6. Get RSN capability
4612 //pBss->WPA2.RsnCapability = *(PUSHORT) pTmp;
4613 pBss->WPA2.RsnCapability = (pTmp[1]<<8) + pTmp[0];
4614 pTmp += sizeof(USHORT);
4615
4616 // Check the Pair & Group, if different, turn on mixed mode flag
4617 if (pBss->WPA2.GroupCipher != pBss->WPA2.PairCipher)
4618 pBss->WPA2.bMixMode = TRUE;
4619
4620 break;
4621 default:
4622 break;
4623 }
4624 Length -= (pEid->Len + 2);
4625 }
4626}
4627
4628// ===========================================================================================
4629// mac_table.c
4630// ===========================================================================================
4631
4632/*! \brief generates a random mac address value for IBSS BSSID
4633 * \param Addr the bssid location
4634 * \return none
4635 * \pre
4636 * \post
4637 */
4638VOID MacAddrRandomBssid(
4639 IN PRTMP_ADAPTER pAd,
4640 OUT PUCHAR pAddr)
4641{
4642 INT i;
4643
4644 for (i = 0; i < MAC_ADDR_LEN; i++)
4645 {
4646 pAddr[i] = RandomByte(pAd);
4647 }
4648
4649 pAddr[0] = (pAddr[0] & 0xfe) | 0x02; // the first 2 bits must be 01xxxxxxxx
4650}
4651
4652/*! \brief init the management mac frame header
4653 * \param p_hdr mac header
4654 * \param subtype subtype of the frame
4655 * \param p_ds destination address, don't care if it is a broadcast address
4656 * \return none
4657 * \pre the station has the following information in the pAd->StaCfg
4658 * - bssid
4659 * - station address
4660 * \post
4661 * \note this function initializes the following field
4662
4663 IRQL = PASSIVE_LEVEL
4664 IRQL = DISPATCH_LEVEL
4665
4666 */
4667VOID MgtMacHeaderInit(
4668 IN PRTMP_ADAPTER pAd,
4669 IN OUT PHEADER_802_11 pHdr80211,
4670 IN UCHAR SubType,
4671 IN UCHAR ToDs,
4672 IN PUCHAR pDA,
4673 IN PUCHAR pBssid)
4674{
4675 NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
4676
4677 pHdr80211->FC.Type = BTYPE_MGMT;
4678 pHdr80211->FC.SubType = SubType;
4679// if (SubType == SUBTYPE_ACK) // sample, no use, it will conflict with ACTION frame sub type
4680// pHdr80211->FC.Type = BTYPE_CNTL;
4681 pHdr80211->FC.ToDs = ToDs;
4682 COPY_MAC_ADDR(pHdr80211->Addr1, pDA);
4683#ifdef CONFIG_STA_SUPPORT
4684 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
4685 COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
4686#endif // CONFIG_STA_SUPPORT //
4687 COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
4688}
4689
4690// ===========================================================================================
4691// mem_mgmt.c
4692// ===========================================================================================
4693
4694/*!***************************************************************************
4695 * This routine build an outgoing frame, and fill all information specified
4696 * in argument list to the frame body. The actual frame size is the summation
4697 * of all arguments.
4698 * input params:
4699 * Buffer - pointer to a pre-allocated memory segment
4700 * args - a list of <int arg_size, arg> pairs.
4701 * NOTE NOTE NOTE!!!! the last argument must be NULL, otherwise this
4702 * function will FAIL!!!
4703 * return:
4704 * Size of the buffer
4705 * usage:
4706 * MakeOutgoingFrame(Buffer, output_length, 2, &fc, 2, &dur, 6, p_addr1, 6,p_addr2, END_OF_ARGS);
4707
4708 IRQL = PASSIVE_LEVEL
4709 IRQL = DISPATCH_LEVEL
4710
4711 ****************************************************************************/
4712ULONG MakeOutgoingFrame(
4713 OUT CHAR *Buffer,
4714 OUT ULONG *FrameLen, ...)
4715{
4716 CHAR *p;
4717 int leng;
4718 ULONG TotLeng;
4719 va_list Args;
4720
4721 // calculates the total length
4722 TotLeng = 0;
4723 va_start(Args, FrameLen);
4724 do
4725 {
4726 leng = va_arg(Args, int);
4727 if (leng == END_OF_ARGS)
4728 {
4729 break;
4730 }
4731 p = va_arg(Args, PVOID);
4732 NdisMoveMemory(&Buffer[TotLeng], p, leng);
4733 TotLeng = TotLeng + leng;
4734 } while(TRUE);
4735
4736 va_end(Args); /* clean up */
4737 *FrameLen = TotLeng;
4738 return TotLeng;
4739}
4740
4741// ===========================================================================================
4742// mlme_queue.c
4743// ===========================================================================================
4744
4745/*! \brief Initialize The MLME Queue, used by MLME Functions
4746 * \param *Queue The MLME Queue
4747 * \return Always Return NDIS_STATE_SUCCESS in this implementation
4748 * \pre
4749 * \post
4750 * \note Because this is done only once (at the init stage), no need to be locked
4751
4752 IRQL = PASSIVE_LEVEL
4753
4754 */
4755NDIS_STATUS MlmeQueueInit(
4756 IN MLME_QUEUE *Queue)
4757{
4758 INT i;
4759
4760 NdisAllocateSpinLock(&Queue->Lock);
4761
4762 Queue->Num = 0;
4763 Queue->Head = 0;
4764 Queue->Tail = 0;
4765
4766 for (i = 0; i < MAX_LEN_OF_MLME_QUEUE; i++)
4767 {
4768 Queue->Entry[i].Occupied = FALSE;
4769 Queue->Entry[i].MsgLen = 0;
4770 NdisZeroMemory(Queue->Entry[i].Msg, MGMT_DMA_BUFFER_SIZE);
4771 }
4772
4773 return NDIS_STATUS_SUCCESS;
4774}
4775
4776/*! \brief Enqueue a message for other threads, if they want to send messages to MLME thread
4777 * \param *Queue The MLME Queue
4778 * \param Machine The State Machine Id
4779 * \param MsgType The Message Type
4780 * \param MsgLen The Message length
4781 * \param *Msg The message pointer
4782 * \return TRUE if enqueue is successful, FALSE if the queue is full
4783 * \pre
4784 * \post
4785 * \note The message has to be initialized
4786
4787 IRQL = PASSIVE_LEVEL
4788 IRQL = DISPATCH_LEVEL
4789
4790 */
4791BOOLEAN MlmeEnqueue(
4792 IN PRTMP_ADAPTER pAd,
4793 IN ULONG Machine,
4794 IN ULONG MsgType,
4795 IN ULONG MsgLen,
4796 IN VOID *Msg)
4797{
4798 INT Tail;
4799 MLME_QUEUE *Queue = (MLME_QUEUE *)&pAd->Mlme.Queue;
4800
4801 // Do nothing if the driver is starting halt state.
4802 // This might happen when timer already been fired before cancel timer with mlmehalt
4803 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
4804 return FALSE;
4805
4806 // First check the size, it MUST not exceed the mlme queue size
4807 if (MsgLen > MGMT_DMA_BUFFER_SIZE)
4808 {
4809 DBGPRINT_ERR(("MlmeEnqueue: msg too large, size = %ld \n", MsgLen));
4810 return FALSE;
4811 }
4812
4813 if (MlmeQueueFull(Queue))
4814 {
4815 return FALSE;
4816 }
4817
4818 NdisAcquireSpinLock(&(Queue->Lock));
4819 Tail = Queue->Tail;
4820 Queue->Tail++;
4821 Queue->Num++;
4822 if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE)
4823 {
4824 Queue->Tail = 0;
4825 }
4826
4827 Queue->Entry[Tail].Wcid = RESERVED_WCID;
4828 Queue->Entry[Tail].Occupied = TRUE;
4829 Queue->Entry[Tail].Machine = Machine;
4830 Queue->Entry[Tail].MsgType = MsgType;
4831 Queue->Entry[Tail].MsgLen = MsgLen;
4832
4833 if (Msg != NULL)
4834 {
4835 NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
4836 }
4837
4838 NdisReleaseSpinLock(&(Queue->Lock));
4839 return TRUE;
4840}
4841
4842/*! \brief This function is used when Recv gets a MLME message
4843 * \param *Queue The MLME Queue
4844 * \param TimeStampHigh The upper 32 bit of timestamp
4845 * \param TimeStampLow The lower 32 bit of timestamp
4846 * \param Rssi The receiving RSSI strength
4847 * \param MsgLen The length of the message
4848 * \param *Msg The message pointer
4849 * \return TRUE if everything ok, FALSE otherwise (like Queue Full)
4850 * \pre
4851 * \post
4852
4853 IRQL = DISPATCH_LEVEL
4854
4855 */
4856BOOLEAN MlmeEnqueueForRecv(
4857 IN PRTMP_ADAPTER pAd,
4858 IN ULONG Wcid,
4859 IN ULONG TimeStampHigh,
4860 IN ULONG TimeStampLow,
4861 IN UCHAR Rssi0,
4862 IN UCHAR Rssi1,
4863 IN UCHAR Rssi2,
4864 IN ULONG MsgLen,
4865 IN VOID *Msg,
4866 IN UCHAR Signal)
4867{
4868 INT Tail, Machine;
4869 PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
4870 INT MsgType;
4871 MLME_QUEUE *Queue = (MLME_QUEUE *)&pAd->Mlme.Queue;
4872
4873#ifdef RALINK_ATE
4874 /* Nothing to do in ATE mode */
4875 if(ATE_ON(pAd))
4876 return FALSE;
4877#endif // RALINK_ATE //
4878
4879 // Do nothing if the driver is starting halt state.
4880 // This might happen when timer already been fired before cancel timer with mlmehalt
4881 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
4882 {
4883 DBGPRINT_ERR(("MlmeEnqueueForRecv: fRTMP_ADAPTER_HALT_IN_PROGRESS\n"));
4884 return FALSE;
4885 }
4886
4887 // First check the size, it MUST not exceed the mlme queue size
4888 if (MsgLen > MGMT_DMA_BUFFER_SIZE)
4889 {
4890 DBGPRINT_ERR(("MlmeEnqueueForRecv: frame too large, size = %ld \n", MsgLen));
4891 return FALSE;
4892 }
4893
4894 if (MlmeQueueFull(Queue))
4895 {
4896 return FALSE;
4897 }
4898
4899#ifdef CONFIG_STA_SUPPORT
4900 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
4901 {
4902 if (!MsgTypeSubst(pAd, pFrame, &Machine, &MsgType))
4903 {
4904 DBGPRINT_ERR(("MlmeEnqueueForRecv: un-recongnized mgmt->subtype=%d\n",pFrame->Hdr.FC.SubType));
4905 return FALSE;
4906 }
4907 }
4908#endif // CONFIG_STA_SUPPORT //
4909
4910 // OK, we got all the informations, it is time to put things into queue
4911 NdisAcquireSpinLock(&(Queue->Lock));
4912 Tail = Queue->Tail;
4913 Queue->Tail++;
4914 Queue->Num++;
4915 if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE)
4916 {
4917 Queue->Tail = 0;
4918 }
4919 Queue->Entry[Tail].Occupied = TRUE;
4920 Queue->Entry[Tail].Machine = Machine;
4921 Queue->Entry[Tail].MsgType = MsgType;
4922 Queue->Entry[Tail].MsgLen = MsgLen;
4923 Queue->Entry[Tail].TimeStamp.u.LowPart = TimeStampLow;
4924 Queue->Entry[Tail].TimeStamp.u.HighPart = TimeStampHigh;
4925 Queue->Entry[Tail].Rssi0 = Rssi0;
4926 Queue->Entry[Tail].Rssi1 = Rssi1;
4927 Queue->Entry[Tail].Rssi2 = Rssi2;
4928 Queue->Entry[Tail].Signal = Signal;
4929 Queue->Entry[Tail].Wcid = (UCHAR)Wcid;
4930
4931 Queue->Entry[Tail].Channel = pAd->LatchRfRegs.Channel;
4932
4933 if (Msg != NULL)
4934 {
4935 NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
4936 }
4937
4938 NdisReleaseSpinLock(&(Queue->Lock));
4939
4940 RT28XX_MLME_HANDLER(pAd);
4941
4942 return TRUE;
4943}
4944
4945
4946/*! \brief Dequeue a message from the MLME Queue
4947 * \param *Queue The MLME Queue
4948 * \param *Elem The message dequeued from MLME Queue
4949 * \return TRUE if the Elem contains something, FALSE otherwise
4950 * \pre
4951 * \post
4952
4953 IRQL = DISPATCH_LEVEL
4954
4955 */
4956BOOLEAN MlmeDequeue(
4957 IN MLME_QUEUE *Queue,
4958 OUT MLME_QUEUE_ELEM **Elem)
4959{
4960 NdisAcquireSpinLock(&(Queue->Lock));
4961 *Elem = &(Queue->Entry[Queue->Head]);
4962 Queue->Num--;
4963 Queue->Head++;
4964 if (Queue->Head == MAX_LEN_OF_MLME_QUEUE)
4965 {
4966 Queue->Head = 0;
4967 }
4968 NdisReleaseSpinLock(&(Queue->Lock));
4969 return TRUE;
4970}
4971
4972// IRQL = DISPATCH_LEVEL
4973VOID MlmeRestartStateMachine(
4974 IN PRTMP_ADAPTER pAd)
4975{
4976#ifdef CONFIG_STA_SUPPORT
4977 BOOLEAN Cancelled;
4978#endif // CONFIG_STA_SUPPORT //
4979
4980 DBGPRINT(RT_DEBUG_TRACE, ("MlmeRestartStateMachine \n"));
4981
4982
4983#ifdef CONFIG_STA_SUPPORT
4984 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
4985 {
4986#ifdef QOS_DLS_SUPPORT
4987 UCHAR i;
4988#endif // QOS_DLS_SUPPORT //
4989 // Cancel all timer events
4990 // Be careful to cancel new added timer
4991 RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled);
4992 RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled);
4993 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
4994 RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled);
4995 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled);
4996 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
4997
4998#ifdef QOS_DLS_SUPPORT
4999 for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
5000 {
5001 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &Cancelled);
5002 }
5003#endif // QOS_DLS_SUPPORT //
5004 }
5005#endif // CONFIG_STA_SUPPORT //
5006
5007 // Change back to original channel in case of doing scan
5008 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
5009 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
5010
5011 // Resume MSDU which is turned off durning scan
5012 RTMPResumeMsduTransmission(pAd);
5013
5014#ifdef CONFIG_STA_SUPPORT
5015 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
5016 {
5017 // Set all state machines back IDLE
5018 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
5019 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
5020 pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
5021 pAd->Mlme.AuthRspMachine.CurrState = AUTH_RSP_IDLE;
5022 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
5023 pAd->Mlme.ActMachine.CurrState = ACT_IDLE;
5024#ifdef QOS_DLS_SUPPORT
5025 pAd->Mlme.DlsMachine.CurrState = DLS_IDLE;
5026#endif // QOS_DLS_SUPPORT //
5027 }
5028#endif // CONFIG_STA_SUPPORT //
5029
5030}
5031
5032/*! \brief test if the MLME Queue is empty
5033 * \param *Queue The MLME Queue
5034 * \return TRUE if the Queue is empty, FALSE otherwise
5035 * \pre
5036 * \post
5037
5038 IRQL = DISPATCH_LEVEL
5039
5040 */
5041BOOLEAN MlmeQueueEmpty(
5042 IN MLME_QUEUE *Queue)
5043{
5044 BOOLEAN Ans;
5045
5046 NdisAcquireSpinLock(&(Queue->Lock));
5047 Ans = (Queue->Num == 0);
5048 NdisReleaseSpinLock(&(Queue->Lock));
5049
5050 return Ans;
5051}
5052
5053/*! \brief test if the MLME Queue is full
5054 * \param *Queue The MLME Queue
5055 * \return TRUE if the Queue is empty, FALSE otherwise
5056 * \pre
5057 * \post
5058
5059 IRQL = PASSIVE_LEVEL
5060 IRQL = DISPATCH_LEVEL
5061
5062 */
5063BOOLEAN MlmeQueueFull(
5064 IN MLME_QUEUE *Queue)
5065{
5066 BOOLEAN Ans;
5067
5068 NdisAcquireSpinLock(&(Queue->Lock));
5069 Ans = (Queue->Num == MAX_LEN_OF_MLME_QUEUE || Queue->Entry[Queue->Tail].Occupied);
5070 NdisReleaseSpinLock(&(Queue->Lock));
5071
5072 return Ans;
5073}
5074
5075/*! \brief The destructor of MLME Queue
5076 * \param
5077 * \return
5078 * \pre
5079 * \post
5080 * \note Clear Mlme Queue, Set Queue->Num to Zero.
5081
5082 IRQL = PASSIVE_LEVEL
5083
5084 */
5085VOID MlmeQueueDestroy(
5086 IN MLME_QUEUE *pQueue)
5087{
5088 NdisAcquireSpinLock(&(pQueue->Lock));
5089 pQueue->Num = 0;
5090 pQueue->Head = 0;
5091 pQueue->Tail = 0;
5092 NdisReleaseSpinLock(&(pQueue->Lock));
5093 NdisFreeSpinLock(&(pQueue->Lock));
5094}
5095
5096/*! \brief To substitute the message type if the message is coming from external
5097 * \param pFrame The frame received
5098 * \param *Machine The state machine
5099 * \param *MsgType the message type for the state machine
5100 * \return TRUE if the substitution is successful, FALSE otherwise
5101 * \pre
5102 * \post
5103
5104 IRQL = DISPATCH_LEVEL
5105
5106 */
5107#ifdef CONFIG_STA_SUPPORT
5108BOOLEAN MsgTypeSubst(
5109 IN PRTMP_ADAPTER pAd,
5110 IN PFRAME_802_11 pFrame,
5111 OUT INT *Machine,
5112 OUT INT *MsgType)
5113{
5114 USHORT Seq;
5115 UCHAR EAPType;
5116 PUCHAR pData;
5117
5118 // Pointer to start of data frames including SNAP header
5119 pData = (PUCHAR) pFrame + LENGTH_802_11;
5120
5121 // The only data type will pass to this function is EAPOL frame
5122 if (pFrame->Hdr.FC.Type == BTYPE_DATA)
5123 {
5124 if (NdisEqualMemory(SNAP_AIRONET, pData, LENGTH_802_1_H))
5125 {
5126 // Cisco Aironet SNAP header
5127 *Machine = AIRONET_STATE_MACHINE;
5128 *MsgType = MT2_AIRONET_MSG;
5129 return (TRUE);
5130 }
5131#ifdef LEAP_SUPPORT
5132 if ( pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP ) //LEAP
5133 {
5134 // LEAP frames
5135 *Machine = LEAP_STATE_MACHINE;
5136 EAPType = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 1);
5137 return (LeapMsgTypeSubst(EAPType, MsgType));
5138 }
5139 else
5140#endif // LEAP_SUPPORT //
5141 {
5142 *Machine = WPA_PSK_STATE_MACHINE;
5143 EAPType = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 1);
5144 return(WpaMsgTypeSubst(EAPType, MsgType));
5145 }
5146 }
5147
5148 switch (pFrame->Hdr.FC.SubType)
5149 {
5150 case SUBTYPE_ASSOC_REQ:
5151 *Machine = ASSOC_STATE_MACHINE;
5152 *MsgType = MT2_PEER_ASSOC_REQ;
5153 break;
5154 case SUBTYPE_ASSOC_RSP:
5155 *Machine = ASSOC_STATE_MACHINE;
5156 *MsgType = MT2_PEER_ASSOC_RSP;
5157 break;
5158 case SUBTYPE_REASSOC_REQ:
5159 *Machine = ASSOC_STATE_MACHINE;
5160 *MsgType = MT2_PEER_REASSOC_REQ;
5161 break;
5162 case SUBTYPE_REASSOC_RSP:
5163 *Machine = ASSOC_STATE_MACHINE;
5164 *MsgType = MT2_PEER_REASSOC_RSP;
5165 break;
5166 case SUBTYPE_PROBE_REQ:
5167 *Machine = SYNC_STATE_MACHINE;
5168 *MsgType = MT2_PEER_PROBE_REQ;
5169 break;
5170 case SUBTYPE_PROBE_RSP:
5171 *Machine = SYNC_STATE_MACHINE;
5172 *MsgType = MT2_PEER_PROBE_RSP;
5173 break;
5174 case SUBTYPE_BEACON:
5175 *Machine = SYNC_STATE_MACHINE;
5176 *MsgType = MT2_PEER_BEACON;
5177 break;
5178 case SUBTYPE_ATIM:
5179 *Machine = SYNC_STATE_MACHINE;
5180 *MsgType = MT2_PEER_ATIM;
5181 break;
5182 case SUBTYPE_DISASSOC:
5183 *Machine = ASSOC_STATE_MACHINE;
5184 *MsgType = MT2_PEER_DISASSOC_REQ;
5185 break;
5186 case SUBTYPE_AUTH:
5187 // get the sequence number from payload 24 Mac Header + 2 bytes algorithm
5188 NdisMoveMemory(&Seq, &pFrame->Octet[2], sizeof(USHORT));
5189 if (Seq == 1 || Seq == 3)
5190 {
5191 *Machine = AUTH_RSP_STATE_MACHINE;
5192 *MsgType = MT2_PEER_AUTH_ODD;
5193 }
5194 else if (Seq == 2 || Seq == 4)
5195 {
5196 *Machine = AUTH_STATE_MACHINE;
5197 *MsgType = MT2_PEER_AUTH_EVEN;
5198 }
5199 else
5200 {
5201 return FALSE;
5202 }
5203 break;
5204 case SUBTYPE_DEAUTH:
5205 *Machine = AUTH_RSP_STATE_MACHINE;
5206 *MsgType = MT2_PEER_DEAUTH;
5207 break;
5208 case SUBTYPE_ACTION:
5209 *Machine = ACTION_STATE_MACHINE;
5210 // Sometimes Sta will return with category bytes with MSB = 1, if they receive catogory out of their support
5211 if ((pFrame->Octet[0]&0x7F) > MAX_PEER_CATE_MSG)
5212 {
5213 *MsgType = MT2_ACT_INVALID;
5214 }
5215 else
5216 {
5217 *MsgType = (pFrame->Octet[0]&0x7F);
5218 }
5219 break;
5220 default:
5221 return FALSE;
5222 break;
5223 }
5224
5225 return TRUE;
5226}
5227#endif // CONFIG_STA_SUPPORT //
5228
5229// ===========================================================================================
5230// state_machine.c
5231// ===========================================================================================
5232
5233/*! \brief Initialize the state machine.
5234 * \param *S pointer to the state machine
5235 * \param Trans State machine transition function
5236 * \param StNr number of states
5237 * \param MsgNr number of messages
5238 * \param DefFunc default function, when there is invalid state/message combination
5239 * \param InitState initial state of the state machine
5240 * \param Base StateMachine base, internal use only
5241 * \pre p_sm should be a legal pointer
5242 * \post
5243
5244 IRQL = PASSIVE_LEVEL
5245
5246 */
5247VOID StateMachineInit(
5248 IN STATE_MACHINE *S,
5249 IN STATE_MACHINE_FUNC Trans[],
5250 IN ULONG StNr,
5251 IN ULONG MsgNr,
5252 IN STATE_MACHINE_FUNC DefFunc,
5253 IN ULONG InitState,
5254 IN ULONG Base)
5255{
5256 ULONG i, j;
5257
5258 // set number of states and messages
5259 S->NrState = StNr;
5260 S->NrMsg = MsgNr;
5261 S->Base = Base;
5262
5263 S->TransFunc = Trans;
5264
5265 // init all state transition to default function
5266 for (i = 0; i < StNr; i++)
5267 {
5268 for (j = 0; j < MsgNr; j++)
5269 {
5270 S->TransFunc[i * MsgNr + j] = DefFunc;
5271 }
5272 }
5273
5274 // set the starting state
5275 S->CurrState = InitState;
5276}
5277
5278/*! \brief This function fills in the function pointer into the cell in the state machine
5279 * \param *S pointer to the state machine
5280 * \param St state
5281 * \param Msg incoming message
5282 * \param f the function to be executed when (state, message) combination occurs at the state machine
5283 * \pre *S should be a legal pointer to the state machine, st, msg, should be all within the range, Base should be set in the initial state
5284 * \post
5285
5286 IRQL = PASSIVE_LEVEL
5287
5288 */
5289VOID StateMachineSetAction(
5290 IN STATE_MACHINE *S,
5291 IN ULONG St,
5292 IN ULONG Msg,
5293 IN STATE_MACHINE_FUNC Func)
5294{
5295 ULONG MsgIdx;
5296
5297 MsgIdx = Msg - S->Base;
5298
5299 if (St < S->NrState && MsgIdx < S->NrMsg)
5300 {
5301 // boundary checking before setting the action
5302 S->TransFunc[St * S->NrMsg + MsgIdx] = Func;
5303 }
5304}
5305
5306/*! \brief This function does the state transition
5307 * \param *Adapter the NIC adapter pointer
5308 * \param *S the state machine
5309 * \param *Elem the message to be executed
5310 * \return None
5311
5312 IRQL = DISPATCH_LEVEL
5313
5314 */
5315VOID StateMachinePerformAction(
5316 IN PRTMP_ADAPTER pAd,
5317 IN STATE_MACHINE *S,
5318 IN MLME_QUEUE_ELEM *Elem)
5319{
5320 (*(S->TransFunc[S->CurrState * S->NrMsg + Elem->MsgType - S->Base]))(pAd, Elem);
5321}
5322
5323/*
5324 ==========================================================================
5325 Description:
5326 The drop function, when machine executes this, the message is simply
5327 ignored. This function does nothing, the message is freed in
5328 StateMachinePerformAction()
5329 ==========================================================================
5330 */
5331VOID Drop(
5332 IN PRTMP_ADAPTER pAd,
5333 IN MLME_QUEUE_ELEM *Elem)
5334{
5335}
5336
5337// ===========================================================================================
5338// lfsr.c
5339// ===========================================================================================
5340
5341/*
5342 ==========================================================================
5343 Description:
5344
5345 IRQL = PASSIVE_LEVEL
5346
5347 ==========================================================================
5348 */
5349VOID LfsrInit(
5350 IN PRTMP_ADAPTER pAd,
5351 IN ULONG Seed)
5352{
5353 if (Seed == 0)
5354 pAd->Mlme.ShiftReg = 1;
5355 else
5356 pAd->Mlme.ShiftReg = Seed;
5357}
5358
5359/*
5360 ==========================================================================
5361 Description:
5362 ==========================================================================
5363 */
5364UCHAR RandomByte(
5365 IN PRTMP_ADAPTER pAd)
5366{
5367 ULONG i;
5368 UCHAR R, Result;
5369
5370 R = 0;
5371
5372 if (pAd->Mlme.ShiftReg == 0)
5373 NdisGetSystemUpTime((ULONG *)&pAd->Mlme.ShiftReg);
5374
5375 for (i = 0; i < 8; i++)
5376 {
5377 if (pAd->Mlme.ShiftReg & 0x00000001)
5378 {
5379 pAd->Mlme.ShiftReg = ((pAd->Mlme.ShiftReg ^ LFSR_MASK) >> 1) | 0x80000000;
5380 Result = 1;
5381 }
5382 else
5383 {
5384 pAd->Mlme.ShiftReg = pAd->Mlme.ShiftReg >> 1;
5385 Result = 0;
5386 }
5387 R = (R << 1) | Result;
5388 }
5389
5390 return R;
5391}
5392
5393VOID AsicUpdateAutoFallBackTable(
5394 IN PRTMP_ADAPTER pAd,
5395 IN PUCHAR pRateTable)
5396{
5397 UCHAR i;
5398 HT_FBK_CFG0_STRUC HtCfg0;
5399 HT_FBK_CFG1_STRUC HtCfg1;
5400 LG_FBK_CFG0_STRUC LgCfg0;
5401 LG_FBK_CFG1_STRUC LgCfg1;
5402 PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate;
5403
5404 // set to initial value
5405 HtCfg0.word = 0x65432100;
5406 HtCfg1.word = 0xedcba988;
5407 LgCfg0.word = 0xedcba988;
5408 LgCfg1.word = 0x00002100;
5409
5410 pNextTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1;
5411 for (i = 1; i < *((PUCHAR) pRateTable); i++)
5412 {
5413 pCurrTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1+i;
5414 switch (pCurrTxRate->Mode)
5415 {
5416 case 0: //CCK
5417 break;
5418 case 1: //OFDM
5419 {
5420 switch(pCurrTxRate->CurrMCS)
5421 {
5422 case 0:
5423 LgCfg0.field.OFDMMCS0FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5424 break;
5425 case 1:
5426 LgCfg0.field.OFDMMCS1FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5427 break;
5428 case 2:
5429 LgCfg0.field.OFDMMCS2FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5430 break;
5431 case 3:
5432 LgCfg0.field.OFDMMCS3FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5433 break;
5434 case 4:
5435 LgCfg0.field.OFDMMCS4FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5436 break;
5437 case 5:
5438 LgCfg0.field.OFDMMCS5FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5439 break;
5440 case 6:
5441 LgCfg0.field.OFDMMCS6FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5442 break;
5443 case 7:
5444 LgCfg0.field.OFDMMCS7FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5445 break;
5446 }
5447 }
5448 break;
5449#ifdef DOT11_N_SUPPORT
5450 case 2: //HT-MIX
5451 case 3: //HT-GF
5452 {
5453 if ((pNextTxRate->Mode >= MODE_HTMIX) && (pCurrTxRate->CurrMCS != pNextTxRate->CurrMCS))
5454 {
5455 switch(pCurrTxRate->CurrMCS)
5456 {
5457 case 0:
5458 HtCfg0.field.HTMCS0FBK = pNextTxRate->CurrMCS;
5459 break;
5460 case 1:
5461 HtCfg0.field.HTMCS1FBK = pNextTxRate->CurrMCS;
5462 break;
5463 case 2:
5464 HtCfg0.field.HTMCS2FBK = pNextTxRate->CurrMCS;
5465 break;
5466 case 3:
5467 HtCfg0.field.HTMCS3FBK = pNextTxRate->CurrMCS;
5468 break;
5469 case 4:
5470 HtCfg0.field.HTMCS4FBK = pNextTxRate->CurrMCS;
5471 break;
5472 case 5:
5473 HtCfg0.field.HTMCS5FBK = pNextTxRate->CurrMCS;
5474 break;
5475 case 6:
5476 HtCfg0.field.HTMCS6FBK = pNextTxRate->CurrMCS;
5477 break;
5478 case 7:
5479 HtCfg0.field.HTMCS7FBK = pNextTxRate->CurrMCS;
5480 break;
5481 case 8:
5482 HtCfg1.field.HTMCS8FBK = pNextTxRate->CurrMCS;
5483 break;
5484 case 9:
5485 HtCfg1.field.HTMCS9FBK = pNextTxRate->CurrMCS;
5486 break;
5487 case 10:
5488 HtCfg1.field.HTMCS10FBK = pNextTxRate->CurrMCS;
5489 break;
5490 case 11:
5491 HtCfg1.field.HTMCS11FBK = pNextTxRate->CurrMCS;
5492 break;
5493 case 12:
5494 HtCfg1.field.HTMCS12FBK = pNextTxRate->CurrMCS;
5495 break;
5496 case 13:
5497 HtCfg1.field.HTMCS13FBK = pNextTxRate->CurrMCS;
5498 break;
5499 case 14:
5500 HtCfg1.field.HTMCS14FBK = pNextTxRate->CurrMCS;
5501 break;
5502 case 15:
5503 HtCfg1.field.HTMCS15FBK = pNextTxRate->CurrMCS;
5504 break;
5505 default:
5506 DBGPRINT(RT_DEBUG_ERROR, ("AsicUpdateAutoFallBackTable: not support CurrMCS=%d\n", pCurrTxRate->CurrMCS));
5507 }
5508 }
5509 }
5510 break;
5511#endif // DOT11_N_SUPPORT //
5512 }
5513
5514 pNextTxRate = pCurrTxRate;
5515 }
5516
5517 RTMP_IO_WRITE32(pAd, HT_FBK_CFG0, HtCfg0.word);
5518 RTMP_IO_WRITE32(pAd, HT_FBK_CFG1, HtCfg1.word);
5519 RTMP_IO_WRITE32(pAd, LG_FBK_CFG0, LgCfg0.word);
5520 RTMP_IO_WRITE32(pAd, LG_FBK_CFG1, LgCfg1.word);
5521}
5522
5523/*
5524 ========================================================================
5525
5526 Routine Description:
5527 Set MAC register value according operation mode.
5528 OperationMode AND bNonGFExist are for MM and GF Proteciton.
5529 If MM or GF mask is not set, those passing argument doesn't not take effect.
5530
5531 Operation mode meaning:
5532 = 0 : Pure HT, no preotection.
5533 = 0x01; there may be non-HT devices in both the control and extension channel, protection is optional in BSS.
5534 = 0x10: No Transmission in 40M is protected.
5535 = 0x11: Transmission in both 40M and 20M shall be protected
5536 if (bNonGFExist)
5537 we should choose not to use GF. But still set correct ASIC registers.
5538 ========================================================================
5539*/
5540VOID AsicUpdateProtect(
5541 IN PRTMP_ADAPTER pAd,
5542 IN USHORT OperationMode,
5543 IN UCHAR SetMask,
5544 IN BOOLEAN bDisableBGProtect,
5545 IN BOOLEAN bNonGFExist)
5546{
5547 PROT_CFG_STRUC ProtCfg, ProtCfg4;
5548 UINT32 Protect[6];
5549 USHORT offset;
5550 UCHAR i;
5551 UINT32 MacReg = 0;
5552
5553#ifdef RALINK_ATE
5554 if (ATE_ON(pAd))
5555 return;
5556#endif // RALINK_ATE //
5557
5558#ifdef DOT11_N_SUPPORT
5559 if (!(pAd->CommonCfg.bHTProtect) && (OperationMode != 8))
5560 {
5561 return;
5562 }
5563
5564 if (pAd->BATable.numAsOriginator)
5565 {
5566 //
5567 // enable the RTS/CTS to avoid channel collision
5568 //
5569 SetMask = ALLN_SETPROTECT;
5570 OperationMode = 8;
5571 }
5572#endif // DOT11_N_SUPPORT //
5573
5574 // Config ASIC RTS threshold register
5575 RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg);
5576 MacReg &= 0xFF0000FF;
5577
5578 // If the user want disable RtsThreshold and enbale Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096
5579 if ((
5580#ifdef DOT11_N_SUPPORT
5581 (pAd->CommonCfg.BACapability.field.AmsduEnable) ||
5582#endif // DOT11_N_SUPPORT //
5583 (pAd->CommonCfg.bAggregationCapable == TRUE))
5584 && pAd->CommonCfg.RtsThreshold == MAX_RTS_THRESHOLD)
5585 {
5586 MacReg |= (0x1000 << 8);
5587 }
5588 else
5589 {
5590 MacReg |= (pAd->CommonCfg.RtsThreshold << 8);
5591 }
5592
5593 RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg);
5594
5595 // Initial common protection settings
5596 RTMPZeroMemory(Protect, sizeof(Protect));
5597 ProtCfg4.word = 0;
5598 ProtCfg.word = 0;
5599 ProtCfg.field.TxopAllowGF40 = 1;
5600 ProtCfg.field.TxopAllowGF20 = 1;
5601 ProtCfg.field.TxopAllowMM40 = 1;
5602 ProtCfg.field.TxopAllowMM20 = 1;
5603 ProtCfg.field.TxopAllowOfdm = 1;
5604 ProtCfg.field.TxopAllowCck = 1;
5605 ProtCfg.field.RTSThEn = 1;
5606 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
5607
5608 // update PHY mode and rate
5609 if (pAd->CommonCfg.Channel > 14)
5610 ProtCfg.field.ProtectRate = 0x4000;
5611 ProtCfg.field.ProtectRate |= pAd->CommonCfg.RtsRate;
5612
5613 // Handle legacy(B/G) protection
5614 if (bDisableBGProtect)
5615 {
5616 //ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
5617 ProtCfg.field.ProtectCtrl = 0;
5618 Protect[0] = ProtCfg.word;
5619 Protect[1] = ProtCfg.word;
5620 }
5621 else
5622 {
5623 //ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
5624 ProtCfg.field.ProtectCtrl = 0; // CCK do not need to be protected
5625 Protect[0] = ProtCfg.word;
5626 ProtCfg.field.ProtectCtrl = ASIC_CTS; // OFDM needs using CCK to protect
5627 Protect[1] = ProtCfg.word;
5628 }
5629
5630#ifdef DOT11_N_SUPPORT
5631 // Decide HT frame protection.
5632 if ((SetMask & ALLN_SETPROTECT) != 0)
5633 {
5634 switch(OperationMode)
5635 {
5636 case 0x0:
5637 // NO PROTECT
5638 // 1.All STAs in the BSS are 20/40 MHz HT
5639 // 2. in ai 20/40MHz BSS
5640 // 3. all STAs are 20MHz in a 20MHz BSS
5641 // Pure HT. no protection.
5642
5643 // MM20_PROT_CFG
5644 // Reserved (31:27)
5645 // PROT_TXOP(25:20) -- 010111
5646 // PROT_NAV(19:18) -- 01 (Short NAV protection)
5647 // PROT_CTRL(17:16) -- 00 (None)
5648 // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
5649 Protect[2] = 0x01744004;
5650
5651 // MM40_PROT_CFG
5652 // Reserved (31:27)
5653 // PROT_TXOP(25:20) -- 111111
5654 // PROT_NAV(19:18) -- 01 (Short NAV protection)
5655 // PROT_CTRL(17:16) -- 00 (None)
5656 // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
5657 Protect[3] = 0x03f44084;
5658
5659 // CF20_PROT_CFG
5660 // Reserved (31:27)
5661 // PROT_TXOP(25:20) -- 010111
5662 // PROT_NAV(19:18) -- 01 (Short NAV protection)
5663 // PROT_CTRL(17:16) -- 00 (None)
5664 // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
5665 Protect[4] = 0x01744004;
5666
5667 // CF40_PROT_CFG
5668 // Reserved (31:27)
5669 // PROT_TXOP(25:20) -- 111111
5670 // PROT_NAV(19:18) -- 01 (Short NAV protection)
5671 // PROT_CTRL(17:16) -- 00 (None)
5672 // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
5673 Protect[5] = 0x03f44084;
5674
5675 if (bNonGFExist)
5676 {
5677 // PROT_NAV(19:18) -- 01 (Short NAV protectiion)
5678 // PROT_CTRL(17:16) -- 01 (RTS/CTS)
5679 Protect[4] = 0x01754004;
5680 Protect[5] = 0x03f54084;
5681 }
5682 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
5683 break;
5684
5685 case 1:
5686 // This is "HT non-member protection mode."
5687 // If there may be non-HT STAs my BSS
5688 ProtCfg.word = 0x01744004; // PROT_CTRL(17:16) : 0 (None)
5689 ProtCfg4.word = 0x03f44084; // duplicaet legacy 24M. BW set 1.
5690 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
5691 {
5692 ProtCfg.word = 0x01740003; //ERP use Protection bit is set, use protection rate at Clause 18..
5693 ProtCfg4.word = 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083;
5694 }
5695 //Assign Protection method for 20&40 MHz packets
5696 ProtCfg.field.ProtectCtrl = ASIC_RTS;
5697 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
5698 ProtCfg4.field.ProtectCtrl = ASIC_RTS;
5699 ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
5700 Protect[2] = ProtCfg.word;
5701 Protect[3] = ProtCfg4.word;
5702 Protect[4] = ProtCfg.word;
5703 Protect[5] = ProtCfg4.word;
5704 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
5705 break;
5706
5707 case 2:
5708 // If only HT STAs are in BSS. at least one is 20MHz. Only protect 40MHz packets
5709 ProtCfg.word = 0x01744004; // PROT_CTRL(17:16) : 0 (None)
5710 ProtCfg4.word = 0x03f44084; // duplicaet legacy 24M. BW set 1.
5711
5712 //Assign Protection method for 40MHz packets
5713 ProtCfg4.field.ProtectCtrl = ASIC_RTS;
5714 ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
5715 Protect[2] = ProtCfg.word;
5716 Protect[3] = ProtCfg4.word;
5717 if (bNonGFExist)
5718 {
5719 ProtCfg.field.ProtectCtrl = ASIC_RTS;
5720 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
5721 }
5722 Protect[4] = ProtCfg.word;
5723 Protect[5] = ProtCfg4.word;
5724
5725 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
5726 break;
5727
5728 case 3:
5729 // HT mixed mode. PROTECT ALL!
5730 // Assign Rate
5731 ProtCfg.word = 0x01744004; //duplicaet legacy 24M. BW set 1.
5732 ProtCfg4.word = 0x03f44084;
5733 // both 20MHz and 40MHz are protected. Whether use RTS or CTS-to-self depends on the
5734 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
5735 {
5736 ProtCfg.word = 0x01740003; //ERP use Protection bit is set, use protection rate at Clause 18..
5737 ProtCfg4.word = 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083
5738 }
5739 //Assign Protection method for 20&40 MHz packets
5740 ProtCfg.field.ProtectCtrl = ASIC_RTS;
5741 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
5742 ProtCfg4.field.ProtectCtrl = ASIC_RTS;
5743 ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
5744 Protect[2] = ProtCfg.word;
5745 Protect[3] = ProtCfg4.word;
5746 Protect[4] = ProtCfg.word;
5747 Protect[5] = ProtCfg4.word;
5748 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
5749 break;
5750
5751 case 8:
5752 Protect[2] = 0x01754004;
5753 Protect[3] = 0x03f54084;
5754 Protect[4] = 0x01754004;
5755 Protect[5] = 0x03f54084;
5756 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
5757 break;
5758 }
5759 }
5760#endif // DOT11_N_SUPPORT //
5761
5762 offset = CCK_PROT_CFG;
5763 for (i = 0;i < 6;i++)
5764 {
5765 if ((SetMask & (1<< i)))
5766 {
5767 RTMP_IO_WRITE32(pAd, offset + i*4, Protect[i]);
5768 }
5769 }
5770}
5771
5772
5773#ifdef RT30xx
5774/*
5775 ========================================================================
5776
5777 Routine Description: Write RT30xx RF register through MAC
5778
5779 Arguments:
5780
5781 Return Value:
5782
5783 IRQL =
5784
5785 Note:
5786
5787 ========================================================================
5788*/
5789NTSTATUS RT30xxWriteRFRegister(
5790 IN PRTMP_ADAPTER pAd,
5791 IN UCHAR RegID,
5792 IN UCHAR Value)
5793{
5794 RF_CSR_CFG_STRUC rfcsr;
5795 UINT i = 0;
5796
5797 do
5798 {
5799 RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
5800
5801 if (!rfcsr.field.RF_CSR_KICK)
5802 break;
5803 i++;
5804 }
5805 while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
5806
5807 if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
5808 {
5809 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
5810 return STATUS_UNSUCCESSFUL;
5811 }
5812
5813 rfcsr.field.RF_CSR_WR = 1;
5814 rfcsr.field.RF_CSR_KICK = 1;
5815 rfcsr.field.TESTCSR_RFACC_REGNUM = RegID;
5816 rfcsr.field.RF_CSR_DATA = Value;
5817
5818 RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);
5819
5820 return STATUS_SUCCESS;
5821}
5822
5823
5824/*
5825 ========================================================================
5826
5827 Routine Description: Read RT30xx RF register through MAC
5828
5829 Arguments:
5830
5831 Return Value:
5832
5833 IRQL =
5834
5835 Note:
5836
5837 ========================================================================
5838*/
5839NTSTATUS RT30xxReadRFRegister(
5840 IN PRTMP_ADAPTER pAd,
5841 IN UCHAR RegID,
5842 IN PUCHAR pValue)
5843{
5844 RF_CSR_CFG_STRUC rfcsr;
5845 UINT i=0, k=0;
5846
5847 for (i=0; i<MAX_BUSY_COUNT; i++)
5848 {
5849 RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
5850
5851 if (rfcsr.field.RF_CSR_KICK == BUSY)
5852 {
5853 continue;
5854 }
5855 rfcsr.word = 0;
5856 rfcsr.field.RF_CSR_WR = 0;
5857 rfcsr.field.RF_CSR_KICK = 1;
5858 rfcsr.field.TESTCSR_RFACC_REGNUM = RegID;
5859 RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);
5860 for (k=0; k<MAX_BUSY_COUNT; k++)
5861 {
5862 RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
5863
5864 if (rfcsr.field.RF_CSR_KICK == IDLE)
5865 break;
5866 }
5867 if ((rfcsr.field.RF_CSR_KICK == IDLE) &&
5868 (rfcsr.field.TESTCSR_RFACC_REGNUM == RegID))
5869 {
5870 *pValue = (UCHAR)rfcsr.field.RF_CSR_DATA;
5871 break;
5872 }
5873 }
5874 if (rfcsr.field.RF_CSR_KICK == BUSY)
5875 {
5876 DBGPRINT_ERR(("RF read R%d=0x%x fail, i[%d], k[%d]\n", RegID, rfcsr.word,i,k));
5877 return STATUS_UNSUCCESSFUL;
5878 }
5879
5880 return STATUS_SUCCESS;
5881}
5882#endif // RT30xx //
5883
5884#ifdef RT30xx
5885// add by johnli, RF power sequence setup
5886/*
5887 ==========================================================================
5888 Description:
5889
5890 Load RF normal operation-mode setup
5891
5892 ==========================================================================
5893 */
5894VOID RT30xxLoadRFNormalModeSetup(
5895 IN PRTMP_ADAPTER pAd)
5896{
5897 UCHAR RFValue;
5898
5899 // RX0_PD & TX0_PD, RF R1 register Bit 2 & Bit 3 to 0 and RF_BLOCK_en,RX1_PD & TX1_PD, Bit0, Bit 4 & Bit5 to 1
5900 RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
5901 RFValue = (RFValue & (~0x0C)) | 0x31;
5902 RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
5903
5904 // TX_LO2_en, RF R15 register Bit 3 to 0
5905 RT30xxReadRFRegister(pAd, RF_R15, &RFValue);
5906 RFValue &= (~0x08);
5907 RT30xxWriteRFRegister(pAd, RF_R15, RFValue);
5908
5909 // TX_LO1_en, RF R17 register Bit 3 to 0
5910 RT30xxReadRFRegister(pAd, RF_R17, &RFValue);
5911 RFValue &= (~0x08);
5912 // to fix rx long range issue
5913 if (((pAd->MACVersion & 0xffff) >= 0x0211) && (pAd->NicConfig2.field.ExternalLNAForG == 0))
5914 {
5915 RFValue |= 0x20;
5916 }
5917 RT30xxWriteRFRegister(pAd, RF_R17, RFValue);
5918
5919 // RX_LO1_en, RF R20 register Bit 3 to 0
5920 RT30xxReadRFRegister(pAd, RF_R20, &RFValue);
5921 RFValue &= (~0x08);
5922 RT30xxWriteRFRegister(pAd, RF_R20, RFValue);
5923
5924 // RX_LO2_en, RF R21 register Bit 3 to 0
5925 RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
5926 RFValue &= (~0x08);
5927 RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
5928
5929 // LDORF_VC, RF R27 register Bit 2 to 0
5930 RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
5931 if ((pAd->MACVersion & 0xffff) < 0x0211)
5932 RFValue = (RFValue & (~0x77)) | 0x3;
5933 else
5934 RFValue = (RFValue & (~0x77));
5935 RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
5936 /* end johnli */
5937}
5938
5939/*
5940 ==========================================================================
5941 Description:
5942
5943 Load RF sleep-mode setup
5944
5945 ==========================================================================
5946 */
5947VOID RT30xxLoadRFSleepModeSetup(
5948 IN PRTMP_ADAPTER pAd)
5949{
5950 UCHAR RFValue;
5951 UINT32 MACValue;
5952
5953 // RF_BLOCK_en. RF R1 register Bit 0 to 0
5954 RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
5955 RFValue &= (~0x01);
5956 RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
5957
5958 // VCO_IC, RF R7 register Bit 4 & Bit 5 to 0
5959 RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
5960 RFValue &= (~0x30);
5961 RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
5962
5963 // Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 0
5964 RT30xxReadRFRegister(pAd, RF_R09, &RFValue);
5965 RFValue &= (~0x0E);
5966 RT30xxWriteRFRegister(pAd, RF_R09, RFValue);
5967
5968 // RX_CTB_en, RF R21 register Bit 7 to 0
5969 RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
5970 RFValue &= (~0x80);
5971 RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
5972
5973 // LDORF_VC, RF R27 register Bit 0, Bit 1 & Bit 2 to 1
5974 RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
5975 RFValue |= 0x77;
5976 RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
5977
5978 RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
5979 MACValue |= 0x1D000000;
5980 RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
5981}
5982
5983/*
5984 ==========================================================================
5985 Description:
5986
5987 Reverse RF sleep-mode setup
5988
5989 ==========================================================================
5990 */
5991VOID RT30xxReverseRFSleepModeSetup(
5992 IN PRTMP_ADAPTER pAd)
5993{
5994 UCHAR RFValue;
5995 UINT32 MACValue;
5996
5997 // RF_BLOCK_en, RF R1 register Bit 0 to 1
5998 RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
5999 RFValue |= 0x01;
6000 RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
6001
6002 // VCO_IC, RF R7 register Bit 4 & Bit 5 to 1
6003 RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
6004 RFValue |= 0x30;
6005 RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
6006
6007 // Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 1
6008 RT30xxReadRFRegister(pAd, RF_R09, &RFValue);
6009 RFValue |= 0x0E;
6010 RT30xxWriteRFRegister(pAd, RF_R09, RFValue);
6011
6012 // RX_CTB_en, RF R21 register Bit 7 to 1
6013 RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
6014 RFValue |= 0x80;
6015 RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
6016
6017 // LDORF_VC, RF R27 register Bit 2 to 0
6018 RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
6019 if ((pAd->MACVersion & 0xffff) < 0x0211)
6020 RFValue = (RFValue & (~0x77)) | 0x3;
6021 else
6022 RFValue = (RFValue & (~0x77));
6023 RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
6024
6025 // RT3071 version E has fixed this issue
6026 if ((pAd->NicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211))
6027 {
6028 // patch tx EVM issue temporarily
6029 RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
6030 MACValue = ((MACValue & 0xE0FFFFFF) | 0x0D000000);
6031 RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
6032 }
6033 else
6034 {
6035 RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
6036 MACValue = ((MACValue & 0xE0FFFFFF) | 0x01000000);
6037 RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
6038 }
6039}
6040// end johnli
6041#endif // RT30xx //
6042
6043/*
6044 ==========================================================================
6045 Description:
6046
6047 IRQL = PASSIVE_LEVEL
6048 IRQL = DISPATCH_LEVEL
6049
6050 ==========================================================================
6051 */
6052VOID AsicSwitchChannel(
6053 IN PRTMP_ADAPTER pAd,
6054 IN UCHAR Channel,
6055 IN BOOLEAN bScan)
6056{
6057 ULONG R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0;
6058 CHAR TxPwer = 0, TxPwer2 = DEFAULT_RF_TX_POWER; //Bbp94 = BBPR94_DEFAULT, TxPwer2 = DEFAULT_RF_TX_POWER;
6059 UCHAR index;
6060 UINT32 Value = 0; //BbpReg, Value;
6061 RTMP_RF_REGS *RFRegTable;
6062
6063 // Search Tx power value
6064#if 1
6065 // We can't use ChannelList to search channel, since some central channl's txpowr doesn't list
6066 // in ChannelList, so use TxPower array instead.
6067 //
6068 for (index = 0; index < MAX_NUM_OF_CHANNELS; index++)
6069 {
6070 if (Channel == pAd->TxPower[index].Channel)
6071 {
6072 TxPwer = pAd->TxPower[index].Power;
6073 TxPwer2 = pAd->TxPower[index].Power2;
6074 break;
6075 }
6076 }
6077#else
6078 for (index = 0; index < pAd->ChannelListNum; index++)
6079 {
6080 if (Channel == pAd->ChannelList[index].Channel)
6081 {
6082 TxPwer = pAd->ChannelList[index].Power;
6083 TxPwer2 = pAd->ChannelList[index].Power2;
6084 break;
6085 }
6086 }
6087#endif
6088
6089 if (index == MAX_NUM_OF_CHANNELS)
6090 {
6091 DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: Can't find the Channel#%d \n", Channel));
6092 }
6093
6094#ifdef RT30xx
6095 // The RF programming sequence is difference between 3xxx and 2xxx
6096 if ((IS_RT3070(pAd) || IS_RT3090(pAd)) && ((pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020) ||
6097 (pAd->RfIcType == RFIC_3021) || (pAd->RfIcType == RFIC_3022)))
6098 {
6099 /* modify by WY for Read RF Reg. error */
6100 UCHAR RFValue;
6101
6102 for (index = 0; index < NUM_OF_3020_CHNL; index++)
6103 {
6104 if (Channel == FreqItems3020[index].Channel)
6105 {
6106 // Programming channel parameters
6107 RT30xxWriteRFRegister(pAd, RF_R02, FreqItems3020[index].N);
6108 RT30xxWriteRFRegister(pAd, RF_R03, FreqItems3020[index].K);
6109 RT30xxReadRFRegister(pAd, RF_R06, &RFValue);
6110 RFValue = (RFValue & 0xFC) | FreqItems3020[index].R;
6111 RT30xxWriteRFRegister(pAd, RF_R06, RFValue);
6112
6113 // Set Tx0 Power
6114 RT30xxReadRFRegister(pAd, RF_R12, &RFValue);
6115 RFValue = (RFValue & 0xE0) | TxPwer;
6116 RT30xxWriteRFRegister(pAd, RF_R12, RFValue);
6117
6118 // Set Tx1 Power
6119 RT30xxReadRFRegister(pAd, RF_R13, &RFValue);
6120 RFValue = (RFValue & 0xE0) | TxPwer2;
6121 RT30xxWriteRFRegister(pAd, RF_R13, RFValue);
6122
6123 // Tx/Rx Stream setting
6124 RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
6125 //if (IS_RT3090(pAd))
6126 // RFValue |= 0x01; // Enable RF block.
6127 RFValue &= 0x03; //clear bit[7~2]
6128 if (pAd->Antenna.field.TxPath == 1)
6129 RFValue |= 0xA0;
6130 else if (pAd->Antenna.field.TxPath == 2)
6131 RFValue |= 0x80;
6132 if (pAd->Antenna.field.RxPath == 1)
6133 RFValue |= 0x50;
6134 else if (pAd->Antenna.field.RxPath == 2)
6135 RFValue |= 0x40;
6136 RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
6137
6138 // Set RF offset
6139 RT30xxReadRFRegister(pAd, RF_R23, &RFValue);
6140 RFValue = (RFValue & 0x80) | pAd->RfFreqOffset;
6141 RT30xxWriteRFRegister(pAd, RF_R23, RFValue);
6142
6143 // Set BW
6144 if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40))
6145 {
6146 RFValue = pAd->Mlme.CaliBW40RfR24;
6147 //DISABLE_11N_CHECK(pAd);
6148 }
6149 else
6150 {
6151 RFValue = pAd->Mlme.CaliBW20RfR24;
6152 }
6153 RT30xxWriteRFRegister(pAd, RF_R24, RFValue);
6154 RT30xxWriteRFRegister(pAd, RF_R31, RFValue);
6155
6156 // Enable RF tuning
6157 RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
6158 RFValue = RFValue | 0x1;
6159 RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
6160
6161 // latch channel for future usage.
6162 pAd->LatchRfRegs.Channel = Channel;
6163
6164 DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n",
6165 Channel,
6166 pAd->RfIcType,
6167 TxPwer,
6168 TxPwer2,
6169 pAd->Antenna.field.TxPath,
6170 FreqItems3020[index].N,
6171 FreqItems3020[index].K,
6172 FreqItems3020[index].R));
6173
6174 break;
6175 }
6176 }
6177 }
6178 else
6179#endif // RT30xx //
6180
6181 {
6182 RFRegTable = RF2850RegTable;
6183
6184 switch (pAd->RfIcType)
6185 {
6186 case RFIC_2820:
6187 case RFIC_2850:
6188 case RFIC_2720:
6189 case RFIC_2750:
6190
6191 for (index = 0; index < NUM_OF_2850_CHNL; index++)
6192 {
6193 if (Channel == RFRegTable[index].Channel)
6194 {
6195 R2 = RFRegTable[index].R2;
6196 if (pAd->Antenna.field.TxPath == 1)
6197 {
6198 R2 |= 0x4000; // If TXpath is 1, bit 14 = 1;
6199 }
6200
6201 if (pAd->Antenna.field.RxPath == 2)
6202 {
6203 R2 |= 0x40; // write 1 to off Rxpath.
6204 }
6205 else if (pAd->Antenna.field.RxPath == 1)
6206 {
6207 R2 |= 0x20040; // write 1 to off RxPath
6208 }
6209
6210 if (Channel > 14)
6211 {
6212 // initialize R3, R4
6213 R3 = (RFRegTable[index].R3 & 0xffffc1ff);
6214 R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15);
6215
6216 // 5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB
6217 // R3
6218 if ((TxPwer >= -7) && (TxPwer < 0))
6219 {
6220 TxPwer = (7+TxPwer);
6221 TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
6222 R3 |= (TxPwer << 10);
6223 DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: TxPwer=%d \n", TxPwer));
6224 }
6225 else
6226 {
6227 TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
6228 R3 |= (TxPwer << 10) | (1 << 9);
6229 }
6230
6231 // R4
6232 if ((TxPwer2 >= -7) && (TxPwer2 < 0))
6233 {
6234 TxPwer2 = (7+TxPwer2);
6235 TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
6236 R4 |= (TxPwer2 << 7);
6237 DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: TxPwer2=%d \n", TxPwer2));
6238 }
6239 else
6240 {
6241 TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
6242 R4 |= (TxPwer2 << 7) | (1 << 6);
6243 }
6244 }
6245 else
6246 {
6247 R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9); // set TX power0
6248 R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15) | (TxPwer2 <<6);// Set freq Offset & TxPwr1
6249 }
6250
6251 // Based on BBP current mode before changing RF channel.
6252 if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40))
6253 {
6254 R4 |=0x200000;
6255 }
6256
6257 // Update variables
6258 pAd->LatchRfRegs.Channel = Channel;
6259 pAd->LatchRfRegs.R1 = RFRegTable[index].R1;
6260 pAd->LatchRfRegs.R2 = R2;
6261 pAd->LatchRfRegs.R3 = R3;
6262 pAd->LatchRfRegs.R4 = R4;
6263
6264 // Set RF value 1's set R3[bit2] = [0]
6265 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
6266 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
6267 RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
6268 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
6269
6270 RTMPusecDelay(200);
6271
6272 // Set RF value 2's set R3[bit2] = [1]
6273 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
6274 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
6275 RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 | 0x04));
6276 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
6277
6278 RTMPusecDelay(200);
6279
6280 // Set RF value 3's set R3[bit2] = [0]
6281 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
6282 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
6283 RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
6284 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
6285
6286 break;
6287 }
6288 }
6289 break;
6290
6291 default:
6292 break;
6293 }
6294 }
6295
6296 // Change BBP setting during siwtch from a->g, g->a
6297 if (Channel <= 14)
6298 {
6299 ULONG TxPinCfg = 0x00050F0A;//Gary 2007/08/09 0x050A0A
6300
6301 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
6302 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
6303 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
6304 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0);//(0x44 - GET_LNA_GAIN(pAd))); // According the Rory's suggestion to solve the middle range issue.
6305 //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
6306
6307 // Rx High power VGA offset for LNA select
6308 if (pAd->NicConfig2.field.ExternalLNAForG)
6309 {
6310 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
6311 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
6312 }
6313 else
6314 {
6315 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84);
6316 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
6317 }
6318
6319 // 5G band selection PIN, bit1 and bit2 are complement
6320 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
6321 Value &= (~0x6);
6322 Value |= (0x04);
6323 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
6324
6325 // Turn off unused PA or LNA when only 1T or 1R
6326 if (pAd->Antenna.field.TxPath == 1)
6327 {
6328 TxPinCfg &= 0xFFFFFFF3;
6329 }
6330 if (pAd->Antenna.field.RxPath == 1)
6331 {
6332 TxPinCfg &= 0xFFFFF3FF;
6333 }
6334
6335 RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
6336 }
6337 else
6338 {
6339 ULONG TxPinCfg = 0x00050F05;//Gary 2007/8/9 0x050505
6340
6341 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
6342 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
6343 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
6344 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0);//(0x44 - GET_LNA_GAIN(pAd))); // According the Rory's suggestion to solve the middle range issue.
6345 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0xF2);
6346
6347 // Rx High power VGA offset for LNA select
6348 if (pAd->NicConfig2.field.ExternalLNAForA)
6349 {
6350 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
6351 }
6352 else
6353 {
6354 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
6355 }
6356
6357 // 5G band selection PIN, bit1 and bit2 are complement
6358 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
6359 Value &= (~0x6);
6360 Value |= (0x02);
6361 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
6362
6363 // Turn off unused PA or LNA when only 1T or 1R
6364 if (pAd->Antenna.field.TxPath == 1)
6365 {
6366 TxPinCfg &= 0xFFFFFFF3;
6367 }
6368 if (pAd->Antenna.field.RxPath == 1)
6369 {
6370 TxPinCfg &= 0xFFFFF3FF;
6371 }
6372
6373 RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
6374 }
6375
6376 // R66 should be set according to Channel and use 20MHz when scanning
6377 //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x2E + GET_LNA_GAIN(pAd)));
6378 if (bScan)
6379 RTMPSetAGCInitValue(pAd, BW_20);
6380 else
6381 RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
6382
6383 //
6384 // On 11A, We should delay and wait RF/BBP to be stable
6385 // and the appropriate time should be 1000 micro seconds
6386 // 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL.
6387 //
6388 RTMPusecDelay(1000);
6389
6390 DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%lu, Pwr1=%lu, %dT) to , R1=0x%08lx, R2=0x%08lx, R3=0x%08lx, R4=0x%08lx\n",
6391 Channel,
6392 pAd->RfIcType,
6393 (R3 & 0x00003e00) >> 9,
6394 (R4 & 0x000007c0) >> 6,
6395 pAd->Antenna.field.TxPath,
6396 pAd->LatchRfRegs.R1,
6397 pAd->LatchRfRegs.R2,
6398 pAd->LatchRfRegs.R3,
6399 pAd->LatchRfRegs.R4));
6400}
6401
6402/*
6403 ==========================================================================
6404 Description:
6405 This function is required for 2421 only, and should not be used during
6406 site survey. It's only required after NIC decided to stay at a channel
6407 for a longer period.
6408 When this function is called, it's always after AsicSwitchChannel().
6409
6410 IRQL = PASSIVE_LEVEL
6411 IRQL = DISPATCH_LEVEL
6412
6413 ==========================================================================
6414 */
6415VOID AsicLockChannel(
6416 IN PRTMP_ADAPTER pAd,
6417 IN UCHAR Channel)
6418{
6419}
6420
6421/*
6422 ==========================================================================
6423 Description:
6424
6425 IRQL = PASSIVE_LEVEL
6426 IRQL = DISPATCH_LEVEL
6427
6428 ==========================================================================
6429 */
6430VOID AsicAntennaSelect(
6431 IN PRTMP_ADAPTER pAd,
6432 IN UCHAR Channel)
6433{
6434 if (pAd->Mlme.OneSecPeriodicRound % 2 == 1)
6435 {
6436 // patch for AsicSetRxAnt failed
6437 pAd->RxAnt.EvaluatePeriod = 0;
6438
6439 // check every 2 second. If rcv-beacon less than 5 in the past 2 second, then AvgRSSI is no longer a
6440 // valid indication of the distance between this AP and its clients.
6441 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
6442 {
6443 SHORT realavgrssi1;
6444
6445 // if no traffic then reset average rssi to trigger evaluation
6446#ifdef CONFIG_STA_SUPPORT
6447 if (pAd->StaCfg.NumOfAvgRssiSample < 5)
6448 {
6449 pAd->RxAnt.Pair1LastAvgRssi = (-99);
6450 pAd->RxAnt.Pair2LastAvgRssi = (-99);
6451 DBGPRINT(RT_DEBUG_TRACE, ("MlmePeriodicExec: no traffic/beacon, reset RSSI\n"));
6452 }
6453
6454 pAd->StaCfg.NumOfAvgRssiSample = 0;
6455#endif // CONFIG_STA_SUPPORT //
6456 realavgrssi1 = (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1PrimaryRxAnt] >> 3);
6457
6458 DBGPRINT(RT_DEBUG_TRACE,("Ant-realrssi0(%d), Lastrssi0(%d), EvaluateStableCnt=%d\n", realavgrssi1, pAd->RxAnt.Pair1LastAvgRssi, pAd->RxAnt.EvaluateStableCnt));
6459
6460 // if the difference between two rssi is larger or less than 5, then evaluate the other antenna
6461 if ((pAd->RxAnt.EvaluateStableCnt < 2) || (realavgrssi1 > (pAd->RxAnt.Pair1LastAvgRssi + 5)) || (realavgrssi1 < (pAd->RxAnt.Pair1LastAvgRssi - 5)))
6462 {
6463 pAd->RxAnt.Pair1LastAvgRssi = realavgrssi1;
6464 AsicEvaluateRxAnt(pAd);
6465 }
6466 }
6467 else
6468 {
6469 // if not connected, always switch antenna to try to connect
6470 UCHAR temp;
6471
6472 temp = pAd->RxAnt.Pair1PrimaryRxAnt;
6473 pAd->RxAnt.Pair1PrimaryRxAnt = pAd->RxAnt.Pair1SecondaryRxAnt;
6474 pAd->RxAnt.Pair1SecondaryRxAnt = temp;
6475
6476 DBGPRINT(RT_DEBUG_TRACE, ("MlmePeriodicExec: no connect, switch to another one to try connection\n"));
6477
6478 AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
6479 }
6480 }
6481}
6482
6483/*
6484 ========================================================================
6485
6486 Routine Description:
6487 Antenna miscellaneous setting.
6488
6489 Arguments:
6490 pAd Pointer to our adapter
6491 BandState Indicate current Band State.
6492
6493 Return Value:
6494 None
6495
6496 IRQL <= DISPATCH_LEVEL
6497
6498 Note:
6499 1.) Frame End type control
6500 only valid for G only (RF_2527 & RF_2529)
6501 0: means DPDT, set BBP R4 bit 5 to 1
6502 1: means SPDT, set BBP R4 bit 5 to 0
6503
6504
6505 ========================================================================
6506*/
6507VOID AsicAntennaSetting(
6508 IN PRTMP_ADAPTER pAd,
6509 IN ABGBAND_STATE BandState)
6510{
6511}
6512
6513VOID AsicRfTuningExec(
6514 IN PVOID SystemSpecific1,
6515 IN PVOID FunctionContext,
6516 IN PVOID SystemSpecific2,
6517 IN PVOID SystemSpecific3)
6518{
6519}
6520
6521/*
6522 ==========================================================================
6523 Description:
6524 Gives CCK TX rate 2 more dB TX power.
6525 This routine works only in LINK UP in INFRASTRUCTURE mode.
6526
6527 calculate desired Tx power in RF R3.Tx0~5, should consider -
6528 0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment)
6529 1. TxPowerPercentage
6530 2. auto calibration based on TSSI feedback
6531 3. extra 2 db for CCK
6532 4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP
6533
6534 NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment),
6535 it should be called AFTER MlmeDynamicTxRatSwitching()
6536 ==========================================================================
6537 */
6538VOID AsicAdjustTxPower(
6539 IN PRTMP_ADAPTER pAd)
6540{
6541 INT i, j;
6542 CHAR DeltaPwr = 0;
6543 BOOLEAN bAutoTxAgc = FALSE;
6544 UCHAR TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep;
6545 UCHAR BbpR1 = 0, BbpR49 = 0, idx;
6546 PCHAR pTxAgcCompensate;
6547 ULONG TxPwr[5];
6548 CHAR Value;
6549
6550
6551
6552 if (pAd->CommonCfg.BBPCurrentBW == BW_40)
6553 {
6554 if (pAd->CommonCfg.CentralChannel > 14)
6555 {
6556 TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
6557 TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
6558 TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
6559 TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
6560 TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
6561 }
6562 else
6563 {
6564 TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
6565 TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
6566 TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
6567 TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
6568 TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
6569 }
6570 }
6571 else
6572 {
6573 if (pAd->CommonCfg.Channel > 14)
6574 {
6575 TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
6576 TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
6577 TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
6578 TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
6579 TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
6580 }
6581 else
6582 {
6583 TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
6584 TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
6585 TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
6586 TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
6587 TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
6588 }
6589 }
6590
6591 // TX power compensation for temperature variation based on TSSI. try every 4 second
6592 if (pAd->Mlme.OneSecPeriodicRound % 4 == 0)
6593 {
6594 if (pAd->CommonCfg.Channel <= 14)
6595 {
6596 /* bg channel */
6597 bAutoTxAgc = pAd->bAutoTxAgcG;
6598 TssiRef = pAd->TssiRefG;
6599 pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0];
6600 pTssiPlusBoundary = &pAd->TssiPlusBoundaryG[0];
6601 TxAgcStep = pAd->TxAgcStepG;
6602 pTxAgcCompensate = &pAd->TxAgcCompensateG;
6603 }
6604 else
6605 {
6606 /* a channel */
6607 bAutoTxAgc = pAd->bAutoTxAgcA;
6608 TssiRef = pAd->TssiRefA;
6609 pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0];
6610 pTssiPlusBoundary = &pAd->TssiPlusBoundaryA[0];
6611 TxAgcStep = pAd->TxAgcStepA;
6612 pTxAgcCompensate = &pAd->TxAgcCompensateA;
6613 }
6614
6615 if (bAutoTxAgc)
6616 {
6617 /* BbpR1 is unsigned char */
6618 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49);
6619
6620 /* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */
6621 /* compensate: +4 +3 +2 +1 0 -1 -2 -3 -4 * steps */
6622 /* step value is defined in pAd->TxAgcStepG for tx power value */
6623
6624 /* [4]+1+[4] p4 p3 p2 p1 o1 m1 m2 m3 m4 */
6625 /* ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
6626 above value are examined in mass factory production */
6627 /* [4] [3] [2] [1] [0] [1] [2] [3] [4] */
6628
6629 /* plus (+) is 0x00 ~ 0x45, minus (-) is 0xa0 ~ 0xf0 */
6630 /* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */
6631 /* if value is 0xa5, tx power will be -= TxAgcStep*(2-1) */
6632
6633 if (BbpR49 > pTssiMinusBoundary[1])
6634 {
6635 // Reading is larger than the reference value
6636 // check for how large we need to decrease the Tx power
6637 for (idx = 1; idx < 5; idx++)
6638 {
6639 if (BbpR49 <= pTssiMinusBoundary[idx]) // Found the range
6640 break;
6641 }
6642 // The index is the step we should decrease, idx = 0 means there is nothing to compensate
6643// if (R3 > (ULONG) (TxAgcStep * (idx-1)))
6644 *pTxAgcCompensate = -(TxAgcStep * (idx-1));
6645// else
6646// *pTxAgcCompensate = -((UCHAR)R3);
6647
6648 DeltaPwr += (*pTxAgcCompensate);
6649 DBGPRINT(RT_DEBUG_TRACE, ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n",
6650 BbpR49, TssiRef, TxAgcStep, idx-1));
6651 }
6652 else if (BbpR49 < pTssiPlusBoundary[1])
6653 {
6654 // Reading is smaller than the reference value
6655 // check for how large we need to increase the Tx power
6656 for (idx = 1; idx < 5; idx++)
6657 {
6658 if (BbpR49 >= pTssiPlusBoundary[idx]) // Found the range
6659 break;
6660 }
6661 // The index is the step we should increase, idx = 0 means there is nothing to compensate
6662 *pTxAgcCompensate = TxAgcStep * (idx-1);
6663 DeltaPwr += (*pTxAgcCompensate);
6664 DBGPRINT(RT_DEBUG_TRACE, ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
6665 BbpR49, TssiRef, TxAgcStep, idx-1));
6666 }
6667 else
6668 {
6669 *pTxAgcCompensate = 0;
6670 DBGPRINT(RT_DEBUG_TRACE, (" Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
6671 BbpR49, TssiRef, TxAgcStep, 0));
6672 }
6673 }
6674 }
6675 else
6676 {
6677 if (pAd->CommonCfg.Channel <= 14)
6678 {
6679 bAutoTxAgc = pAd->bAutoTxAgcG;
6680 pTxAgcCompensate = &pAd->TxAgcCompensateG;
6681 }
6682 else
6683 {
6684 bAutoTxAgc = pAd->bAutoTxAgcA;
6685 pTxAgcCompensate = &pAd->TxAgcCompensateA;
6686 }
6687
6688 if (bAutoTxAgc)
6689 DeltaPwr += (*pTxAgcCompensate);
6690 }
6691
6692 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpR1);
6693 BbpR1 &= 0xFC;
6694
6695#ifdef SINGLE_SKU
6696 // Handle regulatory max tx power constrain
6697 do
6698 {
6699 UCHAR TxPwrInEEPROM = 0xFF, CountryTxPwr = 0xFF, criterion;
6700 UCHAR AdjustMaxTxPwr[40];
6701
6702 if (pAd->CommonCfg.Channel > 14) // 5G band
6703 TxPwrInEEPROM = ((pAd->CommonCfg.DefineMaxTxPwr & 0xFF00) >> 8);
6704 else // 2.4G band
6705 TxPwrInEEPROM = (pAd->CommonCfg.DefineMaxTxPwr & 0x00FF);
6706 CountryTxPwr = GetCuntryMaxTxPwr(pAd, pAd->CommonCfg.Channel);
6707
6708 // error handling, range check
6709 if ((TxPwrInEEPROM > 0x50) || (CountryTxPwr > 0x50))
6710 {
6711 DBGPRINT(RT_DEBUG_ERROR,("AsicAdjustTxPower - Invalid max tx power (=0x%02x), CountryTxPwr=%d\n", TxPwrInEEPROM, CountryTxPwr));
6712 break;
6713 }
6714
6715 criterion = *((PUCHAR)TxPwr + 2) & 0xF; // FAE use OFDM 6M as criterion
6716
6717 DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (criterion=%d, TxPwrInEEPROM=%d, CountryTxPwr=%d)\n", criterion, TxPwrInEEPROM, CountryTxPwr));
6718
6719 // Adjust max tx power according to the relationship of tx power in E2PROM
6720 for (i=0; i<5; i++)
6721 {
6722 // CCK will have 4dBm larger than OFDM
6723 // Therefore, we should separate to parse the tx power field
6724 if (i == 0)
6725 {
6726 for (j=0; j<8; j++)
6727 {
6728 Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F);
6729
6730 if (j < 4)
6731 {
6732 // CCK will have 4dBm larger than OFDM
6733 AdjustMaxTxPwr[i*8+j] = TxPwrInEEPROM + (Value - criterion) + 4;
6734 }
6735 else
6736 {
6737 AdjustMaxTxPwr[i*8+j] = TxPwrInEEPROM + (Value - criterion);
6738 }
6739 DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (i/j=%d/%d, Value=%d, %d)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));
6740 }
6741 }
6742 else
6743 {
6744 for (j=0; j<8; j++)
6745 {
6746 Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F);
6747
6748 AdjustMaxTxPwr[i*8+j] = TxPwrInEEPROM + (Value - criterion);
6749 DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (i/j=%d/%d, Value=%d, %d)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));
6750 }
6751 }
6752 }
6753
6754 // Adjust tx power according to the relationship
6755 for (i=0; i<5; i++)
6756 {
6757 if (TxPwr[i] != 0xffffffff)
6758 {
6759 for (j=0; j<8; j++)
6760 {
6761 Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F);
6762
6763 // The system tx power is larger than the regulatory, the power should be restrain
6764 if (AdjustMaxTxPwr[i*8+j] > CountryTxPwr)
6765 {
6766 // decrease to zero and don't need to take care BBPR1
6767 if ((Value - (AdjustMaxTxPwr[i*8+j] - CountryTxPwr)) > 0)
6768 Value -= (AdjustMaxTxPwr[i*8+j] - CountryTxPwr);
6769 else
6770 Value = 0;
6771
6772 DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (i/j=%d/%d, Value=%d, %d)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));
6773 }
6774 else
6775 DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (i/j=%d/%d, Value=%d, %d, no change)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));
6776
6777 TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4);
6778 }
6779 }
6780 }
6781 } while (FALSE);
6782#endif // SINGLE_SKU //
6783
6784 /* calculate delta power based on the percentage specified from UI */
6785 // E2PROM setting is calibrated for maximum TX power (i.e. 100%)
6786 // We lower TX power here according to the percentage specified from UI
6787 if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff) // AUTO TX POWER control
6788 ;
6789 else if (pAd->CommonCfg.TxPowerPercentage > 90) // 91 ~ 100% & AUTO, treat as 100% in terms of mW
6790 ;
6791 else if (pAd->CommonCfg.TxPowerPercentage > 60) // 61 ~ 90%, treat as 75% in terms of mW // DeltaPwr -= 1;
6792 {
6793 DeltaPwr -= 1;
6794 }
6795 else if (pAd->CommonCfg.TxPowerPercentage > 30) // 31 ~ 60%, treat as 50% in terms of mW // DeltaPwr -= 3;
6796 {
6797 DeltaPwr -= 3;
6798 }
6799 else if (pAd->CommonCfg.TxPowerPercentage > 15) // 16 ~ 30%, treat as 25% in terms of mW // DeltaPwr -= 6;
6800 {
6801 BbpR1 |= 0x01;
6802 }
6803 else if (pAd->CommonCfg.TxPowerPercentage > 9) // 10 ~ 15%, treat as 12.5% in terms of mW // DeltaPwr -= 9;
6804 {
6805 BbpR1 |= 0x01;
6806 DeltaPwr -= 3;
6807 }
6808 else // 0 ~ 9 %, treat as MIN(~3%) in terms of mW // DeltaPwr -= 12;
6809 {
6810 BbpR1 |= 0x02;
6811 }
6812
6813 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1);
6814
6815 /* reset different new tx power for different TX rate */
6816 for(i=0; i<5; i++)
6817 {
6818 if (TxPwr[i] != 0xffffffff)
6819 {
6820 for (j=0; j<8; j++)
6821 {
6822 Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F); /* 0 ~ 15 */
6823
6824 if ((Value + DeltaPwr) < 0)
6825 {
6826 Value = 0; /* min */
6827 }
6828 else if ((Value + DeltaPwr) > 0xF)
6829 {
6830 Value = 0xF; /* max */
6831 }
6832 else
6833 {
6834 Value += DeltaPwr; /* temperature compensation */
6835 }
6836
6837 /* fill new value to CSR offset */
6838 TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4);
6839 }
6840
6841 /* write tx power value to CSR */
6842 /* TX_PWR_CFG_0 (8 tx rate) for TX power for OFDM 12M/18M
6843 TX power for OFDM 6M/9M
6844 TX power for CCK5.5M/11M
6845 TX power for CCK1M/2M */
6846 /* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */
6847 RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, TxPwr[i]);
6848 }
6849 }
6850
6851
6852}
6853
6854#ifdef CONFIG_STA_SUPPORT
6855/*
6856 ==========================================================================
6857 Description:
6858 put PHY to sleep here, and set next wakeup timer. PHY doesn't not wakeup
6859 automatically. Instead, MCU will issue a TwakeUpInterrupt to host after
6860 the wakeup timer timeout. Driver has to issue a separate command to wake
6861 PHY up.
6862
6863 IRQL = DISPATCH_LEVEL
6864
6865 ==========================================================================
6866 */
6867VOID AsicSleepThenAutoWakeup(
6868 IN PRTMP_ADAPTER pAd,
6869 IN USHORT TbttNumToNextWakeUp)
6870{
6871 RT28XX_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp);
6872}
6873
6874/*
6875 ==========================================================================
6876 Description:
6877 AsicForceWakeup() is used whenever manual wakeup is required
6878 AsicForceSleep() should only be used when not in INFRA BSS. When
6879 in INFRA BSS, we should use AsicSleepThenAutoWakeup() instead.
6880 ==========================================================================
6881 */
6882VOID AsicForceSleep(
6883 IN PRTMP_ADAPTER pAd)
6884{
6885
6886}
6887
6888/*
6889 ==========================================================================
6890 Description:
6891 AsicForceWakeup() is used whenever Twakeup timer (set via AsicSleepThenAutoWakeup)
6892 expired.
6893
6894 IRQL = PASSIVE_LEVEL
6895 IRQL = DISPATCH_LEVEL
6896 ==========================================================================
6897 */
6898VOID AsicForceWakeup(
6899 IN PRTMP_ADAPTER pAd,
6900 IN BOOLEAN bFromTx)
6901{
6902 DBGPRINT(RT_DEBUG_TRACE, ("--> AsicForceWakeup \n"));
6903 RT28XX_STA_FORCE_WAKEUP(pAd, bFromTx);
6904}
6905#endif // CONFIG_STA_SUPPORT //
6906/*
6907 ==========================================================================
6908 Description:
6909 Set My BSSID
6910
6911 IRQL = DISPATCH_LEVEL
6912
6913 ==========================================================================
6914 */
6915VOID AsicSetBssid(
6916 IN PRTMP_ADAPTER pAd,
6917 IN PUCHAR pBssid)
6918{
6919 ULONG Addr4;
6920 DBGPRINT(RT_DEBUG_TRACE, ("==============> AsicSetBssid %x:%x:%x:%x:%x:%x\n",
6921 pBssid[0],pBssid[1],pBssid[2],pBssid[3], pBssid[4],pBssid[5]));
6922
6923 Addr4 = (ULONG)(pBssid[0]) |
6924 (ULONG)(pBssid[1] << 8) |
6925 (ULONG)(pBssid[2] << 16) |
6926 (ULONG)(pBssid[3] << 24);
6927 RTMP_IO_WRITE32(pAd, MAC_BSSID_DW0, Addr4);
6928
6929 Addr4 = 0;
6930 // always one BSSID in STA mode
6931 Addr4 = (ULONG)(pBssid[4]) | (ULONG)(pBssid[5] << 8);
6932
6933 RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, Addr4);
6934}
6935
6936VOID AsicSetMcastWC(
6937 IN PRTMP_ADAPTER pAd)
6938{
6939 MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[MCAST_WCID];
6940 USHORT offset;
6941
6942 pEntry->Sst = SST_ASSOC;
6943 pEntry->Aid = MCAST_WCID; // Softap supports 1 BSSID and use WCID=0 as multicast Wcid index
6944 pEntry->PsMode = PWR_ACTIVE;
6945 pEntry->CurrTxRate = pAd->CommonCfg.MlmeRate;
6946 offset = MAC_WCID_BASE + BSS0Mcast_WCID * HW_WCID_ENTRY_SIZE;
6947}
6948
6949/*
6950 ==========================================================================
6951 Description:
6952
6953 IRQL = DISPATCH_LEVEL
6954
6955 ==========================================================================
6956 */
6957VOID AsicDelWcidTab(
6958 IN PRTMP_ADAPTER pAd,
6959 IN UCHAR Wcid)
6960{
6961 ULONG Addr0 = 0x0, Addr1 = 0x0;
6962 ULONG offset;
6963
6964 DBGPRINT(RT_DEBUG_TRACE, ("AsicDelWcidTab==>Wcid = 0x%x\n",Wcid));
6965 offset = MAC_WCID_BASE + Wcid * HW_WCID_ENTRY_SIZE;
6966 RTMP_IO_WRITE32(pAd, offset, Addr0);
6967 offset += 4;
6968 RTMP_IO_WRITE32(pAd, offset, Addr1);
6969}
6970
6971/*
6972 ==========================================================================
6973 Description:
6974
6975 IRQL = DISPATCH_LEVEL
6976
6977 ==========================================================================
6978 */
6979VOID AsicEnableRDG(
6980 IN PRTMP_ADAPTER pAd)
6981{
6982 TX_LINK_CFG_STRUC TxLinkCfg;
6983 UINT32 Data = 0;
6984
6985 RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
6986 TxLinkCfg.field.TxRDGEn = 1;
6987 RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
6988
6989 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
6990 Data &= 0xFFFFFF00;
6991 Data |= 0x80;
6992 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
6993
6994 //OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
6995}
6996
6997/*
6998 ==========================================================================
6999 Description:
7000
7001 IRQL = DISPATCH_LEVEL
7002
7003 ==========================================================================
7004 */
7005VOID AsicDisableRDG(
7006 IN PRTMP_ADAPTER pAd)
7007{
7008 TX_LINK_CFG_STRUC TxLinkCfg;
7009 UINT32 Data = 0;
7010
7011
7012 RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
7013 TxLinkCfg.field.TxRDGEn = 0;
7014 RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
7015
7016 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
7017
7018 Data &= 0xFFFFFF00;
7019 //Data |= 0x20;
7020#ifndef WIFI_TEST
7021 //if ( pAd->CommonCfg.bEnableTxBurst )
7022 // Data |= 0x60; // for performance issue not set the TXOP to 0
7023#endif
7024 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE)
7025#ifdef DOT11_N_SUPPORT
7026 && (pAd->MacTab.fAnyStationMIMOPSDynamic == FALSE)
7027#endif // DOT11_N_SUPPORT //
7028 )
7029 {
7030 // For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
7031 if (pAd->CommonCfg.bEnableTxBurst)
7032 Data |= 0x20;
7033 }
7034 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
7035}
7036
7037/*
7038 ==========================================================================
7039 Description:
7040
7041 IRQL = PASSIVE_LEVEL
7042 IRQL = DISPATCH_LEVEL
7043
7044 ==========================================================================
7045 */
7046VOID AsicDisableSync(
7047 IN PRTMP_ADAPTER pAd)
7048{
7049 BCN_TIME_CFG_STRUC csr;
7050
7051 DBGPRINT(RT_DEBUG_TRACE, ("--->Disable TSF synchronization\n"));
7052
7053 // 2003-12-20 disable TSF and TBTT while NIC in power-saving have side effect
7054 // that NIC will never wakes up because TSF stops and no more
7055 // TBTT interrupts
7056 pAd->TbttTickCount = 0;
7057 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
7058 csr.field.bBeaconGen = 0;
7059 csr.field.bTBTTEnable = 0;
7060 csr.field.TsfSyncMode = 0;
7061 csr.field.bTsfTicking = 0;
7062 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
7063
7064}
7065
7066/*
7067 ==========================================================================
7068 Description:
7069
7070 IRQL = DISPATCH_LEVEL
7071
7072 ==========================================================================
7073 */
7074VOID AsicEnableBssSync(
7075 IN PRTMP_ADAPTER pAd)
7076{
7077 BCN_TIME_CFG_STRUC csr;
7078
7079 DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableBssSync(INFRA mode)\n"));
7080
7081 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
7082// RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, 0x00000000);
7083#ifdef CONFIG_STA_SUPPORT
7084 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
7085 {
7086 csr.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU
7087 csr.field.bTsfTicking = 1;
7088 csr.field.TsfSyncMode = 1; // sync TSF in INFRASTRUCTURE mode
7089 csr.field.bBeaconGen = 0; // do NOT generate BEACON
7090 csr.field.bTBTTEnable = 1;
7091 }
7092#endif // CONFIG_STA_SUPPORT //
7093 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
7094}
7095
7096/*
7097 ==========================================================================
7098 Description:
7099 Note:
7100 BEACON frame in shared memory should be built ok before this routine
7101 can be called. Otherwise, a garbage frame maybe transmitted out every
7102 Beacon period.
7103
7104 IRQL = DISPATCH_LEVEL
7105
7106 ==========================================================================
7107 */
7108VOID AsicEnableIbssSync(
7109 IN PRTMP_ADAPTER pAd)
7110{
7111 BCN_TIME_CFG_STRUC csr9;
7112 PUCHAR ptr;
7113 UINT i;
7114
7115 DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableIbssSync(ADHOC mode. MPDUtotalByteCount = %d)\n", pAd->BeaconTxWI.MPDUtotalByteCount));
7116
7117 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr9.word);
7118 csr9.field.bBeaconGen = 0;
7119 csr9.field.bTBTTEnable = 0;
7120 csr9.field.bTsfTicking = 0;
7121 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
7122
7123
7124#ifdef RT2870
7125 // move BEACON TXD and frame content to on-chip memory
7126 ptr = (PUCHAR)&pAd->BeaconTxWI;
7127 for (i=0; i<TXWI_SIZE; i+=2) // 16-byte TXWI field
7128 {
7129 //UINT32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
7130 //RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + i, longptr);
7131 RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + i, ptr, 2);
7132 ptr += 2;
7133 }
7134
7135 // start right after the 16-byte TXWI field
7136 ptr = pAd->BeaconBuf;
7137 for (i=0; i< pAd->BeaconTxWI.MPDUtotalByteCount; i+=2)
7138 {
7139 //UINT32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
7140 //RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr);
7141 RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, ptr, 2);
7142 ptr +=2;
7143 }
7144#endif // RT2870 //
7145
7146 //
7147 // For Wi-Fi faily generated beacons between participating stations.
7148 // Set TBTT phase adaptive adjustment step to 8us (default 16us)
7149 // don't change settings 2006-5- by Jerry
7150 //RTMP_IO_WRITE32(pAd, TBTT_SYNC_CFG, 0x00001010);
7151
7152 // start sending BEACON
7153 csr9.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU
7154 csr9.field.bTsfTicking = 1;
7155 csr9.field.TsfSyncMode = 2; // sync TSF in IBSS mode
7156 csr9.field.bTBTTEnable = 1;
7157 csr9.field.bBeaconGen = 1;
7158 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
7159}
7160
7161/*
7162 ==========================================================================
7163 Description:
7164
7165 IRQL = PASSIVE_LEVEL
7166 IRQL = DISPATCH_LEVEL
7167
7168 ==========================================================================
7169 */
7170VOID AsicSetEdcaParm(
7171 IN PRTMP_ADAPTER pAd,
7172 IN PEDCA_PARM pEdcaParm)
7173{
7174 EDCA_AC_CFG_STRUC Ac0Cfg, Ac1Cfg, Ac2Cfg, Ac3Cfg;
7175 AC_TXOP_CSR0_STRUC csr0;
7176 AC_TXOP_CSR1_STRUC csr1;
7177 AIFSN_CSR_STRUC AifsnCsr;
7178 CWMIN_CSR_STRUC CwminCsr;
7179 CWMAX_CSR_STRUC CwmaxCsr;
7180 int i;
7181
7182 Ac0Cfg.word = 0;
7183 Ac1Cfg.word = 0;
7184 Ac2Cfg.word = 0;
7185 Ac3Cfg.word = 0;
7186 if ((pEdcaParm == NULL) || (pEdcaParm->bValid == FALSE))
7187 {
7188 DBGPRINT(RT_DEBUG_TRACE,("AsicSetEdcaParm\n"));
7189 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WMM_INUSED);
7190 for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
7191 {
7192 if (pAd->MacTab.Content[i].ValidAsCLI || pAd->MacTab.Content[i].ValidAsApCli)
7193 CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[i], fCLIENT_STATUS_WMM_CAPABLE);
7194 }
7195
7196 //========================================================
7197 // MAC Register has a copy .
7198 //========================================================
7199//#ifndef WIFI_TEST
7200 if( pAd->CommonCfg.bEnableTxBurst )
7201 {
7202 // For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
7203 Ac0Cfg.field.AcTxop = 0x20; // Suggest by John for TxBurst in HT Mode
7204 }
7205 else
7206 Ac0Cfg.field.AcTxop = 0; // QID_AC_BE
7207//#else
7208// Ac0Cfg.field.AcTxop = 0; // QID_AC_BE
7209//#endif
7210 Ac0Cfg.field.Cwmin = CW_MIN_IN_BITS;
7211 Ac0Cfg.field.Cwmax = CW_MAX_IN_BITS;
7212 Ac0Cfg.field.Aifsn = 2;
7213 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
7214
7215 Ac1Cfg.field.AcTxop = 0; // QID_AC_BK
7216 Ac1Cfg.field.Cwmin = CW_MIN_IN_BITS;
7217 Ac1Cfg.field.Cwmax = CW_MAX_IN_BITS;
7218 Ac1Cfg.field.Aifsn = 2;
7219 RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
7220
7221 if (pAd->CommonCfg.PhyMode == PHY_11B)
7222 {
7223 Ac2Cfg.field.AcTxop = 192; // AC_VI: 192*32us ~= 6ms
7224 Ac3Cfg.field.AcTxop = 96; // AC_VO: 96*32us ~= 3ms
7225 }
7226 else
7227 {
7228 Ac2Cfg.field.AcTxop = 96; // AC_VI: 96*32us ~= 3ms
7229 Ac3Cfg.field.AcTxop = 48; // AC_VO: 48*32us ~= 1.5ms
7230 }
7231 Ac2Cfg.field.Cwmin = CW_MIN_IN_BITS;
7232 Ac2Cfg.field.Cwmax = CW_MAX_IN_BITS;
7233 Ac2Cfg.field.Aifsn = 2;
7234 RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
7235 Ac3Cfg.field.Cwmin = CW_MIN_IN_BITS;
7236 Ac3Cfg.field.Cwmax = CW_MAX_IN_BITS;
7237 Ac3Cfg.field.Aifsn = 2;
7238 RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
7239
7240 //========================================================
7241 // DMA Register has a copy too.
7242 //========================================================
7243 csr0.field.Ac0Txop = 0; // QID_AC_BE
7244 csr0.field.Ac1Txop = 0; // QID_AC_BK
7245 RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
7246 if (pAd->CommonCfg.PhyMode == PHY_11B)
7247 {
7248 csr1.field.Ac2Txop = 192; // AC_VI: 192*32us ~= 6ms
7249 csr1.field.Ac3Txop = 96; // AC_VO: 96*32us ~= 3ms
7250 }
7251 else
7252 {
7253 csr1.field.Ac2Txop = 96; // AC_VI: 96*32us ~= 3ms
7254 csr1.field.Ac3Txop = 48; // AC_VO: 48*32us ~= 1.5ms
7255 }
7256 RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
7257
7258 CwminCsr.word = 0;
7259 CwminCsr.field.Cwmin0 = CW_MIN_IN_BITS;
7260 CwminCsr.field.Cwmin1 = CW_MIN_IN_BITS;
7261 CwminCsr.field.Cwmin2 = CW_MIN_IN_BITS;
7262 CwminCsr.field.Cwmin3 = CW_MIN_IN_BITS;
7263 RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
7264
7265 CwmaxCsr.word = 0;
7266 CwmaxCsr.field.Cwmax0 = CW_MAX_IN_BITS;
7267 CwmaxCsr.field.Cwmax1 = CW_MAX_IN_BITS;
7268 CwmaxCsr.field.Cwmax2 = CW_MAX_IN_BITS;
7269 CwmaxCsr.field.Cwmax3 = CW_MAX_IN_BITS;
7270 RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
7271
7272 RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, 0x00002222);
7273
7274 NdisZeroMemory(&pAd->CommonCfg.APEdcaParm, sizeof(EDCA_PARM));
7275 }
7276 else
7277 {
7278 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WMM_INUSED);
7279 //========================================================
7280 // MAC Register has a copy.
7281 //========================================================
7282 //
7283 // Modify Cwmin/Cwmax/Txop on queue[QID_AC_VI], Recommend by Jerry 2005/07/27
7284 // To degrade our VIDO Queue's throughput for WiFi WMM S3T07 Issue.
7285 //
7286 //pEdcaParm->Txop[QID_AC_VI] = pEdcaParm->Txop[QID_AC_VI] * 7 / 10; // rt2860c need this
7287
7288 Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE];
7289 Ac0Cfg.field.Cwmin= pEdcaParm->Cwmin[QID_AC_BE];
7290 Ac0Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BE];
7291 Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]; //+1;
7292
7293 Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK];
7294 Ac1Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_BK]; //+2;
7295 Ac1Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BK];
7296 Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK]; //+1;
7297
7298 Ac2Cfg.field.AcTxop = (pEdcaParm->Txop[QID_AC_VI] * 6) / 10;
7299 Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI];
7300 Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI];
7301 Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI];
7302#ifdef INF_AMAZON_SE
7303#endif // INF_AMAZON_SE //
7304
7305
7306#ifdef CONFIG_STA_SUPPORT
7307 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
7308 {
7309 // Tuning for Wi-Fi WMM S06
7310 if (pAd->CommonCfg.bWiFiTest &&
7311 pEdcaParm->Aifsn[QID_AC_VI] == 10)
7312 Ac2Cfg.field.Aifsn -= 1;
7313
7314 // Tuning for TGn Wi-Fi 5.2.32
7315 // STA TestBed changes in this item: conexant legacy sta ==> broadcom 11n sta
7316 if (STA_TGN_WIFI_ON(pAd) &&
7317 pEdcaParm->Aifsn[QID_AC_VI] == 10)
7318 {
7319 Ac0Cfg.field.Aifsn = 3;
7320 Ac2Cfg.field.AcTxop = 5;
7321 }
7322
7323#ifdef RT30xx
7324 if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020)
7325 {
7326 // Tuning for WiFi WMM S3-T07: connexant legacy sta ==> broadcom 11n sta.
7327 Ac2Cfg.field.Aifsn = 5;
7328 }
7329#endif // RT30xx //
7330 }
7331#endif // CONFIG_STA_SUPPORT //
7332
7333 Ac3Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VO];
7334 Ac3Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VO];
7335 Ac3Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VO];
7336 Ac3Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VO];
7337
7338//#ifdef WIFI_TEST
7339 if (pAd->CommonCfg.bWiFiTest)
7340 {
7341 if (Ac3Cfg.field.AcTxop == 102)
7342 {
7343 Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE] ? pEdcaParm->Txop[QID_AC_BE] : 10;
7344 Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]-1; /* AIFSN must >= 1 */
7345 Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK];
7346 Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK];
7347 Ac2Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VI];
7348 } /* End of if */
7349 }
7350//#endif // WIFI_TEST //
7351
7352 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
7353 RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
7354 RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
7355 RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
7356
7357
7358 //========================================================
7359 // DMA Register has a copy too.
7360 //========================================================
7361 csr0.field.Ac0Txop = Ac0Cfg.field.AcTxop;
7362 csr0.field.Ac1Txop = Ac1Cfg.field.AcTxop;
7363 RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
7364
7365 csr1.field.Ac2Txop = Ac2Cfg.field.AcTxop;
7366 csr1.field.Ac3Txop = Ac3Cfg.field.AcTxop;
7367 RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
7368
7369 CwminCsr.word = 0;
7370 CwminCsr.field.Cwmin0 = pEdcaParm->Cwmin[QID_AC_BE];
7371 CwminCsr.field.Cwmin1 = pEdcaParm->Cwmin[QID_AC_BK];
7372 CwminCsr.field.Cwmin2 = pEdcaParm->Cwmin[QID_AC_VI];
7373#ifdef CONFIG_STA_SUPPORT
7374 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
7375 CwminCsr.field.Cwmin3 = pEdcaParm->Cwmin[QID_AC_VO] - 1; //for TGn wifi test
7376#endif // CONFIG_STA_SUPPORT //
7377 RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
7378
7379 CwmaxCsr.word = 0;
7380 CwmaxCsr.field.Cwmax0 = pEdcaParm->Cwmax[QID_AC_BE];
7381 CwmaxCsr.field.Cwmax1 = pEdcaParm->Cwmax[QID_AC_BK];
7382 CwmaxCsr.field.Cwmax2 = pEdcaParm->Cwmax[QID_AC_VI];
7383 CwmaxCsr.field.Cwmax3 = pEdcaParm->Cwmax[QID_AC_VO];
7384 RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
7385
7386 AifsnCsr.word = 0;
7387 AifsnCsr.field.Aifsn0 = Ac0Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_BE];
7388 AifsnCsr.field.Aifsn1 = Ac1Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_BK];
7389 AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_VI];
7390#ifdef INF_AMAZON_SE
7391#endif // INF_AMAZON_SE //
7392
7393
7394#ifdef CONFIG_STA_SUPPORT
7395 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
7396 {
7397 // Tuning for Wi-Fi WMM S06
7398 if (pAd->CommonCfg.bWiFiTest &&
7399 pEdcaParm->Aifsn[QID_AC_VI] == 10)
7400 AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn - 4;
7401
7402 // Tuning for TGn Wi-Fi 5.2.32
7403 // STA TestBed changes in this item: connexant legacy sta ==> broadcom 11n sta
7404 if (STA_TGN_WIFI_ON(pAd) &&
7405 pEdcaParm->Aifsn[QID_AC_VI] == 10)
7406 {
7407 AifsnCsr.field.Aifsn0 = 3;
7408 AifsnCsr.field.Aifsn2 = 7;
7409 }
7410
7411 if (INFRA_ON(pAd))
7412 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_WMM_CAPABLE);
7413 }
7414#endif // CONFIG_STA_SUPPORT //
7415
7416#ifdef CONFIG_STA_SUPPORT
7417 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
7418 AifsnCsr.field.Aifsn3 = Ac3Cfg.field.Aifsn - 1; //pEdcaParm->Aifsn[QID_AC_VO]; //for TGn wifi test
7419#ifdef RT30xx
7420 if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020)
7421 {
7422 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
7423 AifsnCsr.field.Aifsn2 = 0x2; //pEdcaParm->Aifsn[QID_AC_VI]; //for WiFi WMM S4-T04.
7424 }
7425#endif // RT30xx //
7426#endif // CONFIG_STA_SUPPORT //
7427 RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, AifsnCsr.word);
7428
7429 NdisMoveMemory(&pAd->CommonCfg.APEdcaParm, pEdcaParm, sizeof(EDCA_PARM));
7430 if (!ADHOC_ON(pAd))
7431 {
7432 DBGPRINT(RT_DEBUG_TRACE,("EDCA [#%d]: AIFSN CWmin CWmax TXOP(us) ACM\n", pEdcaParm->EdcaUpdateCount));
7433 DBGPRINT(RT_DEBUG_TRACE,(" AC_BE %2d %2d %2d %4d %d\n",
7434 pEdcaParm->Aifsn[0],
7435 pEdcaParm->Cwmin[0],
7436 pEdcaParm->Cwmax[0],
7437 pEdcaParm->Txop[0]<<5,
7438 pEdcaParm->bACM[0]));
7439 DBGPRINT(RT_DEBUG_TRACE,(" AC_BK %2d %2d %2d %4d %d\n",
7440 pEdcaParm->Aifsn[1],
7441 pEdcaParm->Cwmin[1],
7442 pEdcaParm->Cwmax[1],
7443 pEdcaParm->Txop[1]<<5,
7444 pEdcaParm->bACM[1]));
7445 DBGPRINT(RT_DEBUG_TRACE,(" AC_VI %2d %2d %2d %4d %d\n",
7446 pEdcaParm->Aifsn[2],
7447 pEdcaParm->Cwmin[2],
7448 pEdcaParm->Cwmax[2],
7449 pEdcaParm->Txop[2]<<5,
7450 pEdcaParm->bACM[2]));
7451 DBGPRINT(RT_DEBUG_TRACE,(" AC_VO %2d %2d %2d %4d %d\n",
7452 pEdcaParm->Aifsn[3],
7453 pEdcaParm->Cwmin[3],
7454 pEdcaParm->Cwmax[3],
7455 pEdcaParm->Txop[3]<<5,
7456 pEdcaParm->bACM[3]));
7457 }
7458 }
7459}
7460
7461/*
7462 ==========================================================================
7463 Description:
7464
7465 IRQL = PASSIVE_LEVEL
7466 IRQL = DISPATCH_LEVEL
7467
7468 ==========================================================================
7469 */
7470VOID AsicSetSlotTime(
7471 IN PRTMP_ADAPTER pAd,
7472 IN BOOLEAN bUseShortSlotTime)
7473{
7474 ULONG SlotTime;
7475 UINT32 RegValue = 0;
7476
7477#ifdef CONFIG_STA_SUPPORT
7478 if (pAd->CommonCfg.Channel > 14)
7479 bUseShortSlotTime = TRUE;
7480#endif // CONFIG_STA_SUPPORT //
7481
7482 if (bUseShortSlotTime)
7483 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
7484 else
7485 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
7486
7487 SlotTime = (bUseShortSlotTime)? 9 : 20;
7488
7489#ifdef CONFIG_STA_SUPPORT
7490 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
7491 {
7492 // force using short SLOT time for FAE to demo performance when TxBurst is ON
7493 if (pAd->CommonCfg.bEnableTxBurst)
7494 SlotTime = 9;
7495 }
7496#endif // CONFIG_STA_SUPPORT //
7497
7498 //
7499 // For some reasons, always set it to short slot time.
7500 //
7501 // ToDo: Should consider capability with 11B
7502 //
7503#ifdef CONFIG_STA_SUPPORT
7504 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
7505 {
7506 if (pAd->StaCfg.BssType == BSS_ADHOC)
7507 SlotTime = 20;
7508 }
7509#endif // CONFIG_STA_SUPPORT //
7510
7511 RTMP_IO_READ32(pAd, BKOFF_SLOT_CFG, &RegValue);
7512 RegValue = RegValue & 0xFFFFFF00;
7513
7514 RegValue |= SlotTime;
7515
7516 RTMP_IO_WRITE32(pAd, BKOFF_SLOT_CFG, RegValue);
7517}
7518
7519/*
7520 ========================================================================
7521 Description:
7522 Add Shared key information into ASIC.
7523 Update shared key, TxMic and RxMic to Asic Shared key table
7524 Update its cipherAlg to Asic Shared key Mode.
7525
7526 Return:
7527 ========================================================================
7528*/
7529VOID AsicAddSharedKeyEntry(
7530 IN PRTMP_ADAPTER pAd,
7531 IN UCHAR BssIndex,
7532 IN UCHAR KeyIdx,
7533 IN UCHAR CipherAlg,
7534 IN PUCHAR pKey,
7535 IN PUCHAR pTxMic,
7536 IN PUCHAR pRxMic)
7537{
7538 ULONG offset; //, csr0;
7539 SHAREDKEY_MODE_STRUC csr1;
7540
7541 DBGPRINT(RT_DEBUG_TRACE, ("AsicAddSharedKeyEntry BssIndex=%d, KeyIdx=%d\n", BssIndex,KeyIdx));
7542//============================================================================================
7543
7544 DBGPRINT(RT_DEBUG_TRACE,("AsicAddSharedKeyEntry: %s key #%d\n", CipherName[CipherAlg], BssIndex*4 + KeyIdx));
7545 DBGPRINT_RAW(RT_DEBUG_TRACE, (" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7546 pKey[0],pKey[1],pKey[2],pKey[3],pKey[4],pKey[5],pKey[6],pKey[7],pKey[8],pKey[9],pKey[10],pKey[11],pKey[12],pKey[13],pKey[14],pKey[15]));
7547 if (pRxMic)
7548 {
7549 DBGPRINT_RAW(RT_DEBUG_TRACE, (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7550 pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
7551 }
7552 if (pTxMic)
7553 {
7554 DBGPRINT_RAW(RT_DEBUG_TRACE, (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7555 pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
7556 }
7557//============================================================================================
7558 //
7559 // fill key material - key + TX MIC + RX MIC
7560 //
7561
7562#ifdef RT2870
7563{
7564 offset = SHARED_KEY_TABLE_BASE + (4*BssIndex + KeyIdx)*HW_KEY_ENTRY_SIZE;
7565 RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_SHARE_KEY);
7566
7567 offset += MAX_LEN_OF_SHARE_KEY;
7568 if (pTxMic)
7569 {
7570 RTUSBMultiWrite(pAd, offset, pTxMic, 8);
7571 }
7572
7573 offset += 8;
7574 if (pRxMic)
7575 {
7576 RTUSBMultiWrite(pAd, offset, pRxMic, 8);
7577 }
7578}
7579#endif // RT2870 //
7580
7581 //
7582 // Update cipher algorithm. WSTA always use BSS0
7583 //
7584 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word);
7585 DBGPRINT(RT_DEBUG_TRACE,("Read: SHARED_KEY_MODE_BASE at this Bss[%d] KeyIdx[%d]= 0x%x \n", BssIndex,KeyIdx, csr1.word));
7586 if ((BssIndex%2) == 0)
7587 {
7588 if (KeyIdx == 0)
7589 csr1.field.Bss0Key0CipherAlg = CipherAlg;
7590 else if (KeyIdx == 1)
7591 csr1.field.Bss0Key1CipherAlg = CipherAlg;
7592 else if (KeyIdx == 2)
7593 csr1.field.Bss0Key2CipherAlg = CipherAlg;
7594 else
7595 csr1.field.Bss0Key3CipherAlg = CipherAlg;
7596 }
7597 else
7598 {
7599 if (KeyIdx == 0)
7600 csr1.field.Bss1Key0CipherAlg = CipherAlg;
7601 else if (KeyIdx == 1)
7602 csr1.field.Bss1Key1CipherAlg = CipherAlg;
7603 else if (KeyIdx == 2)
7604 csr1.field.Bss1Key2CipherAlg = CipherAlg;
7605 else
7606 csr1.field.Bss1Key3CipherAlg = CipherAlg;
7607 }
7608 DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word));
7609 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word);
7610
7611}
7612
7613// IRQL = DISPATCH_LEVEL
7614VOID AsicRemoveSharedKeyEntry(
7615 IN PRTMP_ADAPTER pAd,
7616 IN UCHAR BssIndex,
7617 IN UCHAR KeyIdx)
7618{
7619 //ULONG SecCsr0;
7620 SHAREDKEY_MODE_STRUC csr1;
7621
7622 DBGPRINT(RT_DEBUG_TRACE,("AsicRemoveSharedKeyEntry: #%d \n", BssIndex*4 + KeyIdx));
7623
7624 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word);
7625 if ((BssIndex%2) == 0)
7626 {
7627 if (KeyIdx == 0)
7628 csr1.field.Bss0Key0CipherAlg = 0;
7629 else if (KeyIdx == 1)
7630 csr1.field.Bss0Key1CipherAlg = 0;
7631 else if (KeyIdx == 2)
7632 csr1.field.Bss0Key2CipherAlg = 0;
7633 else
7634 csr1.field.Bss0Key3CipherAlg = 0;
7635 }
7636 else
7637 {
7638 if (KeyIdx == 0)
7639 csr1.field.Bss1Key0CipherAlg = 0;
7640 else if (KeyIdx == 1)
7641 csr1.field.Bss1Key1CipherAlg = 0;
7642 else if (KeyIdx == 2)
7643 csr1.field.Bss1Key2CipherAlg = 0;
7644 else
7645 csr1.field.Bss1Key3CipherAlg = 0;
7646 }
7647 DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word));
7648 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word);
7649 ASSERT(BssIndex < 4);
7650 ASSERT(KeyIdx < 4);
7651
7652}
7653
7654
7655VOID AsicUpdateWCIDAttribute(
7656 IN PRTMP_ADAPTER pAd,
7657 IN USHORT WCID,
7658 IN UCHAR BssIndex,
7659 IN UCHAR CipherAlg,
7660 IN BOOLEAN bUsePairewiseKeyTable)
7661{
7662 ULONG WCIDAttri = 0, offset;
7663
7664 //
7665 // Update WCID attribute.
7666 // Only TxKey could update WCID attribute.
7667 //
7668 offset = MAC_WCID_ATTRIBUTE_BASE + (WCID * HW_WCID_ATTRI_SIZE);
7669 WCIDAttri = (BssIndex << 4) | (CipherAlg << 1) | (bUsePairewiseKeyTable);
7670 RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
7671}
7672
7673VOID AsicUpdateWCIDIVEIV(
7674 IN PRTMP_ADAPTER pAd,
7675 IN USHORT WCID,
7676 IN ULONG uIV,
7677 IN ULONG uEIV)
7678{
7679 ULONG offset;
7680
7681 offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
7682
7683 RTMP_IO_WRITE32(pAd, offset, uIV);
7684 RTMP_IO_WRITE32(pAd, offset + 4, uEIV);
7685}
7686
7687VOID AsicUpdateRxWCIDTable(
7688 IN PRTMP_ADAPTER pAd,
7689 IN USHORT WCID,
7690 IN PUCHAR pAddr)
7691{
7692 ULONG offset;
7693 ULONG Addr;
7694
7695 offset = MAC_WCID_BASE + (WCID * HW_WCID_ENTRY_SIZE);
7696 Addr = pAddr[0] + (pAddr[1] << 8) +(pAddr[2] << 16) +(pAddr[3] << 24);
7697 RTMP_IO_WRITE32(pAd, offset, Addr);
7698 Addr = pAddr[4] + (pAddr[5] << 8);
7699 RTMP_IO_WRITE32(pAd, offset + 4, Addr);
7700}
7701
7702
7703/*
7704 ========================================================================
7705
7706 Routine Description:
7707 Set Cipher Key, Cipher algorithm, IV/EIV to Asic
7708
7709 Arguments:
7710 pAd Pointer to our adapter
7711 WCID WCID Entry number.
7712 BssIndex BSSID index, station or none multiple BSSID support
7713 this value should be 0.
7714 KeyIdx This KeyIdx will set to IV's KeyID if bTxKey enabled
7715 pCipherKey Pointer to Cipher Key.
7716 bUsePairewiseKeyTable TRUE means saved the key in SharedKey table,
7717 otherwise PairewiseKey table
7718 bTxKey This is the transmit key if enabled.
7719
7720 Return Value:
7721 None
7722
7723 Note:
7724 This routine will set the relative key stuff to Asic including WCID attribute,
7725 Cipher Key, Cipher algorithm and IV/EIV.
7726
7727 IV/EIV will be update if this CipherKey is the transmission key because
7728 ASIC will base on IV's KeyID value to select Cipher Key.
7729
7730 If bTxKey sets to FALSE, this is not the TX key, but it could be
7731 RX key
7732
7733 For AP mode bTxKey must be always set to TRUE.
7734 ========================================================================
7735*/
7736VOID AsicAddKeyEntry(
7737 IN PRTMP_ADAPTER pAd,
7738 IN USHORT WCID,
7739 IN UCHAR BssIndex,
7740 IN UCHAR KeyIdx,
7741 IN PCIPHER_KEY pCipherKey,
7742 IN BOOLEAN bUsePairewiseKeyTable,
7743 IN BOOLEAN bTxKey)
7744{
7745 ULONG offset;
7746// ULONG WCIDAttri = 0;
7747 UCHAR IV4 = 0;
7748 PUCHAR pKey = pCipherKey->Key;
7749// ULONG KeyLen = pCipherKey->KeyLen;
7750 PUCHAR pTxMic = pCipherKey->TxMic;
7751 PUCHAR pRxMic = pCipherKey->RxMic;
7752 PUCHAR pTxtsc = pCipherKey->TxTsc;
7753 UCHAR CipherAlg = pCipherKey->CipherAlg;
7754 SHAREDKEY_MODE_STRUC csr1;
7755
7756// ASSERT(KeyLen <= MAX_LEN_OF_PEER_KEY);
7757
7758 DBGPRINT(RT_DEBUG_TRACE, ("==> AsicAddKeyEntry\n"));
7759 //
7760 // 1.) decide key table offset
7761 //
7762 if (bUsePairewiseKeyTable)
7763 offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
7764 else
7765 offset = SHARED_KEY_TABLE_BASE + (4 * BssIndex + KeyIdx) * HW_KEY_ENTRY_SIZE;
7766
7767 //
7768 // 2.) Set Key to Asic
7769 //
7770 //for (i = 0; i < KeyLen; i++)
7771
7772#ifdef RT2870
7773 RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_PEER_KEY);
7774 offset += MAX_LEN_OF_PEER_KEY;
7775
7776 //
7777 // 3.) Set MIC key if available
7778 //
7779 if (pTxMic)
7780 {
7781 RTUSBMultiWrite(pAd, offset, pTxMic, 8);
7782 }
7783 offset += LEN_TKIP_TXMICK;
7784
7785 if (pRxMic)
7786 {
7787 RTUSBMultiWrite(pAd, offset, pRxMic, 8);
7788 }
7789#endif // RT2870 //
7790
7791 //
7792 // 4.) Modify IV/EIV if needs
7793 // This will force Asic to use this key ID by setting IV.
7794 //
7795 if (bTxKey)
7796 {
7797
7798#ifdef RT2870
7799 UINT32 tmpVal;
7800
7801 //
7802 // Write IV
7803 //
7804 IV4 = (KeyIdx << 6);
7805 if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) ||(CipherAlg == CIPHER_AES))
7806 IV4 |= 0x20; // turn on extension bit means EIV existence
7807
7808 tmpVal = pTxtsc[1] + (((pTxtsc[1] | 0x20) & 0x7f) << 8) + (pTxtsc[0] << 16) + (IV4 << 24);
7809 RTMP_IO_WRITE32(pAd, offset, tmpVal);
7810
7811 //
7812 // Write EIV
7813 //
7814 offset += 4;
7815 RTMP_IO_WRITE32(pAd, offset, *(PUINT32)&pCipherKey->TxTsc[2]);
7816#endif // RT2870 //
7817 AsicUpdateWCIDAttribute(pAd, WCID, BssIndex, CipherAlg, bUsePairewiseKeyTable);
7818 }
7819
7820 if (!bUsePairewiseKeyTable)
7821 {
7822 //
7823 // Only update the shared key security mode
7824 //
7825 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), &csr1.word);
7826 if ((BssIndex % 2) == 0)
7827 {
7828 if (KeyIdx == 0)
7829 csr1.field.Bss0Key0CipherAlg = CipherAlg;
7830 else if (KeyIdx == 1)
7831 csr1.field.Bss0Key1CipherAlg = CipherAlg;
7832 else if (KeyIdx == 2)
7833 csr1.field.Bss0Key2CipherAlg = CipherAlg;
7834 else
7835 csr1.field.Bss0Key3CipherAlg = CipherAlg;
7836 }
7837 else
7838 {
7839 if (KeyIdx == 0)
7840 csr1.field.Bss1Key0CipherAlg = CipherAlg;
7841 else if (KeyIdx == 1)
7842 csr1.field.Bss1Key1CipherAlg = CipherAlg;
7843 else if (KeyIdx == 2)
7844 csr1.field.Bss1Key2CipherAlg = CipherAlg;
7845 else
7846 csr1.field.Bss1Key3CipherAlg = CipherAlg;
7847 }
7848 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), csr1.word);
7849 }
7850
7851 DBGPRINT(RT_DEBUG_TRACE, ("<== AsicAddKeyEntry\n"));
7852}
7853
7854
7855/*
7856 ========================================================================
7857 Description:
7858 Add Pair-wise key material into ASIC.
7859 Update pairwise key, TxMic and RxMic to Asic Pair-wise key table
7860
7861 Return:
7862 ========================================================================
7863*/
7864VOID AsicAddPairwiseKeyEntry(
7865 IN PRTMP_ADAPTER pAd,
7866 IN PUCHAR pAddr,
7867 IN UCHAR WCID,
7868 IN CIPHER_KEY *pCipherKey)
7869{
7870 INT i;
7871 ULONG offset;
7872 PUCHAR pKey = pCipherKey->Key;
7873 PUCHAR pTxMic = pCipherKey->TxMic;
7874 PUCHAR pRxMic = pCipherKey->RxMic;
7875#ifdef DBG
7876 UCHAR CipherAlg = pCipherKey->CipherAlg;
7877#endif // DBG //
7878
7879 // EKEY
7880 offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
7881#ifdef RT2870
7882 RTUSBMultiWrite(pAd, offset, &pCipherKey->Key[0], MAX_LEN_OF_PEER_KEY);
7883#endif // RT2870 //
7884 for (i=0; i<MAX_LEN_OF_PEER_KEY; i+=4)
7885 {
7886 UINT32 Value;
7887 RTMP_IO_READ32(pAd, offset + i, &Value);
7888 }
7889
7890 offset += MAX_LEN_OF_PEER_KEY;
7891
7892 // MIC KEY
7893 if (pTxMic)
7894 {
7895#ifdef RT2870
7896 RTUSBMultiWrite(pAd, offset, &pCipherKey->TxMic[0], 8);
7897#endif // RT2870 //
7898 }
7899 offset += 8;
7900 if (pRxMic)
7901 {
7902#ifdef RT2870
7903 RTUSBMultiWrite(pAd, offset, &pCipherKey->RxMic[0], 8);
7904#endif // RT2870 //
7905 }
7906
7907 DBGPRINT(RT_DEBUG_TRACE,("AsicAddPairwiseKeyEntry: WCID #%d Alg=%s\n",WCID, CipherName[CipherAlg]));
7908 DBGPRINT(RT_DEBUG_TRACE,(" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7909 pKey[0],pKey[1],pKey[2],pKey[3],pKey[4],pKey[5],pKey[6],pKey[7],pKey[8],pKey[9],pKey[10],pKey[11],pKey[12],pKey[13],pKey[14],pKey[15]));
7910 if (pRxMic)
7911 {
7912 DBGPRINT(RT_DEBUG_TRACE, (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7913 pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
7914 }
7915 if (pTxMic)
7916 {
7917 DBGPRINT(RT_DEBUG_TRACE, (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7918 pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
7919 }
7920}
7921/*
7922 ========================================================================
7923 Description:
7924 Remove Pair-wise key material from ASIC.
7925
7926 Return:
7927 ========================================================================
7928*/
7929VOID AsicRemovePairwiseKeyEntry(
7930 IN PRTMP_ADAPTER pAd,
7931 IN UCHAR BssIdx,
7932 IN UCHAR Wcid)
7933{
7934 ULONG WCIDAttri;
7935 USHORT offset;
7936
7937 // re-set the entry's WCID attribute as OPEN-NONE.
7938 offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE);
7939 WCIDAttri = (BssIdx<<4) | PAIRWISEKEYTABLE;
7940 RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
7941}
7942
7943BOOLEAN AsicSendCommandToMcu(
7944 IN PRTMP_ADAPTER pAd,
7945 IN UCHAR Command,
7946 IN UCHAR Token,
7947 IN UCHAR Arg0,
7948 IN UCHAR Arg1)
7949{
7950 HOST_CMD_CSR_STRUC H2MCmd;
7951 H2M_MAILBOX_STRUC H2MMailbox;
7952 ULONG i = 0;
7953 do
7954 {
7955 RTMP_IO_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word);
7956 if (H2MMailbox.field.Owner == 0)
7957 break;
7958
7959 RTMPusecDelay(2);
7960 } while(i++ < 100);
7961
7962 if (i >= 100)
7963 {
7964 {
7965 DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
7966 }
7967 return FALSE;
7968 }
7969
7970
7971 H2MMailbox.field.Owner = 1; // pass ownership to MCU
7972 H2MMailbox.field.CmdToken = Token;
7973 H2MMailbox.field.HighByte = Arg1;
7974 H2MMailbox.field.LowByte = Arg0;
7975 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word);
7976
7977 H2MCmd.word = 0;
7978 H2MCmd.field.HostCommand = Command;
7979 RTMP_IO_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word);
7980
7981 if (Command != 0x80)
7982 {
7983 }
7984
7985 return TRUE;
7986}
7987
7988
7989/*
7990 ========================================================================
7991
7992 Routine Description:
7993 Verify the support rate for different PHY type
7994
7995 Arguments:
7996 pAd Pointer to our adapter
7997
7998 Return Value:
7999 None
8000
8001 IRQL = PASSIVE_LEVEL
8002
8003 ========================================================================
8004*/
8005VOID RTMPCheckRates(
8006 IN PRTMP_ADAPTER pAd,
8007 IN OUT UCHAR SupRate[],
8008 IN OUT UCHAR *SupRateLen)
8009{
8010 UCHAR RateIdx, i, j;
8011 UCHAR NewRate[12], NewRateLen;
8012
8013 NewRateLen = 0;
8014
8015 if (pAd->CommonCfg.PhyMode == PHY_11B)
8016 RateIdx = 4;
8017 else
8018 RateIdx = 12;
8019
8020 // Check for support rates exclude basic rate bit
8021 for (i = 0; i < *SupRateLen; i++)
8022 for (j = 0; j < RateIdx; j++)
8023 if ((SupRate[i] & 0x7f) == RateIdTo500Kbps[j])
8024 NewRate[NewRateLen++] = SupRate[i];
8025
8026 *SupRateLen = NewRateLen;
8027 NdisMoveMemory(SupRate, NewRate, NewRateLen);
8028}
8029
8030#ifdef CONFIG_STA_SUPPORT
8031#ifdef DOT11_N_SUPPORT
8032BOOLEAN RTMPCheckChannel(
8033 IN PRTMP_ADAPTER pAd,
8034 IN UCHAR CentralChannel,
8035 IN UCHAR Channel)
8036{
8037 UCHAR k;
8038 UCHAR UpperChannel = 0, LowerChannel = 0;
8039 UCHAR NoEffectChannelinList = 0;
8040
8041 // Find upper and lower channel according to 40MHz current operation.
8042 if (CentralChannel < Channel)
8043 {
8044 UpperChannel = Channel;
8045 if (CentralChannel > 2)
8046 LowerChannel = CentralChannel - 2;
8047 else
8048 return FALSE;
8049 }
8050 else if (CentralChannel > Channel)
8051 {
8052 UpperChannel = CentralChannel + 2;
8053 LowerChannel = Channel;
8054 }
8055
8056 for (k = 0;k < pAd->ChannelListNum;k++)
8057 {
8058 if (pAd->ChannelList[k].Channel == UpperChannel)
8059 {
8060 NoEffectChannelinList ++;
8061 }
8062 if (pAd->ChannelList[k].Channel == LowerChannel)
8063 {
8064 NoEffectChannelinList ++;
8065 }
8066 }
8067
8068 DBGPRINT(RT_DEBUG_TRACE,("Total Channel in Channel List = [%d]\n", NoEffectChannelinList));
8069 if (NoEffectChannelinList == 2)
8070 return TRUE;
8071 else
8072 return FALSE;
8073}
8074
8075/*
8076 ========================================================================
8077
8078 Routine Description:
8079 Verify the support rate for HT phy type
8080
8081 Arguments:
8082 pAd Pointer to our adapter
8083
8084 Return Value:
8085 FALSE if pAd->CommonCfg.SupportedHtPhy doesn't accept the pHtCapability. (AP Mode)
8086
8087 IRQL = PASSIVE_LEVEL
8088
8089 ========================================================================
8090*/
8091BOOLEAN RTMPCheckHt(
8092 IN PRTMP_ADAPTER pAd,
8093 IN UCHAR Wcid,
8094 IN HT_CAPABILITY_IE *pHtCapability,
8095 IN ADD_HT_INFO_IE *pAddHtInfo)
8096{
8097 if (Wcid >= MAX_LEN_OF_MAC_TABLE)
8098 return FALSE;
8099
8100 // If use AMSDU, set flag.
8101 if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable)
8102 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_AMSDU_INUSED);
8103 // Save Peer Capability
8104 if (pHtCapability->HtCapInfo.ShortGIfor20)
8105 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_SGI20_CAPABLE);
8106 if (pHtCapability->HtCapInfo.ShortGIfor40)
8107 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_SGI40_CAPABLE);
8108 if (pHtCapability->HtCapInfo.TxSTBC)
8109 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_TxSTBC_CAPABLE);
8110 if (pHtCapability->HtCapInfo.RxSTBC)
8111 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_RxSTBC_CAPABLE);
8112 if (pAd->CommonCfg.bRdg && pHtCapability->ExtHtCapInfo.RDGSupport)
8113 {
8114 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_RDG_CAPABLE);
8115 }
8116
8117 if (Wcid < MAX_LEN_OF_MAC_TABLE)
8118 {
8119 pAd->MacTab.Content[Wcid].MpduDensity = pHtCapability->HtCapParm.MpduDensity;
8120 }
8121
8122 // Will check ChannelWidth for MCSSet[4] below
8123 pAd->MlmeAux.HtCapability.MCSSet[4] = 0x1;
8124 switch (pAd->CommonCfg.RxStream)
8125 {
8126 case 1:
8127 pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
8128 pAd->MlmeAux.HtCapability.MCSSet[1] = 0x00;
8129 pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00;
8130 pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
8131 break;
8132 case 2:
8133 pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
8134 pAd->MlmeAux.HtCapability.MCSSet[1] = 0xff;
8135 pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00;
8136 pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
8137 break;
8138 case 3:
8139 pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
8140 pAd->MlmeAux.HtCapability.MCSSet[1] = 0xff;
8141 pAd->MlmeAux.HtCapability.MCSSet[2] = 0xff;
8142 pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
8143 break;
8144 }
8145
8146 pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth = pAddHtInfo->AddHtInfo.RecomWidth & pAd->CommonCfg.DesiredHtPhy.ChannelWidth;
8147
8148 DBGPRINT(RT_DEBUG_TRACE, ("RTMPCheckHt:: HtCapInfo.ChannelWidth=%d, RecomWidth=%d, DesiredHtPhy.ChannelWidth=%d, BW40MAvailForA/G=%d/%d, PhyMode=%d \n",
8149 pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth, pAddHtInfo->AddHtInfo.RecomWidth, pAd->CommonCfg.DesiredHtPhy.ChannelWidth,
8150 pAd->NicConfig2.field.BW40MAvailForA, pAd->NicConfig2.field.BW40MAvailForG, pAd->CommonCfg.PhyMode));
8151
8152 pAd->MlmeAux.HtCapability.HtCapInfo.GF = pHtCapability->HtCapInfo.GF &pAd->CommonCfg.DesiredHtPhy.GF;
8153
8154 // Send Assoc Req with my HT capability.
8155 pAd->MlmeAux.HtCapability.HtCapInfo.AMsduSize = pAd->CommonCfg.DesiredHtPhy.AmsduSize;
8156 pAd->MlmeAux.HtCapability.HtCapInfo.MimoPs = pAd->CommonCfg.DesiredHtPhy.MimoPs;
8157 pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor20 = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20) & (pHtCapability->HtCapInfo.ShortGIfor20);
8158 pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor40 = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40) & (pHtCapability->HtCapInfo.ShortGIfor40);
8159 pAd->MlmeAux.HtCapability.HtCapInfo.TxSTBC = (pAd->CommonCfg.DesiredHtPhy.TxSTBC)&(pHtCapability->HtCapInfo.RxSTBC);
8160 pAd->MlmeAux.HtCapability.HtCapInfo.RxSTBC = (pAd->CommonCfg.DesiredHtPhy.RxSTBC)&(pHtCapability->HtCapInfo.TxSTBC);
8161 pAd->MlmeAux.HtCapability.HtCapParm.MaxRAmpduFactor = pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor;
8162 pAd->MlmeAux.HtCapability.HtCapParm.MpduDensity = pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity;
8163 pAd->MlmeAux.HtCapability.ExtHtCapInfo.PlusHTC = pHtCapability->ExtHtCapInfo.PlusHTC;
8164 pAd->MacTab.Content[Wcid].HTCapability.ExtHtCapInfo.PlusHTC = pHtCapability->ExtHtCapInfo.PlusHTC;
8165 if (pAd->CommonCfg.bRdg)
8166 {
8167 pAd->MlmeAux.HtCapability.ExtHtCapInfo.RDGSupport = pHtCapability->ExtHtCapInfo.RDGSupport;
8168 pAd->MlmeAux.HtCapability.ExtHtCapInfo.PlusHTC = 1;
8169 }
8170
8171 if (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_20)
8172 pAd->MlmeAux.HtCapability.MCSSet[4] = 0x0; // BW20 can't transmit MCS32
8173
8174 COPY_AP_HTSETTINGS_FROM_BEACON(pAd, pHtCapability);
8175 return TRUE;
8176}
8177#endif // DOT11_N_SUPPORT //
8178#endif // CONFIG_STA_SUPPORT //
8179
8180/*
8181 ========================================================================
8182
8183 Routine Description:
8184 Verify the support rate for different PHY type
8185
8186 Arguments:
8187 pAd Pointer to our adapter
8188
8189 Return Value:
8190 None
8191
8192 IRQL = PASSIVE_LEVEL
8193
8194 ========================================================================
8195*/
8196VOID RTMPUpdateMlmeRate(
8197 IN PRTMP_ADAPTER pAd)
8198{
8199 UCHAR MinimumRate;
8200 UCHAR ProperMlmeRate; //= RATE_54;
8201 UCHAR i, j, RateIdx = 12; //1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54
8202 BOOLEAN bMatch = FALSE;
8203
8204 switch (pAd->CommonCfg.PhyMode)
8205 {
8206 case PHY_11B:
8207 ProperMlmeRate = RATE_11;
8208 MinimumRate = RATE_1;
8209 break;
8210 case PHY_11BG_MIXED:
8211#ifdef DOT11_N_SUPPORT
8212 case PHY_11ABGN_MIXED:
8213 case PHY_11BGN_MIXED:
8214#endif // DOT11_N_SUPPORT //
8215 if ((pAd->MlmeAux.SupRateLen == 4) &&
8216 (pAd->MlmeAux.ExtRateLen == 0))
8217 // B only AP
8218 ProperMlmeRate = RATE_11;
8219 else
8220 ProperMlmeRate = RATE_24;
8221
8222 if (pAd->MlmeAux.Channel <= 14)
8223 MinimumRate = RATE_1;
8224 else
8225 MinimumRate = RATE_6;
8226 break;
8227 case PHY_11A:
8228#ifdef DOT11_N_SUPPORT
8229 case PHY_11N_2_4G: // rt2860 need to check mlmerate for 802.11n
8230 case PHY_11GN_MIXED:
8231 case PHY_11AGN_MIXED:
8232 case PHY_11AN_MIXED:
8233 case PHY_11N_5G:
8234#endif // DOT11_N_SUPPORT //
8235 ProperMlmeRate = RATE_24;
8236 MinimumRate = RATE_6;
8237 break;
8238 case PHY_11ABG_MIXED:
8239 ProperMlmeRate = RATE_24;
8240 if (pAd->MlmeAux.Channel <= 14)
8241 MinimumRate = RATE_1;
8242 else
8243 MinimumRate = RATE_6;
8244 break;
8245 default: // error
8246 ProperMlmeRate = RATE_1;
8247 MinimumRate = RATE_1;
8248 break;
8249 }
8250
8251 for (i = 0; i < pAd->MlmeAux.SupRateLen; i++)
8252 {
8253 for (j = 0; j < RateIdx; j++)
8254 {
8255 if ((pAd->MlmeAux.SupRate[i] & 0x7f) == RateIdTo500Kbps[j])
8256 {
8257 if (j == ProperMlmeRate)
8258 {
8259 bMatch = TRUE;
8260 break;
8261 }
8262 }
8263 }
8264
8265 if (bMatch)
8266 break;
8267 }
8268
8269 if (bMatch == FALSE)
8270 {
8271 for (i = 0; i < pAd->MlmeAux.ExtRateLen; i++)
8272 {
8273 for (j = 0; j < RateIdx; j++)
8274 {
8275 if ((pAd->MlmeAux.ExtRate[i] & 0x7f) == RateIdTo500Kbps[j])
8276 {
8277 if (j == ProperMlmeRate)
8278 {
8279 bMatch = TRUE;
8280 break;
8281 }
8282 }
8283 }
8284
8285 if (bMatch)
8286 break;
8287 }
8288 }
8289
8290 if (bMatch == FALSE)
8291 {
8292 ProperMlmeRate = MinimumRate;
8293 }
8294
8295 pAd->CommonCfg.MlmeRate = MinimumRate;
8296 pAd->CommonCfg.RtsRate = ProperMlmeRate;
8297 if (pAd->CommonCfg.MlmeRate >= RATE_6)
8298 {
8299 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
8300 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
8301 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
8302 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
8303 }
8304 else
8305 {
8306 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
8307 pAd->CommonCfg.MlmeTransmit.field.MCS = pAd->CommonCfg.MlmeRate;
8308 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_CCK;
8309 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = pAd->CommonCfg.MlmeRate;
8310 }
8311
8312 DBGPRINT(RT_DEBUG_TRACE, ("RTMPUpdateMlmeRate ==> MlmeTransmit = 0x%x \n" , pAd->CommonCfg.MlmeTransmit.word));
8313}
8314
8315CHAR RTMPMaxRssi(
8316 IN PRTMP_ADAPTER pAd,
8317 IN CHAR Rssi0,
8318 IN CHAR Rssi1,
8319 IN CHAR Rssi2)
8320{
8321 CHAR larger = -127;
8322
8323 if ((pAd->Antenna.field.RxPath == 1) && (Rssi0 != 0))
8324 {
8325 larger = Rssi0;
8326 }
8327
8328 if ((pAd->Antenna.field.RxPath >= 2) && (Rssi1 != 0))
8329 {
8330 larger = max(Rssi0, Rssi1);
8331 }
8332
8333 if ((pAd->Antenna.field.RxPath == 3) && (Rssi2 != 0))
8334 {
8335 larger = max(larger, Rssi2);
8336 }
8337
8338 if (larger == -127)
8339 larger = 0;
8340
8341 return larger;
8342}
8343
8344
8345// Antenna divesity use GPIO3 and EESK pin for control
8346// Antenna and EEPROM access are both using EESK pin,
8347// Therefor we should avoid accessing EESK at the same time
8348// Then restore antenna after EEPROM access
8349VOID AsicSetRxAnt(
8350 IN PRTMP_ADAPTER pAd,
8351 IN UCHAR Ant)
8352{
8353#ifdef RT30xx
8354 UINT32 Value;
8355 UINT32 x;
8356
8357 if ((pAd->EepromAccess) ||
8358 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) ||
8359 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) ||
8360 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) ||
8361 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
8362 {
8363 return;
8364 }
8365
8366 // the antenna selection is through firmware and MAC register(GPIO3)
8367 if (Ant == 0)
8368 {
8369 // Main antenna
8370 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
8371 x |= (EESK);
8372 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
8373
8374 RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value);
8375 Value &= ~(0x0808);
8376 RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value);
8377 DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to main antenna\n"));
8378 }
8379 else
8380 {
8381 // Aux antenna
8382 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
8383 x &= ~(EESK);
8384 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
8385
8386 RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value);
8387 Value &= ~(0x0808);
8388 Value |= 0x08;
8389 RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value);
8390 DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to aux antenna\n"));
8391 }
8392#endif // RT30xx //
8393}
8394
8395
8396/*
8397 ========================================================================
8398 Routine Description:
8399 Periodic evaluate antenna link status
8400
8401 Arguments:
8402 pAd - Adapter pointer
8403
8404 Return Value:
8405 None
8406
8407 ========================================================================
8408*/
8409VOID AsicEvaluateRxAnt(
8410 IN PRTMP_ADAPTER pAd)
8411{
8412 UCHAR BBPR3 = 0;
8413
8414#ifdef RALINK_ATE
8415 if (ATE_ON(pAd))
8416 return;
8417#endif // RALINK_ATE //
8418
8419 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS |
8420 fRTMP_ADAPTER_HALT_IN_PROGRESS |
8421 fRTMP_ADAPTER_RADIO_OFF |
8422 fRTMP_ADAPTER_NIC_NOT_EXIST |
8423 fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS) ||
8424 OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
8425#ifdef RT30xx
8426 || (pAd->EepromAccess)
8427#endif // RT30xx //
8428 )
8429 return;
8430
8431
8432#ifdef CONFIG_STA_SUPPORT
8433 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
8434 {
8435 //if (pAd->StaCfg.Psm == PWR_SAVE)
8436 // return;
8437 }
8438#endif // CONFIG_STA_SUPPORT //
8439
8440 // two antenna selection mechanism- one is antenna diversity, the other is failed antenna remove
8441 // one is antenna diversity:there is only one antenna can rx and tx
8442 // the other is failed antenna remove:two physical antenna can rx and tx
8443 if (pAd->NicConfig2.field.AntDiversity)
8444 {
8445 DBGPRINT(RT_DEBUG_TRACE,("AntDiv - before evaluate Pair1-Ant (%d,%d)\n",
8446 pAd->RxAnt.Pair1PrimaryRxAnt, pAd->RxAnt.Pair1SecondaryRxAnt));
8447
8448 AsicSetRxAnt(pAd, pAd->RxAnt.Pair1SecondaryRxAnt);
8449
8450 pAd->RxAnt.EvaluatePeriod = 1; // 1:Means switch to SecondaryRxAnt, 0:Means switch to Pair1PrimaryRxAnt
8451 pAd->RxAnt.FirstPktArrivedWhenEvaluate = FALSE;
8452 pAd->RxAnt.RcvPktNumWhenEvaluate = 0;
8453
8454 // a one-shot timer to end the evalution
8455 // dynamic adjust antenna evaluation period according to the traffic
8456 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
8457 RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 100);
8458 else
8459 RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 300);
8460 }
8461 else
8462 {
8463
8464#ifdef CONFIG_STA_SUPPORT
8465 if (pAd->StaCfg.Psm == PWR_SAVE)
8466 return;
8467#endif // CONFIG_STA_SUPPORT //
8468
8469 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
8470 BBPR3 &= (~0x18);
8471 if(pAd->Antenna.field.RxPath == 3)
8472 {
8473 BBPR3 |= (0x10);
8474 }
8475 else if(pAd->Antenna.field.RxPath == 2)
8476 {
8477 BBPR3 |= (0x8);
8478 }
8479 else if(pAd->Antenna.field.RxPath == 1)
8480 {
8481 BBPR3 |= (0x0);
8482 }
8483 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
8484#ifdef CONFIG_STA_SUPPORT
8485#endif // CONFIG_STA_SUPPORT //
8486 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
8487 )
8488 {
8489 ULONG TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
8490 pAd->RalinkCounters.OneSecTxRetryOkCount +
8491 pAd->RalinkCounters.OneSecTxFailCount;
8492
8493 // dynamic adjust antenna evaluation period according to the traffic
8494 if (TxTotalCnt > 50)
8495 {
8496 RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 20);
8497 pAd->Mlme.bLowThroughput = FALSE;
8498 }
8499 else
8500 {
8501 RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 300);
8502 pAd->Mlme.bLowThroughput = TRUE;
8503 }
8504 }
8505 }
8506}
8507
8508/*
8509 ========================================================================
8510 Routine Description:
8511 After evaluation, check antenna link status
8512
8513 Arguments:
8514 pAd - Adapter pointer
8515
8516 Return Value:
8517 None
8518
8519 ========================================================================
8520*/
8521VOID AsicRxAntEvalTimeout(
8522 IN PVOID SystemSpecific1,
8523 IN PVOID FunctionContext,
8524 IN PVOID SystemSpecific2,
8525 IN PVOID SystemSpecific3)
8526{
8527 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
8528#ifdef CONFIG_STA_SUPPORT
8529 UCHAR BBPR3 = 0;
8530 CHAR larger = -127, rssi0, rssi1, rssi2;
8531#endif // CONFIG_STA_SUPPORT //
8532
8533#ifdef RALINK_ATE
8534 if (ATE_ON(pAd))
8535 return;
8536#endif // RALINK_ATE //
8537
8538 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS |
8539 fRTMP_ADAPTER_HALT_IN_PROGRESS |
8540 fRTMP_ADAPTER_RADIO_OFF |
8541 fRTMP_ADAPTER_NIC_NOT_EXIST) ||
8542 OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
8543#ifdef RT30xx
8544 || (pAd->EepromAccess)
8545#endif // RT30xx //
8546 )
8547 return;
8548
8549
8550#ifdef CONFIG_STA_SUPPORT
8551 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
8552 {
8553 //if (pAd->StaCfg.Psm == PWR_SAVE)
8554 // return;
8555
8556 if (pAd->NicConfig2.field.AntDiversity)
8557 {
8558 if ((pAd->RxAnt.RcvPktNumWhenEvaluate != 0) && (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1SecondaryRxAnt] >= pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1PrimaryRxAnt]))
8559 {
8560 UCHAR temp;
8561
8562 //
8563 // select PrimaryRxAntPair
8564 // Role change, Used Pair1SecondaryRxAnt as PrimaryRxAntPair.
8565 // Since Pair1SecondaryRxAnt Quality good than Pair1PrimaryRxAnt
8566 //
8567 temp = pAd->RxAnt.Pair1PrimaryRxAnt;
8568 pAd->RxAnt.Pair1PrimaryRxAnt = pAd->RxAnt.Pair1SecondaryRxAnt;
8569 pAd->RxAnt.Pair1SecondaryRxAnt = temp;
8570
8571 pAd->RxAnt.Pair1LastAvgRssi = (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1SecondaryRxAnt] >> 3);
8572 pAd->RxAnt.EvaluateStableCnt = 0;
8573 }
8574 else
8575 {
8576 // if the evaluated antenna is not better than original, switch back to original antenna
8577 AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
8578 pAd->RxAnt.EvaluateStableCnt ++;
8579 }
8580
8581 pAd->RxAnt.EvaluatePeriod = 0; // 1:Means switch to SecondaryRxAnt, 0:Means switch to Pair1PrimaryRxAnt
8582
8583 DBGPRINT(RT_DEBUG_TRACE,("AsicRxAntEvalAction::After Eval(fix in #%d), <%d, %d>, RcvPktNumWhenEvaluate=%ld\n",
8584 pAd->RxAnt.Pair1PrimaryRxAnt, (pAd->RxAnt.Pair1AvgRssi[0] >> 3), (pAd->RxAnt.Pair1AvgRssi[1] >> 3), pAd->RxAnt.RcvPktNumWhenEvaluate));
8585 }
8586 else
8587 {
8588 if (pAd->StaCfg.Psm == PWR_SAVE)
8589 return;
8590
8591 // if the traffic is low, use average rssi as the criteria
8592 if (pAd->Mlme.bLowThroughput == TRUE)
8593 {
8594 rssi0 = pAd->StaCfg.RssiSample.LastRssi0;
8595 rssi1 = pAd->StaCfg.RssiSample.LastRssi1;
8596 rssi2 = pAd->StaCfg.RssiSample.LastRssi2;
8597 }
8598 else
8599 {
8600 rssi0 = pAd->StaCfg.RssiSample.AvgRssi0;
8601 rssi1 = pAd->StaCfg.RssiSample.AvgRssi1;
8602 rssi2 = pAd->StaCfg.RssiSample.AvgRssi2;
8603 }
8604
8605 if(pAd->Antenna.field.RxPath == 3)
8606 {
8607 larger = max(rssi0, rssi1);
8608
8609 if (larger > (rssi2 + 20))
8610 pAd->Mlme.RealRxPath = 2;
8611 else
8612 pAd->Mlme.RealRxPath = 3;
8613 }
8614 else if(pAd->Antenna.field.RxPath == 2)
8615 {
8616 if (rssi0 > (rssi1 + 20))
8617 pAd->Mlme.RealRxPath = 1;
8618 else
8619 pAd->Mlme.RealRxPath = 2;
8620 }
8621
8622 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
8623 BBPR3 &= (~0x18);
8624 if(pAd->Mlme.RealRxPath == 3)
8625 {
8626 BBPR3 |= (0x10);
8627 }
8628 else if(pAd->Mlme.RealRxPath == 2)
8629 {
8630 BBPR3 |= (0x8);
8631 }
8632 else if(pAd->Mlme.RealRxPath == 1)
8633 {
8634 BBPR3 |= (0x0);
8635 }
8636 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
8637 }
8638 }
8639
8640#endif // CONFIG_STA_SUPPORT //
8641
8642}
8643
8644
8645
8646VOID APSDPeriodicExec(
8647 IN PVOID SystemSpecific1,
8648 IN PVOID FunctionContext,
8649 IN PVOID SystemSpecific2,
8650 IN PVOID SystemSpecific3)
8651{
8652 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
8653
8654 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
8655 return;
8656
8657 pAd->CommonCfg.TriggerTimerCount++;
8658
8659// Driver should not send trigger frame, it should be send by application layer
8660/*
8661 if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable
8662 && (pAd->CommonCfg.bNeedSendTriggerFrame ||
8663 (((pAd->CommonCfg.TriggerTimerCount%20) == 19) && (!pAd->CommonCfg.bAPSDAC_BE || !pAd->CommonCfg.bAPSDAC_BK || !pAd->CommonCfg.bAPSDAC_VI || !pAd->CommonCfg.bAPSDAC_VO))))
8664 {
8665 DBGPRINT(RT_DEBUG_TRACE,("Sending trigger frame and enter service period when support APSD\n"));
8666 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
8667 pAd->CommonCfg.bNeedSendTriggerFrame = FALSE;
8668 pAd->CommonCfg.TriggerTimerCount = 0;
8669 pAd->CommonCfg.bInServicePeriod = TRUE;
8670 }*/
8671}
8672
8673/*
8674 ========================================================================
8675 Routine Description:
8676 Set/reset MAC registers according to bPiggyBack parameter
8677
8678 Arguments:
8679 pAd - Adapter pointer
8680 bPiggyBack - Enable / Disable Piggy-Back
8681
8682 Return Value:
8683 None
8684
8685 ========================================================================
8686*/
8687VOID RTMPSetPiggyBack(
8688 IN PRTMP_ADAPTER pAd,
8689 IN BOOLEAN bPiggyBack)
8690{
8691 TX_LINK_CFG_STRUC TxLinkCfg;
8692
8693 RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
8694
8695 TxLinkCfg.field.TxCFAckEn = bPiggyBack;
8696 RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
8697}
8698
8699/*
8700 ========================================================================
8701 Routine Description:
8702 check if this entry need to switch rate automatically
8703
8704 Arguments:
8705 pAd
8706 pEntry
8707
8708 Return Value:
8709 TURE
8710 FALSE
8711
8712 ========================================================================
8713*/
8714BOOLEAN RTMPCheckEntryEnableAutoRateSwitch(
8715 IN PRTMP_ADAPTER pAd,
8716 IN PMAC_TABLE_ENTRY pEntry)
8717{
8718 BOOLEAN result = TRUE;
8719
8720
8721#ifdef CONFIG_STA_SUPPORT
8722 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
8723 {
8724 // only associated STA counts
8725 if (pEntry && (pEntry->ValidAsCLI) && (pEntry->Sst == SST_ASSOC))
8726 {
8727 result = pAd->StaCfg.bAutoTxRateSwitch;
8728 }
8729 else
8730 result = FALSE;
8731 }
8732#endif // CONFIG_STA_SUPPORT //
8733
8734
8735
8736 return result;
8737}
8738
8739
8740BOOLEAN RTMPAutoRateSwitchCheck(
8741 IN PRTMP_ADAPTER pAd)
8742{
8743
8744#ifdef CONFIG_STA_SUPPORT
8745 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
8746 {
8747 if (pAd->StaCfg.bAutoTxRateSwitch)
8748 return TRUE;
8749 }
8750#endif // CONFIG_STA_SUPPORT //
8751 return FALSE;
8752}
8753
8754
8755/*
8756 ========================================================================
8757 Routine Description:
8758 check if this entry need to fix tx legacy rate
8759
8760 Arguments:
8761 pAd
8762 pEntry
8763
8764 Return Value:
8765 TURE
8766 FALSE
8767
8768 ========================================================================
8769*/
8770UCHAR RTMPStaFixedTxMode(
8771 IN PRTMP_ADAPTER pAd,
8772 IN PMAC_TABLE_ENTRY pEntry)
8773{
8774 UCHAR tx_mode = FIXED_TXMODE_HT;
8775
8776
8777#ifdef CONFIG_STA_SUPPORT
8778 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
8779 {
8780 tx_mode = (UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode;
8781 }
8782#endif // CONFIG_STA_SUPPORT //
8783
8784 return tx_mode;
8785}
8786
8787/*
8788 ========================================================================
8789 Routine Description:
8790 Overwrite HT Tx Mode by Fixed Legency Tx Mode, if specified.
8791
8792 Arguments:
8793 pAd
8794 pEntry
8795
8796 Return Value:
8797 TURE
8798 FALSE
8799
8800 ========================================================================
8801*/
8802VOID RTMPUpdateLegacyTxSetting(
8803 UCHAR fixed_tx_mode,
8804 PMAC_TABLE_ENTRY pEntry)
8805{
8806 HTTRANSMIT_SETTING TransmitSetting;
8807
8808 if (fixed_tx_mode == FIXED_TXMODE_HT)
8809 return;
8810
8811 TransmitSetting.word = 0;
8812
8813 TransmitSetting.field.MODE = pEntry->HTPhyMode.field.MODE;
8814 TransmitSetting.field.MCS = pEntry->HTPhyMode.field.MCS;
8815
8816 if (fixed_tx_mode == FIXED_TXMODE_CCK)
8817 {
8818 TransmitSetting.field.MODE = MODE_CCK;
8819 // CCK mode allow MCS 0~3
8820 if (TransmitSetting.field.MCS > MCS_3)
8821 TransmitSetting.field.MCS = MCS_3;
8822 }
8823 else
8824 {
8825 TransmitSetting.field.MODE = MODE_OFDM;
8826 // OFDM mode allow MCS 0~7
8827 if (TransmitSetting.field.MCS > MCS_7)
8828 TransmitSetting.field.MCS = MCS_7;
8829 }
8830
8831 if (pEntry->HTPhyMode.field.MODE >= TransmitSetting.field.MODE)
8832 {
8833 pEntry->HTPhyMode.word = TransmitSetting.word;
8834 DBGPRINT(RT_DEBUG_TRACE, ("RTMPUpdateLegacyTxSetting : wcid-%d, MODE=%s, MCS=%d \n",
8835 pEntry->Aid, GetPhyMode(pEntry->HTPhyMode.field.MODE), pEntry->HTPhyMode.field.MCS));
8836 }
8837}
8838
8839#ifdef CONFIG_STA_SUPPORT
8840/*
8841 ==========================================================================
8842 Description:
8843 dynamic tune BBP R66 to find a balance between sensibility and
8844 noise isolation
8845
8846 IRQL = DISPATCH_LEVEL
8847
8848 ==========================================================================
8849 */
8850VOID AsicStaBbpTuning(
8851 IN PRTMP_ADAPTER pAd)
8852{
8853 UCHAR OrigR66Value = 0, R66;//, R66UpperBound = 0x30, R66LowerBound = 0x30;
8854 CHAR Rssi;
8855
8856 // 2860C did not support Fase CCA, therefore can't tune
8857 if (pAd->MACVersion == 0x28600100)
8858 return;
8859
8860 //
8861 // work as a STA
8862 //
8863 if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) // no R66 tuning when SCANNING
8864 return;
8865
8866 if ((pAd->OpMode == OPMODE_STA)
8867 && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
8868 )
8869 && !(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
8870 )
8871 {
8872 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &OrigR66Value);
8873 R66 = OrigR66Value;
8874
8875 if (pAd->Antenna.field.RxPath > 1)
8876 Rssi = (pAd->StaCfg.RssiSample.AvgRssi0 + pAd->StaCfg.RssiSample.AvgRssi1) >> 1;
8877 else
8878 Rssi = pAd->StaCfg.RssiSample.AvgRssi0;
8879
8880 if (pAd->LatchRfRegs.Channel <= 14)
8881 { //BG band
8882#ifdef RT30xx
8883 // RT3070 is a no LNA solution, it should have different control regarding to AGC gain control
8884 // Otherwise, it will have some throughput side effect when low RSSI
8885 if (IS_RT30xx(pAd))
8886 {
8887 if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
8888 {
8889 R66 = 0x1C + 2*GET_LNA_GAIN(pAd) + 0x20;
8890 if (OrigR66Value != R66)
8891 {
8892 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8893 }
8894 }
8895 else
8896 {
8897 R66 = 0x1C + 2*GET_LNA_GAIN(pAd);
8898 if (OrigR66Value != R66)
8899 {
8900 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8901 }
8902 }
8903 }
8904 else
8905#endif // RT30xx //
8906 {
8907 if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
8908 {
8909 R66 = (0x2E + GET_LNA_GAIN(pAd)) + 0x10;
8910 if (OrigR66Value != R66)
8911 {
8912 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8913 }
8914 }
8915 else
8916 {
8917 R66 = 0x2E + GET_LNA_GAIN(pAd);
8918 if (OrigR66Value != R66)
8919 {
8920 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8921 }
8922 }
8923 }
8924
8925 }
8926 else
8927 { //A band
8928 if (pAd->CommonCfg.BBPCurrentBW == BW_20)
8929 {
8930 if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
8931 {
8932 R66 = 0x32 + (GET_LNA_GAIN(pAd)*5)/3 + 0x10;
8933 if (OrigR66Value != R66)
8934 {
8935 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8936 }
8937 }
8938 else
8939 {
8940 R66 = 0x32 + (GET_LNA_GAIN(pAd)*5)/3;
8941 if (OrigR66Value != R66)
8942 {
8943 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8944 }
8945 }
8946 }
8947 else
8948 {
8949 if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
8950 {
8951 R66 = 0x3A + (GET_LNA_GAIN(pAd)*5)/3 + 0x10;
8952 if (OrigR66Value != R66)
8953 {
8954 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8955 }
8956 }
8957 else
8958 {
8959 R66 = 0x3A + (GET_LNA_GAIN(pAd)*5)/3;
8960 if (OrigR66Value != R66)
8961 {
8962 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8963 }
8964 }
8965 }
8966 }
8967
8968
8969 }
8970}
8971#endif // CONFIG_STA_SUPPORT //
8972
8973VOID RTMPSetAGCInitValue(
8974 IN PRTMP_ADAPTER pAd,
8975 IN UCHAR BandWidth)
8976{
8977 UCHAR R66 = 0x30;
8978
8979 if (pAd->LatchRfRegs.Channel <= 14)
8980 { // BG band
8981 R66 = 0x2E + GET_LNA_GAIN(pAd);
8982 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8983 }
8984 else
8985 { //A band
8986 if (BandWidth == BW_20)
8987 {
8988 R66 = (UCHAR)(0x32 + (GET_LNA_GAIN(pAd)*5)/3);
8989 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8990 }
8991#ifdef DOT11_N_SUPPORT
8992 else
8993 {
8994 R66 = (UCHAR)(0x3A + (GET_LNA_GAIN(pAd)*5)/3);
8995 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8996 }
8997#endif // DOT11_N_SUPPORT //
8998 }
8999
9000}
9001
9002VOID AsicTurnOffRFClk(
9003 IN PRTMP_ADAPTER pAd,
9004 IN UCHAR Channel)
9005{
9006 // RF R2 bit 18 = 0
9007 UINT32 R1 = 0, R2 = 0, R3 = 0;
9008 UCHAR index;
9009 RTMP_RF_REGS *RFRegTable;
9010
9011#ifdef RT30xx
9012 // The RF programming sequence is difference between 3xxx and 2xxx
9013 if (IS_RT3090(pAd))
9014 {
9015 RT30xxLoadRFSleepModeSetup(pAd); // add by johnli, RF power sequence setup, load RF sleep-mode setup
9016 }
9017 else
9018 {
9019#endif // RT30xx //
9020 RFRegTable = RF2850RegTable;
9021
9022 switch (pAd->RfIcType)
9023 {
9024 case RFIC_2820:
9025 case RFIC_2850:
9026 case RFIC_2720:
9027 case RFIC_2750:
9028
9029 for (index = 0; index < NUM_OF_2850_CHNL; index++)
9030 {
9031 if (Channel == RFRegTable[index].Channel)
9032 {
9033 R1 = RFRegTable[index].R1 & 0xffffdfff;
9034 R2 = RFRegTable[index].R2 & 0xfffbffff;
9035 R3 = RFRegTable[index].R3 & 0xfff3ffff;
9036
9037 RTMP_RF_IO_WRITE32(pAd, R1);
9038 RTMP_RF_IO_WRITE32(pAd, R2);
9039
9040 // Program R1b13 to 1, R3/b18,19 to 0, R2b18 to 0.
9041 // Set RF R2 bit18=0, R3 bit[18:19]=0
9042 //if (pAd->StaCfg.bRadio == FALSE)
9043 if (1)
9044 {
9045 RTMP_RF_IO_WRITE32(pAd, R3);
9046
9047 DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x, R3 = 0x%08x \n",
9048 Channel, pAd->RfIcType, R2, R3));
9049 }
9050 else
9051 DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x \n",
9052 Channel, pAd->RfIcType, R2));
9053 break;
9054 }
9055 }
9056 break;
9057
9058 default:
9059 break;
9060 }
9061#ifdef RT30xx
9062 }
9063#endif // RT30xx //
9064
9065}
9066
9067
9068VOID AsicTurnOnRFClk(
9069 IN PRTMP_ADAPTER pAd,
9070 IN UCHAR Channel)
9071{
9072 // RF R2 bit 18 = 0
9073 UINT32 R1 = 0, R2 = 0, R3 = 0;
9074 UCHAR index;
9075 RTMP_RF_REGS *RFRegTable;
9076
9077#ifdef RT30xx
9078 // The RF programming sequence is difference between 3xxx and 2xxx
9079 if (IS_RT3090(pAd))
9080 {
9081 }
9082 else
9083 {
9084#endif // RT30xx //
9085 RFRegTable = RF2850RegTable;
9086
9087 switch (pAd->RfIcType)
9088 {
9089 case RFIC_2820:
9090 case RFIC_2850:
9091 case RFIC_2720:
9092 case RFIC_2750:
9093
9094 for (index = 0; index < NUM_OF_2850_CHNL; index++)
9095 {
9096 if (Channel == RFRegTable[index].Channel)
9097 {
9098 R3 = pAd->LatchRfRegs.R3;
9099 R3 &= 0xfff3ffff;
9100 R3 |= 0x00080000;
9101 RTMP_RF_IO_WRITE32(pAd, R3);
9102
9103 R1 = RFRegTable[index].R1;
9104 RTMP_RF_IO_WRITE32(pAd, R1);
9105
9106 R2 = RFRegTable[index].R2;
9107 if (pAd->Antenna.field.TxPath == 1)
9108 {
9109 R2 |= 0x4000; // If TXpath is 1, bit 14 = 1;
9110 }
9111
9112 if (pAd->Antenna.field.RxPath == 2)
9113 {
9114 R2 |= 0x40; // write 1 to off Rxpath.
9115 }
9116 else if (pAd->Antenna.field.RxPath == 1)
9117 {
9118 R2 |= 0x20040; // write 1 to off RxPath
9119 }
9120 RTMP_RF_IO_WRITE32(pAd, R2);
9121
9122 break;
9123 }
9124 }
9125 break;
9126
9127 default:
9128 break;
9129 }
9130
9131#ifdef RT30xx
9132 }
9133#endif // RT30xx //
9134
9135}
9136
diff --git a/drivers/staging/rt3070/common/netif_block.c b/drivers/staging/rt3070/common/netif_block.c
new file mode 100644
index 000000000000..4773c11bedd0
--- /dev/null
+++ b/drivers/staging/rt3070/common/netif_block.c
@@ -0,0 +1,136 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26 */
27
28#include "../rt_config.h"
29#include "netif_block.h"
30
31static NETIF_ENTRY freeNetIfEntryPool[FREE_NETIF_POOL_SIZE];
32static LIST_HEADER freeNetIfEntryList;
33
34void initblockQueueTab(
35 IN PRTMP_ADAPTER pAd)
36{
37 int i;
38
39 initList(&freeNetIfEntryList);
40 for (i = 0; i < FREE_NETIF_POOL_SIZE; i++)
41 insertTailList(&freeNetIfEntryList, (PLIST_ENTRY)&freeNetIfEntryPool[i]);
42
43 for (i=0; i < NUM_OF_TX_RING; i++)
44 initList(&pAd->blockQueueTab[i].NetIfList);
45
46 return;
47}
48
49BOOLEAN blockNetIf(
50 IN PBLOCK_QUEUE_ENTRY pBlockQueueEntry,
51 IN PNET_DEV pNetDev)
52{
53 PNETIF_ENTRY pNetIfEntry = NULL;
54
55 if ((pNetIfEntry = (PNETIF_ENTRY)removeHeadList(&freeNetIfEntryList)) != NULL)
56 {
57 netif_stop_queue(pNetDev);
58 pNetIfEntry->pNetDev = pNetDev;
59 insertTailList(&pBlockQueueEntry->NetIfList, (PLIST_ENTRY)pNetIfEntry);
60
61 pBlockQueueEntry->SwTxQueueBlockFlag = TRUE;
62 DBGPRINT(RT_DEBUG_TRACE, ("netif_stop_queue(%s)\n", pNetDev->name));
63 }
64 else
65 return FALSE;
66
67 return TRUE;
68}
69
70VOID releaseNetIf(
71 IN PBLOCK_QUEUE_ENTRY pBlockQueueEntry)
72{
73 PNETIF_ENTRY pNetIfEntry = NULL;
74 PLIST_HEADER pNetIfList = &pBlockQueueEntry->NetIfList;
75
76 while((pNetIfEntry = (PNETIF_ENTRY)removeHeadList(pNetIfList)) != NULL)
77 {
78 PNET_DEV pNetDev = pNetIfEntry->pNetDev;
79 netif_wake_queue(pNetDev);
80 insertTailList(&freeNetIfEntryList, (PLIST_ENTRY)pNetIfEntry);
81
82 DBGPRINT(RT_DEBUG_TRACE, ("netif_wake_queue(%s)\n", pNetDev->name));
83 }
84 pBlockQueueEntry->SwTxQueueBlockFlag = FALSE;
85 return;
86}
87
88
89VOID StopNetIfQueue(
90 IN PRTMP_ADAPTER pAd,
91 IN UCHAR QueIdx,
92 IN PNDIS_PACKET pPacket)
93{
94 PNET_DEV NetDev = NULL;
95 UCHAR IfIdx = 0;
96 BOOLEAN valid = FALSE;
97
98#ifdef WDS_SUPPORT
99 if (RTMP_GET_PACKET_NET_DEVICE(pPacket) >= MIN_NET_DEVICE_FOR_WDS)
100 {
101 IfIdx = (RTMP_GET_PACKET_NET_DEVICE(pPacket) - MIN_NET_DEVICE_FOR_WDS) % MAX_WDS_ENTRY;
102 NetDev = pAd->WdsTab.WdsEntry[IfIdx].dev;
103 }
104 else
105#endif // WDS_SUPPORT //
106 {
107#ifdef MBSS_SUPPORT
108 if (pAd->OpMode == OPMODE_AP)
109 {
110 IfIdx = (RTMP_GET_PACKET_NET_DEVICE(pPacket) - MIN_NET_DEVICE_FOR_MBSSID) % MAX_MBSSID_NUM;
111 NetDev = pAd->ApCfg.MBSSID[IfIdx].MSSIDDev;
112 }
113 else
114 {
115 IfIdx = MAIN_MBSSID;
116 NetDev = pAd->net_dev;
117 }
118#else
119 IfIdx = MAIN_MBSSID;
120 NetDev = pAd->net_dev;
121#endif
122 }
123
124 // WMM support 4 software queues.
125 // One software queue full doesn't mean device have no capbility to transmit packet.
126 // So disable block Net-If queue function while WMM enable.
127#ifdef CONFIG_STA_SUPPORT
128 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
129 valid = (pAd->CommonCfg.bWmmCapable == TRUE) ? FALSE : TRUE;
130#endif // CONFIG_STA_SUPPORT //
131
132 if (valid)
133 blockNetIf(&pAd->blockQueueTab[QueIdx], NetDev);
134 return;
135}
136
diff --git a/drivers/staging/rt3070/common/rtmp_init.c b/drivers/staging/rt3070/common/rtmp_init.c
new file mode 100644
index 000000000000..4503f6c6d954
--- /dev/null
+++ b/drivers/staging/rt3070/common/rtmp_init.c
@@ -0,0 +1,4197 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 rtmp_init.c
29
30 Abstract:
31 Miniport generic portion header file
32
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36 Paul Lin 2002-08-01 created
37 John Chang 2004-08-20 RT2561/2661 use scatter-gather scheme
38 Jan Lee 2006-09-15 RT2860. Change for 802.11n , EEPROM, Led, BA, HT.
39*/
40#include "../rt_config.h"
41#include "../firmware.h"
42
43//#define BIN_IN_FILE /* use *.bin firmware */
44
45UCHAR BIT8[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
46ULONG BIT32[] = {0x00000001, 0x00000002, 0x00000004, 0x00000008,
47 0x00000010, 0x00000020, 0x00000040, 0x00000080,
48 0x00000100, 0x00000200, 0x00000400, 0x00000800,
49 0x00001000, 0x00002000, 0x00004000, 0x00008000,
50 0x00010000, 0x00020000, 0x00040000, 0x00080000,
51 0x00100000, 0x00200000, 0x00400000, 0x00800000,
52 0x01000000, 0x02000000, 0x04000000, 0x08000000,
53 0x10000000, 0x20000000, 0x40000000, 0x80000000};
54
55char* CipherName[] = {"none","wep64","wep128","TKIP","AES","CKIP64","CKIP128"};
56
57const unsigned short ccitt_16Table[] = {
58 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
59 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
60 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
61 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
62 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
63 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
64 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
65 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
66 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
67 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
68 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
69 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
70 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
71 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
72 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
73 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
74 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
75 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
76 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
77 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
78 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
79 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
80 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
81 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
82 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
83 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
84 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
85 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
86 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
87 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
88 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
89 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
90};
91#define ByteCRC16(v, crc) \
92 (unsigned short)((crc << 8) ^ ccitt_16Table[((crc >> 8) ^ (v)) & 255])
93
94unsigned char BitReverse(unsigned char x)
95{
96 int i;
97 unsigned char Temp=0;
98 for(i=0; ; i++)
99 {
100 if(x & 0x80) Temp |= 0x80;
101 if(i==7) break;
102 x <<= 1;
103 Temp >>= 1;
104 }
105 return Temp;
106}
107
108//
109// BBP register initialization set
110//
111REG_PAIR BBPRegTable[] = {
112 {BBP_R65, 0x2C}, // fix rssi issue
113 {BBP_R66, 0x38}, // Also set this default value to pAd->BbpTuning.R66CurrentValue at initial
114 {BBP_R69, 0x12},
115 {BBP_R70, 0xa}, // BBP_R70 will change to 0x8 in ApStartUp and LinkUp for rt2860C, otherwise value is 0xa
116 {BBP_R73, 0x10},
117 {BBP_R81, 0x37},
118 {BBP_R82, 0x62},
119 {BBP_R83, 0x6A},
120 {BBP_R84, 0x99}, // 0x19 is for rt2860E and after. This is for extension channel overlapping IOT. 0x99 is for rt2860D and before
121 {BBP_R86, 0x00}, // middle range issue, Rory @2008-01-28
122 {BBP_R91, 0x04}, // middle range issue, Rory @2008-01-28
123 {BBP_R92, 0x00}, // middle range issue, Rory @2008-01-28
124 {BBP_R103, 0x00}, // near range high-power issue, requested from Gary @2008-0528
125 {BBP_R105, 0x05}, // 0x05 is for rt2860E to turn on FEQ control. It is safe for rt2860D and before, because Bit 7:2 are reserved in rt2860D and before.
126};
127#define NUM_BBP_REG_PARMS (sizeof(BBPRegTable) / sizeof(REG_PAIR))
128
129//
130// RF register initialization set
131//
132#ifdef RT30xx
133REG_PAIR RT30xx_RFRegTable[] = {
134 {RF_R04, 0x40},
135 {RF_R05, 0x03},
136 {RF_R06, 0x02},
137 {RF_R07, 0x70},
138 {RF_R09, 0x0F},
139 {RF_R10, 0x41},
140 {RF_R11, 0x21},
141 {RF_R12, 0x7B},
142 {RF_R14, 0x90},
143 {RF_R15, 0x58},
144 {RF_R16, 0xB3},
145 {RF_R17, 0x92},
146 {RF_R18, 0x2C},
147 {RF_R19, 0x02},
148 {RF_R20, 0xBA},
149 {RF_R21, 0xDB},
150 {RF_R24, 0x16},
151 {RF_R25, 0x01},
152 {RF_R29, 0x1F},
153};
154#define NUM_RF_REG_PARMS (sizeof(RT30xx_RFRegTable) / sizeof(REG_PAIR))
155#endif // RT30xx //
156
157//
158// ASIC register initialization sets
159//
160
161RTMP_REG_PAIR MACRegTable[] = {
162#if defined(HW_BEACON_OFFSET) && (HW_BEACON_OFFSET == 0x200)
163 {BCN_OFFSET0, 0xf8f0e8e0}, /* 0x3800(e0), 0x3A00(e8), 0x3C00(f0), 0x3E00(f8), 512B for each beacon */
164 {BCN_OFFSET1, 0x6f77d0c8}, /* 0x3200(c8), 0x3400(d0), 0x1DC0(77), 0x1BC0(6f), 512B for each beacon */
165#elif defined(HW_BEACON_OFFSET) && (HW_BEACON_OFFSET == 0x100)
166 {BCN_OFFSET0, 0xece8e4e0}, /* 0x3800, 0x3A00, 0x3C00, 0x3E00, 512B for each beacon */
167 {BCN_OFFSET1, 0xfcf8f4f0}, /* 0x3800, 0x3A00, 0x3C00, 0x3E00, 512B for each beacon */
168#else
169 #error You must re-calculate new value for BCN_OFFSET0 & BCN_OFFSET1 in MACRegTable[]!!!
170#endif // HW_BEACON_OFFSET //
171
172 {LEGACY_BASIC_RATE, 0x0000013f}, // Basic rate set bitmap
173 {HT_BASIC_RATE, 0x00008003}, // Basic HT rate set , 20M, MCS=3, MM. Format is the same as in TXWI.
174 {MAC_SYS_CTRL, 0x00}, // 0x1004, , default Disable RX
175 {RX_FILTR_CFG, 0x17f97}, //0x1400 , RX filter control,
176 {BKOFF_SLOT_CFG, 0x209}, // default set short slot time, CC_DELAY_TIME should be 2
177 //{TX_SW_CFG0, 0x40a06}, // Gary,2006-08-23
178 {TX_SW_CFG0, 0x0}, // Gary,2008-05-21 for CWC test
179 {TX_SW_CFG1, 0x80606}, // Gary,2006-08-23
180 {TX_LINK_CFG, 0x1020}, // Gary,2006-08-23
181 {TX_TIMEOUT_CFG, 0x000a2090},
182 {MAX_LEN_CFG, MAX_AGGREGATION_SIZE | 0x00001000}, // 0x3018, MAX frame length. Max PSDU = 16kbytes.
183 {LED_CFG, 0x7f031e46}, // Gary, 2006-08-23
184
185//#ifdef CONFIG_STA_SUPPORT
186// {WMM_AIFSN_CFG, 0x00002273},
187// {WMM_CWMIN_CFG, 0x00002344},
188// {WMM_CWMAX_CFG, 0x000034aa},
189//#endif // CONFIG_STA_SUPPORT //
190#ifdef INF_AMAZON_SE
191 {PBF_MAX_PCNT, 0x1F3F6F6F}, //iverson modify for usb issue, 2008/09/19
192 // 6F + 6F < total page count FE
193 // so that RX doesn't occupy TX's buffer space when WMM congestion.
194#else
195 {PBF_MAX_PCNT, 0x1F3FBF9F}, //0x1F3f7f9f}, //Jan, 2006/04/20
196#endif // INF_AMAZON_SE //
197 //{TX_RTY_CFG, 0x6bb80408}, // Jan, 2006/11/16
198 {TX_RTY_CFG, 0x47d01f0f}, // Jan, 2006/11/16, Set TxWI->ACK =0 in Probe Rsp Modify for 2860E ,2007-08-03
199 {AUTO_RSP_CFG, 0x00000013}, // Initial Auto_Responder, because QA will turn off Auto-Responder
200 {CCK_PROT_CFG, 0x05740003 /*0x01740003*/}, // Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled.
201 {OFDM_PROT_CFG, 0x05740003 /*0x01740003*/}, // Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled.
202//PS packets use Tx1Q (for HCCA) when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
203#ifdef RT2870
204#ifdef CONFIG_STA_SUPPORT
205 {PBF_CFG, 0xf40006}, // Only enable Queue 2
206#endif // CONFIG_STA_SUPPORT //
207 {MM40_PROT_CFG, 0x3F44084}, // Initial Auto_Responder, because QA will turn off Auto-Responder
208 {WPDMA_GLO_CFG, 0x00000030},
209#endif // RT2870 //
210 {GF20_PROT_CFG, 0x01744004}, // set 19:18 --> Short NAV for MIMO PS
211 {GF40_PROT_CFG, 0x03F44084},
212 {MM20_PROT_CFG, 0x01744004},
213 {TXOP_CTRL_CFG, 0x0000583f, /*0x0000243f*/ /*0x000024bf*/}, //Extension channel backoff.
214 {TX_RTS_CFG, 0x00092b20},
215//#ifdef WIFI_TEST
216 {EXP_ACK_TIME, 0x002400ca}, // default value
217//#else
218// {EXP_ACK_TIME, 0x005400ca}, // suggested by Gray @ 20070323 for 11n intel-sta throughput
219//#endif // end - WIFI_TEST //
220 {TXOP_HLDR_ET, 0x00000002},
221
222 /* Jerry comments 2008/01/16: we use SIFS = 10us in CCK defaultly, but it seems that 10us
223 is too small for INTEL 2200bg card, so in MBSS mode, the delta time between beacon0
224 and beacon1 is SIFS (10us), so if INTEL 2200bg card connects to BSS0, the ping
225 will always lost. So we change the SIFS of CCK from 10us to 16us. */
226 {XIFS_TIME_CFG, 0x33a41010},
227 {PWR_PIN_CFG, 0x00000003}, // patch for 2880-E
228};
229
230
231#ifdef CONFIG_STA_SUPPORT
232RTMP_REG_PAIR STAMACRegTable[] = {
233 {WMM_AIFSN_CFG, 0x00002273},
234 {WMM_CWMIN_CFG, 0x00002344},
235 {WMM_CWMAX_CFG, 0x000034aa},
236};
237#endif // CONFIG_STA_SUPPORT //
238
239#define NUM_MAC_REG_PARMS (sizeof(MACRegTable) / sizeof(RTMP_REG_PAIR))
240#ifdef CONFIG_STA_SUPPORT
241#define NUM_STA_MAC_REG_PARMS (sizeof(STAMACRegTable) / sizeof(RTMP_REG_PAIR))
242#endif // CONFIG_STA_SUPPORT //
243
244#ifdef RT2870
245//
246// RT2870 Firmware Spec only used 1 oct for version expression
247//
248#define FIRMWARE_MINOR_VERSION 7
249
250#endif // RT2870 //
251
252// New 8k byte firmware size for RT3071/RT3072
253#define FIRMWAREIMAGE_MAX_LENGTH 0x2000
254#define FIRMWAREIMAGE_LENGTH (sizeof (FirmwareImage) / sizeof(UCHAR))
255#define FIRMWARE_MAJOR_VERSION 0
256
257#define FIRMWAREIMAGEV1_LENGTH 0x1000
258#define FIRMWAREIMAGEV2_LENGTH 0x1000
259
260
261
262/*
263 ========================================================================
264
265 Routine Description:
266 Allocate RTMP_ADAPTER data block and do some initialization
267
268 Arguments:
269 Adapter Pointer to our adapter
270
271 Return Value:
272 NDIS_STATUS_SUCCESS
273 NDIS_STATUS_FAILURE
274
275 IRQL = PASSIVE_LEVEL
276
277 Note:
278
279 ========================================================================
280*/
281NDIS_STATUS RTMPAllocAdapterBlock(
282 IN PVOID handle,
283 OUT PRTMP_ADAPTER *ppAdapter)
284{
285 PRTMP_ADAPTER pAd;
286 NDIS_STATUS Status;
287 INT index;
288 UCHAR *pBeaconBuf = NULL;
289
290 DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocAdapterBlock\n"));
291
292 *ppAdapter = NULL;
293
294 do
295 {
296 // Allocate RTMP_ADAPTER memory block
297 pBeaconBuf = kmalloc(MAX_BEACON_SIZE, MEM_ALLOC_FLAG);
298 if (pBeaconBuf == NULL)
299 {
300 Status = NDIS_STATUS_FAILURE;
301 DBGPRINT_ERR(("Failed to allocate memory - BeaconBuf!\n"));
302 break;
303 }
304
305 Status = AdapterBlockAllocateMemory(handle, (PVOID *)&pAd);
306 if (Status != NDIS_STATUS_SUCCESS)
307 {
308 DBGPRINT_ERR(("Failed to allocate memory - ADAPTER\n"));
309 break;
310 }
311 pAd->BeaconBuf = pBeaconBuf;
312 printk("\n\n=== pAd = %p, size = %d ===\n\n", pAd, (UINT32)sizeof(RTMP_ADAPTER));
313
314
315 // Init spin locks
316 NdisAllocateSpinLock(&pAd->MgmtRingLock);
317
318 for (index =0 ; index < NUM_OF_TX_RING; index++)
319 {
320 NdisAllocateSpinLock(&pAd->TxSwQueueLock[index]);
321 NdisAllocateSpinLock(&pAd->DeQueueLock[index]);
322 pAd->DeQueueRunning[index] = FALSE;
323 }
324
325 NdisAllocateSpinLock(&pAd->irq_lock);
326
327 } while (FALSE);
328
329 if ((Status != NDIS_STATUS_SUCCESS) && (pBeaconBuf))
330 kfree(pBeaconBuf);
331
332 *ppAdapter = pAd;
333
334 DBGPRINT_S(Status, ("<-- RTMPAllocAdapterBlock, Status=%x\n", Status));
335 return Status;
336}
337
338/*
339 ========================================================================
340
341 Routine Description:
342 Read initial Tx power per MCS and BW from EEPROM
343
344 Arguments:
345 Adapter Pointer to our adapter
346
347 Return Value:
348 None
349
350 IRQL = PASSIVE_LEVEL
351
352 Note:
353
354 ========================================================================
355*/
356VOID RTMPReadTxPwrPerRate(
357 IN PRTMP_ADAPTER pAd)
358{
359 ULONG data, Adata, Gdata;
360 USHORT i, value, value2;
361 INT Apwrdelta, Gpwrdelta;
362 UCHAR t1,t2,t3,t4;
363 BOOLEAN bValid, bApwrdeltaMinus = TRUE, bGpwrdeltaMinus = TRUE;
364
365 //
366 // Get power delta for 20MHz and 40MHz.
367 //
368 DBGPRINT(RT_DEBUG_TRACE, ("Txpower per Rate\n"));
369 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_DELTA, value2);
370 Apwrdelta = 0;
371 Gpwrdelta = 0;
372
373 if ((value2 & 0xff) != 0xff)
374 {
375 if ((value2 & 0x80))
376 Gpwrdelta = (value2&0xf);
377
378 if ((value2 & 0x40))
379 bGpwrdeltaMinus = FALSE;
380 else
381 bGpwrdeltaMinus = TRUE;
382 }
383 if ((value2 & 0xff00) != 0xff00)
384 {
385 if ((value2 & 0x8000))
386 Apwrdelta = ((value2&0xf00)>>8);
387
388 if ((value2 & 0x4000))
389 bApwrdeltaMinus = FALSE;
390 else
391 bApwrdeltaMinus = TRUE;
392 }
393 DBGPRINT(RT_DEBUG_TRACE, ("Gpwrdelta = %x, Apwrdelta = %x .\n", Gpwrdelta, Apwrdelta));
394
395 //
396 // Get Txpower per MCS for 20MHz in 2.4G.
397 //
398 for (i=0; i<5; i++)
399 {
400 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_2_4G + i*4, value);
401 data = value;
402 if (bApwrdeltaMinus == FALSE)
403 {
404 t1 = (value&0xf)+(Apwrdelta);
405 if (t1 > 0xf)
406 t1 = 0xf;
407 t2 = ((value&0xf0)>>4)+(Apwrdelta);
408 if (t2 > 0xf)
409 t2 = 0xf;
410 t3 = ((value&0xf00)>>8)+(Apwrdelta);
411 if (t3 > 0xf)
412 t3 = 0xf;
413 t4 = ((value&0xf000)>>12)+(Apwrdelta);
414 if (t4 > 0xf)
415 t4 = 0xf;
416 }
417 else
418 {
419 if ((value&0xf) > Apwrdelta)
420 t1 = (value&0xf)-(Apwrdelta);
421 else
422 t1 = 0;
423 if (((value&0xf0)>>4) > Apwrdelta)
424 t2 = ((value&0xf0)>>4)-(Apwrdelta);
425 else
426 t2 = 0;
427 if (((value&0xf00)>>8) > Apwrdelta)
428 t3 = ((value&0xf00)>>8)-(Apwrdelta);
429 else
430 t3 = 0;
431 if (((value&0xf000)>>12) > Apwrdelta)
432 t4 = ((value&0xf000)>>12)-(Apwrdelta);
433 else
434 t4 = 0;
435 }
436 Adata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
437 if (bGpwrdeltaMinus == FALSE)
438 {
439 t1 = (value&0xf)+(Gpwrdelta);
440 if (t1 > 0xf)
441 t1 = 0xf;
442 t2 = ((value&0xf0)>>4)+(Gpwrdelta);
443 if (t2 > 0xf)
444 t2 = 0xf;
445 t3 = ((value&0xf00)>>8)+(Gpwrdelta);
446 if (t3 > 0xf)
447 t3 = 0xf;
448 t4 = ((value&0xf000)>>12)+(Gpwrdelta);
449 if (t4 > 0xf)
450 t4 = 0xf;
451 }
452 else
453 {
454 if ((value&0xf) > Gpwrdelta)
455 t1 = (value&0xf)-(Gpwrdelta);
456 else
457 t1 = 0;
458 if (((value&0xf0)>>4) > Gpwrdelta)
459 t2 = ((value&0xf0)>>4)-(Gpwrdelta);
460 else
461 t2 = 0;
462 if (((value&0xf00)>>8) > Gpwrdelta)
463 t3 = ((value&0xf00)>>8)-(Gpwrdelta);
464 else
465 t3 = 0;
466 if (((value&0xf000)>>12) > Gpwrdelta)
467 t4 = ((value&0xf000)>>12)-(Gpwrdelta);
468 else
469 t4 = 0;
470 }
471 Gdata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
472
473 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_2_4G + i*4 + 2, value);
474 if (bApwrdeltaMinus == FALSE)
475 {
476 t1 = (value&0xf)+(Apwrdelta);
477 if (t1 > 0xf)
478 t1 = 0xf;
479 t2 = ((value&0xf0)>>4)+(Apwrdelta);
480 if (t2 > 0xf)
481 t2 = 0xf;
482 t3 = ((value&0xf00)>>8)+(Apwrdelta);
483 if (t3 > 0xf)
484 t3 = 0xf;
485 t4 = ((value&0xf000)>>12)+(Apwrdelta);
486 if (t4 > 0xf)
487 t4 = 0xf;
488 }
489 else
490 {
491 if ((value&0xf) > Apwrdelta)
492 t1 = (value&0xf)-(Apwrdelta);
493 else
494 t1 = 0;
495 if (((value&0xf0)>>4) > Apwrdelta)
496 t2 = ((value&0xf0)>>4)-(Apwrdelta);
497 else
498 t2 = 0;
499 if (((value&0xf00)>>8) > Apwrdelta)
500 t3 = ((value&0xf00)>>8)-(Apwrdelta);
501 else
502 t3 = 0;
503 if (((value&0xf000)>>12) > Apwrdelta)
504 t4 = ((value&0xf000)>>12)-(Apwrdelta);
505 else
506 t4 = 0;
507 }
508 Adata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
509 if (bGpwrdeltaMinus == FALSE)
510 {
511 t1 = (value&0xf)+(Gpwrdelta);
512 if (t1 > 0xf)
513 t1 = 0xf;
514 t2 = ((value&0xf0)>>4)+(Gpwrdelta);
515 if (t2 > 0xf)
516 t2 = 0xf;
517 t3 = ((value&0xf00)>>8)+(Gpwrdelta);
518 if (t3 > 0xf)
519 t3 = 0xf;
520 t4 = ((value&0xf000)>>12)+(Gpwrdelta);
521 if (t4 > 0xf)
522 t4 = 0xf;
523 }
524 else
525 {
526 if ((value&0xf) > Gpwrdelta)
527 t1 = (value&0xf)-(Gpwrdelta);
528 else
529 t1 = 0;
530 if (((value&0xf0)>>4) > Gpwrdelta)
531 t2 = ((value&0xf0)>>4)-(Gpwrdelta);
532 else
533 t2 = 0;
534 if (((value&0xf00)>>8) > Gpwrdelta)
535 t3 = ((value&0xf00)>>8)-(Gpwrdelta);
536 else
537 t3 = 0;
538 if (((value&0xf000)>>12) > Gpwrdelta)
539 t4 = ((value&0xf000)>>12)-(Gpwrdelta);
540 else
541 t4 = 0;
542 }
543 Gdata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
544 data |= (value<<16);
545
546 pAd->Tx20MPwrCfgABand[i] = pAd->Tx40MPwrCfgABand[i] = Adata;
547 pAd->Tx20MPwrCfgGBand[i] = pAd->Tx40MPwrCfgGBand[i] = Gdata;
548
549 if (data != 0xffffffff)
550 RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, data);
551 DBGPRINT_RAW(RT_DEBUG_TRACE, ("20MHz BW, 2.4G band-%lx, Adata = %lx, Gdata = %lx \n", data, Adata, Gdata));
552 }
553
554 //
555 // Check this block is valid for 40MHz in 2.4G. If invalid, use parameter for 20MHz in 2.4G
556 //
557 bValid = TRUE;
558 for (i=0; i<6; i++)
559 {
560 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_2_4G + 2 + i*2, value);
561 if (((value & 0x00FF) == 0x00FF) || ((value & 0xFF00) == 0xFF00))
562 {
563 bValid = FALSE;
564 break;
565 }
566 }
567
568 //
569 // Get Txpower per MCS for 40MHz in 2.4G.
570 //
571 if (bValid)
572 {
573 for (i=0; i<4; i++)
574 {
575 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_2_4G + i*4, value);
576 if (bGpwrdeltaMinus == FALSE)
577 {
578 t1 = (value&0xf)+(Gpwrdelta);
579 if (t1 > 0xf)
580 t1 = 0xf;
581 t2 = ((value&0xf0)>>4)+(Gpwrdelta);
582 if (t2 > 0xf)
583 t2 = 0xf;
584 t3 = ((value&0xf00)>>8)+(Gpwrdelta);
585 if (t3 > 0xf)
586 t3 = 0xf;
587 t4 = ((value&0xf000)>>12)+(Gpwrdelta);
588 if (t4 > 0xf)
589 t4 = 0xf;
590 }
591 else
592 {
593 if ((value&0xf) > Gpwrdelta)
594 t1 = (value&0xf)-(Gpwrdelta);
595 else
596 t1 = 0;
597 if (((value&0xf0)>>4) > Gpwrdelta)
598 t2 = ((value&0xf0)>>4)-(Gpwrdelta);
599 else
600 t2 = 0;
601 if (((value&0xf00)>>8) > Gpwrdelta)
602 t3 = ((value&0xf00)>>8)-(Gpwrdelta);
603 else
604 t3 = 0;
605 if (((value&0xf000)>>12) > Gpwrdelta)
606 t4 = ((value&0xf000)>>12)-(Gpwrdelta);
607 else
608 t4 = 0;
609 }
610 Gdata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
611
612 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_2_4G + i*4 + 2, value);
613 if (bGpwrdeltaMinus == FALSE)
614 {
615 t1 = (value&0xf)+(Gpwrdelta);
616 if (t1 > 0xf)
617 t1 = 0xf;
618 t2 = ((value&0xf0)>>4)+(Gpwrdelta);
619 if (t2 > 0xf)
620 t2 = 0xf;
621 t3 = ((value&0xf00)>>8)+(Gpwrdelta);
622 if (t3 > 0xf)
623 t3 = 0xf;
624 t4 = ((value&0xf000)>>12)+(Gpwrdelta);
625 if (t4 > 0xf)
626 t4 = 0xf;
627 }
628 else
629 {
630 if ((value&0xf) > Gpwrdelta)
631 t1 = (value&0xf)-(Gpwrdelta);
632 else
633 t1 = 0;
634 if (((value&0xf0)>>4) > Gpwrdelta)
635 t2 = ((value&0xf0)>>4)-(Gpwrdelta);
636 else
637 t2 = 0;
638 if (((value&0xf00)>>8) > Gpwrdelta)
639 t3 = ((value&0xf00)>>8)-(Gpwrdelta);
640 else
641 t3 = 0;
642 if (((value&0xf000)>>12) > Gpwrdelta)
643 t4 = ((value&0xf000)>>12)-(Gpwrdelta);
644 else
645 t4 = 0;
646 }
647 Gdata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
648
649 if (i == 0)
650 pAd->Tx40MPwrCfgGBand[i+1] = (pAd->Tx40MPwrCfgGBand[i+1] & 0x0000FFFF) | (Gdata & 0xFFFF0000);
651 else
652 pAd->Tx40MPwrCfgGBand[i+1] = Gdata;
653
654 DBGPRINT_RAW(RT_DEBUG_TRACE, ("40MHz BW, 2.4G band, Gdata = %lx \n", Gdata));
655 }
656 }
657
658 //
659 // Check this block is valid for 20MHz in 5G. If invalid, use parameter for 20MHz in 2.4G
660 //
661 bValid = TRUE;
662 for (i=0; i<8; i++)
663 {
664 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_5G + 2 + i*2, value);
665 if (((value & 0x00FF) == 0x00FF) || ((value & 0xFF00) == 0xFF00))
666 {
667 bValid = FALSE;
668 break;
669 }
670 }
671
672 //
673 // Get Txpower per MCS for 20MHz in 5G.
674 //
675 if (bValid)
676 {
677 for (i=0; i<5; i++)
678 {
679 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_5G + i*4, value);
680 if (bApwrdeltaMinus == FALSE)
681 {
682 t1 = (value&0xf)+(Apwrdelta);
683 if (t1 > 0xf)
684 t1 = 0xf;
685 t2 = ((value&0xf0)>>4)+(Apwrdelta);
686 if (t2 > 0xf)
687 t2 = 0xf;
688 t3 = ((value&0xf00)>>8)+(Apwrdelta);
689 if (t3 > 0xf)
690 t3 = 0xf;
691 t4 = ((value&0xf000)>>12)+(Apwrdelta);
692 if (t4 > 0xf)
693 t4 = 0xf;
694 }
695 else
696 {
697 if ((value&0xf) > Apwrdelta)
698 t1 = (value&0xf)-(Apwrdelta);
699 else
700 t1 = 0;
701 if (((value&0xf0)>>4) > Apwrdelta)
702 t2 = ((value&0xf0)>>4)-(Apwrdelta);
703 else
704 t2 = 0;
705 if (((value&0xf00)>>8) > Apwrdelta)
706 t3 = ((value&0xf00)>>8)-(Apwrdelta);
707 else
708 t3 = 0;
709 if (((value&0xf000)>>12) > Apwrdelta)
710 t4 = ((value&0xf000)>>12)-(Apwrdelta);
711 else
712 t4 = 0;
713 }
714 Adata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
715
716 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_5G + i*4 + 2, value);
717 if (bApwrdeltaMinus == FALSE)
718 {
719 t1 = (value&0xf)+(Apwrdelta);
720 if (t1 > 0xf)
721 t1 = 0xf;
722 t2 = ((value&0xf0)>>4)+(Apwrdelta);
723 if (t2 > 0xf)
724 t2 = 0xf;
725 t3 = ((value&0xf00)>>8)+(Apwrdelta);
726 if (t3 > 0xf)
727 t3 = 0xf;
728 t4 = ((value&0xf000)>>12)+(Apwrdelta);
729 if (t4 > 0xf)
730 t4 = 0xf;
731 }
732 else
733 {
734 if ((value&0xf) > Apwrdelta)
735 t1 = (value&0xf)-(Apwrdelta);
736 else
737 t1 = 0;
738 if (((value&0xf0)>>4) > Apwrdelta)
739 t2 = ((value&0xf0)>>4)-(Apwrdelta);
740 else
741 t2 = 0;
742 if (((value&0xf00)>>8) > Apwrdelta)
743 t3 = ((value&0xf00)>>8)-(Apwrdelta);
744 else
745 t3 = 0;
746 if (((value&0xf000)>>12) > Apwrdelta)
747 t4 = ((value&0xf000)>>12)-(Apwrdelta);
748 else
749 t4 = 0;
750 }
751 Adata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
752
753 if (i == 0)
754 pAd->Tx20MPwrCfgABand[i] = (pAd->Tx20MPwrCfgABand[i] & 0x0000FFFF) | (Adata & 0xFFFF0000);
755 else
756 pAd->Tx20MPwrCfgABand[i] = Adata;
757
758 DBGPRINT_RAW(RT_DEBUG_TRACE, ("20MHz BW, 5GHz band, Adata = %lx \n", Adata));
759 }
760 }
761
762 //
763 // Check this block is valid for 40MHz in 5G. If invalid, use parameter for 20MHz in 2.4G
764 //
765 bValid = TRUE;
766 for (i=0; i<6; i++)
767 {
768 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_5G + 2 + i*2, value);
769 if (((value & 0x00FF) == 0x00FF) || ((value & 0xFF00) == 0xFF00))
770 {
771 bValid = FALSE;
772 break;
773 }
774 }
775
776 //
777 // Get Txpower per MCS for 40MHz in 5G.
778 //
779 if (bValid)
780 {
781 for (i=0; i<4; i++)
782 {
783 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_5G + i*4, value);
784 if (bApwrdeltaMinus == FALSE)
785 {
786 t1 = (value&0xf)+(Apwrdelta);
787 if (t1 > 0xf)
788 t1 = 0xf;
789 t2 = ((value&0xf0)>>4)+(Apwrdelta);
790 if (t2 > 0xf)
791 t2 = 0xf;
792 t3 = ((value&0xf00)>>8)+(Apwrdelta);
793 if (t3 > 0xf)
794 t3 = 0xf;
795 t4 = ((value&0xf000)>>12)+(Apwrdelta);
796 if (t4 > 0xf)
797 t4 = 0xf;
798 }
799 else
800 {
801 if ((value&0xf) > Apwrdelta)
802 t1 = (value&0xf)-(Apwrdelta);
803 else
804 t1 = 0;
805 if (((value&0xf0)>>4) > Apwrdelta)
806 t2 = ((value&0xf0)>>4)-(Apwrdelta);
807 else
808 t2 = 0;
809 if (((value&0xf00)>>8) > Apwrdelta)
810 t3 = ((value&0xf00)>>8)-(Apwrdelta);
811 else
812 t3 = 0;
813 if (((value&0xf000)>>12) > Apwrdelta)
814 t4 = ((value&0xf000)>>12)-(Apwrdelta);
815 else
816 t4 = 0;
817 }
818 Adata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
819
820 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_5G + i*4 + 2, value);
821 if (bApwrdeltaMinus == FALSE)
822 {
823 t1 = (value&0xf)+(Apwrdelta);
824 if (t1 > 0xf)
825 t1 = 0xf;
826 t2 = ((value&0xf0)>>4)+(Apwrdelta);
827 if (t2 > 0xf)
828 t2 = 0xf;
829 t3 = ((value&0xf00)>>8)+(Apwrdelta);
830 if (t3 > 0xf)
831 t3 = 0xf;
832 t4 = ((value&0xf000)>>12)+(Apwrdelta);
833 if (t4 > 0xf)
834 t4 = 0xf;
835 }
836 else
837 {
838 if ((value&0xf) > Apwrdelta)
839 t1 = (value&0xf)-(Apwrdelta);
840 else
841 t1 = 0;
842 if (((value&0xf0)>>4) > Apwrdelta)
843 t2 = ((value&0xf0)>>4)-(Apwrdelta);
844 else
845 t2 = 0;
846 if (((value&0xf00)>>8) > Apwrdelta)
847 t3 = ((value&0xf00)>>8)-(Apwrdelta);
848 else
849 t3 = 0;
850 if (((value&0xf000)>>12) > Apwrdelta)
851 t4 = ((value&0xf000)>>12)-(Apwrdelta);
852 else
853 t4 = 0;
854 }
855 Adata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
856
857 if (i == 0)
858 pAd->Tx40MPwrCfgABand[i+1] = (pAd->Tx40MPwrCfgABand[i+1] & 0x0000FFFF) | (Adata & 0xFFFF0000);
859 else
860 pAd->Tx40MPwrCfgABand[i+1] = Adata;
861
862 DBGPRINT_RAW(RT_DEBUG_TRACE, ("40MHz BW, 5GHz band, Adata = %lx \n", Adata));
863 }
864 }
865}
866
867
868/*
869 ========================================================================
870
871 Routine Description:
872 Read initial channel power parameters from EEPROM
873
874 Arguments:
875 Adapter Pointer to our adapter
876
877 Return Value:
878 None
879
880 IRQL = PASSIVE_LEVEL
881
882 Note:
883
884 ========================================================================
885*/
886VOID RTMPReadChannelPwr(
887 IN PRTMP_ADAPTER pAd)
888{
889 UCHAR i, choffset;
890 EEPROM_TX_PWR_STRUC Power;
891 EEPROM_TX_PWR_STRUC Power2;
892
893 // Read Tx power value for all channels
894 // Value from 1 - 0x7f. Default value is 24.
895 // Power value : 2.4G 0x00 (0) ~ 0x1F (31)
896 // : 5.5G 0xF9 (-7) ~ 0x0F (15)
897
898 // 0. 11b/g, ch1 - ch 14
899 for (i = 0; i < 7; i++)
900 {
901// Power.word = RTMP_EEPROM_READ16(pAd, EEPROM_G_TX_PWR_OFFSET + i * 2);
902// Power2.word = RTMP_EEPROM_READ16(pAd, EEPROM_G_TX2_PWR_OFFSET + i * 2);
903 RT28xx_EEPROM_READ16(pAd, EEPROM_G_TX_PWR_OFFSET + i * 2, Power.word);
904 RT28xx_EEPROM_READ16(pAd, EEPROM_G_TX2_PWR_OFFSET + i * 2, Power2.word);
905 pAd->TxPower[i * 2].Channel = i * 2 + 1;
906 pAd->TxPower[i * 2 + 1].Channel = i * 2 + 2;
907
908 if ((Power.field.Byte0 > 31) || (Power.field.Byte0 < 0))
909 pAd->TxPower[i * 2].Power = DEFAULT_RF_TX_POWER;
910 else
911 pAd->TxPower[i * 2].Power = Power.field.Byte0;
912
913 if ((Power.field.Byte1 > 31) || (Power.field.Byte1 < 0))
914 pAd->TxPower[i * 2 + 1].Power = DEFAULT_RF_TX_POWER;
915 else
916 pAd->TxPower[i * 2 + 1].Power = Power.field.Byte1;
917
918 if ((Power2.field.Byte0 > 31) || (Power2.field.Byte0 < 0))
919 pAd->TxPower[i * 2].Power2 = DEFAULT_RF_TX_POWER;
920 else
921 pAd->TxPower[i * 2].Power2 = Power2.field.Byte0;
922
923 if ((Power2.field.Byte1 > 31) || (Power2.field.Byte1 < 0))
924 pAd->TxPower[i * 2 + 1].Power2 = DEFAULT_RF_TX_POWER;
925 else
926 pAd->TxPower[i * 2 + 1].Power2 = Power2.field.Byte1;
927 }
928
929 // 1. U-NII lower/middle band: 36, 38, 40; 44, 46, 48; 52, 54, 56; 60, 62, 64 (including central frequency in BW 40MHz)
930 // 1.1 Fill up channel
931 choffset = 14;
932 for (i = 0; i < 4; i++)
933 {
934 pAd->TxPower[3 * i + choffset + 0].Channel = 36 + i * 8 + 0;
935 pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER;
936 pAd->TxPower[3 * i + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
937
938 pAd->TxPower[3 * i + choffset + 1].Channel = 36 + i * 8 + 2;
939 pAd->TxPower[3 * i + choffset + 1].Power = DEFAULT_RF_TX_POWER;
940 pAd->TxPower[3 * i + choffset + 1].Power2 = DEFAULT_RF_TX_POWER;
941
942 pAd->TxPower[3 * i + choffset + 2].Channel = 36 + i * 8 + 4;
943 pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER;
944 pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER;
945 }
946
947 // 1.2 Fill up power
948 for (i = 0; i < 6; i++)
949 {
950// Power.word = RTMP_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + i * 2);
951// Power2.word = RTMP_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + i * 2);
952 RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + i * 2, Power.word);
953 RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + i * 2, Power2.word);
954
955 if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7))
956 pAd->TxPower[i * 2 + choffset + 0].Power = Power.field.Byte0;
957
958 if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7))
959 pAd->TxPower[i * 2 + choffset + 1].Power = Power.field.Byte1;
960
961 if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7))
962 pAd->TxPower[i * 2 + choffset + 0].Power2 = Power2.field.Byte0;
963
964 if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7))
965 pAd->TxPower[i * 2 + choffset + 1].Power2 = Power2.field.Byte1;
966 }
967
968 // 2. HipperLAN 2 100, 102 ,104; 108, 110, 112; 116, 118, 120; 124, 126, 128; 132, 134, 136; 140 (including central frequency in BW 40MHz)
969 // 2.1 Fill up channel
970 choffset = 14 + 12;
971 for (i = 0; i < 5; i++)
972 {
973 pAd->TxPower[3 * i + choffset + 0].Channel = 100 + i * 8 + 0;
974 pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER;
975 pAd->TxPower[3 * i + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
976
977 pAd->TxPower[3 * i + choffset + 1].Channel = 100 + i * 8 + 2;
978 pAd->TxPower[3 * i + choffset + 1].Power = DEFAULT_RF_TX_POWER;
979 pAd->TxPower[3 * i + choffset + 1].Power2 = DEFAULT_RF_TX_POWER;
980
981 pAd->TxPower[3 * i + choffset + 2].Channel = 100 + i * 8 + 4;
982 pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER;
983 pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER;
984 }
985 pAd->TxPower[3 * 5 + choffset + 0].Channel = 140;
986 pAd->TxPower[3 * 5 + choffset + 0].Power = DEFAULT_RF_TX_POWER;
987 pAd->TxPower[3 * 5 + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
988
989 // 2.2 Fill up power
990 for (i = 0; i < 8; i++)
991 {
992// Power.word = RTMP_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + (choffset - 14) + i * 2);
993// Power2.word = RTMP_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) + i * 2);
994 RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + (choffset - 14) + i * 2, Power.word);
995 RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) + i * 2, Power2.word);
996
997 if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7))
998 pAd->TxPower[i * 2 + choffset + 0].Power = Power.field.Byte0;
999
1000 if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7))
1001 pAd->TxPower[i * 2 + choffset + 1].Power = Power.field.Byte1;
1002
1003 if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7))
1004 pAd->TxPower[i * 2 + choffset + 0].Power2 = Power2.field.Byte0;
1005
1006 if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7))
1007 pAd->TxPower[i * 2 + choffset + 1].Power2 = Power2.field.Byte1;
1008 }
1009
1010 // 3. U-NII upper band: 149, 151, 153; 157, 159, 161; 165 (including central frequency in BW 40MHz)
1011 // 3.1 Fill up channel
1012 choffset = 14 + 12 + 16;
1013 for (i = 0; i < 2; i++)
1014 {
1015 pAd->TxPower[3 * i + choffset + 0].Channel = 149 + i * 8 + 0;
1016 pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER;
1017 pAd->TxPower[3 * i + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
1018
1019 pAd->TxPower[3 * i + choffset + 1].Channel = 149 + i * 8 + 2;
1020 pAd->TxPower[3 * i + choffset + 1].Power = DEFAULT_RF_TX_POWER;
1021 pAd->TxPower[3 * i + choffset + 1].Power2 = DEFAULT_RF_TX_POWER;
1022
1023 pAd->TxPower[3 * i + choffset + 2].Channel = 149 + i * 8 + 4;
1024 pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER;
1025 pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER;
1026 }
1027 pAd->TxPower[3 * 2 + choffset + 0].Channel = 165;
1028 pAd->TxPower[3 * 2 + choffset + 0].Power = DEFAULT_RF_TX_POWER;
1029 pAd->TxPower[3 * 2 + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
1030
1031 // 3.2 Fill up power
1032 for (i = 0; i < 4; i++)
1033 {
1034// Power.word = RTMP_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + (choffset - 14) + i * 2);
1035// Power2.word = RTMP_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) + i * 2);
1036 RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + (choffset - 14) + i * 2, Power.word);
1037 RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) + i * 2, Power2.word);
1038
1039 if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7))
1040 pAd->TxPower[i * 2 + choffset + 0].Power = Power.field.Byte0;
1041
1042 if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7))
1043 pAd->TxPower[i * 2 + choffset + 1].Power = Power.field.Byte1;
1044
1045 if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7))
1046 pAd->TxPower[i * 2 + choffset + 0].Power2 = Power2.field.Byte0;
1047
1048 if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7))
1049 pAd->TxPower[i * 2 + choffset + 1].Power2 = Power2.field.Byte1;
1050 }
1051
1052 // 4. Print and Debug
1053 choffset = 14 + 12 + 16 + 7;
1054
1055}
1056
1057/*
1058 ========================================================================
1059
1060 Routine Description:
1061 Read the following from the registry
1062 1. All the parameters
1063 2. NetworkAddres
1064
1065 Arguments:
1066 Adapter Pointer to our adapter
1067 WrapperConfigurationContext For use by NdisOpenConfiguration
1068
1069 Return Value:
1070 NDIS_STATUS_SUCCESS
1071 NDIS_STATUS_FAILURE
1072 NDIS_STATUS_RESOURCES
1073
1074 IRQL = PASSIVE_LEVEL
1075
1076 Note:
1077
1078 ========================================================================
1079*/
1080NDIS_STATUS NICReadRegParameters(
1081 IN PRTMP_ADAPTER pAd,
1082 IN NDIS_HANDLE WrapperConfigurationContext
1083 )
1084{
1085 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
1086 DBGPRINT_S(Status, ("<-- NICReadRegParameters, Status=%x\n", Status));
1087 return Status;
1088}
1089
1090
1091#ifdef RT30xx
1092/*
1093 ========================================================================
1094
1095 Routine Description:
1096 For RF filter calibration purpose
1097
1098 Arguments:
1099 pAd Pointer to our adapter
1100
1101 Return Value:
1102 None
1103
1104 IRQL = PASSIVE_LEVEL
1105
1106 ========================================================================
1107*/
1108VOID RTMPFilterCalibration(
1109 IN PRTMP_ADAPTER pAd)
1110{
1111 UCHAR R55x = 0, value, FilterTarget = 0x1E, BBPValue=0;
1112 UINT loop = 0, count = 0, loopcnt = 0, ReTry = 0;
1113 UCHAR RF_R24_Value = 0;
1114
1115 // Give bbp filter initial value
1116 pAd->Mlme.CaliBW20RfR24 = 0x1F;
1117 pAd->Mlme.CaliBW40RfR24 = 0x2F; //Bit[5] must be 1 for BW 40
1118
1119 do
1120 {
1121 if (loop == 1) //BandWidth = 40 MHz
1122 {
1123 // Write 0x27 to RF_R24 to program filter
1124 RF_R24_Value = 0x27;
1125 RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
1126 if (IS_RT3090(pAd))
1127 FilterTarget = 0x15;
1128 else
1129 FilterTarget = 0x19;
1130
1131 // when calibrate BW40, BBP mask must set to BW40.
1132 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
1133 BBPValue&= (~0x18);
1134 BBPValue|= (0x10);
1135 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
1136
1137 // set to BW40
1138 RT30xxReadRFRegister(pAd, RF_R31, &value);
1139 value |= 0x20;
1140 RT30xxWriteRFRegister(pAd, RF_R31, value);
1141 }
1142 else //BandWidth = 20 MHz
1143 {
1144 // Write 0x07 to RF_R24 to program filter
1145 RF_R24_Value = 0x07;
1146 RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
1147 if (IS_RT3090(pAd))
1148 FilterTarget = 0x13;
1149 else
1150 FilterTarget = 0x16;
1151
1152 // set to BW20
1153 RT30xxReadRFRegister(pAd, RF_R31, &value);
1154 value &= (~0x20);
1155 RT30xxWriteRFRegister(pAd, RF_R31, value);
1156 }
1157
1158 // Write 0x01 to RF_R22 to enable baseband loopback mode
1159 RT30xxReadRFRegister(pAd, RF_R22, &value);
1160 value |= 0x01;
1161 RT30xxWriteRFRegister(pAd, RF_R22, value);
1162
1163 // Write 0x00 to BBP_R24 to set power & frequency of passband test tone
1164 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0);
1165
1166 do
1167 {
1168 // Write 0x90 to BBP_R25 to transmit test tone
1169 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90);
1170
1171 RTMPusecDelay(1000);
1172 // Read BBP_R55[6:0] for received power, set R55x = BBP_R55[6:0]
1173 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value);
1174 R55x = value & 0xFF;
1175
1176 } while ((ReTry++ < 100) && (R55x == 0));
1177
1178 // Write 0x06 to BBP_R24 to set power & frequency of stopband test tone
1179 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0x06);
1180
1181 while(TRUE)
1182 {
1183 // Write 0x90 to BBP_R25 to transmit test tone
1184 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90);
1185
1186 //We need to wait for calibration
1187 RTMPusecDelay(1000);
1188 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value);
1189 value &= 0xFF;
1190 if ((R55x - value) < FilterTarget)
1191 {
1192 RF_R24_Value ++;
1193 }
1194 else if ((R55x - value) == FilterTarget)
1195 {
1196 RF_R24_Value ++;
1197 count ++;
1198 }
1199 else
1200 {
1201 break;
1202 }
1203
1204 // prevent infinite loop cause driver hang.
1205 if (loopcnt++ > 100)
1206 {
1207 DBGPRINT(RT_DEBUG_ERROR, ("RTMPFilterCalibration - can't find a valid value, loopcnt=%d stop calibrating", loopcnt));
1208 break;
1209 }
1210
1211 // Write RF_R24 to program filter
1212 RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
1213 }
1214
1215 if (count > 0)
1216 {
1217 RF_R24_Value = RF_R24_Value - ((count) ? (1) : (0));
1218 }
1219
1220 // Store for future usage
1221 if (loopcnt < 100)
1222 {
1223 if (loop++ == 0)
1224 {
1225 //BandWidth = 20 MHz
1226 pAd->Mlme.CaliBW20RfR24 = (UCHAR)RF_R24_Value;
1227 }
1228 else
1229 {
1230 //BandWidth = 40 MHz
1231 pAd->Mlme.CaliBW40RfR24 = (UCHAR)RF_R24_Value;
1232 break;
1233 }
1234 }
1235 else
1236 break;
1237
1238 RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
1239
1240 // reset count
1241 count = 0;
1242 } while(TRUE);
1243
1244 //
1245 // Set back to initial state
1246 //
1247 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0);
1248
1249 RT30xxReadRFRegister(pAd, RF_R22, &value);
1250 value &= ~(0x01);
1251 RT30xxWriteRFRegister(pAd, RF_R22, value);
1252
1253 // set BBP back to BW20
1254 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
1255 BBPValue&= (~0x18);
1256 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
1257
1258 DBGPRINT(RT_DEBUG_TRACE, ("RTMPFilterCalibration - CaliBW20RfR24=0x%x, CaliBW40RfR24=0x%x\n", pAd->Mlme.CaliBW20RfR24, pAd->Mlme.CaliBW40RfR24));
1259}
1260#endif // RT30xx //
1261
1262
1263#ifdef RT3070
1264VOID NICInitRT30xxRFRegisters(IN PRTMP_ADAPTER pAd)
1265{
1266 INT i;
1267 // Driver must read EEPROM to get RfIcType before initial RF registers
1268 // Initialize RF register to default value
1269 if (IS_RT3070(pAd) || IS_RT3071(pAd))
1270 {
1271 // Init RF calibration
1272 // Driver should toggle RF R30 bit7 before init RF registers
1273 UINT32 RfReg = 0;
1274 UINT32 data;
1275
1276 RT30xxReadRFRegister(pAd, RF_R30, (PUCHAR)&RfReg);
1277 RfReg |= 0x80;
1278 RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg);
1279 RTMPusecDelay(1000);
1280 RfReg &= 0x7F;
1281 RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg);
1282
1283 // Initialize RF register to default value
1284 for (i = 0; i < NUM_RF_REG_PARMS; i++)
1285 {
1286 RT30xxWriteRFRegister(pAd, RT30xx_RFRegTable[i].Register, RT30xx_RFRegTable[i].Value);
1287 }
1288
1289 // add by johnli
1290 if (IS_RT3070(pAd))
1291 {
1292 // Update MAC 0x05D4 from 01xxxxxx to 0Dxxxxxx (voltage 1.2V to 1.35V) for RT3070 to improve yield rate
1293 RTUSBReadMACRegister(pAd, LDO_CFG0, &data);
1294 data = ((data & 0xF0FFFFFF) | 0x0D000000);
1295 RTUSBWriteMACRegister(pAd, LDO_CFG0, data);
1296 }
1297 else if (IS_RT3071(pAd))
1298 {
1299 // Driver should set RF R6 bit6 on before init RF registers
1300 RT30xxReadRFRegister(pAd, RF_R06, (PUCHAR)&RfReg);
1301 RfReg |= 0x40;
1302 RT30xxWriteRFRegister(pAd, RF_R06, (UCHAR)RfReg);
1303
1304 // init R31
1305 RT30xxWriteRFRegister(pAd, RF_R31, 0x14);
1306
1307 // RT3071 version E has fixed this issue
1308 if ((pAd->NicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211))
1309 {
1310 // patch tx EVM issue temporarily
1311 RTUSBReadMACRegister(pAd, LDO_CFG0, &data);
1312 data = ((data & 0xE0FFFFFF) | 0x0D000000);
1313 RTUSBWriteMACRegister(pAd, LDO_CFG0, data);
1314 }
1315 else
1316 {
1317 RTMP_IO_READ32(pAd, LDO_CFG0, &data);
1318 data = ((data & 0xE0FFFFFF) | 0x01000000);
1319 RTMP_IO_WRITE32(pAd, LDO_CFG0, data);
1320 }
1321
1322 // patch LNA_PE_G1 failed issue
1323 RTUSBReadMACRegister(pAd, GPIO_SWITCH, &data);
1324 data &= ~(0x20);
1325 RTUSBWriteMACRegister(pAd, GPIO_SWITCH, data);
1326 }
1327
1328 //For RF filter Calibration
1329 RTMPFilterCalibration(pAd);
1330
1331 // Initialize RF R27 register, set RF R27 must be behind RTMPFilterCalibration()
1332 if ((pAd->MACVersion & 0xffff) < 0x0211)
1333 RT30xxWriteRFRegister(pAd, RF_R27, 0x3);
1334
1335 // set led open drain enable
1336 RTUSBReadMACRegister(pAd, OPT_14, &data);
1337 data |= 0x01;
1338 RTUSBWriteMACRegister(pAd, OPT_14, data);
1339
1340 if (IS_RT3071(pAd))
1341 {
1342 // add by johnli, RF power sequence setup, load RF normal operation-mode setup
1343 RT30xxLoadRFNormalModeSetup(pAd);
1344 }
1345 }
1346
1347}
1348#endif // RT3070 //
1349
1350
1351/*
1352 ========================================================================
1353
1354 Routine Description:
1355 Read initial parameters from EEPROM
1356
1357 Arguments:
1358 Adapter Pointer to our adapter
1359
1360 Return Value:
1361 None
1362
1363 IRQL = PASSIVE_LEVEL
1364
1365 Note:
1366
1367 ========================================================================
1368*/
1369VOID NICReadEEPROMParameters(
1370 IN PRTMP_ADAPTER pAd,
1371 IN PUCHAR mac_addr)
1372{
1373 UINT32 data = 0;
1374 USHORT i, value, value2;
1375 UCHAR TmpPhy;
1376 EEPROM_TX_PWR_STRUC Power;
1377 EEPROM_VERSION_STRUC Version;
1378 EEPROM_ANTENNA_STRUC Antenna;
1379 EEPROM_NIC_CONFIG2_STRUC NicConfig2;
1380
1381 DBGPRINT(RT_DEBUG_TRACE, ("--> NICReadEEPROMParameters\n"));
1382
1383 // Init EEPROM Address Number, before access EEPROM; if 93c46, EEPROMAddressNum=6, else if 93c66, EEPROMAddressNum=8
1384 RTMP_IO_READ32(pAd, E2PROM_CSR, &data);
1385 DBGPRINT(RT_DEBUG_TRACE, ("--> E2PROM_CSR = 0x%x\n", data));
1386
1387 if((data & 0x30) == 0)
1388 pAd->EEPROMAddressNum = 6; // 93C46
1389 else if((data & 0x30) == 0x10)
1390 pAd->EEPROMAddressNum = 8; // 93C66
1391 else
1392 pAd->EEPROMAddressNum = 8; // 93C86
1393 DBGPRINT(RT_DEBUG_TRACE, ("--> EEPROMAddressNum = %d\n", pAd->EEPROMAddressNum ));
1394
1395 // RT2860 MAC no longer auto load MAC address from E2PROM. Driver has to intialize
1396 // MAC address registers according to E2PROM setting
1397 if (mac_addr == NULL ||
1398 strlen(mac_addr) != 17 ||
1399 mac_addr[2] != ':' || mac_addr[5] != ':' || mac_addr[8] != ':' ||
1400 mac_addr[11] != ':' || mac_addr[14] != ':')
1401 {
1402 USHORT Addr01,Addr23,Addr45 ;
1403
1404 RT28xx_EEPROM_READ16(pAd, 0x04, Addr01);
1405 RT28xx_EEPROM_READ16(pAd, 0x06, Addr23);
1406 RT28xx_EEPROM_READ16(pAd, 0x08, Addr45);
1407
1408 pAd->PermanentAddress[0] = (UCHAR)(Addr01 & 0xff);
1409 pAd->PermanentAddress[1] = (UCHAR)(Addr01 >> 8);
1410 pAd->PermanentAddress[2] = (UCHAR)(Addr23 & 0xff);
1411 pAd->PermanentAddress[3] = (UCHAR)(Addr23 >> 8);
1412 pAd->PermanentAddress[4] = (UCHAR)(Addr45 & 0xff);
1413 pAd->PermanentAddress[5] = (UCHAR)(Addr45 >> 8);
1414
1415 DBGPRINT(RT_DEBUG_TRACE, ("Initialize MAC Address from E2PROM \n"));
1416 }
1417 else
1418 {
1419 INT j;
1420 PUCHAR macptr;
1421
1422 macptr = mac_addr;
1423
1424 for (j=0; j<MAC_ADDR_LEN; j++)
1425 {
1426 AtoH(macptr, &pAd->PermanentAddress[j], 1);
1427 macptr=macptr+3;
1428 }
1429
1430 DBGPRINT(RT_DEBUG_TRACE, ("Initialize MAC Address from module parameter \n"));
1431 }
1432
1433
1434 {
1435 //more conveninet to test mbssid, so ap's bssid &0xf1
1436 if (pAd->PermanentAddress[0] == 0xff)
1437 pAd->PermanentAddress[0] = RandomByte(pAd)&0xf8;
1438
1439 //if (pAd->PermanentAddress[5] == 0xff)
1440 // pAd->PermanentAddress[5] = RandomByte(pAd)&0xf8;
1441
1442 DBGPRINT_RAW(RT_DEBUG_TRACE,("E2PROM MAC: =%02x:%02x:%02x:%02x:%02x:%02x\n",
1443 pAd->PermanentAddress[0], pAd->PermanentAddress[1],
1444 pAd->PermanentAddress[2], pAd->PermanentAddress[3],
1445 pAd->PermanentAddress[4], pAd->PermanentAddress[5]));
1446 if (pAd->bLocalAdminMAC == FALSE)
1447 {
1448 MAC_DW0_STRUC csr2;
1449 MAC_DW1_STRUC csr3;
1450 COPY_MAC_ADDR(pAd->CurrentAddress, pAd->PermanentAddress);
1451 csr2.field.Byte0 = pAd->CurrentAddress[0];
1452 csr2.field.Byte1 = pAd->CurrentAddress[1];
1453 csr2.field.Byte2 = pAd->CurrentAddress[2];
1454 csr2.field.Byte3 = pAd->CurrentAddress[3];
1455 RTMP_IO_WRITE32(pAd, MAC_ADDR_DW0, csr2.word);
1456 csr3.word = 0;
1457 csr3.field.Byte4 = pAd->CurrentAddress[4];
1458 csr3.field.Byte5 = pAd->CurrentAddress[5];
1459 csr3.field.U2MeMask = 0xff;
1460 RTMP_IO_WRITE32(pAd, MAC_ADDR_DW1, csr3.word);
1461 DBGPRINT_RAW(RT_DEBUG_TRACE,("E2PROM MAC: =%02x:%02x:%02x:%02x:%02x:%02x\n",
1462 pAd->PermanentAddress[0], pAd->PermanentAddress[1],
1463 pAd->PermanentAddress[2], pAd->PermanentAddress[3],
1464 pAd->PermanentAddress[4], pAd->PermanentAddress[5]));
1465 }
1466 }
1467
1468 // if not return early. cause fail at emulation.
1469 // Init the channel number for TX channel power
1470 RTMPReadChannelPwr(pAd);
1471
1472 // if E2PROM version mismatch with driver's expectation, then skip
1473 // all subsequent E2RPOM retieval and set a system error bit to notify GUI
1474 RT28xx_EEPROM_READ16(pAd, EEPROM_VERSION_OFFSET, Version.word);
1475 pAd->EepromVersion = Version.field.Version + Version.field.FaeReleaseNumber * 256;
1476 DBGPRINT(RT_DEBUG_TRACE, ("E2PROM: Version = %d, FAE release #%d\n", Version.field.Version, Version.field.FaeReleaseNumber));
1477
1478 if (Version.field.Version > VALID_EEPROM_VERSION)
1479 {
1480 DBGPRINT_ERR(("E2PROM: WRONG VERSION 0x%x, should be %d\n",Version.field.Version, VALID_EEPROM_VERSION));
1481 /*pAd->SystemErrorBitmap |= 0x00000001;
1482
1483 // hard-code default value when no proper E2PROM installed
1484 pAd->bAutoTxAgcA = FALSE;
1485 pAd->bAutoTxAgcG = FALSE;
1486
1487 // Default the channel power
1488 for (i = 0; i < MAX_NUM_OF_CHANNELS; i++)
1489 pAd->TxPower[i].Power = DEFAULT_RF_TX_POWER;
1490
1491 // Default the channel power
1492 for (i = 0; i < MAX_NUM_OF_11JCHANNELS; i++)
1493 pAd->TxPower11J[i].Power = DEFAULT_RF_TX_POWER;
1494
1495 for(i = 0; i < NUM_EEPROM_BBP_PARMS; i++)
1496 pAd->EEPROMDefaultValue[i] = 0xffff;
1497 return; */
1498 }
1499
1500 // Read BBP default value from EEPROM and store to array(EEPROMDefaultValue) in pAd
1501 RT28xx_EEPROM_READ16(pAd, EEPROM_NIC1_OFFSET, value);
1502 pAd->EEPROMDefaultValue[0] = value;
1503
1504 RT28xx_EEPROM_READ16(pAd, EEPROM_NIC2_OFFSET, value);
1505 pAd->EEPROMDefaultValue[1] = value;
1506
1507 RT28xx_EEPROM_READ16(pAd, 0x38, value); // Country Region
1508 pAd->EEPROMDefaultValue[2] = value;
1509
1510 for(i = 0; i < 8; i++)
1511 {
1512 RT28xx_EEPROM_READ16(pAd, EEPROM_BBP_BASE_OFFSET + i*2, value);
1513 pAd->EEPROMDefaultValue[i+3] = value;
1514 }
1515
1516 // We have to parse NIC configuration 0 at here.
1517 // If TSSI did not have preloaded value, it should reset the TxAutoAgc to false
1518 // Therefore, we have to read TxAutoAgc control beforehand.
1519 // Read Tx AGC control bit
1520 Antenna.word = pAd->EEPROMDefaultValue[0];
1521 if (Antenna.word == 0xFFFF)
1522 {
1523#ifdef RT30xx
1524 if(IS_RT3090(pAd))
1525 {
1526 Antenna.word = 0;
1527 Antenna.field.RfIcType = RFIC_3020;
1528 Antenna.field.TxPath = 1;
1529 Antenna.field.RxPath = 1;
1530 }
1531 else
1532 {
1533#endif // RT30xx //
1534 Antenna.word = 0;
1535 Antenna.field.RfIcType = RFIC_2820;
1536 Antenna.field.TxPath = 1;
1537 Antenna.field.RxPath = 2;
1538 DBGPRINT(RT_DEBUG_WARN, ("E2PROM error, hard code as 0x%04x\n", Antenna.word));
1539#ifdef RT30xx
1540 }
1541#endif // RT30xx //
1542 }
1543
1544 // Choose the desired Tx&Rx stream.
1545 if ((pAd->CommonCfg.TxStream == 0) || (pAd->CommonCfg.TxStream > Antenna.field.TxPath))
1546 pAd->CommonCfg.TxStream = Antenna.field.TxPath;
1547
1548 if ((pAd->CommonCfg.RxStream == 0) || (pAd->CommonCfg.RxStream > Antenna.field.RxPath))
1549 {
1550 pAd->CommonCfg.RxStream = Antenna.field.RxPath;
1551
1552 if ((pAd->MACVersion < RALINK_2883_VERSION) &&
1553 (pAd->CommonCfg.RxStream > 2))
1554 {
1555 // only 2 Rx streams for RT2860 series
1556 pAd->CommonCfg.RxStream = 2;
1557 }
1558 }
1559
1560 // 3*3
1561 // read value from EEPROM and set them to CSR174 ~ 177 in chain0 ~ chain2
1562 // yet implement
1563 for(i=0; i<3; i++)
1564 {
1565 }
1566
1567 NicConfig2.word = pAd->EEPROMDefaultValue[1];
1568
1569
1570
1571#ifdef CONFIG_STA_SUPPORT
1572 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1573 {
1574 if ((NicConfig2.word & 0x00ff) == 0xff)
1575 {
1576 NicConfig2.word &= 0xff00;
1577 }
1578
1579 if ((NicConfig2.word >> 8) == 0xff)
1580 {
1581 NicConfig2.word &= 0x00ff;
1582 }
1583 }
1584#endif // CONFIG_STA_SUPPORT //
1585
1586 if (NicConfig2.field.DynamicTxAgcControl == 1)
1587 pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = TRUE;
1588 else
1589 pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = FALSE;
1590
1591 DBGPRINT_RAW(RT_DEBUG_TRACE, ("NICReadEEPROMParameters: RxPath = %d, TxPath = %d\n", Antenna.field.RxPath, Antenna.field.TxPath));
1592
1593 // Save the antenna for future use
1594 pAd->Antenna.word = Antenna.word;
1595
1596 //
1597 // Reset PhyMode if we don't support 802.11a
1598 // Only RFIC_2850 & RFIC_2750 support 802.11a
1599 //
1600 if ((Antenna.field.RfIcType != RFIC_2850) && (Antenna.field.RfIcType != RFIC_2750))
1601 {
1602 if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED) ||
1603 (pAd->CommonCfg.PhyMode == PHY_11A))
1604 pAd->CommonCfg.PhyMode = PHY_11BG_MIXED;
1605#ifdef DOT11_N_SUPPORT
1606 else if ((pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) ||
1607 (pAd->CommonCfg.PhyMode == PHY_11AN_MIXED) ||
1608 (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED) ||
1609 (pAd->CommonCfg.PhyMode == PHY_11N_5G))
1610 pAd->CommonCfg.PhyMode = PHY_11BGN_MIXED;
1611#endif // DOT11_N_SUPPORT //
1612 }
1613
1614 // Read TSSI reference and TSSI boundary for temperature compensation. This is ugly
1615 // 0. 11b/g
1616 {
1617 /* these are tempature reference value (0x00 ~ 0xFE)
1618 ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
1619 TssiPlusBoundaryG [4] [3] [2] [1] [0] (smaller) +
1620 TssiMinusBoundaryG[0] [1] [2] [3] [4] (larger) */
1621 RT28xx_EEPROM_READ16(pAd, 0x6E, Power.word);
1622 pAd->TssiMinusBoundaryG[4] = Power.field.Byte0;
1623 pAd->TssiMinusBoundaryG[3] = Power.field.Byte1;
1624 RT28xx_EEPROM_READ16(pAd, 0x70, Power.word);
1625 pAd->TssiMinusBoundaryG[2] = Power.field.Byte0;
1626 pAd->TssiMinusBoundaryG[1] = Power.field.Byte1;
1627 RT28xx_EEPROM_READ16(pAd, 0x72, Power.word);
1628 pAd->TssiRefG = Power.field.Byte0; /* reference value [0] */
1629 pAd->TssiPlusBoundaryG[1] = Power.field.Byte1;
1630 RT28xx_EEPROM_READ16(pAd, 0x74, Power.word);
1631 pAd->TssiPlusBoundaryG[2] = Power.field.Byte0;
1632 pAd->TssiPlusBoundaryG[3] = Power.field.Byte1;
1633 RT28xx_EEPROM_READ16(pAd, 0x76, Power.word);
1634 pAd->TssiPlusBoundaryG[4] = Power.field.Byte0;
1635 pAd->TxAgcStepG = Power.field.Byte1;
1636 pAd->TxAgcCompensateG = 0;
1637 pAd->TssiMinusBoundaryG[0] = pAd->TssiRefG;
1638 pAd->TssiPlusBoundaryG[0] = pAd->TssiRefG;
1639
1640 // Disable TxAgc if the based value is not right
1641 if (pAd->TssiRefG == 0xff)
1642 pAd->bAutoTxAgcG = FALSE;
1643
1644 DBGPRINT(RT_DEBUG_TRACE,("E2PROM: G Tssi[-4 .. +4] = %d %d %d %d - %d -%d %d %d %d, step=%d, tuning=%d\n",
1645 pAd->TssiMinusBoundaryG[4], pAd->TssiMinusBoundaryG[3], pAd->TssiMinusBoundaryG[2], pAd->TssiMinusBoundaryG[1],
1646 pAd->TssiRefG,
1647 pAd->TssiPlusBoundaryG[1], pAd->TssiPlusBoundaryG[2], pAd->TssiPlusBoundaryG[3], pAd->TssiPlusBoundaryG[4],
1648 pAd->TxAgcStepG, pAd->bAutoTxAgcG));
1649 }
1650 // 1. 11a
1651 {
1652 RT28xx_EEPROM_READ16(pAd, 0xD4, Power.word);
1653 pAd->TssiMinusBoundaryA[4] = Power.field.Byte0;
1654 pAd->TssiMinusBoundaryA[3] = Power.field.Byte1;
1655 RT28xx_EEPROM_READ16(pAd, 0xD6, Power.word);
1656 pAd->TssiMinusBoundaryA[2] = Power.field.Byte0;
1657 pAd->TssiMinusBoundaryA[1] = Power.field.Byte1;
1658 RT28xx_EEPROM_READ16(pAd, 0xD8, Power.word);
1659 pAd->TssiRefA = Power.field.Byte0;
1660 pAd->TssiPlusBoundaryA[1] = Power.field.Byte1;
1661 RT28xx_EEPROM_READ16(pAd, 0xDA, Power.word);
1662 pAd->TssiPlusBoundaryA[2] = Power.field.Byte0;
1663 pAd->TssiPlusBoundaryA[3] = Power.field.Byte1;
1664 RT28xx_EEPROM_READ16(pAd, 0xDC, Power.word);
1665 pAd->TssiPlusBoundaryA[4] = Power.field.Byte0;
1666 pAd->TxAgcStepA = Power.field.Byte1;
1667 pAd->TxAgcCompensateA = 0;
1668 pAd->TssiMinusBoundaryA[0] = pAd->TssiRefA;
1669 pAd->TssiPlusBoundaryA[0] = pAd->TssiRefA;
1670
1671 // Disable TxAgc if the based value is not right
1672 if (pAd->TssiRefA == 0xff)
1673 pAd->bAutoTxAgcA = FALSE;
1674
1675 DBGPRINT(RT_DEBUG_TRACE,("E2PROM: A Tssi[-4 .. +4] = %d %d %d %d - %d -%d %d %d %d, step=%d, tuning=%d\n",
1676 pAd->TssiMinusBoundaryA[4], pAd->TssiMinusBoundaryA[3], pAd->TssiMinusBoundaryA[2], pAd->TssiMinusBoundaryA[1],
1677 pAd->TssiRefA,
1678 pAd->TssiPlusBoundaryA[1], pAd->TssiPlusBoundaryA[2], pAd->TssiPlusBoundaryA[3], pAd->TssiPlusBoundaryA[4],
1679 pAd->TxAgcStepA, pAd->bAutoTxAgcA));
1680 }
1681 pAd->BbpRssiToDbmDelta = 0x0;
1682
1683 // Read frequency offset setting for RF
1684 RT28xx_EEPROM_READ16(pAd, EEPROM_FREQ_OFFSET, value);
1685 if ((value & 0x00FF) != 0x00FF)
1686 pAd->RfFreqOffset = (ULONG) (value & 0x00FF);
1687 else
1688 pAd->RfFreqOffset = 0;
1689 DBGPRINT(RT_DEBUG_TRACE, ("E2PROM: RF FreqOffset=0x%lx \n", pAd->RfFreqOffset));
1690
1691 //CountryRegion byte offset (38h)
1692 value = pAd->EEPROMDefaultValue[2] >> 8; // 2.4G band
1693 value2 = pAd->EEPROMDefaultValue[2] & 0x00FF; // 5G band
1694
1695 if ((value <= REGION_MAXIMUM_BG_BAND) && (value2 <= REGION_MAXIMUM_A_BAND))
1696 {
1697 pAd->CommonCfg.CountryRegion = ((UCHAR) value) | 0x80;
1698 pAd->CommonCfg.CountryRegionForABand = ((UCHAR) value2) | 0x80;
1699 TmpPhy = pAd->CommonCfg.PhyMode;
1700 pAd->CommonCfg.PhyMode = 0xff;
1701 RTMPSetPhyMode(pAd, TmpPhy);
1702#ifdef DOT11_N_SUPPORT
1703 SetCommonHT(pAd);
1704#endif // DOT11_N_SUPPORT //
1705 }
1706
1707 //
1708 // Get RSSI Offset on EEPROM 0x9Ah & 0x9Ch.
1709 // The valid value are (-10 ~ 10)
1710 //
1711 RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET, value);
1712 pAd->BGRssiOffset0 = value & 0x00ff;
1713 pAd->BGRssiOffset1 = (value >> 8);
1714 RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET+2, value);
1715 pAd->BGRssiOffset2 = value & 0x00ff;
1716 pAd->ALNAGain1 = (value >> 8);
1717 RT28xx_EEPROM_READ16(pAd, EEPROM_LNA_OFFSET, value);
1718 pAd->BLNAGain = value & 0x00ff;
1719 pAd->ALNAGain0 = (value >> 8);
1720
1721 // Validate 11b/g RSSI_0 offset.
1722 if ((pAd->BGRssiOffset0 < -10) || (pAd->BGRssiOffset0 > 10))
1723 pAd->BGRssiOffset0 = 0;
1724
1725 // Validate 11b/g RSSI_1 offset.
1726 if ((pAd->BGRssiOffset1 < -10) || (pAd->BGRssiOffset1 > 10))
1727 pAd->BGRssiOffset1 = 0;
1728
1729 // Validate 11b/g RSSI_2 offset.
1730 if ((pAd->BGRssiOffset2 < -10) || (pAd->BGRssiOffset2 > 10))
1731 pAd->BGRssiOffset2 = 0;
1732
1733 RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_A_OFFSET, value);
1734 pAd->ARssiOffset0 = value & 0x00ff;
1735 pAd->ARssiOffset1 = (value >> 8);
1736 RT28xx_EEPROM_READ16(pAd, (EEPROM_RSSI_A_OFFSET+2), value);
1737 pAd->ARssiOffset2 = value & 0x00ff;
1738 pAd->ALNAGain2 = (value >> 8);
1739
1740 if (((UCHAR)pAd->ALNAGain1 == 0xFF) || (pAd->ALNAGain1 == 0x00))
1741 pAd->ALNAGain1 = pAd->ALNAGain0;
1742 if (((UCHAR)pAd->ALNAGain2 == 0xFF) || (pAd->ALNAGain2 == 0x00))
1743 pAd->ALNAGain2 = pAd->ALNAGain0;
1744
1745 // Validate 11a RSSI_0 offset.
1746 if ((pAd->ARssiOffset0 < -10) || (pAd->ARssiOffset0 > 10))
1747 pAd->ARssiOffset0 = 0;
1748
1749 // Validate 11a RSSI_1 offset.
1750 if ((pAd->ARssiOffset1 < -10) || (pAd->ARssiOffset1 > 10))
1751 pAd->ARssiOffset1 = 0;
1752
1753 //Validate 11a RSSI_2 offset.
1754 if ((pAd->ARssiOffset2 < -10) || (pAd->ARssiOffset2 > 10))
1755 pAd->ARssiOffset2 = 0;
1756
1757 //
1758 // Get LED Setting.
1759 //
1760 RT28xx_EEPROM_READ16(pAd, 0x3a, value);
1761 pAd->LedCntl.word = (value&0xff00) >> 8;
1762 RT28xx_EEPROM_READ16(pAd, EEPROM_LED1_OFFSET, value);
1763 pAd->Led1 = value;
1764 RT28xx_EEPROM_READ16(pAd, EEPROM_LED2_OFFSET, value);
1765 pAd->Led2 = value;
1766 RT28xx_EEPROM_READ16(pAd, EEPROM_LED3_OFFSET, value);
1767 pAd->Led3 = value;
1768
1769 RTMPReadTxPwrPerRate(pAd);
1770
1771#ifdef SINGLE_SKU
1772 //pAd->CommonCfg.DefineMaxTxPwr = RTMP_EEPROM_READ16(pAd, EEPROM_DEFINE_MAX_TXPWR);
1773 RT28xx_EEPROM_READ16(pAd, EEPROM_DEFINE_MAX_TXPWR, pAd->CommonCfg.DefineMaxTxPwr);
1774#endif // SINGLE_SKU //
1775#ifdef RT30xx
1776 if (IS_RT30xx(pAd))
1777 {
1778 eFusePhysicalReadRegisters(pAd, EFUSE_TAG, 2, &value);
1779 pAd->EFuseTag = (value & 0xff);
1780 }
1781#endif // RT30xx //
1782
1783 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICReadEEPROMParameters\n"));
1784}
1785
1786/*
1787 ========================================================================
1788
1789 Routine Description:
1790 Set default value from EEPROM
1791
1792 Arguments:
1793 Adapter Pointer to our adapter
1794
1795 Return Value:
1796 None
1797
1798 IRQL = PASSIVE_LEVEL
1799
1800 Note:
1801
1802 ========================================================================
1803*/
1804VOID NICInitAsicFromEEPROM(
1805 IN PRTMP_ADAPTER pAd)
1806{
1807#ifdef CONFIG_STA_SUPPORT
1808 UINT32 data = 0;
1809 UCHAR BBPR1 = 0;
1810#endif // CONFIG_STA_SUPPORT //
1811 USHORT i;
1812 EEPROM_ANTENNA_STRUC Antenna;
1813 EEPROM_NIC_CONFIG2_STRUC NicConfig2;
1814 UCHAR BBPR3 = 0;
1815
1816 DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitAsicFromEEPROM\n"));
1817 for(i = 3; i < NUM_EEPROM_BBP_PARMS; i++)
1818 {
1819 UCHAR BbpRegIdx, BbpValue;
1820
1821 if ((pAd->EEPROMDefaultValue[i] != 0xFFFF) && (pAd->EEPROMDefaultValue[i] != 0))
1822 {
1823 BbpRegIdx = (UCHAR)(pAd->EEPROMDefaultValue[i] >> 8);
1824 BbpValue = (UCHAR)(pAd->EEPROMDefaultValue[i] & 0xff);
1825 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BbpRegIdx, BbpValue);
1826 }
1827 }
1828
1829 Antenna.word = pAd->EEPROMDefaultValue[0];
1830 if (Antenna.word == 0xFFFF)
1831 {
1832 DBGPRINT(RT_DEBUG_ERROR, ("E2PROM error, hard code as 0x%04x\n", Antenna.word));
1833 BUG_ON(Antenna.word == 0xFFFF);
1834 }
1835 pAd->Mlme.RealRxPath = (UCHAR) Antenna.field.RxPath;
1836 pAd->RfIcType = (UCHAR) Antenna.field.RfIcType;
1837
1838 DBGPRINT(RT_DEBUG_WARN, ("pAd->RfIcType = %d, RealRxPath=%d, TxPath = %d\n", pAd->RfIcType, pAd->Mlme.RealRxPath,Antenna.field.TxPath));
1839
1840 // Save the antenna for future use
1841 pAd->Antenna.word = Antenna.word;
1842
1843 NicConfig2.word = pAd->EEPROMDefaultValue[1];
1844
1845
1846#ifdef CONFIG_STA_SUPPORT
1847 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1848 {
1849 if ((NicConfig2.word & 0x00ff) == 0xff)
1850 {
1851 NicConfig2.word &= 0xff00;
1852 }
1853
1854 if ((NicConfig2.word >> 8) == 0xff)
1855 {
1856 NicConfig2.word &= 0x00ff;
1857 }
1858 }
1859#endif // CONFIG_STA_SUPPORT //
1860
1861 // Save the antenna for future use
1862 pAd->NicConfig2.word = NicConfig2.word;
1863
1864 // set default antenna as main
1865 if (pAd->RfIcType == RFIC_3020)
1866 AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
1867
1868 //
1869 // Send LED Setting to MCU.
1870 //
1871 if (pAd->LedCntl.word == 0xFF)
1872 {
1873 pAd->LedCntl.word = 0x01;
1874 pAd->Led1 = 0x5555;
1875 pAd->Led2 = 0x2221;
1876
1877#ifdef RT2870
1878 pAd->Led3 = 0x5627;
1879#endif // RT2870 //
1880 }
1881
1882 AsicSendCommandToMcu(pAd, 0x52, 0xff, (UCHAR)pAd->Led1, (UCHAR)(pAd->Led1 >> 8));
1883 AsicSendCommandToMcu(pAd, 0x53, 0xff, (UCHAR)pAd->Led2, (UCHAR)(pAd->Led2 >> 8));
1884 AsicSendCommandToMcu(pAd, 0x54, 0xff, (UCHAR)pAd->Led3, (UCHAR)(pAd->Led3 >> 8));
1885 pAd->LedIndicatorStregth = 0xFF;
1886 RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, before link up
1887
1888#ifdef CONFIG_STA_SUPPORT
1889 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1890 {
1891 // Read Hardware controlled Radio state enable bit
1892 if (NicConfig2.field.HardwareRadioControl == 1)
1893 {
1894 pAd->StaCfg.bHardwareRadio = TRUE;
1895
1896 // Read GPIO pin2 as Hardware controlled radio state
1897 RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &data);
1898 if ((data & 0x04) == 0)
1899 {
1900 pAd->StaCfg.bHwRadio = FALSE;
1901 pAd->StaCfg.bRadio = FALSE;
1902// RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x00001818);
1903 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
1904 }
1905 }
1906 else
1907 pAd->StaCfg.bHardwareRadio = FALSE;
1908
1909 if (pAd->StaCfg.bRadio == FALSE)
1910 {
1911 RTMPSetLED(pAd, LED_RADIO_OFF);
1912 }
1913 else
1914 {
1915 RTMPSetLED(pAd, LED_RADIO_ON);
1916 }
1917 }
1918#endif // CONFIG_STA_SUPPORT //
1919
1920 // Turn off patching for cardbus controller
1921 if (NicConfig2.field.CardbusAcceleration == 1)
1922 {
1923// pAd->bTest1 = TRUE;
1924 }
1925
1926 if (NicConfig2.field.DynamicTxAgcControl == 1)
1927 pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = TRUE;
1928 else
1929 pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = FALSE;
1930 //
1931 // Since BBP has been progamed, to make sure BBP setting will be
1932 // upate inside of AsicAntennaSelect, so reset to UNKNOWN_BAND!!
1933 //
1934 pAd->CommonCfg.BandState = UNKNOWN_BAND;
1935
1936 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
1937 BBPR3 &= (~0x18);
1938 if(pAd->Antenna.field.RxPath == 3)
1939 {
1940 BBPR3 |= (0x10);
1941 }
1942 else if(pAd->Antenna.field.RxPath == 2)
1943 {
1944 BBPR3 |= (0x8);
1945 }
1946 else if(pAd->Antenna.field.RxPath == 1)
1947 {
1948 BBPR3 |= (0x0);
1949 }
1950 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
1951
1952#ifdef CONFIG_STA_SUPPORT
1953 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1954 {
1955 // Handle the difference when 1T
1956 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BBPR1);
1957 if(pAd->Antenna.field.TxPath == 1)
1958 {
1959 BBPR1 &= (~0x18);
1960 }
1961 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BBPR1);
1962
1963 DBGPRINT(RT_DEBUG_TRACE, ("Use Hw Radio Control Pin=%d; if used Pin=%d;\n", pAd->CommonCfg.bHardwareRadio, pAd->CommonCfg.bHardwareRadio));
1964 }
1965#endif // CONFIG_STA_SUPPORT //
1966 DBGPRINT(RT_DEBUG_TRACE, ("TxPath = %d, RxPath = %d, RFIC=%d, Polar+LED mode=%x\n", pAd->Antenna.field.TxPath, pAd->Antenna.field.RxPath, pAd->RfIcType, pAd->LedCntl.word));
1967 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitAsicFromEEPROM\n"));
1968}
1969
1970/*
1971 ========================================================================
1972
1973 Routine Description:
1974 Initialize NIC hardware
1975
1976 Arguments:
1977 Adapter Pointer to our adapter
1978
1979 Return Value:
1980 None
1981
1982 IRQL = PASSIVE_LEVEL
1983
1984 Note:
1985
1986 ========================================================================
1987*/
1988NDIS_STATUS NICInitializeAdapter(
1989 IN PRTMP_ADAPTER pAd,
1990 IN BOOLEAN bHardReset)
1991{
1992 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
1993 WPDMA_GLO_CFG_STRUC GloCfg;
1994// INT_MASK_CSR_STRUC IntMask;
1995 ULONG i =0, j=0;
1996 AC_TXOP_CSR0_STRUC csr0;
1997
1998 DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAdapter\n"));
1999
2000 // 3. Set DMA global configuration except TX_DMA_EN and RX_DMA_EN bits:
2001retry:
2002 i = 0;
2003 do
2004 {
2005 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
2006 if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
2007 break;
2008
2009 RTMPusecDelay(1000);
2010 i++;
2011 }while ( i<100);
2012 DBGPRINT(RT_DEBUG_TRACE, ("<== DMA offset 0x208 = 0x%x\n", GloCfg.word));
2013 GloCfg.word &= 0xff0;
2014 GloCfg.field.EnTXWriteBackDDONE =1;
2015 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
2016
2017 // Record HW Beacon offset
2018 pAd->BeaconOffset[0] = HW_BEACON_BASE0;
2019 pAd->BeaconOffset[1] = HW_BEACON_BASE1;
2020 pAd->BeaconOffset[2] = HW_BEACON_BASE2;
2021 pAd->BeaconOffset[3] = HW_BEACON_BASE3;
2022 pAd->BeaconOffset[4] = HW_BEACON_BASE4;
2023 pAd->BeaconOffset[5] = HW_BEACON_BASE5;
2024 pAd->BeaconOffset[6] = HW_BEACON_BASE6;
2025 pAd->BeaconOffset[7] = HW_BEACON_BASE7;
2026
2027 //
2028 // write all shared Ring's base address into ASIC
2029 //
2030
2031 // asic simulation sequence put this ahead before loading firmware.
2032 // pbf hardware reset
2033
2034 // Initialze ASIC for TX & Rx operation
2035 if (NICInitializeAsic(pAd , bHardReset) != NDIS_STATUS_SUCCESS)
2036 {
2037 if (j++ == 0)
2038 {
2039 NICLoadFirmware(pAd);
2040 goto retry;
2041 }
2042 return NDIS_STATUS_FAILURE;
2043 }
2044
2045
2046
2047
2048 // WMM parameter
2049 csr0.word = 0;
2050 RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
2051 if (pAd->CommonCfg.PhyMode == PHY_11B)
2052 {
2053 csr0.field.Ac0Txop = 192; // AC_VI: 192*32us ~= 6ms
2054 csr0.field.Ac1Txop = 96; // AC_VO: 96*32us ~= 3ms
2055 }
2056 else
2057 {
2058 csr0.field.Ac0Txop = 96; // AC_VI: 96*32us ~= 3ms
2059 csr0.field.Ac1Txop = 48; // AC_VO: 48*32us ~= 1.5ms
2060 }
2061 RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr0.word);
2062
2063
2064
2065
2066 // reset action
2067 // Load firmware
2068 // Status = NICLoadFirmware(pAd);
2069
2070 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitializeAdapter\n"));
2071 return Status;
2072}
2073
2074/*
2075 ========================================================================
2076
2077 Routine Description:
2078 Initialize ASIC
2079
2080 Arguments:
2081 Adapter Pointer to our adapter
2082
2083 Return Value:
2084 None
2085
2086 IRQL = PASSIVE_LEVEL
2087
2088 Note:
2089
2090 ========================================================================
2091*/
2092NDIS_STATUS NICInitializeAsic(
2093 IN PRTMP_ADAPTER pAd,
2094 IN BOOLEAN bHardReset)
2095{
2096 ULONG Index = 0;
2097 UCHAR R0 = 0xff;
2098 UINT32 MacCsr12 = 0, Counter = 0;
2099#ifdef RT2870
2100 UINT32 MacCsr0 = 0;
2101 NTSTATUS Status;
2102 UCHAR Value = 0xff;
2103#endif // RT2870 //
2104#ifdef RT30xx
2105 UINT32 eFuseCtrl;
2106#endif // RT30xx //
2107 USHORT KeyIdx;
2108 INT i,apidx;
2109
2110 DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAsic\n"));
2111
2112
2113#ifdef RT2870
2114 //
2115 // Make sure MAC gets ready after NICLoadFirmware().
2116 //
2117 Index = 0;
2118
2119 //To avoid hang-on issue when interface up in kernel 2.4,
2120 //we use a local variable "MacCsr0" instead of using "pAd->MACVersion" directly.
2121 do
2122 {
2123 RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
2124
2125 if ((MacCsr0 != 0x00) && (MacCsr0 != 0xFFFFFFFF))
2126 break;
2127
2128 RTMPusecDelay(10);
2129 } while (Index++ < 100);
2130
2131 pAd->MACVersion = MacCsr0;
2132 DBGPRINT(RT_DEBUG_TRACE, ("MAC_CSR0 [ Ver:Rev=0x%08x]\n", pAd->MACVersion));
2133 // turn on bit13 (set to zero) after rt2860D. This is to solve high-current issue.
2134 RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacCsr12);
2135 MacCsr12 &= (~0x2000);
2136 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, MacCsr12);
2137
2138 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x3);
2139 RTMP_IO_WRITE32(pAd, USB_DMA_CFG, 0x0);
2140 Status = RTUSBVenderReset(pAd);
2141
2142 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
2143
2144 // Initialize MAC register to default value
2145 for(Index=0; Index<NUM_MAC_REG_PARMS; Index++)
2146 {
2147#ifdef RT3070
2148 if ((MACRegTable[Index].Register == TX_SW_CFG0) && (IS_RT3070(pAd) || IS_RT3071(pAd)))
2149 {
2150 MACRegTable[Index].Value = 0x00000400;
2151 }
2152#endif // RT3070 //
2153 RTMP_IO_WRITE32(pAd, (USHORT)MACRegTable[Index].Register, MACRegTable[Index].Value);
2154 }
2155
2156
2157#ifdef CONFIG_STA_SUPPORT
2158 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2159 {
2160 for (Index = 0; Index < NUM_STA_MAC_REG_PARMS; Index++)
2161 {
2162 RTMP_IO_WRITE32(pAd, (USHORT)STAMACRegTable[Index].Register, STAMACRegTable[Index].Value);
2163 }
2164 }
2165#endif // CONFIG_STA_SUPPORT //
2166#endif // RT2870 //
2167
2168#ifdef RT30xx
2169 // Initialize RT3070 serial MAc registers which is different from RT2870 serial
2170 if (IS_RT3090(pAd))
2171 {
2172 RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0);
2173
2174 // RT3071 version E has fixed this issue
2175 if ((pAd->MACVersion & 0xffff) < 0x0211)
2176 {
2177 if (pAd->NicConfig2.field.DACTestBit == 1)
2178 {
2179 RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x1F); // To fix throughput drop drastically
2180 }
2181 else
2182 {
2183 RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0F); // To fix throughput drop drastically
2184 }
2185 }
2186 else
2187 {
2188 RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0);
2189 }
2190 }
2191 else if (IS_RT3070(pAd))
2192 {
2193 RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0);
2194 RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x1F); // To fix throughput drop drastically
2195 }
2196#endif // RT30xx //
2197
2198 //
2199 // Before program BBP, we need to wait BBP/RF get wake up.
2200 //
2201 Index = 0;
2202 do
2203 {
2204 RTMP_IO_READ32(pAd, MAC_STATUS_CFG, &MacCsr12);
2205
2206 if ((MacCsr12 & 0x03) == 0) // if BB.RF is stable
2207 break;
2208
2209 DBGPRINT(RT_DEBUG_TRACE, ("Check MAC_STATUS_CFG = Busy = %x\n", MacCsr12));
2210 RTMPusecDelay(1000);
2211 } while (Index++ < 100);
2212
2213 // The commands to firmware should be after these commands, these commands will init firmware
2214 // PCI and USB are not the same because PCI driver needs to wait for PCI bus ready
2215 RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, 0); // initialize BBP R/W access agent
2216 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, 0);
2217 RTMPusecDelay(1000);
2218
2219 // Read BBP register, make sure BBP is up and running before write new data
2220 Index = 0;
2221 do
2222 {
2223 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R0, &R0);
2224 DBGPRINT(RT_DEBUG_TRACE, ("BBP version = %x\n", R0));
2225 } while ((++Index < 20) && ((R0 == 0xff) || (R0 == 0x00)));
2226 //ASSERT(Index < 20); //this will cause BSOD on Check-build driver
2227
2228 if ((R0 == 0xff) || (R0 == 0x00))
2229 return NDIS_STATUS_FAILURE;
2230
2231 // Initialize BBP register to default value
2232 for (Index = 0; Index < NUM_BBP_REG_PARMS; Index++)
2233 {
2234 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[Index].Register, BBPRegTable[Index].Value);
2235 }
2236
2237 // for rt2860E and after, init BBP_R84 with 0x19. This is for extension channel overlapping IOT.
2238 // RT3090 should not program BBP R84 to 0x19, otherwise TX will block.
2239 if (((pAd->MACVersion&0xffff) != 0x0101) && (!IS_RT30xx(pAd)))
2240 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R84, 0x19);
2241
2242// add by johnli, RF power sequence setup
2243#ifdef RT30xx
2244 if (IS_RT30xx(pAd))
2245 { //update for RT3070/71/72/90/91/92.
2246 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R79, 0x13);
2247 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R80, 0x05);
2248 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R81, 0x33);
2249 }
2250
2251 if (IS_RT3090(pAd))
2252 {
2253 UCHAR bbpreg=0;
2254
2255 // enable DC filter
2256 if ((pAd->MACVersion & 0xffff) >= 0x0211)
2257 {
2258 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R103, 0xc0);
2259 }
2260
2261 // improve power consumption
2262 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R138, &bbpreg);
2263 if (pAd->Antenna.field.TxPath == 1)
2264 {
2265 // turn off tx DAC_1
2266 bbpreg = (bbpreg | 0x20);
2267 }
2268
2269 if (pAd->Antenna.field.RxPath == 1)
2270 {
2271 // turn off tx ADC_1
2272 bbpreg &= (~0x2);
2273 }
2274 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R138, bbpreg);
2275
2276 // improve power consumption in RT3071 Ver.E
2277 if ((pAd->MACVersion & 0xffff) >= 0x0211)
2278 {
2279 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R31, &bbpreg);
2280 bbpreg &= (~0x3);
2281 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R31, bbpreg);
2282 }
2283 }
2284#endif // RT30xx //
2285// end johnli
2286
2287 if (pAd->MACVersion == 0x28600100)
2288 {
2289 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
2290 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x12);
2291 }
2292
2293 if (pAd->MACVersion >= RALINK_2880E_VERSION && pAd->MACVersion < RALINK_3070_VERSION) // 3*3
2294 {
2295 // enlarge MAX_LEN_CFG
2296 UINT32 csr;
2297 RTMP_IO_READ32(pAd, MAX_LEN_CFG, &csr);
2298 csr &= 0xFFF;
2299 csr |= 0x2000;
2300 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, csr);
2301 }
2302
2303#ifdef RT2870
2304{
2305 UCHAR MAC_Value[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0,0};
2306
2307 //Initialize WCID table
2308 Value = 0xff;
2309 for(Index =0 ;Index < 254;Index++)
2310 {
2311 RTUSBMultiWrite(pAd, (USHORT)(MAC_WCID_BASE + Index * 8), MAC_Value, 8);
2312 }
2313}
2314#endif // RT2870 //
2315
2316 // Add radio off control
2317#ifdef CONFIG_STA_SUPPORT
2318 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2319 {
2320 if (pAd->StaCfg.bRadio == FALSE)
2321 {
2322// RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x00001818);
2323 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
2324 DBGPRINT(RT_DEBUG_TRACE, ("Set Radio Off\n"));
2325 }
2326 }
2327#endif // CONFIG_STA_SUPPORT //
2328
2329 // Clear raw counters
2330 RTMP_IO_READ32(pAd, RX_STA_CNT0, &Counter);
2331 RTMP_IO_READ32(pAd, RX_STA_CNT1, &Counter);
2332 RTMP_IO_READ32(pAd, RX_STA_CNT2, &Counter);
2333 RTMP_IO_READ32(pAd, TX_STA_CNT0, &Counter);
2334 RTMP_IO_READ32(pAd, TX_STA_CNT1, &Counter);
2335 RTMP_IO_READ32(pAd, TX_STA_CNT2, &Counter);
2336
2337 // ASIC will keep garbage value after boot
2338 // Clear all seared key table when initial
2339 // This routine can be ignored in radio-ON/OFF operation.
2340 if (bHardReset)
2341 {
2342 for (KeyIdx = 0; KeyIdx < 4; KeyIdx++)
2343 {
2344 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4*KeyIdx, 0);
2345 }
2346
2347 // Clear all pairwise key table when initial
2348 for (KeyIdx = 0; KeyIdx < 256; KeyIdx++)
2349 {
2350 RTMP_IO_WRITE32(pAd, MAC_WCID_ATTRIBUTE_BASE + (KeyIdx * HW_WCID_ATTRI_SIZE), 1);
2351 }
2352 }
2353
2354 // assert HOST ready bit
2355// RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x0); // 2004-09-14 asked by Mark
2356// RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x4);
2357
2358 // It isn't necessary to clear this space when not hard reset.
2359 if (bHardReset == TRUE)
2360 {
2361 // clear all on-chip BEACON frame space
2362 for (apidx = 0; apidx < HW_BEACON_MAX_COUNT; apidx++)
2363 {
2364 for (i = 0; i < HW_BEACON_OFFSET>>2; i+=4)
2365 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[apidx] + i, 0x00);
2366 }
2367 }
2368#ifdef RT2870
2369 AsicDisableSync(pAd);
2370 // Clear raw counters
2371 RTMP_IO_READ32(pAd, RX_STA_CNT0, &Counter);
2372 RTMP_IO_READ32(pAd, RX_STA_CNT1, &Counter);
2373 RTMP_IO_READ32(pAd, RX_STA_CNT2, &Counter);
2374 RTMP_IO_READ32(pAd, TX_STA_CNT0, &Counter);
2375 RTMP_IO_READ32(pAd, TX_STA_CNT1, &Counter);
2376 RTMP_IO_READ32(pAd, TX_STA_CNT2, &Counter);
2377 // Default PCI clock cycle per ms is different as default setting, which is based on PCI.
2378 RTMP_IO_READ32(pAd, USB_CYC_CFG, &Counter);
2379 Counter&=0xffffff00;
2380 Counter|=0x000001e;
2381 RTMP_IO_WRITE32(pAd, USB_CYC_CFG, Counter);
2382#endif // RT2870 //
2383#ifdef RT30xx
2384 pAd->bUseEfuse=FALSE;
2385 RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrl);
2386 pAd->bUseEfuse = ( (eFuseCtrl & 0x80000000) == 0x80000000) ? 1 : 0;
2387 if(pAd->bUseEfuse)
2388 {
2389 DBGPRINT(RT_DEBUG_TRACE, ("NVM is Efuse\n"));
2390 }
2391 else
2392 {
2393 DBGPRINT(RT_DEBUG_TRACE, ("NVM is EEPROM\n"));
2394
2395 }
2396#endif // RT30xx //
2397
2398#ifdef CONFIG_STA_SUPPORT
2399 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2400 {
2401 // for rt2860E and after, init TXOP_CTRL_CFG with 0x583f. This is for extension channel overlapping IOT.
2402 if ((pAd->MACVersion&0xffff) != 0x0101)
2403 RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x583f);
2404 }
2405#endif // CONFIG_STA_SUPPORT //
2406
2407 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitializeAsic\n"));
2408 return NDIS_STATUS_SUCCESS;
2409}
2410
2411/*
2412 ========================================================================
2413
2414 Routine Description:
2415 Reset NIC Asics
2416
2417 Arguments:
2418 Adapter Pointer to our adapter
2419
2420 Return Value:
2421 None
2422
2423 IRQL = PASSIVE_LEVEL
2424
2425 Note:
2426 Reset NIC to initial state AS IS system boot up time.
2427
2428 ========================================================================
2429*/
2430VOID NICIssueReset(
2431 IN PRTMP_ADAPTER pAd)
2432{
2433 UINT32 Value = 0;
2434 DBGPRINT(RT_DEBUG_TRACE, ("--> NICIssueReset\n"));
2435
2436 // Abort Tx, prevent ASIC from writing to Host memory
2437 //RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x001f0000);
2438
2439 // Disable Rx, register value supposed will remain after reset
2440 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
2441 Value &= (0xfffffff3);
2442 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
2443
2444 // Issue reset and clear from reset state
2445 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x03); // 2004-09-17 change from 0x01
2446 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x00);
2447
2448 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICIssueReset\n"));
2449}
2450
2451/*
2452 ========================================================================
2453
2454 Routine Description:
2455 Check ASIC registers and find any reason the system might hang
2456
2457 Arguments:
2458 Adapter Pointer to our adapter
2459
2460 Return Value:
2461 None
2462
2463 IRQL = DISPATCH_LEVEL
2464
2465 ========================================================================
2466*/
2467BOOLEAN NICCheckForHang(
2468 IN PRTMP_ADAPTER pAd)
2469{
2470 return (FALSE);
2471}
2472
2473VOID NICUpdateFifoStaCounters(
2474 IN PRTMP_ADAPTER pAd)
2475{
2476 TX_STA_FIFO_STRUC StaFifo;
2477 MAC_TABLE_ENTRY *pEntry;
2478 UCHAR i = 0;
2479 UCHAR pid = 0, wcid = 0;
2480 CHAR reTry;
2481 UCHAR succMCS;
2482
2483#ifdef RALINK_ATE
2484 /* Nothing to do in ATE mode */
2485 if (ATE_ON(pAd))
2486 return;
2487#endif // RALINK_ATE //
2488
2489 do
2490 {
2491 RTMP_IO_READ32(pAd, TX_STA_FIFO, &StaFifo.word);
2492
2493 if (StaFifo.field.bValid == 0)
2494 break;
2495
2496 wcid = (UCHAR)StaFifo.field.wcid;
2497
2498
2499 /* ignore NoACK and MGMT frame use 0xFF as WCID */
2500 if ((StaFifo.field.TxAckRequired == 0) || (wcid >= MAX_LEN_OF_MAC_TABLE))
2501 {
2502 i++;
2503 continue;
2504 }
2505
2506 /* PID store Tx MCS Rate */
2507 pid = (UCHAR)StaFifo.field.PidType;
2508
2509 pEntry = &pAd->MacTab.Content[wcid];
2510
2511 pEntry->DebugFIFOCount++;
2512
2513#ifdef DOT11_N_SUPPORT
2514 if (StaFifo.field.TxBF) // 3*3
2515 pEntry->TxBFCount++;
2516#endif // DOT11_N_SUPPORT //
2517
2518#ifdef UAPSD_AP_SUPPORT
2519 UAPSD_SP_AUE_Handle(pAd, pEntry, StaFifo.field.TxSuccess);
2520#endif // UAPSD_AP_SUPPORT //
2521
2522 if (!StaFifo.field.TxSuccess)
2523 {
2524 pEntry->FIFOCount++;
2525 pEntry->OneSecTxFailCount++;
2526
2527 if (pEntry->FIFOCount >= 1)
2528 {
2529 DBGPRINT(RT_DEBUG_TRACE, ("#"));
2530#ifdef DOT11_N_SUPPORT
2531 pEntry->NoBADataCountDown = 64;
2532#endif // DOT11_N_SUPPORT //
2533
2534 if(pEntry->PsMode == PWR_ACTIVE)
2535 {
2536#ifdef DOT11_N_SUPPORT
2537 int tid;
2538 for (tid=0; tid<NUM_OF_TID; tid++)
2539 {
2540 BAOriSessionTearDown(pAd, pEntry->Aid, tid, FALSE, FALSE);
2541 }
2542#endif // DOT11_N_SUPPORT //
2543
2544 // Update the continuous transmission counter except PS mode
2545 pEntry->ContinueTxFailCnt++;
2546 }
2547 else
2548 {
2549 // Clear the FIFOCount when sta in Power Save mode. Basically we assume
2550 // this tx error happened due to sta just go to sleep.
2551 pEntry->FIFOCount = 0;
2552 pEntry->ContinueTxFailCnt = 0;
2553 }
2554 //pEntry->FIFOCount = 0;
2555 }
2556 //pEntry->bSendBAR = TRUE;
2557 }
2558 else
2559 {
2560#ifdef DOT11_N_SUPPORT
2561 if ((pEntry->PsMode != PWR_SAVE) && (pEntry->NoBADataCountDown > 0))
2562 {
2563 pEntry->NoBADataCountDown--;
2564 if (pEntry->NoBADataCountDown==0)
2565 {
2566 DBGPRINT(RT_DEBUG_TRACE, ("@\n"));
2567 }
2568 }
2569#endif // DOT11_N_SUPPORT //
2570 pEntry->FIFOCount = 0;
2571 pEntry->OneSecTxNoRetryOkCount++;
2572 // update NoDataIdleCount when sucessful send packet to STA.
2573 pEntry->NoDataIdleCount = 0;
2574 pEntry->ContinueTxFailCnt = 0;
2575 }
2576
2577 succMCS = StaFifo.field.SuccessRate & 0x7F;
2578
2579 reTry = pid - succMCS;
2580
2581 if (StaFifo.field.TxSuccess)
2582 {
2583 pEntry->TXMCSExpected[pid]++;
2584 if (pid == succMCS)
2585 {
2586 pEntry->TXMCSSuccessful[pid]++;
2587 }
2588 else
2589 {
2590 pEntry->TXMCSAutoFallBack[pid][succMCS]++;
2591 }
2592 }
2593 else
2594 {
2595 pEntry->TXMCSFailed[pid]++;
2596 }
2597
2598 if (reTry > 0)
2599 {
2600 if ((pid >= 12) && succMCS <=7)
2601 {
2602 reTry -= 4;
2603 }
2604 pEntry->OneSecTxRetryOkCount += reTry;
2605 }
2606
2607 i++;
2608 // ASIC store 16 stack
2609 } while ( i < (2*TX_RING_SIZE) );
2610
2611}
2612
2613/*
2614 ========================================================================
2615
2616 Routine Description:
2617 Read statistical counters from hardware registers and record them
2618 in software variables for later on query
2619
2620 Arguments:
2621 pAd Pointer to our adapter
2622
2623 Return Value:
2624 None
2625
2626 IRQL = DISPATCH_LEVEL
2627
2628 ========================================================================
2629*/
2630VOID NICUpdateRawCounters(
2631 IN PRTMP_ADAPTER pAd)
2632{
2633 UINT32 OldValue;//, Value2;
2634 //ULONG PageSum, OneSecTransmitCount;
2635 //ULONG TxErrorRatio, Retry, Fail;
2636 RX_STA_CNT0_STRUC RxStaCnt0;
2637 RX_STA_CNT1_STRUC RxStaCnt1;
2638 RX_STA_CNT2_STRUC RxStaCnt2;
2639 TX_STA_CNT0_STRUC TxStaCnt0;
2640 TX_STA_CNT1_STRUC StaTx1;
2641 TX_STA_CNT2_STRUC StaTx2;
2642 TX_AGG_CNT_STRUC TxAggCnt;
2643 TX_AGG_CNT0_STRUC TxAggCnt0;
2644 TX_AGG_CNT1_STRUC TxAggCnt1;
2645 TX_AGG_CNT2_STRUC TxAggCnt2;
2646 TX_AGG_CNT3_STRUC TxAggCnt3;
2647 TX_AGG_CNT4_STRUC TxAggCnt4;
2648 TX_AGG_CNT5_STRUC TxAggCnt5;
2649 TX_AGG_CNT6_STRUC TxAggCnt6;
2650 TX_AGG_CNT7_STRUC TxAggCnt7;
2651
2652 RTMP_IO_READ32(pAd, RX_STA_CNT0, &RxStaCnt0.word);
2653 RTMP_IO_READ32(pAd, RX_STA_CNT2, &RxStaCnt2.word);
2654
2655 {
2656 RTMP_IO_READ32(pAd, RX_STA_CNT1, &RxStaCnt1.word);
2657 // Update RX PLCP error counter
2658 pAd->PrivateInfo.PhyRxErrCnt += RxStaCnt1.field.PlcpErr;
2659 // Update False CCA counter
2660 pAd->RalinkCounters.OneSecFalseCCACnt += RxStaCnt1.field.FalseCca;
2661 }
2662
2663 // Update FCS counters
2664 OldValue= pAd->WlanCounters.FCSErrorCount.u.LowPart;
2665 pAd->WlanCounters.FCSErrorCount.u.LowPart += (RxStaCnt0.field.CrcErr); // >> 7);
2666 if (pAd->WlanCounters.FCSErrorCount.u.LowPart < OldValue)
2667 pAd->WlanCounters.FCSErrorCount.u.HighPart++;
2668
2669 // Add FCS error count to private counters
2670 pAd->RalinkCounters.OneSecRxFcsErrCnt += RxStaCnt0.field.CrcErr;
2671 OldValue = pAd->RalinkCounters.RealFcsErrCount.u.LowPart;
2672 pAd->RalinkCounters.RealFcsErrCount.u.LowPart += RxStaCnt0.field.CrcErr;
2673 if (pAd->RalinkCounters.RealFcsErrCount.u.LowPart < OldValue)
2674 pAd->RalinkCounters.RealFcsErrCount.u.HighPart++;
2675
2676 // Update Duplicate Rcv check
2677 pAd->RalinkCounters.DuplicateRcv += RxStaCnt2.field.RxDupliCount;
2678 pAd->WlanCounters.FrameDuplicateCount.u.LowPart += RxStaCnt2.field.RxDupliCount;
2679 // Update RX Overflow counter
2680 pAd->Counters8023.RxNoBuffer += (RxStaCnt2.field.RxFifoOverflowCount);
2681
2682 //pAd->RalinkCounters.RxCount = 0;
2683#ifdef RT2870
2684 if (pAd->RalinkCounters.RxCount != pAd->watchDogRxCnt)
2685 {
2686 pAd->watchDogRxCnt = pAd->RalinkCounters.RxCount;
2687 pAd->watchDogRxOverFlowCnt = 0;
2688 }
2689 else
2690 {
2691 if (RxStaCnt2.field.RxFifoOverflowCount)
2692 pAd->watchDogRxOverFlowCnt++;
2693 else
2694 pAd->watchDogRxOverFlowCnt = 0;
2695 }
2696#endif // RT2870 //
2697
2698
2699 //if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) ||
2700 // (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) && (pAd->MacTab.Size != 1)))
2701 if (!pAd->bUpdateBcnCntDone)
2702 {
2703 // Update BEACON sent count
2704 RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
2705 RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
2706 RTMP_IO_READ32(pAd, TX_STA_CNT2, &StaTx2.word);
2707 pAd->RalinkCounters.OneSecBeaconSentCnt += TxStaCnt0.field.TxBeaconCount;
2708 pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
2709 pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
2710 pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
2711 pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
2712 pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
2713 pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
2714 }
2715
2716 //if (pAd->bStaFifoTest == TRUE)
2717 {
2718 RTMP_IO_READ32(pAd, TX_AGG_CNT, &TxAggCnt.word);
2719 RTMP_IO_READ32(pAd, TX_AGG_CNT0, &TxAggCnt0.word);
2720 RTMP_IO_READ32(pAd, TX_AGG_CNT1, &TxAggCnt1.word);
2721 RTMP_IO_READ32(pAd, TX_AGG_CNT2, &TxAggCnt2.word);
2722 RTMP_IO_READ32(pAd, TX_AGG_CNT3, &TxAggCnt3.word);
2723 RTMP_IO_READ32(pAd, TX_AGG_CNT4, &TxAggCnt4.word);
2724 RTMP_IO_READ32(pAd, TX_AGG_CNT5, &TxAggCnt5.word);
2725 RTMP_IO_READ32(pAd, TX_AGG_CNT6, &TxAggCnt6.word);
2726 RTMP_IO_READ32(pAd, TX_AGG_CNT7, &TxAggCnt7.word);
2727 pAd->RalinkCounters.TxAggCount += TxAggCnt.field.AggTxCount;
2728 pAd->RalinkCounters.TxNonAggCount += TxAggCnt.field.NonAggTxCount;
2729 pAd->RalinkCounters.TxAgg1MPDUCount += TxAggCnt0.field.AggSize1Count;
2730 pAd->RalinkCounters.TxAgg2MPDUCount += TxAggCnt0.field.AggSize2Count;
2731
2732 pAd->RalinkCounters.TxAgg3MPDUCount += TxAggCnt1.field.AggSize3Count;
2733 pAd->RalinkCounters.TxAgg4MPDUCount += TxAggCnt1.field.AggSize4Count;
2734 pAd->RalinkCounters.TxAgg5MPDUCount += TxAggCnt2.field.AggSize5Count;
2735 pAd->RalinkCounters.TxAgg6MPDUCount += TxAggCnt2.field.AggSize6Count;
2736
2737 pAd->RalinkCounters.TxAgg7MPDUCount += TxAggCnt3.field.AggSize7Count;
2738 pAd->RalinkCounters.TxAgg8MPDUCount += TxAggCnt3.field.AggSize8Count;
2739 pAd->RalinkCounters.TxAgg9MPDUCount += TxAggCnt4.field.AggSize9Count;
2740 pAd->RalinkCounters.TxAgg10MPDUCount += TxAggCnt4.field.AggSize10Count;
2741
2742 pAd->RalinkCounters.TxAgg11MPDUCount += TxAggCnt5.field.AggSize11Count;
2743 pAd->RalinkCounters.TxAgg12MPDUCount += TxAggCnt5.field.AggSize12Count;
2744 pAd->RalinkCounters.TxAgg13MPDUCount += TxAggCnt6.field.AggSize13Count;
2745 pAd->RalinkCounters.TxAgg14MPDUCount += TxAggCnt6.field.AggSize14Count;
2746
2747 pAd->RalinkCounters.TxAgg15MPDUCount += TxAggCnt7.field.AggSize15Count;
2748 pAd->RalinkCounters.TxAgg16MPDUCount += TxAggCnt7.field.AggSize16Count;
2749
2750 // Calculate the transmitted A-MPDU count
2751 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += TxAggCnt0.field.AggSize1Count;
2752 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt0.field.AggSize2Count / 2);
2753
2754 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt1.field.AggSize3Count / 3);
2755 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt1.field.AggSize4Count / 4);
2756
2757 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt2.field.AggSize5Count / 5);
2758 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt2.field.AggSize6Count / 6);
2759
2760 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt3.field.AggSize7Count / 7);
2761 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt3.field.AggSize8Count / 8);
2762
2763 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt4.field.AggSize9Count / 9);
2764 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt4.field.AggSize10Count / 10);
2765
2766 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt5.field.AggSize11Count / 11);
2767 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt5.field.AggSize12Count / 12);
2768
2769 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt6.field.AggSize13Count / 13);
2770 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt6.field.AggSize14Count / 14);
2771
2772 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt7.field.AggSize15Count / 15);
2773 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt7.field.AggSize16Count / 16);
2774 }
2775
2776#ifdef DBG_DIAGNOSE
2777 {
2778 RtmpDiagStruct *pDiag;
2779 COUNTER_RALINK *pRalinkCounters;
2780 UCHAR ArrayCurIdx, i;
2781
2782 pDiag = &pAd->DiagStruct;
2783 pRalinkCounters = &pAd->RalinkCounters;
2784 ArrayCurIdx = pDiag->ArrayCurIdx;
2785
2786 if (pDiag->inited == 0)
2787 {
2788 NdisZeroMemory(pDiag, sizeof(struct _RtmpDiagStrcut_));
2789 pDiag->ArrayStartIdx = pDiag->ArrayCurIdx = 0;
2790 pDiag->inited = 1;
2791 }
2792 else
2793 {
2794 // Tx
2795 pDiag->TxFailCnt[ArrayCurIdx] = TxStaCnt0.field.TxFailCount;
2796 pDiag->TxAggCnt[ArrayCurIdx] = TxAggCnt.field.AggTxCount;
2797 pDiag->TxNonAggCnt[ArrayCurIdx] = TxAggCnt.field.NonAggTxCount;
2798 pDiag->TxAMPDUCnt[ArrayCurIdx][0] = TxAggCnt0.field.AggSize1Count;
2799 pDiag->TxAMPDUCnt[ArrayCurIdx][1] = TxAggCnt0.field.AggSize2Count;
2800 pDiag->TxAMPDUCnt[ArrayCurIdx][2] = TxAggCnt1.field.AggSize3Count;
2801 pDiag->TxAMPDUCnt[ArrayCurIdx][3] = TxAggCnt1.field.AggSize4Count;
2802 pDiag->TxAMPDUCnt[ArrayCurIdx][4] = TxAggCnt2.field.AggSize5Count;
2803 pDiag->TxAMPDUCnt[ArrayCurIdx][5] = TxAggCnt2.field.AggSize6Count;
2804 pDiag->TxAMPDUCnt[ArrayCurIdx][6] = TxAggCnt3.field.AggSize7Count;
2805 pDiag->TxAMPDUCnt[ArrayCurIdx][7] = TxAggCnt3.field.AggSize8Count;
2806 pDiag->TxAMPDUCnt[ArrayCurIdx][8] = TxAggCnt4.field.AggSize9Count;
2807 pDiag->TxAMPDUCnt[ArrayCurIdx][9] = TxAggCnt4.field.AggSize10Count;
2808 pDiag->TxAMPDUCnt[ArrayCurIdx][10] = TxAggCnt5.field.AggSize11Count;
2809 pDiag->TxAMPDUCnt[ArrayCurIdx][11] = TxAggCnt5.field.AggSize12Count;
2810 pDiag->TxAMPDUCnt[ArrayCurIdx][12] = TxAggCnt6.field.AggSize13Count;
2811 pDiag->TxAMPDUCnt[ArrayCurIdx][13] = TxAggCnt6.field.AggSize14Count;
2812 pDiag->TxAMPDUCnt[ArrayCurIdx][14] = TxAggCnt7.field.AggSize15Count;
2813 pDiag->TxAMPDUCnt[ArrayCurIdx][15] = TxAggCnt7.field.AggSize16Count;
2814
2815 pDiag->RxCrcErrCnt[ArrayCurIdx] = RxStaCnt0.field.CrcErr;
2816
2817 INC_RING_INDEX(pDiag->ArrayCurIdx, DIAGNOSE_TIME);
2818 ArrayCurIdx = pDiag->ArrayCurIdx;
2819 for (i =0; i < 9; i++)
2820 {
2821 pDiag->TxDescCnt[ArrayCurIdx][i]= 0;
2822 pDiag->TxSWQueCnt[ArrayCurIdx][i] =0;
2823 pDiag->TxMcsCnt[ArrayCurIdx][i] = 0;
2824 pDiag->RxMcsCnt[ArrayCurIdx][i] = 0;
2825 }
2826 pDiag->TxDataCnt[ArrayCurIdx] = 0;
2827 pDiag->TxFailCnt[ArrayCurIdx] = 0;
2828 pDiag->RxDataCnt[ArrayCurIdx] = 0;
2829 pDiag->RxCrcErrCnt[ArrayCurIdx] = 0;
2830// for (i = 9; i < 16; i++)
2831 for (i = 9; i < 24; i++) // 3*3
2832 {
2833 pDiag->TxDescCnt[ArrayCurIdx][i] = 0;
2834 pDiag->TxMcsCnt[ArrayCurIdx][i] = 0;
2835 pDiag->RxMcsCnt[ArrayCurIdx][i] = 0;
2836}
2837
2838 if (pDiag->ArrayCurIdx == pDiag->ArrayStartIdx)
2839 INC_RING_INDEX(pDiag->ArrayStartIdx, DIAGNOSE_TIME);
2840 }
2841
2842 }
2843#endif // DBG_DIAGNOSE //
2844
2845
2846}
2847
2848
2849/*
2850 ========================================================================
2851
2852 Routine Description:
2853 Reset NIC from error
2854
2855 Arguments:
2856 Adapter Pointer to our adapter
2857
2858 Return Value:
2859 None
2860
2861 IRQL = PASSIVE_LEVEL
2862
2863 Note:
2864 Reset NIC from error state
2865
2866 ========================================================================
2867*/
2868VOID NICResetFromError(
2869 IN PRTMP_ADAPTER pAd)
2870{
2871 // Reset BBP (according to alex, reset ASIC will force reset BBP
2872 // Therefore, skip the reset BBP
2873 // RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x2);
2874
2875 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1);
2876 // Remove ASIC from reset state
2877 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
2878
2879 NICInitializeAdapter(pAd, FALSE);
2880 NICInitAsicFromEEPROM(pAd);
2881
2882 // Switch to current channel, since during reset process, the connection should remains on.
2883 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
2884 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
2885}
2886
2887/*
2888 ========================================================================
2889
2890 Routine Description:
2891 erase 8051 firmware image in MAC ASIC
2892
2893 Arguments:
2894 Adapter Pointer to our adapter
2895
2896 IRQL = PASSIVE_LEVEL
2897
2898 ========================================================================
2899*/
2900VOID NICEraseFirmware(
2901 IN PRTMP_ADAPTER pAd)
2902{
2903 ULONG i;
2904
2905 for(i=0; i<MAX_FIRMWARE_IMAGE_SIZE; i+=4)
2906 RTMP_IO_WRITE32(pAd, FIRMWARE_IMAGE_BASE + i, 0);
2907
2908}/* End of NICEraseFirmware */
2909
2910/*
2911 ========================================================================
2912
2913 Routine Description:
2914 Load 8051 firmware RT2561.BIN file into MAC ASIC
2915
2916 Arguments:
2917 Adapter Pointer to our adapter
2918
2919 Return Value:
2920 NDIS_STATUS_SUCCESS firmware image load ok
2921 NDIS_STATUS_FAILURE image not found
2922
2923 IRQL = PASSIVE_LEVEL
2924
2925 ========================================================================
2926*/
2927NDIS_STATUS NICLoadFirmware(
2928 IN PRTMP_ADAPTER pAd)
2929{
2930#ifdef BIN_IN_FILE
2931#define NICLF_DEFAULT_USE() \
2932 flg_default_firm_use = TRUE; \
2933 printk("%s - Use default firmware!\n", __FUNCTION__);
2934
2935 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
2936 PUCHAR src;
2937 struct file *srcf;
2938 INT retval, orgfsuid, orgfsgid, i;
2939 mm_segment_t orgfs;
2940 PUCHAR pFirmwareImage;
2941 UINT FileLength = 0;
2942 UINT32 MacReg;
2943 ULONG Index;
2944 ULONG firm;
2945 BOOLEAN flg_default_firm_use = FALSE;
2946
2947
2948 DBGPRINT(RT_DEBUG_TRACE, ("===> %s\n", __FUNCTION__));
2949
2950 /* init */
2951 pFirmwareImage = NULL;
2952 src = RTMP_FIRMWARE_FILE_NAME;
2953
2954 /* save uid and gid used for filesystem access.
2955 set user and group to 0 (root) */
2956 orgfsuid = current->fsuid;
2957 orgfsgid = current->fsgid;
2958 current->fsuid = current->fsgid = 0;
2959 orgfs = get_fs();
2960 set_fs(KERNEL_DS);
2961
2962 pAd->FirmwareVersion = (FIRMWARE_MAJOR_VERSION << 8) + \
2963 FIRMWARE_MINOR_VERSION;
2964
2965
2966 /* allocate firmware buffer */
2967 pFirmwareImage = kmalloc(MAX_FIRMWARE_IMAGE_SIZE, MEM_ALLOC_FLAG);
2968 if (pFirmwareImage == NULL)
2969 {
2970 /* allocate fail, use default firmware array in firmware.h */
2971 printk("%s - Allocate memory fail!\n", __FUNCTION__);
2972 NICLF_DEFAULT_USE();
2973 }
2974 else
2975 {
2976 /* allocate ok! zero the firmware buffer */
2977 memset(pFirmwareImage, 0x00, MAX_FIRMWARE_IMAGE_SIZE);
2978 } /* End of if */
2979
2980
2981 /* if ok, read firmware file from *.bin file */
2982 if (flg_default_firm_use == FALSE)
2983 {
2984 do
2985 {
2986 /* open the bin file */
2987 srcf = filp_open(src, O_RDONLY, 0);
2988
2989 if (IS_ERR(srcf))
2990 {
2991 printk("%s - Error %ld opening %s\n",
2992 __FUNCTION__, -PTR_ERR(srcf), src);
2993 NICLF_DEFAULT_USE();
2994 break;
2995 } /* End of if */
2996
2997 /* the object must have a read method */
2998 if ((srcf->f_op == NULL) || (srcf->f_op->read == NULL))
2999 {
3000 printk("%s - %s does not have a write method\n", __FUNCTION__, src);
3001 NICLF_DEFAULT_USE();
3002 break;
3003 } /* End of if */
3004
3005 /* read the firmware from the file *.bin */
3006 FileLength = srcf->f_op->read(srcf,
3007 pFirmwareImage,
3008 MAX_FIRMWARE_IMAGE_SIZE,
3009 &srcf->f_pos);
3010
3011 if (FileLength != MAX_FIRMWARE_IMAGE_SIZE)
3012 {
3013 printk("%s: error file length (=%d) in RT2860AP.BIN\n",
3014 __FUNCTION__, FileLength);
3015 NICLF_DEFAULT_USE();
3016 break;
3017 }
3018 else
3019 {
3020 PUCHAR ptr = pFirmwareImage;
3021 USHORT crc = 0xffff;
3022
3023
3024 /* calculate firmware CRC */
3025 for(i=0; i<(MAX_FIRMWARE_IMAGE_SIZE-2); i++, ptr++)
3026 crc = ByteCRC16(BitReverse(*ptr), crc);
3027 /* End of for */
3028
3029 if ((pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-2] != \
3030 (UCHAR)BitReverse((UCHAR)(crc>>8))) ||
3031 (pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-1] != \
3032 (UCHAR)BitReverse((UCHAR)crc)))
3033 {
3034 /* CRC fail */
3035 printk("%s: CRC = 0x%02x 0x%02x "
3036 "error, should be 0x%02x 0x%02x\n",
3037 __FUNCTION__,
3038 pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-2],
3039 pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-1],
3040 (UCHAR)(crc>>8), (UCHAR)(crc));
3041 NICLF_DEFAULT_USE();
3042 break;
3043 }
3044 else
3045 {
3046 /* firmware is ok */
3047 pAd->FirmwareVersion = \
3048 (pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-4] << 8) +
3049 pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-3];
3050
3051 /* check if firmware version of the file is too old */
3052 if ((pAd->FirmwareVersion) < \
3053 ((FIRMWARE_MAJOR_VERSION << 8) +
3054 FIRMWARE_MINOR_VERSION))
3055 {
3056 printk("%s: firmware version too old!\n", __FUNCTION__);
3057 NICLF_DEFAULT_USE();
3058 break;
3059 } /* End of if */
3060 } /* End of if */
3061
3062 DBGPRINT(RT_DEBUG_TRACE,
3063 ("NICLoadFirmware: CRC ok, ver=%d.%d\n",
3064 pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-4],
3065 pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-3]));
3066 } /* End of if (FileLength == MAX_FIRMWARE_IMAGE_SIZE) */
3067 break;
3068 } while(TRUE);
3069
3070 /* close firmware file */
3071 if (IS_ERR(srcf))
3072 ;
3073 else
3074 {
3075 retval = filp_close(srcf, NULL);
3076 if (retval)
3077 {
3078 DBGPRINT(RT_DEBUG_ERROR,
3079 ("--> Error %d closing %s\n", -retval, src));
3080 } /* End of if */
3081 } /* End of if */
3082 } /* End of if */
3083
3084
3085 /* write firmware to ASIC */
3086 if (flg_default_firm_use == TRUE)
3087 {
3088 /* use default fimeware, free allocated buffer */
3089 if (pFirmwareImage != NULL)
3090 kfree(pFirmwareImage);
3091 /* End of if */
3092
3093 /* use default *.bin array */
3094 pFirmwareImage = FirmwareImage;
3095 FileLength = sizeof(FirmwareImage);
3096 } /* End of if */
3097
3098 /* enable Host program ram write selection */
3099 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x10000);
3100
3101 for(i=0; i<FileLength; i+=4)
3102 {
3103 firm = pFirmwareImage[i] +
3104 (pFirmwareImage[i+3] << 24) +
3105 (pFirmwareImage[i+2] << 16) +
3106 (pFirmwareImage[i+1] << 8);
3107
3108 RTMP_IO_WRITE32(pAd, FIRMWARE_IMAGE_BASE + i, firm);
3109 } /* End of for */
3110
3111 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x00000);
3112 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x00001);
3113
3114 /* initialize BBP R/W access agent */
3115 RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, 0);
3116 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, 0);
3117
3118 if (flg_default_firm_use == FALSE)
3119 {
3120 /* use file firmware, free allocated buffer */
3121 if (pFirmwareImage != NULL)
3122 kfree(pFirmwareImage);
3123 /* End of if */
3124 } /* End of if */
3125
3126 set_fs(orgfs);
3127 current->fsuid = orgfsuid;
3128 current->fsgid = orgfsgid;
3129#else
3130
3131 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
3132 PUCHAR pFirmwareImage;
3133 ULONG FileLength, Index;
3134 //ULONG firm;
3135 UINT32 MacReg = 0;
3136 UINT32 Version = (pAd->MACVersion >> 16);
3137
3138 pFirmwareImage = FirmwareImage;
3139 FileLength = sizeof(FirmwareImage);
3140
3141 // New 8k byte firmware size for RT3071/RT3072
3142 //printk("Usb Chip\n");
3143 if (FIRMWAREIMAGE_LENGTH == FIRMWAREIMAGE_MAX_LENGTH)
3144 //The firmware image consists of two parts. One is the origianl and the other is the new.
3145 //Use Second Part
3146 {
3147#ifdef RT2870
3148 if ((Version != 0x2860) && (Version != 0x2872) && (Version != 0x3070))
3149 { // Use Firmware V2.
3150 //printk("KH:Use New Version,part2\n");
3151 pFirmwareImage = (PUCHAR)&FirmwareImage[FIRMWAREIMAGEV1_LENGTH];
3152 FileLength = FIRMWAREIMAGEV2_LENGTH;
3153 }
3154 else
3155 {
3156 //printk("KH:Use New Version,part1\n");
3157 pFirmwareImage = FirmwareImage;
3158 FileLength = FIRMWAREIMAGEV1_LENGTH;
3159 }
3160#endif // RT2870 //
3161 }
3162 else
3163 {
3164 DBGPRINT(RT_DEBUG_ERROR, ("KH: bin file should be 8KB.\n"));
3165 Status = NDIS_STATUS_FAILURE;
3166 }
3167
3168 RT28XX_WRITE_FIRMWARE(pAd, pFirmwareImage, FileLength);
3169
3170#endif
3171
3172 /* check if MCU is ready */
3173 Index = 0;
3174 do
3175 {
3176 RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacReg);
3177
3178 if (MacReg & 0x80)
3179 break;
3180
3181 RTMPusecDelay(1000);
3182 } while (Index++ < 1000);
3183
3184 if (Index >= 1000)
3185 {
3186 Status = NDIS_STATUS_FAILURE;
3187 DBGPRINT(RT_DEBUG_ERROR, ("NICLoadFirmware: MCU is not ready\n\n\n"));
3188 } /* End of if */
3189
3190 DBGPRINT(RT_DEBUG_TRACE,
3191 ("<=== %s (status=%d)\n", __FUNCTION__, Status));
3192 return Status;
3193} /* End of NICLoadFirmware */
3194
3195
3196/*
3197 ========================================================================
3198
3199 Routine Description:
3200 Load Tx rate switching parameters
3201
3202 Arguments:
3203 Adapter Pointer to our adapter
3204
3205 Return Value:
3206 NDIS_STATUS_SUCCESS firmware image load ok
3207 NDIS_STATUS_FAILURE image not found
3208
3209 IRQL = PASSIVE_LEVEL
3210
3211 Rate Table Format:
3212 1. (B0: Valid Item number) (B1:Initial item from zero)
3213 2. Item Number(Dec) Mode(Hex) Current MCS(Dec) TrainUp(Dec) TrainDown(Dec)
3214
3215 ========================================================================
3216*/
3217NDIS_STATUS NICLoadRateSwitchingParams(
3218 IN PRTMP_ADAPTER pAd)
3219{
3220 return NDIS_STATUS_SUCCESS;
3221}
3222
3223/*
3224 ========================================================================
3225
3226 Routine Description:
3227 if pSrc1 all zero with length Length, return 0.
3228 If not all zero, return 1
3229
3230 Arguments:
3231 pSrc1
3232
3233 Return Value:
3234 1: not all zero
3235 0: all zero
3236
3237 IRQL = DISPATCH_LEVEL
3238
3239 Note:
3240
3241 ========================================================================
3242*/
3243ULONG RTMPNotAllZero(
3244 IN PVOID pSrc1,
3245 IN ULONG Length)
3246{
3247 PUCHAR pMem1;
3248 ULONG Index = 0;
3249
3250 pMem1 = (PUCHAR) pSrc1;
3251
3252 for (Index = 0; Index < Length; Index++)
3253 {
3254 if (pMem1[Index] != 0x0)
3255 {
3256 break;
3257 }
3258 }
3259
3260 if (Index == Length)
3261 {
3262 return (0);
3263 }
3264 else
3265 {
3266 return (1);
3267 }
3268}
3269
3270/*
3271 ========================================================================
3272
3273 Routine Description:
3274 Compare two memory block
3275
3276 Arguments:
3277 pSrc1 Pointer to first memory address
3278 pSrc2 Pointer to second memory address
3279
3280 Return Value:
3281 0: memory is equal
3282 1: pSrc1 memory is larger
3283 2: pSrc2 memory is larger
3284
3285 IRQL = DISPATCH_LEVEL
3286
3287 Note:
3288
3289 ========================================================================
3290*/
3291ULONG RTMPCompareMemory(
3292 IN PVOID pSrc1,
3293 IN PVOID pSrc2,
3294 IN ULONG Length)
3295{
3296 PUCHAR pMem1;
3297 PUCHAR pMem2;
3298 ULONG Index = 0;
3299
3300 pMem1 = (PUCHAR) pSrc1;
3301 pMem2 = (PUCHAR) pSrc2;
3302
3303 for (Index = 0; Index < Length; Index++)
3304 {
3305 if (pMem1[Index] > pMem2[Index])
3306 return (1);
3307 else if (pMem1[Index] < pMem2[Index])
3308 return (2);
3309 }
3310
3311 // Equal
3312 return (0);
3313}
3314
3315/*
3316 ========================================================================
3317
3318 Routine Description:
3319 Zero out memory block
3320
3321 Arguments:
3322 pSrc1 Pointer to memory address
3323 Length Size
3324
3325 Return Value:
3326 None
3327
3328 IRQL = PASSIVE_LEVEL
3329 IRQL = DISPATCH_LEVEL
3330
3331 Note:
3332
3333 ========================================================================
3334*/
3335VOID RTMPZeroMemory(
3336 IN PVOID pSrc,
3337 IN ULONG Length)
3338{
3339 PUCHAR pMem;
3340 ULONG Index = 0;
3341
3342 pMem = (PUCHAR) pSrc;
3343
3344 for (Index = 0; Index < Length; Index++)
3345 {
3346 pMem[Index] = 0x00;
3347 }
3348}
3349
3350VOID RTMPFillMemory(
3351 IN PVOID pSrc,
3352 IN ULONG Length,
3353 IN UCHAR Fill)
3354{
3355 PUCHAR pMem;
3356 ULONG Index = 0;
3357
3358 pMem = (PUCHAR) pSrc;
3359
3360 for (Index = 0; Index < Length; Index++)
3361 {
3362 pMem[Index] = Fill;
3363 }
3364}
3365
3366/*
3367 ========================================================================
3368
3369 Routine Description:
3370 Copy data from memory block 1 to memory block 2
3371
3372 Arguments:
3373 pDest Pointer to destination memory address
3374 pSrc Pointer to source memory address
3375 Length Copy size
3376
3377 Return Value:
3378 None
3379
3380 IRQL = PASSIVE_LEVEL
3381 IRQL = DISPATCH_LEVEL
3382
3383 Note:
3384
3385 ========================================================================
3386*/
3387VOID RTMPMoveMemory(
3388 OUT PVOID pDest,
3389 IN PVOID pSrc,
3390 IN ULONG Length)
3391{
3392 PUCHAR pMem1;
3393 PUCHAR pMem2;
3394 UINT Index;
3395
3396 ASSERT((Length==0) || (pDest && pSrc));
3397
3398 pMem1 = (PUCHAR) pDest;
3399 pMem2 = (PUCHAR) pSrc;
3400
3401 for (Index = 0; Index < Length; Index++)
3402 {
3403 pMem1[Index] = pMem2[Index];
3404 }
3405}
3406
3407/*
3408 ========================================================================
3409
3410 Routine Description:
3411 Initialize port configuration structure
3412
3413 Arguments:
3414 Adapter Pointer to our adapter
3415
3416 Return Value:
3417 None
3418
3419 IRQL = PASSIVE_LEVEL
3420
3421 Note:
3422
3423 ========================================================================
3424*/
3425VOID UserCfgInit(
3426 IN PRTMP_ADAPTER pAd)
3427{
3428// EDCA_PARM DefaultEdcaParm;
3429 UINT key_index, bss_index;
3430
3431 DBGPRINT(RT_DEBUG_TRACE, ("--> UserCfgInit\n"));
3432
3433 //
3434 // part I. intialize common configuration
3435 //
3436#ifdef RT2870
3437 pAd->BulkOutReq = 0;
3438
3439 pAd->BulkOutComplete = 0;
3440 pAd->BulkOutCompleteOther = 0;
3441 pAd->BulkOutCompleteCancel = 0;
3442 pAd->BulkInReq = 0;
3443 pAd->BulkInComplete = 0;
3444 pAd->BulkInCompleteFail = 0;
3445
3446 //pAd->QuickTimerP = 100;
3447 //pAd->TurnAggrBulkInCount = 0;
3448 pAd->bUsbTxBulkAggre = 0;
3449
3450 // init as unsed value to ensure driver will set to MCU once.
3451 pAd->LedIndicatorStregth = 0xFF;
3452
3453 pAd->CommonCfg.MaxPktOneTxBulk = 2;
3454 pAd->CommonCfg.TxBulkFactor = 1;
3455 pAd->CommonCfg.RxBulkFactor =1;
3456
3457 pAd->CommonCfg.TxPower = 100; //mW
3458
3459 NdisZeroMemory(&pAd->CommonCfg.IOTestParm, sizeof(pAd->CommonCfg.IOTestParm));
3460#endif // RT2870 //
3461
3462 for(key_index=0; key_index<SHARE_KEY_NUM; key_index++)
3463 {
3464 for(bss_index = 0; bss_index < MAX_MBSSID_NUM; bss_index++)
3465 {
3466 pAd->SharedKey[bss_index][key_index].KeyLen = 0;
3467 pAd->SharedKey[bss_index][key_index].CipherAlg = CIPHER_NONE;
3468 } /* End of for */
3469 } /* End of for */
3470
3471 pAd->EepromAccess = FALSE;
3472
3473 pAd->Antenna.word = 0;
3474 pAd->CommonCfg.BBPCurrentBW = BW_20;
3475
3476 pAd->LedCntl.word = 0;
3477
3478 pAd->bAutoTxAgcA = FALSE; // Default is OFF
3479 pAd->bAutoTxAgcG = FALSE; // Default is OFF
3480 pAd->RfIcType = RFIC_2820;
3481
3482 // Init timer for reset complete event
3483 pAd->CommonCfg.CentralChannel = 1;
3484 pAd->bForcePrintTX = FALSE;
3485 pAd->bForcePrintRX = FALSE;
3486 pAd->bStaFifoTest = FALSE;
3487 pAd->bProtectionTest = FALSE;
3488 pAd->bHCCATest = FALSE;
3489 pAd->bGenOneHCCA = FALSE;
3490 pAd->CommonCfg.Dsifs = 10; // in units of usec
3491 pAd->CommonCfg.TxPower = 100; //mW
3492 pAd->CommonCfg.TxPowerPercentage = 0xffffffff; // AUTO
3493 pAd->CommonCfg.TxPowerDefault = 0xffffffff; // AUTO
3494 pAd->CommonCfg.TxPreamble = Rt802_11PreambleAuto; // use Long preamble on TX by defaut
3495 pAd->CommonCfg.bUseZeroToDisableFragment = FALSE;
3496 pAd->CommonCfg.RtsThreshold = 2347;
3497 pAd->CommonCfg.FragmentThreshold = 2346;
3498 pAd->CommonCfg.UseBGProtection = 0; // 0: AUTO
3499 pAd->CommonCfg.bEnableTxBurst = TRUE; //0;
3500 pAd->CommonCfg.PhyMode = 0xff; // unknown
3501 pAd->CommonCfg.BandState = UNKNOWN_BAND;
3502 pAd->CommonCfg.RadarDetect.CSPeriod = 10;
3503 pAd->CommonCfg.RadarDetect.CSCount = 0;
3504 pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
3505 pAd->CommonCfg.RadarDetect.ChMovingTime = 65;
3506 pAd->CommonCfg.RadarDetect.LongPulseRadarTh = 3;
3507 pAd->CommonCfg.bAPSDCapable = FALSE;
3508 pAd->CommonCfg.bNeedSendTriggerFrame = FALSE;
3509 pAd->CommonCfg.TriggerTimerCount = 0;
3510 pAd->CommonCfg.bAPSDForcePowerSave = FALSE;
3511 pAd->CommonCfg.bCountryFlag = FALSE;
3512 pAd->CommonCfg.TxStream = 0;
3513 pAd->CommonCfg.RxStream = 0;
3514
3515 NdisZeroMemory(&pAd->BeaconTxWI, sizeof(pAd->BeaconTxWI));
3516
3517#ifdef DOT11_N_SUPPORT
3518 NdisZeroMemory(&pAd->CommonCfg.HtCapability, sizeof(pAd->CommonCfg.HtCapability));
3519 pAd->HTCEnable = FALSE;
3520 pAd->bBroadComHT = FALSE;
3521 pAd->CommonCfg.bRdg = FALSE;
3522
3523#ifdef DOT11N_DRAFT3
3524 pAd->CommonCfg.Dot11OBssScanPassiveDwell = dot11OBSSScanPassiveDwell; // Unit : TU. 5~1000
3525 pAd->CommonCfg.Dot11OBssScanActiveDwell = dot11OBSSScanActiveDwell; // Unit : TU. 10~1000
3526 pAd->CommonCfg.Dot11BssWidthTriggerScanInt = dot11BSSWidthTriggerScanInterval; // Unit : Second
3527 pAd->CommonCfg.Dot11OBssScanPassiveTotalPerChannel = dot11OBSSScanPassiveTotalPerChannel; // Unit : TU. 200~10000
3528 pAd->CommonCfg.Dot11OBssScanActiveTotalPerChannel = dot11OBSSScanActiveTotalPerChannel; // Unit : TU. 20~10000
3529 pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor = dot11BSSWidthChannelTransactionDelayFactor;
3530 pAd->CommonCfg.Dot11OBssScanActivityThre = dot11BSSScanActivityThreshold; // Unit : percentage
3531 pAd->CommonCfg.Dot11BssWidthChanTranDelay = (pAd->CommonCfg.Dot11BssWidthTriggerScanInt * pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor);
3532#endif // DOT11N_DRAFT3 //
3533
3534 NdisZeroMemory(&pAd->CommonCfg.AddHTInfo, sizeof(pAd->CommonCfg.AddHTInfo));
3535 pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
3536 pAd->CommonCfg.BACapability.field.MpduDensity = 0;
3537 pAd->CommonCfg.BACapability.field.Policy = IMMED_BA;
3538 pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64; //32;
3539 pAd->CommonCfg.BACapability.field.TxBAWinLimit = 64; //32;
3540 DBGPRINT(RT_DEBUG_TRACE, ("--> UserCfgInit. BACapability = 0x%x\n", pAd->CommonCfg.BACapability.word));
3541
3542 pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
3543 BATableInit(pAd, &pAd->BATable);
3544
3545 pAd->CommonCfg.bExtChannelSwitchAnnouncement = 1;
3546 pAd->CommonCfg.bHTProtect = 1;
3547 pAd->CommonCfg.bMIMOPSEnable = TRUE;
3548 pAd->CommonCfg.bBADecline = FALSE;
3549 pAd->CommonCfg.bDisableReordering = FALSE;
3550
3551 pAd->CommonCfg.TxBASize = 7;
3552
3553 pAd->CommonCfg.REGBACapability.word = pAd->CommonCfg.BACapability.word;
3554#endif // DOT11_N_SUPPORT //
3555
3556 //pAd->CommonCfg.HTPhyMode.field.BW = BW_20;
3557 //pAd->CommonCfg.HTPhyMode.field.MCS = MCS_AUTO;
3558 //pAd->CommonCfg.HTPhyMode.field.ShortGI = GI_800;
3559 //pAd->CommonCfg.HTPhyMode.field.STBC = STBC_NONE;
3560 pAd->CommonCfg.TxRate = RATE_6;
3561
3562 pAd->CommonCfg.MlmeTransmit.field.MCS = MCS_RATE_6;
3563 pAd->CommonCfg.MlmeTransmit.field.BW = BW_20;
3564 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
3565
3566 pAd->CommonCfg.BeaconPeriod = 100; // in mSec
3567
3568 //
3569 // part II. intialize STA specific configuration
3570 //
3571#ifdef CONFIG_STA_SUPPORT
3572 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3573 {
3574 RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_DIRECT);
3575 RX_FILTER_CLEAR_FLAG(pAd, fRX_FILTER_ACCEPT_MULTICAST);
3576 RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_BROADCAST);
3577 RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_ALL_MULTICAST);
3578
3579 pAd->StaCfg.Psm = PWR_ACTIVE;
3580
3581 pAd->StaCfg.OrigWepStatus = Ndis802_11EncryptionDisabled;
3582 pAd->StaCfg.PairCipher = Ndis802_11EncryptionDisabled;
3583 pAd->StaCfg.GroupCipher = Ndis802_11EncryptionDisabled;
3584 pAd->StaCfg.bMixCipher = FALSE;
3585 pAd->StaCfg.DefaultKeyId = 0;
3586
3587 // 802.1x port control
3588 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
3589 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
3590 pAd->StaCfg.LastMicErrorTime = 0;
3591 pAd->StaCfg.MicErrCnt = 0;
3592 pAd->StaCfg.bBlockAssoc = FALSE;
3593 pAd->StaCfg.WpaState = SS_NOTUSE;
3594
3595 pAd->CommonCfg.NdisRadioStateOff = FALSE; // New to support microsoft disable radio with OID command
3596
3597 pAd->StaCfg.RssiTrigger = 0;
3598 NdisZeroMemory(&pAd->StaCfg.RssiSample, sizeof(RSSI_SAMPLE));
3599 pAd->StaCfg.RssiTriggerMode = RSSI_TRIGGERED_UPON_BELOW_THRESHOLD;
3600 pAd->StaCfg.AtimWin = 0;
3601 pAd->StaCfg.DefaultListenCount = 3;//default listen count;
3602 pAd->StaCfg.BssType = BSS_INFRA; // BSS_INFRA or BSS_ADHOC or BSS_MONITOR
3603 pAd->StaCfg.bScanReqIsFromWebUI = FALSE;
3604 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
3605 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WAKEUP_NOW);
3606
3607 pAd->StaCfg.bAutoTxRateSwitch = TRUE;
3608 pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
3609 }
3610
3611#ifdef EXT_BUILD_CHANNEL_LIST
3612 pAd->StaCfg.IEEE80211dClientMode = Rt802_11_D_None;
3613#endif // EXT_BUILD_CHANNEL_LIST //
3614#endif // CONFIG_STA_SUPPORT //
3615
3616 // global variables mXXXX used in MAC protocol state machines
3617 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
3618 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
3619 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
3620
3621 // PHY specification
3622 pAd->CommonCfg.PhyMode = PHY_11BG_MIXED; // default PHY mode
3623 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED); // CCK use LONG preamble
3624
3625#ifdef CONFIG_STA_SUPPORT
3626 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3627 {
3628 // user desired power mode
3629 pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
3630 pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
3631 pAd->StaCfg.bWindowsACCAMEnable = FALSE;
3632
3633#ifdef LEAP_SUPPORT
3634 // CCX v1.0 releated init value
3635 RTMPInitTimer(pAd, &pAd->StaCfg.LeapAuthTimer, GET_TIMER_FUNCTION(LeapAuthTimeout), pAd, FALSE);
3636 pAd->StaCfg.LeapAuthMode = CISCO_AuthModeLEAPNone;
3637 pAd->StaCfg.bCkipOn = FALSE;
3638#endif // LEAP_SUPPORT //
3639
3640 RTMPInitTimer(pAd, &pAd->StaCfg.StaQuickResponeForRateUpTimer, GET_TIMER_FUNCTION(StaQuickResponeForRateUpExec), pAd, FALSE);
3641 pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE;
3642
3643 // Patch for Ndtest
3644 pAd->StaCfg.ScanCnt = 0;
3645
3646 // CCX 2.0 control flag init
3647 pAd->StaCfg.CCXEnable = FALSE;
3648 pAd->StaCfg.CCXReqType = MSRN_TYPE_UNUSED;
3649 pAd->StaCfg.CCXQosECWMin = 4;
3650 pAd->StaCfg.CCXQosECWMax = 10;
3651
3652 pAd->StaCfg.bHwRadio = TRUE; // Default Hardware Radio status is On
3653 pAd->StaCfg.bSwRadio = TRUE; // Default Software Radio status is On
3654 pAd->StaCfg.bRadio = TRUE; // bHwRadio && bSwRadio
3655 pAd->StaCfg.bHardwareRadio = FALSE; // Default is OFF
3656 pAd->StaCfg.bShowHiddenSSID = FALSE; // Default no show
3657
3658 // Nitro mode control
3659 pAd->StaCfg.bAutoReconnect = TRUE;
3660
3661 // Save the init time as last scan time, the system should do scan after 2 seconds.
3662 // This patch is for driver wake up from standby mode, system will do scan right away.
3663 pAd->StaCfg.LastScanTime = 0;
3664 NdisZeroMemory(pAd->nickname, IW_ESSID_MAX_SIZE+1);
3665 sprintf(pAd->nickname, "%s", STA_NIC_DEVICE_NAME);
3666 RTMPInitTimer(pAd, &pAd->StaCfg.WpaDisassocAndBlockAssocTimer, GET_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc), pAd, FALSE);
3667#ifdef WPA_SUPPLICANT_SUPPORT
3668 pAd->StaCfg.IEEE8021X = FALSE;
3669 pAd->StaCfg.IEEE8021x_required_keys = FALSE;
3670 pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
3671#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
3672 pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE;
3673#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
3674#endif // WPA_SUPPLICANT_SUPPORT //
3675
3676 }
3677#endif // CONFIG_STA_SUPPORT //
3678
3679 // Default for extra information is not valid
3680 pAd->ExtraInfo = EXTRA_INFO_CLEAR;
3681
3682 // Default Config change flag
3683 pAd->bConfigChanged = FALSE;
3684
3685 //
3686 // part III. AP configurations
3687 //
3688
3689
3690 //
3691 // part IV. others
3692 //
3693 // dynamic BBP R66:sensibity tuning to overcome background noise
3694 pAd->BbpTuning.bEnable = TRUE;
3695 pAd->BbpTuning.FalseCcaLowerThreshold = 100;
3696 pAd->BbpTuning.FalseCcaUpperThreshold = 512;
3697 pAd->BbpTuning.R66Delta = 4;
3698 pAd->Mlme.bEnableAutoAntennaCheck = TRUE;
3699
3700 //
3701 // Also initial R66CurrentValue, RTUSBResumeMsduTransmission might use this value.
3702 // if not initial this value, the default value will be 0.
3703 //
3704 pAd->BbpTuning.R66CurrentValue = 0x38;
3705
3706 pAd->Bbp94 = BBPR94_DEFAULT;
3707 pAd->BbpForCCK = FALSE;
3708
3709 // Default is FALSE for test bit 1
3710 //pAd->bTest1 = FALSE;
3711
3712 // initialize MAC table and allocate spin lock
3713 NdisZeroMemory(&pAd->MacTab, sizeof(MAC_TABLE));
3714 InitializeQueueHeader(&pAd->MacTab.McastPsQueue);
3715 NdisAllocateSpinLock(&pAd->MacTabLock);
3716
3717 //RTMPInitTimer(pAd, &pAd->RECBATimer, RECBATimerTimeout, pAd, TRUE);
3718 //RTMPSetTimer(&pAd->RECBATimer, REORDER_EXEC_INTV);
3719
3720#ifdef RALINK_ATE
3721 NdisZeroMemory(&pAd->ate, sizeof(ATE_INFO));
3722 pAd->ate.Mode = ATE_STOP;
3723 pAd->ate.TxCount = 200;/* to exceed TX_RING_SIZE ... */
3724 pAd->ate.TxLength = 1024;
3725 pAd->ate.TxWI.ShortGI = 0;// LONG GI : 800 ns
3726 pAd->ate.TxWI.PHYMODE = MODE_CCK;
3727 pAd->ate.TxWI.MCS = 3;
3728 pAd->ate.TxWI.BW = BW_20;
3729 pAd->ate.Channel = 1;
3730 pAd->ate.QID = QID_AC_BE;
3731 pAd->ate.Addr1[0] = 0x00;
3732 pAd->ate.Addr1[1] = 0x11;
3733 pAd->ate.Addr1[2] = 0x22;
3734 pAd->ate.Addr1[3] = 0xAA;
3735 pAd->ate.Addr1[4] = 0xBB;
3736 pAd->ate.Addr1[5] = 0xCC;
3737 NdisMoveMemory(pAd->ate.Addr2, pAd->ate.Addr1, ETH_LENGTH_OF_ADDRESS);
3738 NdisMoveMemory(pAd->ate.Addr3, pAd->ate.Addr1, ETH_LENGTH_OF_ADDRESS);
3739 pAd->ate.bRxFer = 0;
3740 pAd->ate.bQATxStart = FALSE;
3741 pAd->ate.bQARxStart = FALSE;
3742#ifdef RALINK_28xx_QA
3743 //pAd->ate.Repeat = 0;
3744 pAd->ate.TxStatus = 0;
3745 pAd->ate.AtePid = 0;
3746#endif // RALINK_28xx_QA //
3747#endif // RALINK_ATE //
3748
3749
3750 pAd->CommonCfg.bWiFiTest = FALSE;
3751
3752
3753 DBGPRINT(RT_DEBUG_TRACE, ("<-- UserCfgInit\n"));
3754}
3755
3756// IRQL = PASSIVE_LEVEL
3757UCHAR BtoH(char ch)
3758{
3759 if (ch >= '0' && ch <= '9') return (ch - '0'); // Handle numerals
3760 if (ch >= 'A' && ch <= 'F') return (ch - 'A' + 0xA); // Handle capitol hex digits
3761 if (ch >= 'a' && ch <= 'f') return (ch - 'a' + 0xA); // Handle small hex digits
3762 return(255);
3763}
3764
3765//
3766// FUNCTION: AtoH(char *, UCHAR *, int)
3767//
3768// PURPOSE: Converts ascii string to network order hex
3769//
3770// PARAMETERS:
3771// src - pointer to input ascii string
3772// dest - pointer to output hex
3773// destlen - size of dest
3774//
3775// COMMENTS:
3776//
3777// 2 ascii bytes make a hex byte so must put 1st ascii byte of pair
3778// into upper nibble and 2nd ascii byte of pair into lower nibble.
3779//
3780// IRQL = PASSIVE_LEVEL
3781
3782void AtoH(char * src, UCHAR * dest, int destlen)
3783{
3784 char * srcptr;
3785 PUCHAR destTemp;
3786
3787 srcptr = src;
3788 destTemp = (PUCHAR) dest;
3789
3790 while(destlen--)
3791 {
3792 *destTemp = BtoH(*srcptr++) << 4; // Put 1st ascii byte in upper nibble.
3793 *destTemp += BtoH(*srcptr++); // Add 2nd ascii byte to above.
3794 destTemp++;
3795 }
3796}
3797
3798VOID RTMPPatchMacBbpBug(
3799 IN PRTMP_ADAPTER pAd)
3800{
3801 ULONG Index;
3802
3803 // Initialize BBP register to default value
3804 for (Index = 0; Index < NUM_BBP_REG_PARMS; Index++)
3805 {
3806 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[Index].Register, (UCHAR)BBPRegTable[Index].Value);
3807 }
3808
3809 // Initialize RF register to default value
3810 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
3811 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
3812
3813 // Re-init BBP register from EEPROM value
3814 NICInitAsicFromEEPROM(pAd);
3815}
3816
3817/*
3818 ========================================================================
3819
3820 Routine Description:
3821 Init timer objects
3822
3823 Arguments:
3824 pAd Pointer to our adapter
3825 pTimer Timer structure
3826 pTimerFunc Function to execute when timer expired
3827 Repeat Ture for period timer
3828
3829 Return Value:
3830 None
3831
3832 Note:
3833
3834 ========================================================================
3835*/
3836VOID RTMPInitTimer(
3837 IN PRTMP_ADAPTER pAd,
3838 IN PRALINK_TIMER_STRUCT pTimer,
3839 IN PVOID pTimerFunc,
3840 IN PVOID pData,
3841 IN BOOLEAN Repeat)
3842{
3843 //
3844 // Set Valid to TRUE for later used.
3845 // It will crash if we cancel a timer or set a timer
3846 // that we haven't initialize before.
3847 //
3848 pTimer->Valid = TRUE;
3849
3850 pTimer->PeriodicType = Repeat;
3851 pTimer->State = FALSE;
3852 pTimer->cookie = (ULONG) pData;
3853
3854#ifdef RT2870
3855 pTimer->pAd = pAd;
3856#endif // RT2870 //
3857
3858 RTMP_OS_Init_Timer(pAd, &pTimer->TimerObj, pTimerFunc, (PVOID) pTimer);
3859}
3860
3861/*
3862 ========================================================================
3863
3864 Routine Description:
3865 Init timer objects
3866
3867 Arguments:
3868 pTimer Timer structure
3869 Value Timer value in milliseconds
3870
3871 Return Value:
3872 None
3873
3874 Note:
3875 To use this routine, must call RTMPInitTimer before.
3876
3877 ========================================================================
3878*/
3879VOID RTMPSetTimer(
3880 IN PRALINK_TIMER_STRUCT pTimer,
3881 IN ULONG Value)
3882{
3883 if (pTimer->Valid)
3884 {
3885 pTimer->TimerValue = Value;
3886 pTimer->State = FALSE;
3887 if (pTimer->PeriodicType == TRUE)
3888 {
3889 pTimer->Repeat = TRUE;
3890 RTMP_SetPeriodicTimer(&pTimer->TimerObj, Value);
3891 }
3892 else
3893 {
3894 pTimer->Repeat = FALSE;
3895 RTMP_OS_Add_Timer(&pTimer->TimerObj, Value);
3896 }
3897 }
3898 else
3899 {
3900 DBGPRINT_ERR(("RTMPSetTimer failed, Timer hasn't been initialize!\n"));
3901 }
3902}
3903
3904
3905/*
3906 ========================================================================
3907
3908 Routine Description:
3909 Init timer objects
3910
3911 Arguments:
3912 pTimer Timer structure
3913 Value Timer value in milliseconds
3914
3915 Return Value:
3916 None
3917
3918 Note:
3919 To use this routine, must call RTMPInitTimer before.
3920
3921 ========================================================================
3922*/
3923VOID RTMPModTimer(
3924 IN PRALINK_TIMER_STRUCT pTimer,
3925 IN ULONG Value)
3926{
3927 BOOLEAN Cancel;
3928
3929 if (pTimer->Valid)
3930 {
3931 pTimer->TimerValue = Value;
3932 pTimer->State = FALSE;
3933 if (pTimer->PeriodicType == TRUE)
3934 {
3935 RTMPCancelTimer(pTimer, &Cancel);
3936 RTMPSetTimer(pTimer, Value);
3937 }
3938 else
3939 {
3940 RTMP_OS_Mod_Timer(&pTimer->TimerObj, Value);
3941 }
3942 }
3943 else
3944 {
3945 DBGPRINT_ERR(("RTMPModTimer failed, Timer hasn't been initialize!\n"));
3946 }
3947}
3948
3949/*
3950 ========================================================================
3951
3952 Routine Description:
3953 Cancel timer objects
3954
3955 Arguments:
3956 Adapter Pointer to our adapter
3957
3958 Return Value:
3959 None
3960
3961 IRQL = PASSIVE_LEVEL
3962 IRQL = DISPATCH_LEVEL
3963
3964 Note:
3965 1.) To use this routine, must call RTMPInitTimer before.
3966 2.) Reset NIC to initial state AS IS system boot up time.
3967
3968 ========================================================================
3969*/
3970VOID RTMPCancelTimer(
3971 IN PRALINK_TIMER_STRUCT pTimer,
3972 OUT BOOLEAN *pCancelled)
3973{
3974 if (pTimer->Valid)
3975 {
3976 if (pTimer->State == FALSE)
3977 pTimer->Repeat = FALSE;
3978 RTMP_OS_Del_Timer(&pTimer->TimerObj, pCancelled);
3979
3980 if (*pCancelled == TRUE)
3981 pTimer->State = TRUE;
3982
3983#ifdef RT2870
3984 // We need to go-through the TimerQ to findout this timer handler and remove it if
3985 // it's still waiting for execution.
3986
3987 RT2870_TimerQ_Remove(pTimer->pAd, pTimer);
3988#endif // RT2870 //
3989 }
3990 else
3991 {
3992 //
3993 // NdisMCancelTimer just canced the timer and not mean release the timer.
3994 // And don't set the "Valid" to False. So that we can use this timer again.
3995 //
3996 DBGPRINT_ERR(("RTMPCancelTimer failed, Timer hasn't been initialize!\n"));
3997 }
3998}
3999
4000/*
4001 ========================================================================
4002
4003 Routine Description:
4004 Set LED Status
4005
4006 Arguments:
4007 pAd Pointer to our adapter
4008 Status LED Status
4009
4010 Return Value:
4011 None
4012
4013 IRQL = PASSIVE_LEVEL
4014 IRQL = DISPATCH_LEVEL
4015
4016 Note:
4017
4018 ========================================================================
4019*/
4020VOID RTMPSetLED(
4021 IN PRTMP_ADAPTER pAd,
4022 IN UCHAR Status)
4023{
4024 //ULONG data;
4025 UCHAR HighByte = 0;
4026 UCHAR LowByte;
4027
4028// In ATE mode of RT2860 AP/STA, we have erased 8051 firmware.
4029// So LED mode is not supported when ATE is running.
4030#ifdef RALINK_ATE
4031 if (ATE_ON(pAd))
4032 return;
4033#endif // RALINK_ATE //
4034
4035 LowByte = pAd->LedCntl.field.LedMode&0x7f;
4036 switch (Status)
4037 {
4038 case LED_LINK_DOWN:
4039 HighByte = 0x20;
4040 AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
4041 pAd->LedIndicatorStregth = 0;
4042 break;
4043 case LED_LINK_UP:
4044 if (pAd->CommonCfg.Channel > 14)
4045 HighByte = 0xa0;
4046 else
4047 HighByte = 0x60;
4048 AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
4049 break;
4050 case LED_RADIO_ON:
4051 HighByte = 0x20;
4052 AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
4053 break;
4054 case LED_HALT:
4055 LowByte = 0; // Driver sets MAC register and MAC controls LED
4056 case LED_RADIO_OFF:
4057 HighByte = 0;
4058 AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
4059 break;
4060 case LED_WPS:
4061 HighByte = 0x10;
4062 AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
4063 break;
4064 case LED_ON_SITE_SURVEY:
4065 HighByte = 0x08;
4066 AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
4067 break;
4068 case LED_POWER_UP:
4069 HighByte = 0x04;
4070 AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
4071 break;
4072 default:
4073 DBGPRINT(RT_DEBUG_WARN, ("RTMPSetLED::Unknown Status %d\n", Status));
4074 break;
4075 }
4076
4077 //
4078 // Keep LED status for LED SiteSurvey mode.
4079 // After SiteSurvey, we will set the LED mode to previous status.
4080 //
4081 if ((Status != LED_ON_SITE_SURVEY) && (Status != LED_POWER_UP))
4082 pAd->LedStatus = Status;
4083
4084 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetLED::Mode=%d,HighByte=0x%02x,LowByte=0x%02x\n", pAd->LedCntl.field.LedMode, HighByte, LowByte));
4085}
4086
4087/*
4088 ========================================================================
4089
4090 Routine Description:
4091 Set LED Signal Stregth
4092
4093 Arguments:
4094 pAd Pointer to our adapter
4095 Dbm Signal Stregth
4096
4097 Return Value:
4098 None
4099
4100 IRQL = PASSIVE_LEVEL
4101
4102 Note:
4103 Can be run on any IRQL level.
4104
4105 According to Microsoft Zero Config Wireless Signal Stregth definition as belows.
4106 <= -90 No Signal
4107 <= -81 Very Low
4108 <= -71 Low
4109 <= -67 Good
4110 <= -57 Very Good
4111 > -57 Excellent
4112 ========================================================================
4113*/
4114VOID RTMPSetSignalLED(
4115 IN PRTMP_ADAPTER pAd,
4116 IN NDIS_802_11_RSSI Dbm)
4117{
4118 UCHAR nLed = 0;
4119
4120 //
4121 // if not Signal Stregth, then do nothing.
4122 //
4123 if (pAd->LedCntl.field.LedMode != LED_MODE_SIGNAL_STREGTH)
4124 {
4125 return;
4126 }
4127
4128 if (Dbm <= -90)
4129 nLed = 0;
4130 else if (Dbm <= -81)
4131 nLed = 1;
4132 else if (Dbm <= -71)
4133 nLed = 3;
4134 else if (Dbm <= -67)
4135 nLed = 7;
4136 else if (Dbm <= -57)
4137 nLed = 15;
4138 else
4139 nLed = 31;
4140
4141 //
4142 // Update Signal Stregth to firmware if changed.
4143 //
4144 if (pAd->LedIndicatorStregth != nLed)
4145 {
4146 AsicSendCommandToMcu(pAd, 0x51, 0xff, nLed, pAd->LedCntl.field.Polarity);
4147 pAd->LedIndicatorStregth = nLed;
4148 }
4149}
4150
4151/*
4152 ========================================================================
4153
4154 Routine Description:
4155 Enable RX
4156
4157 Arguments:
4158 pAd Pointer to our adapter
4159
4160 Return Value:
4161 None
4162
4163 IRQL <= DISPATCH_LEVEL
4164
4165 Note:
4166 Before Enable RX, make sure you have enabled Interrupt.
4167 ========================================================================
4168*/
4169VOID RTMPEnableRxTx(
4170 IN PRTMP_ADAPTER pAd)
4171{
4172// WPDMA_GLO_CFG_STRUC GloCfg;
4173// ULONG i = 0;
4174
4175 DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPEnableRxTx\n"));
4176
4177 // Enable Rx DMA.
4178 RT28XXDMAEnable(pAd);
4179
4180 // enable RX of MAC block
4181 if (pAd->OpMode == OPMODE_AP)
4182 {
4183 UINT32 rx_filter_flag = APNORMAL;
4184
4185
4186 RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, rx_filter_flag); // enable RX of DMA block
4187 }
4188 else
4189 {
4190 RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL); // Staion not drop control frame will fail WiFi Certification.
4191 }
4192
4193 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xc);
4194 DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPEnableRxTx\n"));
4195}
4196
4197
diff --git a/drivers/staging/rt3070/common/rtmp_tkip.c b/drivers/staging/rt3070/common/rtmp_tkip.c
new file mode 100644
index 000000000000..bf8986e83679
--- /dev/null
+++ b/drivers/staging/rt3070/common/rtmp_tkip.c
@@ -0,0 +1,1613 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 rtmp_tkip.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Paul Wu 02-25-02 Initial
36*/
37
38#include "../rt_config.h"
39
40// Rotation functions on 32 bit values
41#define ROL32( A, n ) \
42 ( ((A) << (n)) | ( ((A)>>(32-(n))) & ( (1UL << (n)) - 1 ) ) )
43#define ROR32( A, n ) ROL32( (A), 32-(n) )
44
45UINT Tkip_Sbox_Lower[256] =
46{
47 0xA5,0x84,0x99,0x8D,0x0D,0xBD,0xB1,0x54,
48 0x50,0x03,0xA9,0x7D,0x19,0x62,0xE6,0x9A,
49 0x45,0x9D,0x40,0x87,0x15,0xEB,0xC9,0x0B,
50 0xEC,0x67,0xFD,0xEA,0xBF,0xF7,0x96,0x5B,
51 0xC2,0x1C,0xAE,0x6A,0x5A,0x41,0x02,0x4F,
52 0x5C,0xF4,0x34,0x08,0x93,0x73,0x53,0x3F,
53 0x0C,0x52,0x65,0x5E,0x28,0xA1,0x0F,0xB5,
54 0x09,0x36,0x9B,0x3D,0x26,0x69,0xCD,0x9F,
55 0x1B,0x9E,0x74,0x2E,0x2D,0xB2,0xEE,0xFB,
56 0xF6,0x4D,0x61,0xCE,0x7B,0x3E,0x71,0x97,
57 0xF5,0x68,0x00,0x2C,0x60,0x1F,0xC8,0xED,
58 0xBE,0x46,0xD9,0x4B,0xDE,0xD4,0xE8,0x4A,
59 0x6B,0x2A,0xE5,0x16,0xC5,0xD7,0x55,0x94,
60 0xCF,0x10,0x06,0x81,0xF0,0x44,0xBA,0xE3,
61 0xF3,0xFE,0xC0,0x8A,0xAD,0xBC,0x48,0x04,
62 0xDF,0xC1,0x75,0x63,0x30,0x1A,0x0E,0x6D,
63 0x4C,0x14,0x35,0x2F,0xE1,0xA2,0xCC,0x39,
64 0x57,0xF2,0x82,0x47,0xAC,0xE7,0x2B,0x95,
65 0xA0,0x98,0xD1,0x7F,0x66,0x7E,0xAB,0x83,
66 0xCA,0x29,0xD3,0x3C,0x79,0xE2,0x1D,0x76,
67 0x3B,0x56,0x4E,0x1E,0xDB,0x0A,0x6C,0xE4,
68 0x5D,0x6E,0xEF,0xA6,0xA8,0xA4,0x37,0x8B,
69 0x32,0x43,0x59,0xB7,0x8C,0x64,0xD2,0xE0,
70 0xB4,0xFA,0x07,0x25,0xAF,0x8E,0xE9,0x18,
71 0xD5,0x88,0x6F,0x72,0x24,0xF1,0xC7,0x51,
72 0x23,0x7C,0x9C,0x21,0xDD,0xDC,0x86,0x85,
73 0x90,0x42,0xC4,0xAA,0xD8,0x05,0x01,0x12,
74 0xA3,0x5F,0xF9,0xD0,0x91,0x58,0x27,0xB9,
75 0x38,0x13,0xB3,0x33,0xBB,0x70,0x89,0xA7,
76 0xB6,0x22,0x92,0x20,0x49,0xFF,0x78,0x7A,
77 0x8F,0xF8,0x80,0x17,0xDA,0x31,0xC6,0xB8,
78 0xC3,0xB0,0x77,0x11,0xCB,0xFC,0xD6,0x3A
79};
80
81UINT Tkip_Sbox_Upper[256] =
82{
83 0xC6,0xF8,0xEE,0xF6,0xFF,0xD6,0xDE,0x91,
84 0x60,0x02,0xCE,0x56,0xE7,0xB5,0x4D,0xEC,
85 0x8F,0x1F,0x89,0xFA,0xEF,0xB2,0x8E,0xFB,
86 0x41,0xB3,0x5F,0x45,0x23,0x53,0xE4,0x9B,
87 0x75,0xE1,0x3D,0x4C,0x6C,0x7E,0xF5,0x83,
88 0x68,0x51,0xD1,0xF9,0xE2,0xAB,0x62,0x2A,
89 0x08,0x95,0x46,0x9D,0x30,0x37,0x0A,0x2F,
90 0x0E,0x24,0x1B,0xDF,0xCD,0x4E,0x7F,0xEA,
91 0x12,0x1D,0x58,0x34,0x36,0xDC,0xB4,0x5B,
92 0xA4,0x76,0xB7,0x7D,0x52,0xDD,0x5E,0x13,
93 0xA6,0xB9,0x00,0xC1,0x40,0xE3,0x79,0xB6,
94 0xD4,0x8D,0x67,0x72,0x94,0x98,0xB0,0x85,
95 0xBB,0xC5,0x4F,0xED,0x86,0x9A,0x66,0x11,
96 0x8A,0xE9,0x04,0xFE,0xA0,0x78,0x25,0x4B,
97 0xA2,0x5D,0x80,0x05,0x3F,0x21,0x70,0xF1,
98 0x63,0x77,0xAF,0x42,0x20,0xE5,0xFD,0xBF,
99 0x81,0x18,0x26,0xC3,0xBE,0x35,0x88,0x2E,
100 0x93,0x55,0xFC,0x7A,0xC8,0xBA,0x32,0xE6,
101 0xC0,0x19,0x9E,0xA3,0x44,0x54,0x3B,0x0B,
102 0x8C,0xC7,0x6B,0x28,0xA7,0xBC,0x16,0xAD,
103 0xDB,0x64,0x74,0x14,0x92,0x0C,0x48,0xB8,
104 0x9F,0xBD,0x43,0xC4,0x39,0x31,0xD3,0xF2,
105 0xD5,0x8B,0x6E,0xDA,0x01,0xB1,0x9C,0x49,
106 0xD8,0xAC,0xF3,0xCF,0xCA,0xF4,0x47,0x10,
107 0x6F,0xF0,0x4A,0x5C,0x38,0x57,0x73,0x97,
108 0xCB,0xA1,0xE8,0x3E,0x96,0x61,0x0D,0x0F,
109 0xE0,0x7C,0x71,0xCC,0x90,0x06,0xF7,0x1C,
110 0xC2,0x6A,0xAE,0x69,0x17,0x99,0x3A,0x27,
111 0xD9,0xEB,0x2B,0x22,0xD2,0xA9,0x07,0x33,
112 0x2D,0x3C,0x15,0xC9,0x87,0xAA,0x50,0xA5,
113 0x03,0x59,0x09,0x1A,0x65,0xD7,0x84,0xD0,
114 0x82,0x29,0x5A,0x1E,0x7B,0xA8,0x6D,0x2C
115};
116
117/*****************************/
118/******** SBOX Table *********/
119/*****************************/
120
121UCHAR SboxTable[256] =
122{
123 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
124 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
125 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
126 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
127 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
128 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
129 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
130 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
131 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
132 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
133 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
134 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
135 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
136 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
137 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
138 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
139 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
140 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
141 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
142 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
143 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
144 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
145 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
146 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
147 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
148 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
149 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
150 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
151 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
152 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
153 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
154 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
155};
156
157VOID xor_32(
158 IN PUCHAR a,
159 IN PUCHAR b,
160 OUT PUCHAR out);
161
162VOID xor_128(
163 IN PUCHAR a,
164 IN PUCHAR b,
165 OUT PUCHAR out);
166
167VOID next_key(
168 IN PUCHAR key,
169 IN INT round);
170
171VOID byte_sub(
172 IN PUCHAR in,
173 OUT PUCHAR out);
174
175VOID shift_row(
176 IN PUCHAR in,
177 OUT PUCHAR out);
178
179VOID mix_column(
180 IN PUCHAR in,
181 OUT PUCHAR out);
182
183UCHAR RTMPCkipSbox(
184 IN UCHAR a);
185//
186// Expanded IV for TKIP function.
187//
188typedef struct PACKED _IV_CONTROL_
189{
190 union PACKED
191 {
192 struct PACKED
193 {
194 UCHAR rc0;
195 UCHAR rc1;
196 UCHAR rc2;
197
198 union PACKED
199 {
200 struct PACKED
201 {
202#ifdef RT_BIG_ENDIAN
203 UCHAR KeyID:2;
204 UCHAR ExtIV:1;
205 UCHAR Rsvd:5;
206#else
207 UCHAR Rsvd:5;
208 UCHAR ExtIV:1;
209 UCHAR KeyID:2;
210#endif
211 } field;
212 UCHAR Byte;
213 } CONTROL;
214 } field;
215
216 ULONG word;
217 } IV16;
218
219 ULONG IV32;
220} TKIP_IV, *PTKIP_IV;
221
222
223/*
224 ========================================================================
225
226 Routine Description:
227 Convert from UCHAR[] to ULONG in a portable way
228
229 Arguments:
230 pMICKey pointer to MIC Key
231
232 Return Value:
233 None
234
235 Note:
236
237 ========================================================================
238*/
239ULONG RTMPTkipGetUInt32(
240 IN PUCHAR pMICKey)
241{
242 ULONG res = 0;
243 INT i;
244
245 for (i = 0; i < 4; i++)
246 {
247 res |= (*pMICKey++) << (8 * i);
248 }
249
250 return res;
251}
252
253/*
254 ========================================================================
255
256 Routine Description:
257 Convert from ULONG to UCHAR[] in a portable way
258
259 Arguments:
260 pDst pointer to destination for convert ULONG to UCHAR[]
261 val the value for convert
262
263 Return Value:
264 None
265
266 IRQL = DISPATCH_LEVEL
267
268 Note:
269
270 ========================================================================
271*/
272VOID RTMPTkipPutUInt32(
273 IN OUT PUCHAR pDst,
274 IN ULONG val)
275{
276 INT i;
277
278 for(i = 0; i < 4; i++)
279 {
280 *pDst++ = (UCHAR) (val & 0xff);
281 val >>= 8;
282 }
283}
284
285/*
286 ========================================================================
287
288 Routine Description:
289 Set the MIC Key.
290
291 Arguments:
292 pAd Pointer to our adapter
293 pMICKey pointer to MIC Key
294
295 Return Value:
296 None
297
298 IRQL = DISPATCH_LEVEL
299
300 Note:
301
302 ========================================================================
303*/
304VOID RTMPTkipSetMICKey(
305 IN PTKIP_KEY_INFO pTkip,
306 IN PUCHAR pMICKey)
307{
308 // Set the key
309 pTkip->K0 = RTMPTkipGetUInt32(pMICKey);
310 pTkip->K1 = RTMPTkipGetUInt32(pMICKey + 4);
311 // and reset the message
312 pTkip->L = pTkip->K0;
313 pTkip->R = pTkip->K1;
314 pTkip->nBytesInM = 0;
315 pTkip->M = 0;
316}
317
318/*
319 ========================================================================
320
321 Routine Description:
322 Calculate the MIC Value.
323
324 Arguments:
325 pAd Pointer to our adapter
326 uChar Append this uChar
327
328 Return Value:
329 None
330
331 IRQL = DISPATCH_LEVEL
332
333 Note:
334
335 ========================================================================
336*/
337VOID RTMPTkipAppendByte(
338 IN PTKIP_KEY_INFO pTkip,
339 IN UCHAR uChar)
340{
341 // Append the byte to our word-sized buffer
342 pTkip->M |= (uChar << (8* pTkip->nBytesInM));
343 pTkip->nBytesInM++;
344 // Process the word if it is full.
345 if( pTkip->nBytesInM >= 4 )
346 {
347 pTkip->L ^= pTkip->M;
348 pTkip->R ^= ROL32( pTkip->L, 17 );
349 pTkip->L += pTkip->R;
350 pTkip->R ^= ((pTkip->L & 0xff00ff00) >> 8) | ((pTkip->L & 0x00ff00ff) << 8);
351 pTkip->L += pTkip->R;
352 pTkip->R ^= ROL32( pTkip->L, 3 );
353 pTkip->L += pTkip->R;
354 pTkip->R ^= ROR32( pTkip->L, 2 );
355 pTkip->L += pTkip->R;
356 // Clear the buffer
357 pTkip->M = 0;
358 pTkip->nBytesInM = 0;
359 }
360}
361
362/*
363 ========================================================================
364
365 Routine Description:
366 Calculate the MIC Value.
367
368 Arguments:
369 pAd Pointer to our adapter
370 pSrc Pointer to source data for Calculate MIC Value
371 Len Indicate the length of the source data
372
373 Return Value:
374 None
375
376 IRQL = DISPATCH_LEVEL
377
378 Note:
379
380 ========================================================================
381*/
382VOID RTMPTkipAppend(
383 IN PTKIP_KEY_INFO pTkip,
384 IN PUCHAR pSrc,
385 IN UINT nBytes)
386{
387 // This is simple
388 while(nBytes > 0)
389 {
390 RTMPTkipAppendByte(pTkip, *pSrc++);
391 nBytes--;
392 }
393}
394
395/*
396 ========================================================================
397
398 Routine Description:
399 Get the MIC Value.
400
401 Arguments:
402 pAd Pointer to our adapter
403
404 Return Value:
405 None
406
407 IRQL = DISPATCH_LEVEL
408
409 Note:
410 the MIC Value is store in pAd->PrivateInfo.MIC
411 ========================================================================
412*/
413VOID RTMPTkipGetMIC(
414 IN PTKIP_KEY_INFO pTkip)
415{
416 // Append the minimum padding
417 RTMPTkipAppendByte(pTkip, 0x5a );
418 RTMPTkipAppendByte(pTkip, 0 );
419 RTMPTkipAppendByte(pTkip, 0 );
420 RTMPTkipAppendByte(pTkip, 0 );
421 RTMPTkipAppendByte(pTkip, 0 );
422 // and then zeroes until the length is a multiple of 4
423 while( pTkip->nBytesInM != 0 )
424 {
425 RTMPTkipAppendByte(pTkip, 0 );
426 }
427 // The appendByte function has already computed the result.
428 RTMPTkipPutUInt32(pTkip->MIC, pTkip->L);
429 RTMPTkipPutUInt32(pTkip->MIC + 4, pTkip->R);
430}
431
432/*
433 ========================================================================
434
435 Routine Description:
436 Init Tkip function.
437
438 Arguments:
439 pAd Pointer to our adapter
440 pTKey Pointer to the Temporal Key (TK), TK shall be 128bits.
441 KeyId TK Key ID
442 pTA Pointer to transmitter address
443 pMICKey pointer to MIC Key
444
445 Return Value:
446 None
447
448 IRQL = DISPATCH_LEVEL
449
450 Note:
451
452 ========================================================================
453*/
454VOID RTMPInitTkipEngine(
455 IN PRTMP_ADAPTER pAd,
456 IN PUCHAR pKey,
457 IN UCHAR KeyId,
458 IN PUCHAR pTA,
459 IN PUCHAR pMICKey,
460 IN PUCHAR pTSC,
461 OUT PULONG pIV16,
462 OUT PULONG pIV32)
463{
464 TKIP_IV tkipIv;
465
466 // Prepare 8 bytes TKIP encapsulation for MPDU
467 NdisZeroMemory(&tkipIv, sizeof(TKIP_IV));
468 tkipIv.IV16.field.rc0 = *(pTSC + 1);
469 tkipIv.IV16.field.rc1 = (tkipIv.IV16.field.rc0 | 0x20) & 0x7f;
470 tkipIv.IV16.field.rc2 = *pTSC;
471 tkipIv.IV16.field.CONTROL.field.ExtIV = 1; // 0: non-extended IV, 1: an extended IV
472 tkipIv.IV16.field.CONTROL.field.KeyID = KeyId;
473// tkipIv.IV32 = *(PULONG)(pTSC + 2);
474 NdisMoveMemory(&tkipIv.IV32, (pTSC + 2), 4); // Copy IV
475
476 *pIV16 = tkipIv.IV16.word;
477 *pIV32 = tkipIv.IV32;
478}
479
480/*
481 ========================================================================
482
483 Routine Description:
484 Init MIC Value calculation function which include set MIC key &
485 calculate first 16 bytes (DA + SA + priority + 0)
486
487 Arguments:
488 pAd Pointer to our adapter
489 pTKey Pointer to the Temporal Key (TK), TK shall be 128bits.
490 pDA Pointer to DA address
491 pSA Pointer to SA address
492 pMICKey pointer to MIC Key
493
494 Return Value:
495 None
496
497 Note:
498
499 ========================================================================
500*/
501VOID RTMPInitMICEngine(
502 IN PRTMP_ADAPTER pAd,
503 IN PUCHAR pKey,
504 IN PUCHAR pDA,
505 IN PUCHAR pSA,
506 IN UCHAR UserPriority,
507 IN PUCHAR pMICKey)
508{
509 ULONG Priority = UserPriority;
510
511 // Init MIC value calculation
512 RTMPTkipSetMICKey(&pAd->PrivateInfo.Tx, pMICKey);
513 // DA
514 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pDA, MAC_ADDR_LEN);
515 // SA
516 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSA, MAC_ADDR_LEN);
517 // Priority + 3 bytes of 0
518 RTMPTkipAppend(&pAd->PrivateInfo.Tx, (PUCHAR)&Priority, 4);
519}
520
521/*
522 ========================================================================
523
524 Routine Description:
525 Compare MIC value of received MSDU
526
527 Arguments:
528 pAd Pointer to our adapter
529 pSrc Pointer to the received Plain text data
530 pDA Pointer to DA address
531 pSA Pointer to SA address
532 pMICKey pointer to MIC Key
533 Len the length of the received plain text data exclude MIC value
534
535 Return Value:
536 TRUE MIC value matched
537 FALSE MIC value mismatched
538
539 IRQL = DISPATCH_LEVEL
540
541 Note:
542
543 ========================================================================
544*/
545BOOLEAN RTMPTkipCompareMICValue(
546 IN PRTMP_ADAPTER pAd,
547 IN PUCHAR pSrc,
548 IN PUCHAR pDA,
549 IN PUCHAR pSA,
550 IN PUCHAR pMICKey,
551 IN UCHAR UserPriority,
552 IN UINT Len)
553{
554 UCHAR OldMic[8];
555 ULONG Priority = UserPriority;
556
557 // Init MIC value calculation
558 RTMPTkipSetMICKey(&pAd->PrivateInfo.Rx, pMICKey);
559 // DA
560 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pDA, MAC_ADDR_LEN);
561 // SA
562 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSA, MAC_ADDR_LEN);
563 // Priority + 3 bytes of 0
564 RTMPTkipAppend(&pAd->PrivateInfo.Rx, (PUCHAR)&Priority, 4);
565
566 // Calculate MIC value from plain text data
567 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSrc, Len);
568
569 // Get MIC valude from received frame
570 NdisMoveMemory(OldMic, pSrc + Len, 8);
571
572 // Get MIC value from decrypted plain data
573 RTMPTkipGetMIC(&pAd->PrivateInfo.Rx);
574
575 // Move MIC value from MSDU, this steps should move to data path.
576 // Since the MIC value might cross MPDUs.
577 if(!NdisEqualMemory(pAd->PrivateInfo.Rx.MIC, OldMic, 8))
578 {
579 DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTMPTkipCompareMICValue(): TKIP MIC Error !\n")); //MIC error.
580
581
582 return (FALSE);
583 }
584 return (TRUE);
585}
586
587/*
588 ========================================================================
589
590 Routine Description:
591 Compare MIC value of received MSDU
592
593 Arguments:
594 pAd Pointer to our adapter
595 pLLC LLC header
596 pSrc Pointer to the received Plain text data
597 pDA Pointer to DA address
598 pSA Pointer to SA address
599 pMICKey pointer to MIC Key
600 Len the length of the received plain text data exclude MIC value
601
602 Return Value:
603 TRUE MIC value matched
604 FALSE MIC value mismatched
605
606 IRQL = DISPATCH_LEVEL
607
608 Note:
609
610 ========================================================================
611*/
612BOOLEAN RTMPTkipCompareMICValueWithLLC(
613 IN PRTMP_ADAPTER pAd,
614 IN PUCHAR pLLC,
615 IN PUCHAR pSrc,
616 IN PUCHAR pDA,
617 IN PUCHAR pSA,
618 IN PUCHAR pMICKey,
619 IN UINT Len)
620{
621 UCHAR OldMic[8];
622 ULONG Priority = 0;
623
624 // Init MIC value calculation
625 RTMPTkipSetMICKey(&pAd->PrivateInfo.Rx, pMICKey);
626 // DA
627 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pDA, MAC_ADDR_LEN);
628 // SA
629 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSA, MAC_ADDR_LEN);
630 // Priority + 3 bytes of 0
631 RTMPTkipAppend(&pAd->PrivateInfo.Rx, (PUCHAR)&Priority, 4);
632
633 // Start with LLC header
634 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pLLC, 8);
635
636 // Calculate MIC value from plain text data
637 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSrc, Len);
638
639 // Get MIC valude from received frame
640 NdisMoveMemory(OldMic, pSrc + Len, 8);
641
642 // Get MIC value from decrypted plain data
643 RTMPTkipGetMIC(&pAd->PrivateInfo.Rx);
644
645 // Move MIC value from MSDU, this steps should move to data path.
646 // Since the MIC value might cross MPDUs.
647 if(!NdisEqualMemory(pAd->PrivateInfo.Rx.MIC, OldMic, 8))
648 {
649 DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTMPTkipCompareMICValueWithLLC(): TKIP MIC Error !\n")); //MIC error.
650
651
652 return (FALSE);
653 }
654 return (TRUE);
655}
656/*
657 ========================================================================
658
659 Routine Description:
660 Copy frame from waiting queue into relative ring buffer and set
661 appropriate ASIC register to kick hardware transmit function
662
663 Arguments:
664 pAd Pointer to our adapter
665 PNDIS_PACKET Pointer to Ndis Packet for MIC calculation
666 pEncap Pointer to LLC encap data
667 LenEncap Total encap length, might be 0 which indicates no encap
668
669 Return Value:
670 None
671
672 IRQL = DISPATCH_LEVEL
673
674 Note:
675
676 ========================================================================
677*/
678VOID RTMPCalculateMICValue(
679 IN PRTMP_ADAPTER pAd,
680 IN PNDIS_PACKET pPacket,
681 IN PUCHAR pEncap,
682 IN PCIPHER_KEY pKey,
683 IN UCHAR apidx)
684{
685 PACKET_INFO PacketInfo;
686 PUCHAR pSrcBufVA;
687 UINT SrcBufLen;
688 PUCHAR pSrc;
689 UCHAR UserPriority;
690 UCHAR vlan_offset = 0;
691
692 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
693
694 UserPriority = RTMP_GET_PACKET_UP(pPacket);
695 pSrc = pSrcBufVA;
696
697 // determine if this is a vlan packet
698 if (((*(pSrc + 12) << 8) + *(pSrc + 13)) == 0x8100)
699 vlan_offset = 4;
700
701#ifdef CONFIG_STA_SUPPORT
702#endif // CONFIG_STA_SUPPORT //
703 {
704 RTMPInitMICEngine(
705 pAd,
706 pKey->Key,
707 pSrc,
708 pSrc + 6,
709 UserPriority,
710 pKey->TxMic);
711 }
712
713
714 if (pEncap != NULL)
715 {
716 // LLC encapsulation
717 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pEncap, 6);
718 // Protocol Type
719 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc + 12 + vlan_offset, 2);
720 }
721 SrcBufLen -= (14 + vlan_offset);
722 pSrc += (14 + vlan_offset);
723 do
724 {
725 if (SrcBufLen > 0)
726 {
727 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc, SrcBufLen);
728 }
729
730 break; // No need handle next packet
731
732 } while (TRUE); // End of copying payload
733
734 // Compute the final MIC Value
735 RTMPTkipGetMIC(&pAd->PrivateInfo.Tx);
736}
737
738
739/************************************************************/
740/* tkip_sbox() */
741/* Returns a 16 bit value from a 64K entry table. The Table */
742/* is synthesized from two 256 entry byte wide tables. */
743/************************************************************/
744
745UINT tkip_sbox(UINT index)
746{
747 UINT index_low;
748 UINT index_high;
749 UINT left, right;
750
751 index_low = (index % 256);
752 index_high = ((index >> 8) % 256);
753
754 left = Tkip_Sbox_Lower[index_low] + (Tkip_Sbox_Upper[index_low] * 256);
755 right = Tkip_Sbox_Upper[index_high] + (Tkip_Sbox_Lower[index_high] * 256);
756
757 return (left ^ right);
758}
759
760UINT rotr1(UINT a)
761{
762 unsigned int b;
763
764 if ((a & 0x01) == 0x01)
765 {
766 b = (a >> 1) | 0x8000;
767 }
768 else
769 {
770 b = (a >> 1) & 0x7fff;
771 }
772 b = b % 65536;
773 return b;
774}
775
776VOID RTMPTkipMixKey(
777 UCHAR *key,
778 UCHAR *ta,
779 ULONG pnl, /* Least significant 16 bits of PN */
780 ULONG pnh, /* Most significant 32 bits of PN */
781 UCHAR *rc4key,
782 UINT *p1k)
783{
784
785 UINT tsc0;
786 UINT tsc1;
787 UINT tsc2;
788
789 UINT ppk0;
790 UINT ppk1;
791 UINT ppk2;
792 UINT ppk3;
793 UINT ppk4;
794 UINT ppk5;
795
796 INT i;
797 INT j;
798
799 tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */
800 tsc1 = (unsigned int)(pnh % 65536);
801 tsc2 = (unsigned int)(pnl % 65536); /* lsb */
802
803 /* Phase 1, step 1 */
804 p1k[0] = tsc1;
805 p1k[1] = tsc0;
806 p1k[2] = (UINT)(ta[0] + (ta[1]*256));
807 p1k[3] = (UINT)(ta[2] + (ta[3]*256));
808 p1k[4] = (UINT)(ta[4] + (ta[5]*256));
809
810 /* Phase 1, step 2 */
811 for (i=0; i<8; i++)
812 {
813 j = 2*(i & 1);
814 p1k[0] = (p1k[0] + tkip_sbox( (p1k[4] ^ ((256*key[1+j]) + key[j])) % 65536 )) % 65536;
815 p1k[1] = (p1k[1] + tkip_sbox( (p1k[0] ^ ((256*key[5+j]) + key[4+j])) % 65536 )) % 65536;
816 p1k[2] = (p1k[2] + tkip_sbox( (p1k[1] ^ ((256*key[9+j]) + key[8+j])) % 65536 )) % 65536;
817 p1k[3] = (p1k[3] + tkip_sbox( (p1k[2] ^ ((256*key[13+j]) + key[12+j])) % 65536 )) % 65536;
818 p1k[4] = (p1k[4] + tkip_sbox( (p1k[3] ^ (((256*key[1+j]) + key[j]))) % 65536 )) % 65536;
819 p1k[4] = (p1k[4] + i) % 65536;
820 }
821
822 /* Phase 2, Step 1 */
823 ppk0 = p1k[0];
824 ppk1 = p1k[1];
825 ppk2 = p1k[2];
826 ppk3 = p1k[3];
827 ppk4 = p1k[4];
828 ppk5 = (p1k[4] + tsc2) % 65536;
829
830 /* Phase2, Step 2 */
831 ppk0 = ppk0 + tkip_sbox( (ppk5 ^ ((256*key[1]) + key[0])) % 65536);
832 ppk1 = ppk1 + tkip_sbox( (ppk0 ^ ((256*key[3]) + key[2])) % 65536);
833 ppk2 = ppk2 + tkip_sbox( (ppk1 ^ ((256*key[5]) + key[4])) % 65536);
834 ppk3 = ppk3 + tkip_sbox( (ppk2 ^ ((256*key[7]) + key[6])) % 65536);
835 ppk4 = ppk4 + tkip_sbox( (ppk3 ^ ((256*key[9]) + key[8])) % 65536);
836 ppk5 = ppk5 + tkip_sbox( (ppk4 ^ ((256*key[11]) + key[10])) % 65536);
837
838 ppk0 = ppk0 + rotr1(ppk5 ^ ((256*key[13]) + key[12]));
839 ppk1 = ppk1 + rotr1(ppk0 ^ ((256*key[15]) + key[14]));
840 ppk2 = ppk2 + rotr1(ppk1);
841 ppk3 = ppk3 + rotr1(ppk2);
842 ppk4 = ppk4 + rotr1(ppk3);
843 ppk5 = ppk5 + rotr1(ppk4);
844
845 /* Phase 2, Step 3 */
846 /* Phase 2, Step 3 */
847
848 tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */
849 tsc1 = (unsigned int)(pnh % 65536);
850 tsc2 = (unsigned int)(pnl % 65536); /* lsb */
851
852 rc4key[0] = (tsc2 >> 8) % 256;
853 rc4key[1] = (((tsc2 >> 8) % 256) | 0x20) & 0x7f;
854 rc4key[2] = tsc2 % 256;
855 rc4key[3] = ((ppk5 ^ ((256*key[1]) + key[0])) >> 1) % 256;
856
857 rc4key[4] = ppk0 % 256;
858 rc4key[5] = (ppk0 >> 8) % 256;
859
860 rc4key[6] = ppk1 % 256;
861 rc4key[7] = (ppk1 >> 8) % 256;
862
863 rc4key[8] = ppk2 % 256;
864 rc4key[9] = (ppk2 >> 8) % 256;
865
866 rc4key[10] = ppk3 % 256;
867 rc4key[11] = (ppk3 >> 8) % 256;
868
869 rc4key[12] = ppk4 % 256;
870 rc4key[13] = (ppk4 >> 8) % 256;
871
872 rc4key[14] = ppk5 % 256;
873 rc4key[15] = (ppk5 >> 8) % 256;
874}
875
876
877/************************************************/
878/* construct_mic_header1() */
879/* Builds the first MIC header block from */
880/* header fields. */
881/************************************************/
882
883void construct_mic_header1(
884 unsigned char *mic_header1,
885 int header_length,
886 unsigned char *mpdu)
887{
888 mic_header1[0] = (unsigned char)((header_length - 2) / 256);
889 mic_header1[1] = (unsigned char)((header_length - 2) % 256);
890 mic_header1[2] = mpdu[0] & 0xcf; /* Mute CF poll & CF ack bits */
891 mic_header1[3] = mpdu[1] & 0xc7; /* Mute retry, more data and pwr mgt bits */
892 mic_header1[4] = mpdu[4]; /* A1 */
893 mic_header1[5] = mpdu[5];
894 mic_header1[6] = mpdu[6];
895 mic_header1[7] = mpdu[7];
896 mic_header1[8] = mpdu[8];
897 mic_header1[9] = mpdu[9];
898 mic_header1[10] = mpdu[10]; /* A2 */
899 mic_header1[11] = mpdu[11];
900 mic_header1[12] = mpdu[12];
901 mic_header1[13] = mpdu[13];
902 mic_header1[14] = mpdu[14];
903 mic_header1[15] = mpdu[15];
904}
905
906/************************************************/
907/* construct_mic_header2() */
908/* Builds the last MIC header block from */
909/* header fields. */
910/************************************************/
911
912void construct_mic_header2(
913 unsigned char *mic_header2,
914 unsigned char *mpdu,
915 int a4_exists,
916 int qc_exists)
917{
918 int i;
919
920 for (i = 0; i<16; i++) mic_header2[i]=0x00;
921
922 mic_header2[0] = mpdu[16]; /* A3 */
923 mic_header2[1] = mpdu[17];
924 mic_header2[2] = mpdu[18];
925 mic_header2[3] = mpdu[19];
926 mic_header2[4] = mpdu[20];
927 mic_header2[5] = mpdu[21];
928
929 // In Sequence Control field, mute sequence numer bits (12-bit)
930 mic_header2[6] = mpdu[22] & 0x0f; /* SC */
931 mic_header2[7] = 0x00; /* mpdu[23]; */
932
933 if ((!qc_exists) & a4_exists)
934 {
935 for (i=0;i<6;i++) mic_header2[8+i] = mpdu[24+i]; /* A4 */
936
937 }
938
939 if (qc_exists && (!a4_exists))
940 {
941 mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */
942 mic_header2[9] = mpdu[25] & 0x00;
943 }
944
945 if (qc_exists && a4_exists)
946 {
947 for (i=0;i<6;i++) mic_header2[8+i] = mpdu[24+i]; /* A4 */
948
949 mic_header2[14] = mpdu[30] & 0x0f;
950 mic_header2[15] = mpdu[31] & 0x00;
951 }
952}
953
954
955/************************************************/
956/* construct_mic_iv() */
957/* Builds the MIC IV from header fields and PN */
958/************************************************/
959
960void construct_mic_iv(
961 unsigned char *mic_iv,
962 int qc_exists,
963 int a4_exists,
964 unsigned char *mpdu,
965 unsigned int payload_length,
966 unsigned char *pn_vector)
967{
968 int i;
969
970 mic_iv[0] = 0x59;
971 if (qc_exists && a4_exists)
972 mic_iv[1] = mpdu[30] & 0x0f; /* QoS_TC */
973 if (qc_exists && !a4_exists)
974 mic_iv[1] = mpdu[24] & 0x0f; /* mute bits 7-4 */
975 if (!qc_exists)
976 mic_iv[1] = 0x00;
977 for (i = 2; i < 8; i++)
978 mic_iv[i] = mpdu[i + 8]; /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */
979#ifdef CONSISTENT_PN_ORDER
980 for (i = 8; i < 14; i++)
981 mic_iv[i] = pn_vector[i - 8]; /* mic_iv[8:13] = PN[0:5] */
982#else
983 for (i = 8; i < 14; i++)
984 mic_iv[i] = pn_vector[13 - i]; /* mic_iv[8:13] = PN[5:0] */
985#endif
986 i = (payload_length / 256);
987 i = (payload_length % 256);
988 mic_iv[14] = (unsigned char) (payload_length / 256);
989 mic_iv[15] = (unsigned char) (payload_length % 256);
990
991}
992
993
994
995/************************************/
996/* bitwise_xor() */
997/* A 128 bit, bitwise exclusive or */
998/************************************/
999
1000void bitwise_xor(unsigned char *ina, unsigned char *inb, unsigned char *out)
1001{
1002 int i;
1003 for (i=0; i<16; i++)
1004 {
1005 out[i] = ina[i] ^ inb[i];
1006 }
1007}
1008
1009
1010void aes128k128d(unsigned char *key, unsigned char *data, unsigned char *ciphertext)
1011{
1012 int round;
1013 int i;
1014 unsigned char intermediatea[16];
1015 unsigned char intermediateb[16];
1016 unsigned char round_key[16];
1017
1018 for(i=0; i<16; i++) round_key[i] = key[i];
1019
1020 for (round = 0; round < 11; round++)
1021 {
1022 if (round == 0)
1023 {
1024 xor_128(round_key, data, ciphertext);
1025 next_key(round_key, round);
1026 }
1027 else if (round == 10)
1028 {
1029 byte_sub(ciphertext, intermediatea);
1030 shift_row(intermediatea, intermediateb);
1031 xor_128(intermediateb, round_key, ciphertext);
1032 }
1033 else /* 1 - 9 */
1034 {
1035 byte_sub(ciphertext, intermediatea);
1036 shift_row(intermediatea, intermediateb);
1037 mix_column(&intermediateb[0], &intermediatea[0]);
1038 mix_column(&intermediateb[4], &intermediatea[4]);
1039 mix_column(&intermediateb[8], &intermediatea[8]);
1040 mix_column(&intermediateb[12], &intermediatea[12]);
1041 xor_128(intermediatea, round_key, ciphertext);
1042 next_key(round_key, round);
1043 }
1044 }
1045
1046}
1047
1048void construct_ctr_preload(
1049 unsigned char *ctr_preload,
1050 int a4_exists,
1051 int qc_exists,
1052 unsigned char *mpdu,
1053 unsigned char *pn_vector,
1054 int c)
1055{
1056
1057 int i = 0;
1058 for (i=0; i<16; i++) ctr_preload[i] = 0x00;
1059 i = 0;
1060
1061 ctr_preload[0] = 0x01; /* flag */
1062 if (qc_exists && a4_exists) ctr_preload[1] = mpdu[30] & 0x0f; /* QoC_Control */
1063 if (qc_exists && !a4_exists) ctr_preload[1] = mpdu[24] & 0x0f;
1064
1065 for (i = 2; i < 8; i++)
1066 ctr_preload[i] = mpdu[i + 8]; /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */
1067#ifdef CONSISTENT_PN_ORDER
1068 for (i = 8; i < 14; i++)
1069 ctr_preload[i] = pn_vector[i - 8]; /* ctr_preload[8:13] = PN[0:5] */
1070#else
1071 for (i = 8; i < 14; i++)
1072 ctr_preload[i] = pn_vector[13 - i]; /* ctr_preload[8:13] = PN[5:0] */
1073#endif
1074 ctr_preload[14] = (unsigned char) (c / 256); // Ctr
1075 ctr_preload[15] = (unsigned char) (c % 256);
1076
1077}
1078
1079
1080//
1081// TRUE: Success!
1082// FALSE: Decrypt Error!
1083//
1084BOOLEAN RTMPSoftDecryptTKIP(
1085 IN PRTMP_ADAPTER pAd,
1086 IN PUCHAR pData,
1087 IN ULONG DataByteCnt,
1088 IN UCHAR UserPriority,
1089 IN PCIPHER_KEY pWpaKey)
1090{
1091 UCHAR KeyID;
1092 UINT HeaderLen;
1093 UCHAR fc0;
1094 UCHAR fc1;
1095 USHORT fc;
1096 UINT frame_type;
1097 UINT frame_subtype;
1098 UINT from_ds;
1099 UINT to_ds;
1100 INT a4_exists;
1101 INT qc_exists;
1102 USHORT duration;
1103 USHORT seq_control;
1104 USHORT qos_control;
1105 UCHAR TA[MAC_ADDR_LEN];
1106 UCHAR DA[MAC_ADDR_LEN];
1107 UCHAR SA[MAC_ADDR_LEN];
1108 UCHAR RC4Key[16];
1109 UINT p1k[5]; //for mix_key;
1110 ULONG pnl;/* Least significant 16 bits of PN */
1111 ULONG pnh;/* Most significant 32 bits of PN */
1112 UINT num_blocks;
1113 UINT payload_remainder;
1114 ARCFOURCONTEXT ArcFourContext;
1115 UINT crc32 = 0;
1116 UINT trailfcs = 0;
1117 UCHAR MIC[8];
1118 UCHAR TrailMIC[8];
1119
1120#ifdef RT_BIG_ENDIAN
1121 RTMPFrameEndianChange(pAd, (PUCHAR)pData, DIR_READ, FALSE);
1122#endif
1123
1124 fc0 = *pData;
1125 fc1 = *(pData + 1);
1126
1127 fc = *((PUSHORT)pData);
1128
1129 frame_type = ((fc0 >> 2) & 0x03);
1130 frame_subtype = ((fc0 >> 4) & 0x0f);
1131
1132 from_ds = (fc1 & 0x2) >> 1;
1133 to_ds = (fc1 & 0x1);
1134
1135 a4_exists = (from_ds & to_ds);
1136 qc_exists = ((frame_subtype == 0x08) || /* Assumed QoS subtypes */
1137 (frame_subtype == 0x09) || /* Likely to change. */
1138 (frame_subtype == 0x0a) ||
1139 (frame_subtype == 0x0b)
1140 );
1141
1142 HeaderLen = 24;
1143 if (a4_exists)
1144 HeaderLen += 6;
1145
1146 KeyID = *((PUCHAR)(pData+ HeaderLen + 3));
1147 KeyID = KeyID >> 6;
1148
1149 if (pWpaKey[KeyID].KeyLen == 0)
1150 {
1151 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptTKIP failed!(KeyID[%d] Length can not be 0)\n", KeyID));
1152 return FALSE;
1153 }
1154
1155 duration = *((PUSHORT)(pData+2));
1156
1157 seq_control = *((PUSHORT)(pData+22));
1158
1159 if (qc_exists)
1160 {
1161 if (a4_exists)
1162 {
1163 qos_control = *((PUSHORT)(pData+30));
1164 }
1165 else
1166 {
1167 qos_control = *((PUSHORT)(pData+24));
1168 }
1169 }
1170
1171 if (to_ds == 0 && from_ds == 1)
1172 {
1173 NdisMoveMemory(DA, pData+4, MAC_ADDR_LEN);
1174 NdisMoveMemory(SA, pData+16, MAC_ADDR_LEN);
1175 NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN); //BSSID
1176 }
1177 else if (to_ds == 0 && from_ds == 0 )
1178 {
1179 NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN);
1180 NdisMoveMemory(DA, pData+4, MAC_ADDR_LEN);
1181 NdisMoveMemory(SA, pData+10, MAC_ADDR_LEN);
1182 }
1183 else if (to_ds == 1 && from_ds == 0)
1184 {
1185 NdisMoveMemory(SA, pData+10, MAC_ADDR_LEN);
1186 NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN);
1187 NdisMoveMemory(DA, pData+16, MAC_ADDR_LEN);
1188 }
1189 else if (to_ds == 1 && from_ds == 1)
1190 {
1191 NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN);
1192 NdisMoveMemory(DA, pData+16, MAC_ADDR_LEN);
1193 NdisMoveMemory(SA, pData+22, MAC_ADDR_LEN);
1194 }
1195
1196 num_blocks = (DataByteCnt - 16) / 16;
1197 payload_remainder = (DataByteCnt - 16) % 16;
1198
1199 pnl = (*(pData + HeaderLen)) * 256 + *(pData + HeaderLen + 2);
1200 pnh = *((PULONG)(pData + HeaderLen + 4));
1201 pnh = cpu2le32(pnh);
1202 RTMPTkipMixKey(pWpaKey[KeyID].Key, TA, pnl, pnh, RC4Key, p1k);
1203
1204 ARCFOUR_INIT(&ArcFourContext, RC4Key, 16);
1205
1206 ARCFOUR_DECRYPT(&ArcFourContext, pData + HeaderLen, pData + HeaderLen + 8, DataByteCnt - HeaderLen - 8);
1207 NdisMoveMemory(&trailfcs, pData + DataByteCnt - 8 - 4, 4);
1208 crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pData + HeaderLen, DataByteCnt - HeaderLen - 8 - 4); //Skip IV+EIV 8 bytes & Skip last 4 bytes(FCS).
1209 crc32 ^= 0xffffffff; /* complement */
1210
1211 if(crc32 != cpu2le32(trailfcs))
1212 {
1213 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptTKIP, WEP Data ICV Error !\n")); //ICV error.
1214
1215 return (FALSE);
1216 }
1217
1218 NdisMoveMemory(TrailMIC, pData + DataByteCnt - 8 - 8 - 4, 8);
1219 RTMPInitMICEngine(pAd, pWpaKey[KeyID].Key, DA, SA, UserPriority, pWpaKey[KeyID].RxMic);
1220 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pData + HeaderLen, DataByteCnt - HeaderLen - 8 - 12);
1221 RTMPTkipGetMIC(&pAd->PrivateInfo.Tx);
1222 NdisMoveMemory(MIC, pAd->PrivateInfo.Tx.MIC, 8);
1223
1224 if (!NdisEqualMemory(MIC, TrailMIC, 8))
1225 {
1226 DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptTKIP, WEP Data MIC Error !\n")); //MIC error.
1227 //RTMPReportMicError(pAd, &pWpaKey[KeyID]); // marked by AlbertY @ 20060630
1228 return (FALSE);
1229 }
1230
1231#ifdef RT_BIG_ENDIAN
1232 RTMPFrameEndianChange(pAd, (PUCHAR)pData, DIR_READ, FALSE);
1233#endif
1234 //DBGPRINT(RT_DEBUG_TRACE, "RTMPSoftDecryptTKIP Decript done!!\n");
1235 return TRUE;
1236}
1237
1238
1239
1240
1241BOOLEAN RTMPSoftDecryptAES(
1242 IN PRTMP_ADAPTER pAd,
1243 IN PUCHAR pData,
1244 IN ULONG DataByteCnt,
1245 IN PCIPHER_KEY pWpaKey)
1246{
1247 UCHAR KeyID;
1248 UINT HeaderLen;
1249 UCHAR PN[6];
1250 UINT payload_len;
1251 UINT num_blocks;
1252 UINT payload_remainder;
1253 USHORT fc;
1254 UCHAR fc0;
1255 UCHAR fc1;
1256 UINT frame_type;
1257 UINT frame_subtype;
1258 UINT from_ds;
1259 UINT to_ds;
1260 INT a4_exists;
1261 INT qc_exists;
1262 UCHAR aes_out[16];
1263 int payload_index;
1264 UINT i;
1265 UCHAR ctr_preload[16];
1266 UCHAR chain_buffer[16];
1267 UCHAR padded_buffer[16];
1268 UCHAR mic_iv[16];
1269 UCHAR mic_header1[16];
1270 UCHAR mic_header2[16];
1271 UCHAR MIC[8];
1272 UCHAR TrailMIC[8];
1273
1274#ifdef RT_BIG_ENDIAN
1275 RTMPFrameEndianChange(pAd, (PUCHAR)pData, DIR_READ, FALSE);
1276#endif
1277
1278 fc0 = *pData;
1279 fc1 = *(pData + 1);
1280
1281 fc = *((PUSHORT)pData);
1282
1283 frame_type = ((fc0 >> 2) & 0x03);
1284 frame_subtype = ((fc0 >> 4) & 0x0f);
1285
1286 from_ds = (fc1 & 0x2) >> 1;
1287 to_ds = (fc1 & 0x1);
1288
1289 a4_exists = (from_ds & to_ds);
1290 qc_exists = ((frame_subtype == 0x08) || /* Assumed QoS subtypes */
1291 (frame_subtype == 0x09) || /* Likely to change. */
1292 (frame_subtype == 0x0a) ||
1293 (frame_subtype == 0x0b)
1294 );
1295
1296 HeaderLen = 24;
1297 if (a4_exists)
1298 HeaderLen += 6;
1299
1300 KeyID = *((PUCHAR)(pData+ HeaderLen + 3));
1301 KeyID = KeyID >> 6;
1302
1303 if (pWpaKey[KeyID].KeyLen == 0)
1304 {
1305 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptAES failed!(KeyID[%d] Length can not be 0)\n", KeyID));
1306 return FALSE;
1307 }
1308
1309 PN[0] = *(pData+ HeaderLen);
1310 PN[1] = *(pData+ HeaderLen + 1);
1311 PN[2] = *(pData+ HeaderLen + 4);
1312 PN[3] = *(pData+ HeaderLen + 5);
1313 PN[4] = *(pData+ HeaderLen + 6);
1314 PN[5] = *(pData+ HeaderLen + 7);
1315
1316 payload_len = DataByteCnt - HeaderLen - 8 - 8; // 8 bytes for CCMP header , 8 bytes for MIC
1317 payload_remainder = (payload_len) % 16;
1318 num_blocks = (payload_len) / 16;
1319
1320
1321
1322 // Find start of payload
1323 payload_index = HeaderLen + 8; //IV+EIV
1324
1325 for (i=0; i< num_blocks; i++)
1326 {
1327 construct_ctr_preload(ctr_preload,
1328 a4_exists,
1329 qc_exists,
1330 pData,
1331 PN,
1332 i+1 );
1333
1334 aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
1335
1336 bitwise_xor(aes_out, pData + payload_index, chain_buffer);
1337 NdisMoveMemory(pData + payload_index - 8, chain_buffer, 16);
1338 payload_index += 16;
1339 }
1340
1341 //
1342 // If there is a short final block, then pad it
1343 // encrypt it and copy the unpadded part back
1344 //
1345 if (payload_remainder > 0)
1346 {
1347 construct_ctr_preload(ctr_preload,
1348 a4_exists,
1349 qc_exists,
1350 pData,
1351 PN,
1352 num_blocks + 1);
1353
1354 NdisZeroMemory(padded_buffer, 16);
1355 NdisMoveMemory(padded_buffer, pData + payload_index, payload_remainder);
1356
1357 aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
1358
1359 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1360 NdisMoveMemory(pData + payload_index - 8, chain_buffer, payload_remainder);
1361 payload_index += payload_remainder;
1362 }
1363
1364 //
1365 // Descrypt the MIC
1366 //
1367 construct_ctr_preload(ctr_preload,
1368 a4_exists,
1369 qc_exists,
1370 pData,
1371 PN,
1372 0);
1373 NdisZeroMemory(padded_buffer, 16);
1374 NdisMoveMemory(padded_buffer, pData + payload_index, 8);
1375
1376 aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
1377
1378 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1379
1380 NdisMoveMemory(TrailMIC, chain_buffer, 8);
1381
1382 //
1383 // Calculate MIC
1384 //
1385
1386 //Force the protected frame bit on
1387 *(pData + 1) = *(pData + 1) | 0x40;
1388
1389 // Find start of payload
1390 // Because the CCMP header has been removed
1391 payload_index = HeaderLen;
1392
1393 construct_mic_iv(
1394 mic_iv,
1395 qc_exists,
1396 a4_exists,
1397 pData,
1398 payload_len,
1399 PN);
1400
1401 construct_mic_header1(
1402 mic_header1,
1403 HeaderLen,
1404 pData);
1405
1406 construct_mic_header2(
1407 mic_header2,
1408 pData,
1409 a4_exists,
1410 qc_exists);
1411
1412 aes128k128d(pWpaKey[KeyID].Key, mic_iv, aes_out);
1413 bitwise_xor(aes_out, mic_header1, chain_buffer);
1414 aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
1415 bitwise_xor(aes_out, mic_header2, chain_buffer);
1416 aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
1417
1418 // iterate through each 16 byte payload block
1419 for (i = 0; i < num_blocks; i++)
1420 {
1421 bitwise_xor(aes_out, pData + payload_index, chain_buffer);
1422 payload_index += 16;
1423 aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
1424 }
1425
1426 // Add on the final payload block if it needs padding
1427 if (payload_remainder > 0)
1428 {
1429 NdisZeroMemory(padded_buffer, 16);
1430 NdisMoveMemory(padded_buffer, pData + payload_index, payload_remainder);
1431
1432 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1433 aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
1434 }
1435
1436 // aes_out contains padded mic, discard most significant
1437 // 8 bytes to generate 64 bit MIC
1438 for (i = 0 ; i < 8; i++) MIC[i] = aes_out[i];
1439
1440 if (!NdisEqualMemory(MIC, TrailMIC, 8))
1441 {
1442 DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptAES, MIC Error !\n")); //MIC error.
1443 return FALSE;
1444 }
1445
1446#ifdef RT_BIG_ENDIAN
1447 RTMPFrameEndianChange(pAd, (PUCHAR)pData, DIR_READ, FALSE);
1448#endif
1449
1450 return TRUE;
1451}
1452
1453/****************************************/
1454/* aes128k128d() */
1455/* Performs a 128 bit AES encrypt with */
1456/* 128 bit data. */
1457/****************************************/
1458VOID xor_128(
1459 IN PUCHAR a,
1460 IN PUCHAR b,
1461 OUT PUCHAR out)
1462{
1463 INT i;
1464
1465 for (i=0;i<16; i++)
1466 {
1467 out[i] = a[i] ^ b[i];
1468 }
1469}
1470
1471VOID next_key(
1472 IN PUCHAR key,
1473 IN INT round)
1474{
1475 UCHAR rcon;
1476 UCHAR sbox_key[4];
1477 UCHAR rcon_table[12] =
1478 {
1479 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
1480 0x1b, 0x36, 0x36, 0x36
1481 };
1482
1483 sbox_key[0] = RTMPCkipSbox(key[13]);
1484 sbox_key[1] = RTMPCkipSbox(key[14]);
1485 sbox_key[2] = RTMPCkipSbox(key[15]);
1486 sbox_key[3] = RTMPCkipSbox(key[12]);
1487
1488 rcon = rcon_table[round];
1489
1490 xor_32(&key[0], sbox_key, &key[0]);
1491 key[0] = key[0] ^ rcon;
1492
1493 xor_32(&key[4], &key[0], &key[4]);
1494 xor_32(&key[8], &key[4], &key[8]);
1495 xor_32(&key[12], &key[8], &key[12]);
1496}
1497
1498VOID xor_32(
1499 IN PUCHAR a,
1500 IN PUCHAR b,
1501 OUT PUCHAR out)
1502{
1503 INT i;
1504
1505 for (i=0;i<4; i++)
1506 {
1507 out[i] = a[i] ^ b[i];
1508 }
1509}
1510
1511VOID byte_sub(
1512 IN PUCHAR in,
1513 OUT PUCHAR out)
1514{
1515 INT i;
1516
1517 for (i=0; i< 16; i++)
1518 {
1519 out[i] = RTMPCkipSbox(in[i]);
1520 }
1521}
1522
1523UCHAR RTMPCkipSbox(
1524 IN UCHAR a)
1525{
1526 return SboxTable[(int)a];
1527}
1528
1529VOID shift_row(
1530 IN PUCHAR in,
1531 OUT PUCHAR out)
1532{
1533 out[0] = in[0];
1534 out[1] = in[5];
1535 out[2] = in[10];
1536 out[3] = in[15];
1537 out[4] = in[4];
1538 out[5] = in[9];
1539 out[6] = in[14];
1540 out[7] = in[3];
1541 out[8] = in[8];
1542 out[9] = in[13];
1543 out[10] = in[2];
1544 out[11] = in[7];
1545 out[12] = in[12];
1546 out[13] = in[1];
1547 out[14] = in[6];
1548 out[15] = in[11];
1549}
1550
1551VOID mix_column(
1552 IN PUCHAR in,
1553 OUT PUCHAR out)
1554{
1555 INT i;
1556 UCHAR add1b[4];
1557 UCHAR add1bf7[4];
1558 UCHAR rotl[4];
1559 UCHAR swap_halfs[4];
1560 UCHAR andf7[4];
1561 UCHAR rotr[4];
1562 UCHAR temp[4];
1563 UCHAR tempb[4];
1564
1565 for (i=0 ; i<4; i++)
1566 {
1567 if ((in[i] & 0x80)== 0x80)
1568 add1b[i] = 0x1b;
1569 else
1570 add1b[i] = 0x00;
1571 }
1572
1573 swap_halfs[0] = in[2]; /* Swap halfs */
1574 swap_halfs[1] = in[3];
1575 swap_halfs[2] = in[0];
1576 swap_halfs[3] = in[1];
1577
1578 rotl[0] = in[3]; /* Rotate left 8 bits */
1579 rotl[1] = in[0];
1580 rotl[2] = in[1];
1581 rotl[3] = in[2];
1582
1583 andf7[0] = in[0] & 0x7f;
1584 andf7[1] = in[1] & 0x7f;
1585 andf7[2] = in[2] & 0x7f;
1586 andf7[3] = in[3] & 0x7f;
1587
1588 for (i = 3; i>0; i--) /* logical shift left 1 bit */
1589 {
1590 andf7[i] = andf7[i] << 1;
1591 if ((andf7[i-1] & 0x80) == 0x80)
1592 {
1593 andf7[i] = (andf7[i] | 0x01);
1594 }
1595 }
1596 andf7[0] = andf7[0] << 1;
1597 andf7[0] = andf7[0] & 0xfe;
1598
1599 xor_32(add1b, andf7, add1bf7);
1600
1601 xor_32(in, add1bf7, rotr);
1602
1603 temp[0] = rotr[0]; /* Rotate right 8 bits */
1604 rotr[0] = rotr[1];
1605 rotr[1] = rotr[2];
1606 rotr[2] = rotr[3];
1607 rotr[3] = temp[0];
1608
1609 xor_32(add1bf7, rotr, temp);
1610 xor_32(swap_halfs, rotl,tempb);
1611 xor_32(temp, tempb, out);
1612}
1613
diff --git a/drivers/staging/rt3070/common/rtmp_wep.c b/drivers/staging/rt3070/common/rtmp_wep.c
new file mode 100644
index 000000000000..f5f0a3bb17eb
--- /dev/null
+++ b/drivers/staging/rt3070/common/rtmp_wep.c
@@ -0,0 +1,508 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 rtmp_wep.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Paul Wu 10-28-02 Initial
36*/
37
38#include "../rt_config.h"
39
40UINT FCSTAB_32[256] =
41{
42 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
43 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
44 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
45 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
46 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
47 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
48 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
49 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
50 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
51 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
52 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
53 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
54 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
55 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
56 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
57 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
58 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
59 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
60 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
61 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
62 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
63 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
64 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
65 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
66 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
67 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
68 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
69 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
70 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
71 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
72 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
73 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
74 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
75 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
76 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
77 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
78 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
79 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
80 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
81 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
82 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
83 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
84 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
85 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
86 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
87 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
88 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
89 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
90 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
91 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
92 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
93 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
94 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
95 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
96 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
97 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
98 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
99 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
100 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
101 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
102 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
103 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
104 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
105 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
106};
107
108/*
109UCHAR WEPKEY[] = {
110 //IV
111 0x00, 0x11, 0x22,
112 //WEP KEY
113 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
114 };
115 */
116
117/*
118 ========================================================================
119
120 Routine Description:
121 Init WEP function.
122
123 Arguments:
124 pAd Pointer to our adapter
125 pKey Pointer to the WEP KEY
126 KeyId WEP Key ID
127 KeyLen the length of WEP KEY
128 pDest Pointer to the destination which Encryption data will store in.
129
130 Return Value:
131 None
132
133 IRQL = DISPATCH_LEVEL
134
135 Note:
136
137 ========================================================================
138*/
139VOID RTMPInitWepEngine(
140 IN PRTMP_ADAPTER pAd,
141 IN PUCHAR pKey,
142 IN UCHAR KeyId,
143 IN UCHAR KeyLen,
144 IN OUT PUCHAR pDest)
145{
146 UINT i;
147 UCHAR WEPKEY[] = {
148 //IV
149 0x00, 0x11, 0x22,
150 //WEP KEY
151 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
152 };
153
154 pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32; //Init crc32.
155
156#ifdef CONFIG_STA_SUPPORT
157 if (pAd->StaCfg.bCkipOn && (pAd->StaCfg.CkipFlag & 0x10) && (pAd->OpMode == OPMODE_STA))
158 {
159 ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, pKey, KeyLen); //INIT SBOX, KEYLEN+3(IV)
160 NdisMoveMemory(pDest, pKey, 3); //Append Init Vector
161 }
162 else
163#endif // CONFIG_STA_SUPPORT //
164 {
165 NdisMoveMemory(WEPKEY + 3, pKey, KeyLen);
166
167 for(i = 0; i < 3; i++)
168 WEPKEY[i] = RandomByte(pAd); //Call mlme RandomByte() function.
169 ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY, KeyLen + 3); //INIT SBOX, KEYLEN+3(IV)
170
171 NdisMoveMemory(pDest, WEPKEY, 3); //Append Init Vector
172 }
173 *(pDest+3) = (KeyId << 6); //Append KEYID
174
175}
176
177/*
178 ========================================================================
179
180 Routine Description:
181 Encrypt transimitted data
182
183 Arguments:
184 pAd Pointer to our adapter
185 pSrc Pointer to the transimitted source data that will be encrypt
186 pDest Pointer to the destination where entryption data will be store in.
187 Len Indicate the length of the source data
188
189 Return Value:
190 None
191
192 IRQL = DISPATCH_LEVEL
193
194 Note:
195
196 ========================================================================
197*/
198VOID RTMPEncryptData(
199 IN PRTMP_ADAPTER pAd,
200 IN PUCHAR pSrc,
201 IN PUCHAR pDest,
202 IN UINT Len)
203{
204 pAd->PrivateInfo.FCSCRC32 = RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, pSrc, Len);
205 ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, pSrc, Len);
206}
207
208
209/*
210 ========================================================================
211
212 Routine Description:
213 Decrypt received WEP data
214
215 Arguments:
216 pAdapter Pointer to our adapter
217 pSrc Pointer to the received data
218 Len the length of the received data
219
220 Return Value:
221 TRUE Decrypt WEP data success
222 FALSE Decrypt WEP data failed
223
224 Note:
225
226 ========================================================================
227*/
228BOOLEAN RTMPSoftDecryptWEP(
229 IN PRTMP_ADAPTER pAd,
230 IN PUCHAR pData,
231 IN ULONG DataByteCnt,
232 IN PCIPHER_KEY pGroupKey)
233{
234 UINT trailfcs;
235 UINT crc32;
236 UCHAR KeyIdx;
237 UCHAR WEPKEY[] = {
238 //IV
239 0x00, 0x11, 0x22,
240 //WEP KEY
241 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
242 };
243 UCHAR *pPayload = (UCHAR *)pData + LENGTH_802_11;
244 ULONG payload_len = DataByteCnt - LENGTH_802_11;
245
246 NdisMoveMemory(WEPKEY, pPayload, 3); //Get WEP IV
247
248 KeyIdx = (*(pPayload + 3) & 0xc0) >> 6;
249 if (pGroupKey[KeyIdx].KeyLen == 0)
250 return (FALSE);
251
252 NdisMoveMemory(WEPKEY + 3, pGroupKey[KeyIdx].Key, pGroupKey[KeyIdx].KeyLen);
253 ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY, pGroupKey[KeyIdx].KeyLen + 3);
254 ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, pPayload, pPayload + 4, payload_len - 4);
255 NdisMoveMemory(&trailfcs, pPayload + payload_len - 8, 4);
256 crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pPayload, payload_len - 8); //Skip last 4 bytes(FCS).
257 crc32 ^= 0xffffffff; /* complement */
258
259 if(crc32 != cpu2le32(trailfcs))
260 {
261 DBGPRINT(RT_DEBUG_TRACE, ("! WEP Data CRC Error !\n")); //CRC error.
262 return (FALSE);
263 }
264 return (TRUE);
265}
266
267/*
268 ========================================================================
269
270 Routine Description:
271 The Stream Cipher Encryption Algorithm "ARCFOUR" initialize
272
273 Arguments:
274 Ctx Pointer to ARCFOUR CONTEXT (SBOX)
275 pKey Pointer to the WEP KEY
276 KeyLen Indicate the length fo the WEP KEY
277
278 Return Value:
279 None
280
281 IRQL = DISPATCH_LEVEL
282
283 Note:
284
285 ========================================================================
286*/
287VOID ARCFOUR_INIT(
288 IN PARCFOURCONTEXT Ctx,
289 IN PUCHAR pKey,
290 IN UINT KeyLen)
291{
292 UCHAR t, u;
293 UINT keyindex;
294 UINT stateindex;
295 PUCHAR state;
296 UINT counter;
297
298 state = Ctx->STATE;
299 Ctx->X = 0;
300 Ctx->Y = 0;
301 for (counter = 0; counter < 256; counter++)
302 state[counter] = (UCHAR)counter;
303 keyindex = 0;
304 stateindex = 0;
305 for (counter = 0; counter < 256; counter++)
306 {
307 t = state[counter];
308 stateindex = (stateindex + pKey[keyindex] + t) & 0xff;
309 u = state[stateindex];
310 state[stateindex] = t;
311 state[counter] = u;
312 if (++keyindex >= KeyLen)
313 keyindex = 0;
314 }
315}
316
317/*
318 ========================================================================
319
320 Routine Description:
321 Get bytes from ARCFOUR CONTEXT (S-BOX)
322
323 Arguments:
324 Ctx Pointer to ARCFOUR CONTEXT (SBOX)
325
326 Return Value:
327 UCHAR - the value of the ARCFOUR CONTEXT (S-BOX)
328
329 Note:
330
331 ========================================================================
332*/
333UCHAR ARCFOUR_BYTE(
334 IN PARCFOURCONTEXT Ctx)
335{
336 UINT x;
337 UINT y;
338 UCHAR sx, sy;
339 PUCHAR state;
340
341 state = Ctx->STATE;
342 x = (Ctx->X + 1) & 0xff;
343 sx = state[x];
344 y = (sx + Ctx->Y) & 0xff;
345 sy = state[y];
346 Ctx->X = x;
347 Ctx->Y = y;
348 state[y] = sx;
349 state[x] = sy;
350
351 return(state[(sx + sy) & 0xff]);
352
353}
354
355/*
356 ========================================================================
357
358 Routine Description:
359 The Stream Cipher Decryption Algorithm
360
361 Arguments:
362 Ctx Pointer to ARCFOUR CONTEXT (SBOX)
363 pDest Pointer to the Destination
364 pSrc Pointer to the Source data
365 Len Indicate the length of the Source data
366
367 Return Value:
368 None
369
370 Note:
371
372 ========================================================================
373*/
374VOID ARCFOUR_DECRYPT(
375 IN PARCFOURCONTEXT Ctx,
376 IN PUCHAR pDest,
377 IN PUCHAR pSrc,
378 IN UINT Len)
379{
380 UINT i;
381
382 for (i = 0; i < Len; i++)
383 pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
384}
385
386/*
387 ========================================================================
388
389 Routine Description:
390 The Stream Cipher Encryption Algorithm
391
392 Arguments:
393 Ctx Pointer to ARCFOUR CONTEXT (SBOX)
394 pDest Pointer to the Destination
395 pSrc Pointer to the Source data
396 Len Indicate the length of the Source dta
397
398 Return Value:
399 None
400
401 IRQL = DISPATCH_LEVEL
402
403 Note:
404
405 ========================================================================
406*/
407VOID ARCFOUR_ENCRYPT(
408 IN PARCFOURCONTEXT Ctx,
409 IN PUCHAR pDest,
410 IN PUCHAR pSrc,
411 IN UINT Len)
412{
413 UINT i;
414
415 for (i = 0; i < Len; i++)
416 pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
417}
418
419/*
420 ========================================================================
421
422 Routine Description:
423 The Stream Cipher Encryption Algorithm which conform to the special requirement to encrypt GTK.
424
425 Arguments:
426 Ctx Pointer to ARCFOUR CONTEXT (SBOX)
427 pDest Pointer to the Destination
428 pSrc Pointer to the Source data
429 Len Indicate the length of the Source dta
430
431
432 ========================================================================
433*/
434
435VOID WPAARCFOUR_ENCRYPT(
436 IN PARCFOURCONTEXT Ctx,
437 IN PUCHAR pDest,
438 IN PUCHAR pSrc,
439 IN UINT Len)
440{
441 UINT i;
442 //discard first 256 bytes
443 for (i = 0; i < 256; i++)
444 ARCFOUR_BYTE(Ctx);
445
446 for (i = 0; i < Len; i++)
447 pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
448}
449
450
451/*
452 ========================================================================
453
454 Routine Description:
455 Calculate a new FCS given the current FCS and the new data.
456
457 Arguments:
458 Fcs the original FCS value
459 Cp pointer to the data which will be calculate the FCS
460 Len the length of the data
461
462 Return Value:
463 UINT - FCS 32 bits
464
465 IRQL = DISPATCH_LEVEL
466
467 Note:
468
469 ========================================================================
470*/
471UINT RTMP_CALC_FCS32(
472 IN UINT Fcs,
473 IN PUCHAR Cp,
474 IN INT Len)
475{
476 while (Len--)
477 Fcs = (((Fcs) >> 8) ^ FCSTAB_32[((Fcs) ^ (*Cp++)) & 0xff]);
478
479 return (Fcs);
480}
481
482
483/*
484 ========================================================================
485
486 Routine Description:
487 Get last FCS and encrypt it to the destination
488
489 Arguments:
490 pDest Pointer to the Destination
491
492 Return Value:
493 None
494
495 Note:
496
497 ========================================================================
498*/
499VOID RTMPSetICV(
500 IN PRTMP_ADAPTER pAd,
501 IN PUCHAR pDest)
502{
503 pAd->PrivateInfo.FCSCRC32 ^= 0xffffffff; /* complement */
504 pAd->PrivateInfo.FCSCRC32 = cpu2le32(pAd->PrivateInfo.FCSCRC32);
505
506 ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, (PUCHAR) &pAd->PrivateInfo.FCSCRC32, 4);
507}
508
diff --git a/drivers/staging/rt3070/common/rtusb_bulk.c b/drivers/staging/rt3070/common/rtusb_bulk.c
new file mode 100644
index 000000000000..1a05703520fc
--- /dev/null
+++ b/drivers/staging/rt3070/common/rtusb_bulk.c
@@ -0,0 +1,1382 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 rtusb_bulk.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Name Date Modification logs
36 Paul Lin 06-25-2004 created
37
38*/
39
40#include "../rt_config.h"
41// Match total 6 bulkout endpoint to corresponding queue.
42UCHAR EpToQueue[6]={FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_MGMT};
43
44//static BOOLEAN SingleBulkOut = FALSE;
45
46void RTUSB_FILL_BULK_URB (struct urb *pUrb,
47 struct usb_device *pUsb_Dev,
48 unsigned int bulkpipe,
49 void *pTransferBuf,
50 int BufSize,
51 usb_complete_t Complete,
52 void *pContext)
53{
54
55#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
56 usb_fill_bulk_urb(pUrb, pUsb_Dev, bulkpipe, pTransferBuf, BufSize, (usb_complete_t)Complete, pContext);
57#else
58 FILL_BULK_URB(pUrb, pUsb_Dev, bulkpipe, pTransferBuf, BufSize, Complete, pContext);
59#endif
60
61}
62
63VOID RTUSBInitTxDesc(
64 IN PRTMP_ADAPTER pAd,
65 IN PTX_CONTEXT pTxContext,
66 IN UCHAR BulkOutPipeId,
67 IN usb_complete_t Func)
68{
69 PURB pUrb;
70 PUCHAR pSrc = NULL;
71 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
72
73 pUrb = pTxContext->pUrb;
74 ASSERT(pUrb);
75
76 // Store BulkOut PipeId
77 pTxContext->BulkOutPipeId = BulkOutPipeId;
78
79 if (pTxContext->bAggregatible)
80 {
81 pSrc = &pTxContext->TransferBuffer->Aggregation[2];
82 }
83 else
84 {
85 pSrc = (PUCHAR) pTxContext->TransferBuffer->field.WirelessPacket;
86 }
87
88
89 //Initialize a tx bulk urb
90 RTUSB_FILL_BULK_URB(pUrb,
91 pObj->pUsb_Dev,
92 usb_sndbulkpipe(pObj->pUsb_Dev, pAd->BulkOutEpAddr[BulkOutPipeId]),
93 pSrc,
94 pTxContext->BulkOutSize,
95 Func,
96 pTxContext);
97
98#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
99 if (pTxContext->bAggregatible)
100 pUrb->transfer_dma = (pTxContext->data_dma + TX_BUFFER_NORMSIZE + 2);
101 else
102 pUrb->transfer_dma = pTxContext->data_dma;
103
104 pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
105#endif
106
107}
108
109VOID RTUSBInitHTTxDesc(
110 IN PRTMP_ADAPTER pAd,
111 IN PHT_TX_CONTEXT pTxContext,
112 IN UCHAR BulkOutPipeId,
113 IN ULONG BulkOutSize,
114 IN usb_complete_t Func)
115{
116 PURB pUrb;
117 PUCHAR pSrc = NULL;
118 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
119
120 pUrb = pTxContext->pUrb;
121 ASSERT(pUrb);
122
123 // Store BulkOut PipeId
124 pTxContext->BulkOutPipeId = BulkOutPipeId;
125
126 pSrc = &pTxContext->TransferBuffer->field.WirelessPacket[pTxContext->NextBulkOutPosition];
127
128
129 //Initialize a tx bulk urb
130 RTUSB_FILL_BULK_URB(pUrb,
131 pObj->pUsb_Dev,
132 usb_sndbulkpipe(pObj->pUsb_Dev, pAd->BulkOutEpAddr[BulkOutPipeId]),
133 pSrc,
134 BulkOutSize,
135 Func,
136 pTxContext);
137
138#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
139 pUrb->transfer_dma = (pTxContext->data_dma + pTxContext->NextBulkOutPosition);
140 pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
141#endif
142
143}
144
145VOID RTUSBInitRxDesc(
146 IN PRTMP_ADAPTER pAd,
147 IN PRX_CONTEXT pRxContext)
148{
149 PURB pUrb;
150 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
151 ULONG RX_bulk_size;
152
153
154 pUrb = pRxContext->pUrb;
155 ASSERT(pUrb);
156
157 if ( pAd->BulkInMaxPacketSize == 64)
158 RX_bulk_size = 4096;
159 else
160 RX_bulk_size = MAX_RXBULK_SIZE;
161
162 //Initialize a rx bulk urb
163 RTUSB_FILL_BULK_URB(pUrb,
164 pObj->pUsb_Dev,
165 usb_rcvbulkpipe(pObj->pUsb_Dev, pAd->BulkInEpAddr),
166 &(pRxContext->TransferBuffer[pAd->NextRxBulkInPosition]),
167 RX_bulk_size - (pAd->NextRxBulkInPosition),
168 (usb_complete_t)RTUSBBulkRxComplete,
169 (void *)pRxContext);
170
171#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
172 pUrb->transfer_dma = pRxContext->data_dma + pAd->NextRxBulkInPosition;
173 pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
174#endif
175
176
177}
178
179/*
180 ========================================================================
181
182 Routine Description:
183
184 Arguments:
185
186 Return Value:
187
188 Note:
189
190 ========================================================================
191*/
192
193#define BULK_OUT_LOCK(pLock, IrqFlags) \
194 if(1 /*!(in_interrupt() & 0xffff0000)*/) \
195 RTMP_IRQ_LOCK((pLock), IrqFlags);
196
197#define BULK_OUT_UNLOCK(pLock, IrqFlags) \
198 if(1 /*!(in_interrupt() & 0xffff0000)*/) \
199 RTMP_IRQ_UNLOCK((pLock), IrqFlags);
200
201
202VOID RTUSBBulkOutDataPacket(
203 IN PRTMP_ADAPTER pAd,
204 IN UCHAR BulkOutPipeId,
205 IN UCHAR Index)
206{
207
208 PHT_TX_CONTEXT pHTTXContext;
209 PURB pUrb;
210 int ret = 0;
211 PTXINFO_STRUC pTxInfo, pLastTxInfo = NULL;
212 PTXWI_STRUC pTxWI;
213 ULONG TmpBulkEndPos, ThisBulkSize;
214 unsigned long IrqFlags = 0, IrqFlags2 = 0;
215 PUCHAR pWirelessPkt, pAppendant;
216 BOOLEAN bTxQLastRound = FALSE;
217 UCHAR allzero[4]= {0x0,0x0,0x0,0x0};
218
219 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
220 if ((pAd->BulkOutPending[BulkOutPipeId] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
221 {
222 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
223 return;
224 }
225 pAd->BulkOutPending[BulkOutPipeId] = TRUE;
226
227 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
228 )
229 {
230 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
231 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
232 return;
233 }
234 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
235
236
237 pHTTXContext = &(pAd->TxContext[BulkOutPipeId]);
238
239 BULK_OUT_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
240 if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition)
241 || ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition))
242 {
243 BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
244
245 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
246 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
247
248 // Clear Data flag
249 RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId));
250 RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
251
252 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
253 return;
254 }
255
256 // Clear Data flag
257 RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId));
258 RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
259
260 //DBGPRINT(RT_DEBUG_TRACE,("BulkOut-B:I=0x%lx, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", in_interrupt(),
261 // pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition,
262 // pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
263 pHTTXContext->NextBulkOutPosition = pHTTXContext->ENextBulkOutPosition;
264 ThisBulkSize = 0;
265 TmpBulkEndPos = pHTTXContext->NextBulkOutPosition;
266 pWirelessPkt = &pHTTXContext->TransferBuffer->field.WirelessPacket[0];
267
268 if ((pHTTXContext->bCopySavePad == TRUE))
269 {
270 if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4))
271 {
272 DBGPRINT_RAW(RT_DEBUG_ERROR,("e1, allzero : %x %x %x %x %x %x %x %x \n",
273 pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3]
274 ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7]));
275 }
276 NdisMoveMemory(&pWirelessPkt[TmpBulkEndPos], pHTTXContext->SavedPad, 8);
277 pHTTXContext->bCopySavePad = FALSE;
278 if (pAd->bForcePrintTX == TRUE)
279 DBGPRINT(RT_DEBUG_TRACE,("RTUSBBulkOutDataPacket --> COPY PAD. CurWrite = %ld, NextBulk = %ld. ENextBulk = %ld.\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition));
280 }
281
282 do
283 {
284 pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[TmpBulkEndPos];
285 pTxWI = (PTXWI_STRUC)&pWirelessPkt[TmpBulkEndPos + TXINFO_SIZE];
286
287 if (pAd->bForcePrintTX == TRUE)
288 DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkOutDataPacket AMPDU = %d.\n", pTxWI->AMPDU));
289
290 // add by Iverson, limit BulkOut size to 4k to pass WMM b mode 2T1R test items
291 //if ((ThisBulkSize != 0) && (pTxWI->AMPDU == 0))
292 if ((ThisBulkSize != 0) && (pTxWI->PHYMODE == MODE_CCK))
293 {
294#ifdef INF_AMAZON_SE
295 /*Iverson Add for AMAZON USB (RT2070 && RT3070) to pass WMM A2-T4 ~ A2-T10*/
296 if(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))
297 {
298 /*Iverson patch for WMM A5-T07 ,WirelessStaToWirelessSta do not bulk out aggregate*/
299 if(pTxWI->PacketId == 6)
300 {
301 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
302 break;
303 }
304 else if (BulkOutPipeId == 1)
305 {
306 /*BK No Limit BulkOut size .*/
307 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
308 break;
309 }
310 else if (((ThisBulkSize&0xffff8000) != 0) || (((ThisBulkSize&0x1000) == 0x1000) && (BulkOutPipeId == 0) ))
311 {
312 /*BE Limit BulkOut size to about 4k bytes.*/
313 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
314 break;
315 }
316 else if (((ThisBulkSize&0xffff8000) != 0) || (((ThisBulkSize&0x1c00) == 0x1c00) && (BulkOutPipeId == 2) ))
317 {
318 /*VI Limit BulkOut size to about 7k bytes.*/
319 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
320 break;
321 }
322 else if (((ThisBulkSize&0xffff8000) != 0) || (((ThisBulkSize&0x2500) == 0x2500) && (BulkOutPipeId == 3) ))
323 {
324 /*VO Limit BulkOut size to about 9k bytes.*/
325 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
326 break;
327 }
328 }
329 else if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x1000) == 0x1000))
330 {
331 /* Limit BulkOut size to about 4k bytes.*/
332 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
333 break;
334 }
335#else
336 if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x1000) == 0x1000))
337 {
338 // Limit BulkOut size to about 4k bytes.
339 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
340 break;
341 }
342#endif // INF_AMAZON_SE //
343
344 else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/)
345 {
346 // For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size.
347 // For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04.
348 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
349 break;
350 }
351 }
352 // end Iverson
353 else
354 {
355#ifdef INF_AMAZON_SE
356//#ifdef DOT11_N_SUPPORT
357// if(((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000) || ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0)))
358// {
359// /* AMAZON_SE: BG mode Disable BulkOut Aggregate, N mode BulkOut Aggregaet size 24K */
360// pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
361// break;
362// }
363// else
364//#endif // DOT11_N_SUPPORT //
365// {
366 if(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && (pTxWI->AMPDU == 0))
367 {
368 if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0)) ||
369 (ThisBulkSize != 0))
370 {
371 /* AMAZON_SE: RT2070 Disable BulkOut Aggregate when WMM for USB issue */
372 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
373 break;
374 }
375 }
376/*
377 else if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000))
378 {
379 // Limit BulkOut size to about 24k bytes.
380 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
381 break;
382 }
383 }
384*/
385#endif // INF_AMAZON_SE //
386
387 if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000))
388 { // Limit BulkOut size to about 24k bytes.
389 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
390 break;
391 }
392
393 else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/)
394 { // For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size.
395 // For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04.
396 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
397 break;
398 }
399 }
400
401 if (TmpBulkEndPos == pHTTXContext->CurWritePosition)
402 {
403 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
404 break;
405 }
406 //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
407#ifdef CONFIG_STA_SUPPORT
408 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
409 {
410 if (pTxInfo->QSEL != FIFO_EDCA)
411 {
412 printk("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n", __FUNCTION__, pTxInfo->QSEL);
413 printk("\tCWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad);
414 hex_dump("Wrong QSel Pkt:", (PUCHAR)&pWirelessPkt[TmpBulkEndPos], (pHTTXContext->CurWritePosition - pHTTXContext->NextBulkOutPosition));
415 }
416 }
417#endif // CONFIG_STA_SUPPORT //
418
419 if (pTxInfo->USBDMATxPktLen <= 8)
420 {
421 BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
422 DBGPRINT(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("e2, USBDMATxPktLen==0, Size=%ld, bCSPad=%d, CWPos=%ld, NBPos=%ld, CWRPos=%ld!\n",
423 pHTTXContext->BulkOutSize, pHTTXContext->bCopySavePad, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->CurWriteRealPos));
424 {
425 DBGPRINT_RAW(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("%x %x %x %x %x %x %x %x \n",
426 pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3]
427 ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7]));
428 }
429 pAd->bForcePrintTX = TRUE;
430 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
431 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
432 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
433 //DBGPRINT(RT_DEBUG_LOUD,("Out:pTxInfo->USBDMATxPktLen=%d!\n", pTxInfo->USBDMATxPktLen));
434 return;
435 }
436
437 // Increase Total transmit byte counter
438 pAd->RalinkCounters.OneSecTransmittedByteCount += pTxWI->MPDUtotalByteCount;
439 pAd->RalinkCounters.TransmittedByteCount += pTxWI->MPDUtotalByteCount;
440
441 pLastTxInfo = pTxInfo;
442
443 // Make sure we use EDCA QUEUE.
444#ifdef CONFIG_STA_SUPPORT
445 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
446 pTxInfo->QSEL = FIFO_EDCA; //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
447#endif // CONFIG_STA_SUPPORT //
448 ThisBulkSize += (pTxInfo->USBDMATxPktLen+4);
449 TmpBulkEndPos += (pTxInfo->USBDMATxPktLen+4);
450
451 if (TmpBulkEndPos != pHTTXContext->CurWritePosition)
452 pTxInfo->USBDMANextVLD = 1;
453
454 if (pTxInfo->SwUseLastRound == 1)
455 {
456 if (pHTTXContext->CurWritePosition == 8)
457 pTxInfo->USBDMANextVLD = 0;
458 pTxInfo->SwUseLastRound = 0;
459
460 bTxQLastRound = TRUE;
461 pHTTXContext->ENextBulkOutPosition = 8;
462
463 #ifdef RT_BIG_ENDIAN
464 RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO);
465 RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
466 #endif // RT_BIG_ENDIAN //
467
468 break;
469 }
470
471#ifdef RT_BIG_ENDIAN
472 RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO);
473 RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
474#endif // RT_BIG_ENDIAN //
475
476 }while (TRUE);
477
478 // adjust the pTxInfo->USBDMANextVLD value of last pTxInfo.
479 if (pLastTxInfo)
480 {
481#ifdef RT_BIG_ENDIAN
482 RTMPDescriptorEndianChange((PUCHAR)pLastTxInfo, TYPE_TXINFO);
483#endif // RT_BIG_ENDIAN //
484 pLastTxInfo->USBDMANextVLD = 0;
485#ifdef RT_BIG_ENDIAN
486 RTMPDescriptorEndianChange((PUCHAR)pLastTxInfo, TYPE_TXINFO);
487#endif // RT_BIG_ENDIAN //
488 }
489
490 /*
491 We need to copy SavedPad when following condition matched!
492 1. Not the last round of the TxQueue and
493 2. any match of following cases:
494 (1). The End Position of this bulk out is reach to the Currenct Write position and
495 the TxInfo and related header already write to the CurWritePosition.
496 =>(ENextBulkOutPosition == CurWritePosition) && (CurWriteRealPos > CurWritePosition)
497
498 (2). The EndPosition of the bulk out is not reach to the Current Write Position.
499 =>(ENextBulkOutPosition != CurWritePosition)
500 */
501 if ((bTxQLastRound == FALSE) &&
502 (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) && (pHTTXContext->CurWriteRealPos > pHTTXContext->CurWritePosition)) ||
503 (pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition))
504 )
505 {
506 NdisMoveMemory(pHTTXContext->SavedPad, &pWirelessPkt[pHTTXContext->ENextBulkOutPosition], 8);
507 pHTTXContext->bCopySavePad = TRUE;
508 if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4))
509 {
510 PUCHAR pBuf = &pHTTXContext->SavedPad[0];
511 DBGPRINT_RAW(RT_DEBUG_ERROR,("WARNING-Zero-3:%02x%02x%02x%02x%02x%02x%02x%02x,CWPos=%ld, CWRPos=%ld, bCW=%d, NBPos=%ld, TBPos=%ld, TBSize=%ld\n",
512 pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7], pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos,
513 pHTTXContext->bCurWriting, pHTTXContext->NextBulkOutPosition, TmpBulkEndPos, ThisBulkSize));
514
515 pBuf = &pWirelessPkt[pHTTXContext->CurWritePosition];
516 DBGPRINT_RAW(RT_DEBUG_ERROR,("\tCWPos=%02x%02x%02x%02x%02x%02x%02x%02x\n", pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7]));
517 }
518 //DBGPRINT(RT_DEBUG_LOUD,("ENPos==CWPos=%ld, CWRPos=%ld, bCSPad=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->bCopySavePad));
519 }
520
521 if (pAd->bForcePrintTX == TRUE)
522 DBGPRINT(RT_DEBUG_TRACE,("BulkOut-A:Size=%ld, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", ThisBulkSize, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
523 //DBGPRINT(RT_DEBUG_LOUD,("BulkOut-A:Size=%ld, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, bLRound=%d!\n", ThisBulkSize, pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad, bTxQLastRound));
524
525 // USB DMA engine requires to pad extra 4 bytes. This pad doesn't count into real bulkoutsize.
526 pAppendant = &pWirelessPkt[TmpBulkEndPos];
527 NdisZeroMemory(pAppendant, 8);
528 ThisBulkSize += 4;
529 pHTTXContext->LastOne = TRUE;
530 if ((ThisBulkSize % pAd->BulkOutMaxPacketSize) == 0)
531 ThisBulkSize += 4;
532 pHTTXContext->BulkOutSize = ThisBulkSize;
533
534 pAd->watchDogTxPendingCnt[BulkOutPipeId] = 1;
535 BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
536
537 // Init Tx context descriptor
538 RTUSBInitHTTxDesc(pAd, pHTTXContext, BulkOutPipeId, ThisBulkSize, (usb_complete_t)RTUSBBulkOutDataPacketComplete);
539
540 pUrb = pHTTXContext->pUrb;
541 if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
542 {
543 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret));
544
545 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
546 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
547 pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;
548 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
549
550 return;
551 }
552
553 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
554 pHTTXContext->IRPPending = TRUE;
555 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
556 pAd->BulkOutReq++;
557
558}
559
560
561VOID RTUSBBulkOutDataPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
562{
563 PHT_TX_CONTEXT pHTTXContext;
564 PRTMP_ADAPTER pAd;
565 POS_COOKIE pObj;
566 UCHAR BulkOutPipeId;
567
568
569 pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
570 pAd = pHTTXContext->pAd;
571 pObj = (POS_COOKIE) pAd->OS_Cookie;
572
573 // Store BulkOut PipeId
574 BulkOutPipeId = pHTTXContext->BulkOutPipeId;
575 pAd->BulkOutDataOneSecCount++;
576
577 switch (BulkOutPipeId)
578 {
579 case 0:
580 pObj->ac0_dma_done_task.data = (unsigned long)pUrb;
581 tasklet_hi_schedule(&pObj->ac0_dma_done_task);
582 break;
583 case 1:
584 pObj->ac1_dma_done_task.data = (unsigned long)pUrb;
585 tasklet_hi_schedule(&pObj->ac1_dma_done_task);
586 break;
587 case 2:
588 pObj->ac2_dma_done_task.data = (unsigned long)pUrb;
589 tasklet_hi_schedule(&pObj->ac2_dma_done_task);
590 break;
591 case 3:
592 pObj->ac3_dma_done_task.data = (unsigned long)pUrb;
593 tasklet_hi_schedule(&pObj->ac3_dma_done_task);
594 break;
595 case 4:
596 pObj->hcca_dma_done_task.data = (unsigned long)pUrb;
597 tasklet_hi_schedule(&pObj->hcca_dma_done_task);
598 break;
599 }
600}
601
602
603/*
604 ========================================================================
605
606 Routine Description:
607
608 Arguments:
609
610 Return Value:
611
612 Note: NULL frame use BulkOutPipeId = 0
613
614 ========================================================================
615*/
616VOID RTUSBBulkOutNullFrame(
617 IN PRTMP_ADAPTER pAd)
618{
619 PTX_CONTEXT pNullContext = &(pAd->NullContext);
620 PURB pUrb;
621 int ret = 0;
622 unsigned long IrqFlags;
623
624 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
625 if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
626 {
627 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
628 return;
629 }
630 pAd->BulkOutPending[0] = TRUE;
631 pAd->watchDogTxPendingCnt[0] = 1;
632 pNullContext->IRPPending = TRUE;
633 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
634
635 // Increase Total transmit byte counter
636 pAd->RalinkCounters.TransmittedByteCount += pNullContext->BulkOutSize;
637
638
639 // Clear Null frame bulk flag
640 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);
641
642#ifdef RT_BIG_ENDIAN
643 RTMPDescriptorEndianChange((PUCHAR)pNullContext->TransferBuffer, TYPE_TXINFO);
644#endif // RT_BIG_ENDIAN //
645
646 // Init Tx context descriptor
647 RTUSBInitTxDesc(pAd, pNullContext, 0, (usb_complete_t)RTUSBBulkOutNullFrameComplete);
648
649 pUrb = pNullContext->pUrb;
650 if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
651 {
652 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
653 pAd->BulkOutPending[0] = FALSE;
654 pAd->watchDogTxPendingCnt[0] = 0;
655 pNullContext->IRPPending = FALSE;
656 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
657
658 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutNullFrame: Submit Tx URB failed %d\n", ret));
659 return;
660 }
661
662}
663
664// NULL frame use BulkOutPipeId = 0
665VOID RTUSBBulkOutNullFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs)
666{
667 PRTMP_ADAPTER pAd;
668 PTX_CONTEXT pNullContext;
669 NTSTATUS Status;
670 POS_COOKIE pObj;
671
672
673 pNullContext = (PTX_CONTEXT)pUrb->context;
674 pAd = pNullContext->pAd;
675 Status = pUrb->status;
676
677 pObj = (POS_COOKIE) pAd->OS_Cookie;
678 pObj->null_frame_complete_task.data = (unsigned long)pUrb;
679 tasklet_hi_schedule(&pObj->null_frame_complete_task);
680
681}
682
683/*
684 ========================================================================
685
686 Routine Description:
687
688 Arguments:
689
690 Return Value:
691
692 Note: MLME use BulkOutPipeId = 0
693
694 ========================================================================
695*/
696VOID RTUSBBulkOutMLMEPacket(
697 IN PRTMP_ADAPTER pAd,
698 IN UCHAR Index)
699{
700 PTX_CONTEXT pMLMEContext;
701 PURB pUrb;
702 int ret = 0;
703 unsigned long IrqFlags;
704
705 pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa;
706 pUrb = pMLMEContext->pUrb;
707
708 if ((pAd->MgmtRing.TxSwFreeIdx >= MGMT_RING_SIZE) ||
709 (pMLMEContext->InUse == FALSE) ||
710 (pMLMEContext->bWaitingBulkOut == FALSE))
711 {
712
713
714 // Clear MLME bulk flag
715 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
716
717 return;
718 }
719
720
721 RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
722 if ((pAd->BulkOutPending[MGMTPIPEIDX] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
723 {
724 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
725 return;
726 }
727
728 pAd->BulkOutPending[MGMTPIPEIDX] = TRUE;
729 pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 1;
730 pMLMEContext->IRPPending = TRUE;
731 pMLMEContext->bWaitingBulkOut = FALSE;
732 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
733
734 // Increase Total transmit byte counter
735 pAd->RalinkCounters.TransmittedByteCount += pMLMEContext->BulkOutSize;
736
737 // Clear MLME bulk flag
738 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
739
740#ifdef RT_BIG_ENDIAN
741 RTMPDescriptorEndianChange((PUCHAR)pMLMEContext->TransferBuffer, TYPE_TXINFO);
742#endif // RT_BIG_ENDIAN //
743
744 // Init Tx context descriptor
745 RTUSBInitTxDesc(pAd, pMLMEContext, MGMTPIPEIDX, (usb_complete_t)RTUSBBulkOutMLMEPacketComplete);
746
747#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
748 //For mgmt urb buffer, because we use sk_buff, so we need to notify the USB controller do dma mapping.
749 pUrb->transfer_dma = 0;
750 pUrb->transfer_flags &= (~URB_NO_TRANSFER_DMA_MAP);
751#endif
752
753 pUrb = pMLMEContext->pUrb;
754 if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
755 {
756 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutMLMEPacket: Submit MLME URB failed %d\n", ret));
757 RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
758 pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
759 pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 0;
760 pMLMEContext->IRPPending = FALSE;
761 pMLMEContext->bWaitingBulkOut = TRUE;
762 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
763
764 return;
765 }
766
767 //DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutMLMEPacket \n"));
768// printk("<---RTUSBBulkOutMLMEPacket,Cpu=%d!, Dma=%d, SwIdx=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx);
769}
770
771
772VOID RTUSBBulkOutMLMEPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
773{
774 PTX_CONTEXT pMLMEContext;
775 PRTMP_ADAPTER pAd;
776 NTSTATUS Status;
777 POS_COOKIE pObj;
778 int index;
779
780 //DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutMLMEPacketComplete\n"));
781 pMLMEContext = (PTX_CONTEXT)pUrb->context;
782 pAd = pMLMEContext->pAd;
783 pObj = (POS_COOKIE)pAd->OS_Cookie;
784 Status = pUrb->status;
785 index = pMLMEContext->SelfIdx;
786
787 pObj->mgmt_dma_done_task.data = (unsigned long)pUrb;
788 tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
789}
790
791
792/*
793 ========================================================================
794
795 Routine Description:
796
797 Arguments:
798
799 Return Value:
800
801 Note: PsPoll use BulkOutPipeId = 0
802
803 ========================================================================
804*/
805VOID RTUSBBulkOutPsPoll(
806 IN PRTMP_ADAPTER pAd)
807{
808 PTX_CONTEXT pPsPollContext = &(pAd->PsPollContext);
809 PURB pUrb;
810 int ret = 0;
811 unsigned long IrqFlags;
812
813 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
814 if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
815 {
816 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
817 return;
818 }
819 pAd->BulkOutPending[0] = TRUE;
820 pAd->watchDogTxPendingCnt[0] = 1;
821 pPsPollContext->IRPPending = TRUE;
822 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
823
824
825 // Clear PS-Poll bulk flag
826 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL);
827
828#ifdef RT_BIG_ENDIAN
829 RTMPDescriptorEndianChange((PUCHAR)pPsPollContext->TransferBuffer, TYPE_TXINFO);
830#endif // RT_BIG_ENDIAN //
831
832 // Init Tx context descriptor
833 RTUSBInitTxDesc(pAd, pPsPollContext, MGMTPIPEIDX, (usb_complete_t)RTUSBBulkOutPsPollComplete);
834
835 pUrb = pPsPollContext->pUrb;
836 if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
837 {
838 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
839 pAd->BulkOutPending[0] = FALSE;
840 pAd->watchDogTxPendingCnt[0] = 0;
841 pPsPollContext->IRPPending = FALSE;
842 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
843
844 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutPsPoll: Submit Tx URB failed %d\n", ret));
845 return;
846 }
847
848}
849
850// PS-Poll frame use BulkOutPipeId = 0
851VOID RTUSBBulkOutPsPollComplete(purbb_t pUrb,struct pt_regs *pt_regs)
852{
853 PRTMP_ADAPTER pAd;
854 PTX_CONTEXT pPsPollContext;
855 NTSTATUS Status;
856 POS_COOKIE pObj;
857
858
859 pPsPollContext= (PTX_CONTEXT)pUrb->context;
860 pAd = pPsPollContext->pAd;
861 Status = pUrb->status;
862 pObj = (POS_COOKIE) pAd->OS_Cookie;
863 pObj->pspoll_frame_complete_task.data = (unsigned long)pUrb;
864 tasklet_hi_schedule(&pObj->pspoll_frame_complete_task);
865
866}
867
868VOID DoBulkIn(IN RTMP_ADAPTER *pAd)
869{
870 PRX_CONTEXT pRxContext;
871 PURB pUrb;
872 int ret = 0;
873 unsigned long IrqFlags;
874
875 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
876 pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
877 if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) || (pRxContext->InUse == TRUE))
878 {
879 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
880 return;
881 }
882 pRxContext->InUse = TRUE;
883 pRxContext->IRPPending = TRUE;
884 pAd->PendingRx++;
885 pAd->BulkInReq++;
886 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
887
888 // Init Rx context descriptor
889 NdisZeroMemory(pRxContext->TransferBuffer, pRxContext->BulkInOffset);
890 RTUSBInitRxDesc(pAd, pRxContext);
891
892 pUrb = pRxContext->pUrb;
893 if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
894 { // fail
895
896 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
897 pRxContext->InUse = FALSE;
898 pRxContext->IRPPending = FALSE;
899 pAd->PendingRx--;
900 pAd->BulkInReq--;
901 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
902 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkReceive: Submit Rx URB failed %d\n", ret));
903 }
904 else
905 { // success
906 ASSERT((pRxContext->InUse == pRxContext->IRPPending));
907 //printk("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex);
908 }
909}
910
911
912/*
913 ========================================================================
914
915 Routine Description:
916 USB_RxPacket initializes a URB and uses the Rx IRP to submit it
917 to USB. It checks if an Rx Descriptor is available and passes the
918 the coresponding buffer to be filled. If no descriptor is available
919 fails the request. When setting the completion routine we pass our
920 Adapter Object as Context.
921
922 Arguments:
923
924 Return Value:
925 TRUE found matched tuple cache
926 FALSE no matched found
927
928 Note:
929
930 ========================================================================
931*/
932#define fRTMP_ADAPTER_NEED_STOP_RX \
933 (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
934 fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
935 fRTMP_ADAPTER_REMOVE_IN_PROGRESS | fRTMP_ADAPTER_BULKIN_RESET)
936
937#define fRTMP_ADAPTER_NEED_STOP_HANDLE_RX \
938 (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
939 fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
940 fRTMP_ADAPTER_REMOVE_IN_PROGRESS)
941
942VOID RTUSBBulkReceive(
943 IN PRTMP_ADAPTER pAd)
944{
945 PRX_CONTEXT pRxContext;
946 unsigned long IrqFlags;
947
948
949 /* sanity check */
950 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_HANDLE_RX))
951 return;
952
953 while(1)
954 {
955
956 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
957 pRxContext = &(pAd->RxContext[pAd->NextRxBulkInReadIndex]);
958 if (((pRxContext->InUse == FALSE) && (pRxContext->Readable == TRUE)) &&
959 (pRxContext->bRxHandling == FALSE))
960 {
961 pRxContext->bRxHandling = TRUE;
962 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
963
964 // read RxContext, Since not
965#ifdef CONFIG_STA_SUPPORT
966 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
967 STARxDoneInterruptHandle(pAd, TRUE);
968#endif // CONFIG_STA_SUPPORT //
969
970 // Finish to handle this bulkIn buffer.
971 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
972 pRxContext->BulkInOffset = 0;
973 pRxContext->Readable = FALSE;
974 pRxContext->bRxHandling = FALSE;
975 pAd->ReadPosition = 0;
976 pAd->TransferBufferLength = 0;
977 INC_RING_INDEX(pAd->NextRxBulkInReadIndex, RX_RING_SIZE);
978 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
979
980 }
981 else
982 {
983 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
984 break;
985 }
986 }
987
988 if (!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_RX)))
989 DoBulkIn(pAd);
990
991}
992
993
994/*
995 ========================================================================
996
997 Routine Description:
998 This routine process Rx Irp and call rx complete function.
999
1000 Arguments:
1001 DeviceObject Pointer to the device object for next lower
1002 device. DeviceObject passed in here belongs to
1003 the next lower driver in the stack because we
1004 were invoked via IoCallDriver in USB_RxPacket
1005 AND it is not OUR device object
1006 Irp Ptr to completed IRP
1007 Context Ptr to our Adapter object (context specified
1008 in IoSetCompletionRoutine
1009
1010 Return Value:
1011 Always returns STATUS_MORE_PROCESSING_REQUIRED
1012
1013 Note:
1014 Always returns STATUS_MORE_PROCESSING_REQUIRED
1015 ========================================================================
1016*/
1017VOID RTUSBBulkRxComplete(purbb_t pUrb, struct pt_regs *pt_regs)
1018{
1019 // use a receive tasklet to handle received packets;
1020 // or sometimes hardware IRQ will be disabled here, so we can not
1021 // use spin_lock_bh()/spin_unlock_bh() after IRQ is disabled. :<
1022 PRX_CONTEXT pRxContext;
1023 PRTMP_ADAPTER pAd;
1024 POS_COOKIE pObj;
1025
1026
1027 pRxContext = (PRX_CONTEXT)pUrb->context;
1028 pAd = pRxContext->pAd;
1029 pObj = (POS_COOKIE) pAd->OS_Cookie;
1030
1031 pObj->rx_done_task.data = (unsigned long)pUrb;
1032 tasklet_hi_schedule(&pObj->rx_done_task);
1033
1034}
1035
1036/*
1037 ========================================================================
1038
1039 Routine Description:
1040
1041 Arguments:
1042
1043 Return Value:
1044
1045 Note:
1046
1047 ========================================================================
1048*/
1049VOID RTUSBKickBulkOut(
1050 IN PRTMP_ADAPTER pAd)
1051{
1052 // BulkIn Reset will reset whole USB PHY. So we need to make sure fRTMP_ADAPTER_BULKIN_RESET not flaged.
1053 if (!RTMP_TEST_FLAG(pAd ,fRTMP_ADAPTER_NEED_STOP_TX)
1054#ifdef RALINK_ATE
1055 && !(ATE_ON(pAd))
1056#endif // RALINK_ATE //
1057 )
1058 {
1059 // 2. PS-Poll frame is next
1060 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL))
1061 {
1062 RTUSBBulkOutPsPoll(pAd);
1063 }
1064
1065 // 5. Mlme frame is next
1066 else if ((RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME)) &&
1067 (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE))
1068 {
1069 RTUSBBulkOutMLMEPacket(pAd, pAd->MgmtRing.TxDmaIdx);
1070 }
1071
1072 // 6. Data frame normal is next
1073 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL))
1074 {
1075 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1076 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1077 ))
1078 {
1079 RTUSBBulkOutDataPacket(pAd, 0, pAd->NextBulkOutIndex[0]);
1080 }
1081 }
1082 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_2))
1083 {
1084 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1085 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1086 ))
1087 {
1088 RTUSBBulkOutDataPacket(pAd, 1, pAd->NextBulkOutIndex[1]);
1089 }
1090 }
1091 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_3))
1092 {
1093 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1094 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1095 ))
1096 {
1097 RTUSBBulkOutDataPacket(pAd, 2, pAd->NextBulkOutIndex[2]);
1098 }
1099 }
1100 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_4))
1101 {
1102 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1103 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1104 ))
1105 {
1106 RTUSBBulkOutDataPacket(pAd, 3, pAd->NextBulkOutIndex[3]);
1107 }
1108 }
1109 //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
1110 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_5))
1111 {
1112 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1113 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1114 ))
1115 {
1116 }
1117 }
1118
1119 // 7. Null frame is the last
1120 else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL))
1121 {
1122 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1123 {
1124 RTUSBBulkOutNullFrame(pAd);
1125 }
1126 }
1127
1128 // 8. No data avaliable
1129 else
1130 {
1131
1132 }
1133 }
1134#ifdef RALINK_ATE
1135 /* If the mode is in ATE mode. */
1136 else if((ATE_ON(pAd)) &&
1137 !RTMP_TEST_FLAG(pAd ,fRTMP_ADAPTER_NEED_STOP_TX))// PETER : watch out !
1138 {
1139 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE))
1140 {
1141 ATE_RTUSBBulkOutDataPacket(pAd, 0);
1142 }
1143 }
1144#endif // RALINK_ATE //
1145
1146}
1147
1148/*
1149 ========================================================================
1150
1151 Routine Description:
1152 Call from Reset action after BulkOut failed.
1153 Arguments:
1154
1155 Return Value:
1156
1157 Note:
1158
1159 ========================================================================
1160*/
1161VOID RTUSBCleanUpDataBulkOutQueue(
1162 IN PRTMP_ADAPTER pAd)
1163{
1164 UCHAR Idx;
1165 PHT_TX_CONTEXT pTxContext;
1166
1167 DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpDataBulkOutQueue\n"));
1168
1169 for (Idx = 0; Idx < 4; Idx++)
1170 {
1171 pTxContext = &pAd->TxContext[Idx];
1172
1173 pTxContext->CurWritePosition = pTxContext->NextBulkOutPosition;
1174 pTxContext->LastOne = FALSE;
1175 NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
1176 pAd->BulkOutPending[Idx] = FALSE;
1177 NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
1178 }
1179
1180 DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpDataBulkOutQueue\n"));
1181}
1182
1183/*
1184 ========================================================================
1185
1186 Routine Description:
1187
1188 Arguments:
1189
1190 Return Value:
1191
1192 Note:
1193
1194 ========================================================================
1195*/
1196VOID RTUSBCleanUpMLMEBulkOutQueue(
1197 IN PRTMP_ADAPTER pAd)
1198{
1199 DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpMLMEBulkOutQueue\n"));
1200 DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpMLMEBulkOutQueue\n"));
1201}
1202
1203
1204/*
1205 ========================================================================
1206
1207 Routine Description:
1208
1209 Arguments:
1210
1211 Return Value:
1212
1213
1214 Note:
1215
1216 ========================================================================
1217*/
1218VOID RTUSBCancelPendingIRPs(
1219 IN PRTMP_ADAPTER pAd)
1220{
1221 RTUSBCancelPendingBulkInIRP(pAd);
1222 RTUSBCancelPendingBulkOutIRP(pAd);
1223}
1224
1225/*
1226 ========================================================================
1227
1228 Routine Description:
1229
1230 Arguments:
1231
1232 Return Value:
1233
1234 Note:
1235
1236 ========================================================================
1237*/
1238VOID RTUSBCancelPendingBulkInIRP(
1239 IN PRTMP_ADAPTER pAd)
1240{
1241 PRX_CONTEXT pRxContext;
1242 UINT i;
1243
1244 DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->RTUSBCancelPendingBulkInIRP\n"));
1245 for ( i = 0; i < (RX_RING_SIZE); i++)
1246 {
1247 pRxContext = &(pAd->RxContext[i]);
1248 if(pRxContext->IRPPending == TRUE)
1249 {
1250 RTUSB_UNLINK_URB(pRxContext->pUrb);
1251 pRxContext->IRPPending = FALSE;
1252 pRxContext->InUse = FALSE;
1253 //NdisInterlockedDecrement(&pAd->PendingRx);
1254 //pAd->PendingRx--;
1255 }
1256 }
1257 DBGPRINT_RAW(RT_DEBUG_TRACE, ("<---RTUSBCancelPendingBulkInIRP\n"));
1258}
1259
1260
1261/*
1262 ========================================================================
1263
1264 Routine Description:
1265
1266 Arguments:
1267
1268 Return Value:
1269
1270 Note:
1271
1272 ========================================================================
1273*/
1274VOID RTUSBCancelPendingBulkOutIRP(
1275 IN PRTMP_ADAPTER pAd)
1276{
1277 PHT_TX_CONTEXT pHTTXContext;
1278 PTX_CONTEXT pMLMEContext;
1279 PTX_CONTEXT pBeaconContext;
1280 PTX_CONTEXT pNullContext;
1281 PTX_CONTEXT pPsPollContext;
1282 PTX_CONTEXT pRTSContext;
1283 UINT i, Idx;
1284// unsigned int IrqFlags;
1285// NDIS_SPIN_LOCK *pLock;
1286// BOOLEAN *pPending;
1287
1288
1289// pLock = &pAd->BulkOutLock[MGMTPIPEIDX];
1290// pPending = &pAd->BulkOutPending[MGMTPIPEIDX];
1291
1292 for (Idx = 0; Idx < 4; Idx++)
1293 {
1294 pHTTXContext = &(pAd->TxContext[Idx]);
1295
1296 if (pHTTXContext->IRPPending == TRUE)
1297 {
1298
1299 // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
1300 // remove it from the HeadPendingSendList and NULL out HeadPendingSendList
1301 // when the last IRP on the list has been cancelled; that's how we exit this loop
1302 //
1303
1304 RTUSB_UNLINK_URB(pHTTXContext->pUrb);
1305
1306 // Sleep 200 microseconds to give cancellation time to work
1307 RTMPusecDelay(200);
1308 }
1309
1310#ifdef RALINK_ATE
1311 pHTTXContext->bCopySavePad = 0;
1312 pHTTXContext->CurWritePosition = 0;
1313 pHTTXContext->CurWriteRealPos = 0;
1314 pHTTXContext->bCurWriting = FALSE;
1315 pHTTXContext->NextBulkOutPosition = 0;
1316 pHTTXContext->ENextBulkOutPosition = 0;
1317#endif // RALINK_ATE //
1318 pAd->BulkOutPending[Idx] = FALSE;
1319 }
1320
1321 //RTMP_IRQ_LOCK(pLock, IrqFlags);
1322 for (i = 0; i < MGMT_RING_SIZE; i++)
1323 {
1324 pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa;
1325 if(pMLMEContext && (pMLMEContext->IRPPending == TRUE))
1326 {
1327
1328 // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
1329 // remove it from the HeadPendingSendList and NULL out HeadPendingSendList
1330 // when the last IRP on the list has been cancelled; that's how we exit this loop
1331 //
1332
1333 RTUSB_UNLINK_URB(pMLMEContext->pUrb);
1334 pMLMEContext->IRPPending = FALSE;
1335
1336 // Sleep 200 microsecs to give cancellation time to work
1337 RTMPusecDelay(200);
1338 }
1339 }
1340 pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
1341 //RTMP_IRQ_UNLOCK(pLock, IrqFlags);
1342
1343
1344 for (i = 0; i < BEACON_RING_SIZE; i++)
1345 {
1346 pBeaconContext = &(pAd->BeaconContext[i]);
1347
1348 if(pBeaconContext->IRPPending == TRUE)
1349 {
1350
1351 // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
1352 // remove it from the HeadPendingSendList and NULL out HeadPendingSendList
1353 // when the last IRP on the list has been cancelled; that's how we exit this loop
1354 //
1355
1356 RTUSB_UNLINK_URB(pBeaconContext->pUrb);
1357
1358 // Sleep 200 microsecs to give cancellation time to work
1359 RTMPusecDelay(200);
1360 }
1361 }
1362
1363 pNullContext = &(pAd->NullContext);
1364 if (pNullContext->IRPPending == TRUE)
1365 RTUSB_UNLINK_URB(pNullContext->pUrb);
1366
1367 pRTSContext = &(pAd->RTSContext);
1368 if (pRTSContext->IRPPending == TRUE)
1369 RTUSB_UNLINK_URB(pRTSContext->pUrb);
1370
1371 pPsPollContext = &(pAd->PsPollContext);
1372 if (pPsPollContext->IRPPending == TRUE)
1373 RTUSB_UNLINK_URB(pPsPollContext->pUrb);
1374
1375 for (Idx = 0; Idx < 4; Idx++)
1376 {
1377 NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
1378 pAd->BulkOutPending[Idx] = FALSE;
1379 NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
1380 }
1381}
1382
diff --git a/drivers/staging/rt3070/common/rtusb_data.c b/drivers/staging/rt3070/common/rtusb_data.c
new file mode 100644
index 000000000000..521309a2ae53
--- /dev/null
+++ b/drivers/staging/rt3070/common/rtusb_data.c
@@ -0,0 +1,218 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 rtusb_data.c
29
30 Abstract:
31 Ralink USB driver Tx/Rx functions.
32
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36 Jan 03-25-2006 created
37
38*/
39#include "../rt_config.h"
40
41extern UCHAR Phy11BGNextRateUpward[]; // defined in mlme.c
42extern UCHAR EpToQueue[];
43
44
45VOID REPORT_AMSDU_FRAMES_TO_LLC(
46 IN PRTMP_ADAPTER pAd,
47 IN PUCHAR pData,
48 IN ULONG DataSize)
49{
50 PNDIS_PACKET pPacket;
51 UINT nMSDU;
52 struct sk_buff *pSkb;
53
54 nMSDU = 0;
55 /* allocate a rx packet */
56 pSkb = dev_alloc_skb(RX_BUFFER_AGGRESIZE);
57 pPacket = (PNDIS_PACKET)OSPKT_TO_RTPKT(pSkb);
58 if (pSkb)
59 {
60
61 /* convert 802.11 to 802.3 packet */
62 pSkb->dev = get_netdev_from_bssid(pAd, BSS0);
63 RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
64 deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize);
65 }
66 else
67 {
68 DBGPRINT(RT_DEBUG_ERROR,("Can't allocate skb\n"));
69 }
70}
71
72NDIS_STATUS RTUSBFreeDescriptorRequest(
73 IN PRTMP_ADAPTER pAd,
74 IN UCHAR BulkOutPipeId,
75 IN UINT32 NumberRequired)
76{
77// UCHAR FreeNumber = 0;
78// UINT Index;
79 NDIS_STATUS Status = NDIS_STATUS_FAILURE;
80 unsigned long IrqFlags;
81 HT_TX_CONTEXT *pHTTXContext;
82
83
84 pHTTXContext = &pAd->TxContext[BulkOutPipeId];
85 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
86 if ((pHTTXContext->CurWritePosition < pHTTXContext->NextBulkOutPosition) && ((pHTTXContext->CurWritePosition + NumberRequired + LOCAL_TXBUF_SIZE) > pHTTXContext->NextBulkOutPosition))
87 {
88
89 RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
90 }
91 else if ((pHTTXContext->CurWritePosition == 8) && (pHTTXContext->NextBulkOutPosition < (NumberRequired + LOCAL_TXBUF_SIZE)))
92 {
93 RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
94 }
95 else if (pHTTXContext->bCurWriting == TRUE)
96 {
97 DBGPRINT(RT_DEBUG_TRACE,("RTUSBFreeD c3 --> QueIdx=%d, CWPos=%ld, NBOutPos=%ld!\n", BulkOutPipeId, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition));
98 RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
99 }
100 else
101 {
102 Status = NDIS_STATUS_SUCCESS;
103 }
104 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
105
106
107 return (Status);
108}
109
110
111NDIS_STATUS RTUSBFreeDescriptorRelease(
112 IN RTMP_ADAPTER *pAd,
113 IN UCHAR BulkOutPipeId)
114{
115 unsigned long IrqFlags;
116 HT_TX_CONTEXT *pHTTXContext;
117
118 pHTTXContext = &pAd->TxContext[BulkOutPipeId];
119 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
120 pHTTXContext->bCurWriting = FALSE;
121 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
122
123 return (NDIS_STATUS_SUCCESS);
124}
125
126
127BOOLEAN RTUSBNeedQueueBackForAgg(
128 IN RTMP_ADAPTER *pAd,
129 IN UCHAR BulkOutPipeId)
130{
131 unsigned long IrqFlags;
132 HT_TX_CONTEXT *pHTTXContext;
133 BOOLEAN needQueBack = FALSE;
134
135 pHTTXContext = &pAd->TxContext[BulkOutPipeId];
136
137 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
138 if ((pHTTXContext->IRPPending == TRUE) /*&& (pAd->TxSwQueue[BulkOutPipeId].Number == 0) */)
139 {
140 if ((pHTTXContext->CurWritePosition < pHTTXContext->ENextBulkOutPosition) &&
141 (((pHTTXContext->ENextBulkOutPosition+MAX_AGGREGATION_SIZE) < MAX_TXBULK_LIMIT) || (pHTTXContext->CurWritePosition > MAX_AGGREGATION_SIZE)))
142 {
143 needQueBack = TRUE;
144 }
145 else if ((pHTTXContext->CurWritePosition > pHTTXContext->ENextBulkOutPosition) &&
146 ((pHTTXContext->ENextBulkOutPosition + MAX_AGGREGATION_SIZE) < pHTTXContext->CurWritePosition))
147 {
148 needQueBack = TRUE;
149 }
150 }
151 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
152
153 return needQueBack;
154
155}
156
157
158/*
159 ========================================================================
160
161 Routine Description:
162
163 Arguments:
164
165 Return Value:
166
167 IRQL =
168
169 Note:
170
171 ========================================================================
172*/
173VOID RTUSBRejectPendingPackets(
174 IN PRTMP_ADAPTER pAd)
175{
176 UCHAR Index;
177 PQUEUE_ENTRY pEntry;
178 PNDIS_PACKET pPacket;
179 PQUEUE_HEADER pQueue;
180
181
182 for (Index = 0; Index < 4; Index++)
183 {
184 NdisAcquireSpinLock(&pAd->TxSwQueueLock[Index]);
185 while (pAd->TxSwQueue[Index].Head != NULL)
186 {
187 pQueue = (PQUEUE_HEADER) &(pAd->TxSwQueue[Index]);
188 pEntry = RemoveHeadQueue(pQueue);
189 pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
190 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
191 }
192 NdisReleaseSpinLock(&pAd->TxSwQueueLock[Index]);
193
194 }
195
196}
197
198VOID RTMPWriteTxInfo(
199 IN PRTMP_ADAPTER pAd,
200 IN PTXINFO_STRUC pTxInfo,
201 IN USHORT USBDMApktLen,
202 IN BOOLEAN bWiv,
203 IN UCHAR QueueSel,
204 IN UCHAR NextValid,
205 IN UCHAR TxBurst)
206{
207 pTxInfo->USBDMATxPktLen = USBDMApktLen;
208 pTxInfo->QSEL = QueueSel;
209 if (QueueSel != FIFO_EDCA)
210 DBGPRINT(RT_DEBUG_TRACE, ("====> QueueSel != FIFO_EDCA<============\n"));
211 pTxInfo->USBDMANextVLD = FALSE; //NextValid; // Need to check with Jan about this.
212 pTxInfo->USBDMATxburst = TxBurst;
213 pTxInfo->WIV = bWiv;
214 pTxInfo->SwUseLastRound = 0;
215 pTxInfo->rsv = 0;
216 pTxInfo->rsv2 = 0;
217}
218
diff --git a/drivers/staging/rt3070/common/rtusb_io.c b/drivers/staging/rt3070/common/rtusb_io.c
new file mode 100644
index 000000000000..a6a52e3445f9
--- /dev/null
+++ b/drivers/staging/rt3070/common/rtusb_io.c
@@ -0,0 +1,1908 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 rtusb_io.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Name Date Modification logs
36 Paul Lin 06-25-2004 created
37*/
38
39#include "../rt_config.h"
40
41
42/*
43 ========================================================================
44
45 Routine Description: NIC initialization complete
46
47 Arguments:
48
49 Return Value:
50
51 IRQL =
52
53 Note:
54
55 ========================================================================
56*/
57
58NTSTATUS RTUSBFirmwareRun(
59 IN PRTMP_ADAPTER pAd)
60{
61 NTSTATUS Status;
62
63 Status = RTUSB_VendorRequest(
64 pAd,
65 USBD_TRANSFER_DIRECTION_OUT,
66 DEVICE_VENDOR_REQUEST_OUT,
67 0x01,
68 0x8,
69 0,
70 NULL,
71 0);
72
73 return Status;
74}
75
76
77
78/*
79 ========================================================================
80
81 Routine Description: Write Firmware to NIC.
82
83 Arguments:
84
85 Return Value:
86
87 IRQL =
88
89 Note:
90
91 ========================================================================
92*/
93NTSTATUS RTUSBFirmwareWrite(
94 IN PRTMP_ADAPTER pAd,
95 IN PUCHAR pFwImage,
96 IN ULONG FwLen)
97{
98 UINT32 MacReg;
99 NTSTATUS Status;
100// ULONG i;
101 USHORT writeLen;
102
103 Status = RTUSBReadMACRegister(pAd, MAC_CSR0, &MacReg);
104
105
106 writeLen = FwLen;
107 RTUSBMultiWrite(pAd, FIRMWARE_IMAGE_BASE, pFwImage, writeLen);
108
109 Status = RTUSBWriteMACRegister(pAd, 0x7014, 0xffffffff);
110 Status = RTUSBWriteMACRegister(pAd, 0x701c, 0xffffffff);
111 Status = RTUSBFirmwareRun(pAd);
112
113 RTMPusecDelay(10000);
114 RTUSBWriteMACRegister(pAd,H2M_MAILBOX_CSR,0);
115 AsicSendCommandToMcu(pAd, 0x72, 0x00, 0x00, 0x00);//reset rf by MCU supported by new firmware
116
117 return Status;
118}
119
120
121/*
122 ========================================================================
123
124 Routine Description: Get current firmware operation mode (Return Value)
125
126 Arguments:
127
128 Return Value:
129 0 or 1 = Downloaded by host driver
130 others = Driver doesn't download firmware
131
132 IRQL =
133
134 Note:
135
136 ========================================================================
137*/
138NTSTATUS RTUSBFirmwareOpmode(
139 IN PRTMP_ADAPTER pAd,
140 OUT PUINT32 pValue)
141{
142 NTSTATUS Status;
143
144 Status = RTUSB_VendorRequest(
145 pAd,
146 (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
147 DEVICE_VENDOR_REQUEST_IN,
148 0x1,
149 0x11,
150 0,
151 pValue,
152 4);
153 return Status;
154}
155NTSTATUS RTUSBVenderReset(
156 IN PRTMP_ADAPTER pAd)
157{
158 NTSTATUS Status;
159 DBGPRINT_RAW(RT_DEBUG_ERROR, ("-->RTUSBVenderReset\n"));
160 Status = RTUSB_VendorRequest(
161 pAd,
162 USBD_TRANSFER_DIRECTION_OUT,
163 DEVICE_VENDOR_REQUEST_OUT,
164 0x01,
165 0x1,
166 0,
167 NULL,
168 0);
169
170 DBGPRINT_RAW(RT_DEBUG_ERROR, ("<--RTUSBVenderReset\n"));
171 return Status;
172}
173/*
174 ========================================================================
175
176 Routine Description: Read various length data from RT2573
177
178 Arguments:
179
180 Return Value:
181
182 IRQL =
183
184 Note:
185
186 ========================================================================
187*/
188NTSTATUS RTUSBMultiRead(
189 IN PRTMP_ADAPTER pAd,
190 IN USHORT Offset,
191 OUT PUCHAR pData,
192 IN USHORT length)
193{
194 NTSTATUS Status;
195
196 Status = RTUSB_VendorRequest(
197 pAd,
198 (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
199 DEVICE_VENDOR_REQUEST_IN,
200 0x7,
201 0,
202 Offset,
203 pData,
204 length);
205
206 return Status;
207}
208
209/*
210 ========================================================================
211
212 Routine Description: Write various length data to RT2573
213
214 Arguments:
215
216 Return Value:
217
218 IRQL =
219
220 Note:
221
222 ========================================================================
223*/
224NTSTATUS RTUSBMultiWrite_OneByte(
225 IN PRTMP_ADAPTER pAd,
226 IN USHORT Offset,
227 IN PUCHAR pData)
228{
229 NTSTATUS Status;
230
231 // TODO: In 2870, use this funciton carefully cause it's not stable.
232 Status = RTUSB_VendorRequest(
233 pAd,
234 USBD_TRANSFER_DIRECTION_OUT,
235 DEVICE_VENDOR_REQUEST_OUT,
236 0x6,
237 0,
238 Offset,
239 pData,
240 1);
241
242 return Status;
243}
244
245NTSTATUS RTUSBMultiWrite(
246 IN PRTMP_ADAPTER pAd,
247 IN USHORT Offset,
248 IN PUCHAR pData,
249 IN USHORT length)
250{
251 NTSTATUS Status;
252
253
254 USHORT index = 0,Value;
255 PUCHAR pSrc = pData;
256 USHORT resude = 0;
257
258 resude = length % 2;
259 length += resude;
260 do
261 {
262 Value =(USHORT)( *pSrc | (*(pSrc + 1) << 8));
263 Status = RTUSBSingleWrite(pAd,Offset + index,Value);
264 index +=2;
265 length -= 2;
266 pSrc = pSrc + 2;
267 }while(length > 0);
268
269 return Status;
270}
271
272
273NTSTATUS RTUSBSingleWrite(
274 IN RTMP_ADAPTER *pAd,
275 IN USHORT Offset,
276 IN USHORT Value)
277{
278 NTSTATUS Status;
279
280 Status = RTUSB_VendorRequest(
281 pAd,
282 USBD_TRANSFER_DIRECTION_OUT,
283 DEVICE_VENDOR_REQUEST_OUT,
284 0x2,
285 Value,
286 Offset,
287 NULL,
288 0);
289
290 return Status;
291
292}
293
294
295/*
296 ========================================================================
297
298 Routine Description: Read 32-bit MAC register
299
300 Arguments:
301
302 Return Value:
303
304 IRQL =
305
306 Note:
307
308 ========================================================================
309*/
310NTSTATUS RTUSBReadMACRegister(
311 IN PRTMP_ADAPTER pAd,
312 IN USHORT Offset,
313 OUT PUINT32 pValue)
314{
315 NTSTATUS Status;
316 UINT32 localVal;
317
318 Status = RTUSB_VendorRequest(
319 pAd,
320 (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
321 DEVICE_VENDOR_REQUEST_IN,
322 0x7,
323 0,
324 Offset,
325 &localVal,
326 4);
327
328 *pValue = le2cpu32(localVal);
329
330
331 if (Status < 0)
332 *pValue = 0xffffffff;
333
334 return Status;
335}
336
337
338/*
339 ========================================================================
340
341 Routine Description: Write 32-bit MAC register
342
343 Arguments:
344
345 Return Value:
346
347 IRQL =
348
349 Note:
350
351 ========================================================================
352*/
353NTSTATUS RTUSBWriteMACRegister(
354 IN PRTMP_ADAPTER pAd,
355 IN USHORT Offset,
356 IN UINT32 Value)
357{
358 NTSTATUS Status;
359 UINT32 localVal;
360
361 localVal = Value;
362
363 Status = RTUSBSingleWrite(pAd, Offset, (USHORT)(localVal & 0xffff));
364 Status = RTUSBSingleWrite(pAd, Offset + 2, (USHORT)((localVal & 0xffff0000) >> 16));
365
366 return Status;
367}
368
369
370
371#if 1
372/*
373 ========================================================================
374
375 Routine Description: Read 8-bit BBP register
376
377 Arguments:
378
379 Return Value:
380
381 IRQL =
382
383 Note:
384
385 ========================================================================
386*/
387NTSTATUS RTUSBReadBBPRegister(
388 IN PRTMP_ADAPTER pAd,
389 IN UCHAR Id,
390 IN PUCHAR pValue)
391{
392 BBP_CSR_CFG_STRUC BbpCsr;
393 UINT i = 0;
394 NTSTATUS status;
395
396 // Verify the busy condition
397 do
398 {
399 status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word);
400 if(status >= 0)
401 {
402 if (!(BbpCsr.field.Busy == BUSY))
403 break;
404 }
405 printk("RTUSBReadBBPRegister(BBP_CSR_CFG_1):retry count=%d!\n", i);
406 i++;
407 }
408 while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
409
410 if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
411 {
412 //
413 // Read failed then Return Default value.
414 //
415 *pValue = pAd->BbpWriteLatch[Id];
416
417 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
418 return STATUS_UNSUCCESSFUL;
419 }
420
421 // Prepare for write material
422 BbpCsr.word = 0;
423 BbpCsr.field.fRead = 1;
424 BbpCsr.field.Busy = 1;
425 BbpCsr.field.RegNum = Id;
426 RTUSBWriteMACRegister(pAd, BBP_CSR_CFG, BbpCsr.word);
427
428 i = 0;
429 // Verify the busy condition
430 do
431 {
432 status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word);
433 if (status >= 0)
434 {
435 if (!(BbpCsr.field.Busy == BUSY))
436 {
437 *pValue = (UCHAR)BbpCsr.field.Value;
438 break;
439 }
440 }
441 printk("RTUSBReadBBPRegister(BBP_CSR_CFG_2):retry count=%d!\n", i);
442 i++;
443 }
444 while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
445
446 if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
447 {
448 //
449 // Read failed then Return Default value.
450 //
451 *pValue = pAd->BbpWriteLatch[Id];
452
453 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
454 return STATUS_UNSUCCESSFUL;
455 }
456
457 return STATUS_SUCCESS;
458}
459#else
460/*
461 ========================================================================
462
463 Routine Description: Read 8-bit BBP register via firmware
464
465 Arguments:
466
467 Return Value:
468
469 IRQL =
470
471 Note:
472
473 ========================================================================
474*/
475NTSTATUS RTUSBReadBBPRegister(
476 IN PRTMP_ADAPTER pAd,
477 IN UCHAR Id,
478 IN PUCHAR pValue)
479{
480 BBP_CSR_CFG_STRUC BbpCsr;
481 int i, k;
482 for (i=0; i<MAX_BUSY_COUNT; i++)
483 {
484 RTUSBReadMACRegister(pAd, H2M_BBP_AGENT, &BbpCsr.word);
485 if (BbpCsr.field.Busy == BUSY)
486 {
487 continue;
488 }
489 BbpCsr.word = 0;
490 BbpCsr.field.fRead = 1;
491 BbpCsr.field.BBP_RW_MODE = 1;
492 BbpCsr.field.Busy = 1;
493 BbpCsr.field.RegNum = Id;
494 RTUSBWriteMACRegister(pAd, H2M_BBP_AGENT, BbpCsr.word);
495 AsicSendCommandToMcu(pAd, 0x80, 0xff, 0x0, 0x0);
496 for (k=0; k<MAX_BUSY_COUNT; k++)
497 {
498 RTUSBReadMACRegister(pAd, H2M_BBP_AGENT, &BbpCsr.word);
499 if (BbpCsr.field.Busy == IDLE)
500 break;
501 }
502 if ((BbpCsr.field.Busy == IDLE) &&
503 (BbpCsr.field.RegNum == Id))
504 {
505 *pValue = (UCHAR)BbpCsr.field.Value;
506 break;
507 }
508 }
509 if (BbpCsr.field.Busy == BUSY)
510 {
511 DBGPRINT_ERR(("BBP read R%d=0x%x fail\n", Id, BbpCsr.word));
512 *pValue = pAd->BbpWriteLatch[Id];
513 return STATUS_UNSUCCESSFUL;
514 }
515 return STATUS_SUCCESS;
516}
517#endif
518
519#if 1
520/*
521 ========================================================================
522
523 Routine Description: Write 8-bit BBP register
524
525 Arguments:
526
527 Return Value:
528
529 IRQL =
530
531 Note:
532
533 ========================================================================
534*/
535NTSTATUS RTUSBWriteBBPRegister(
536 IN PRTMP_ADAPTER pAd,
537 IN UCHAR Id,
538 IN UCHAR Value)
539{
540 BBP_CSR_CFG_STRUC BbpCsr;
541 UINT i = 0;
542 NTSTATUS status;
543 // Verify the busy condition
544 do
545 {
546 status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word);
547 if (status >= 0)
548 {
549 if (!(BbpCsr.field.Busy == BUSY))
550 break;
551 }
552 printk("RTUSBWriteBBPRegister(BBP_CSR_CFG):retry count=%d!\n", i);
553 i++;
554 }
555 while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
556
557 if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
558 {
559 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
560 return STATUS_UNSUCCESSFUL;
561 }
562
563 // Prepare for write material
564 BbpCsr.word = 0;
565 BbpCsr.field.fRead = 0;
566 BbpCsr.field.Value = Value;
567 BbpCsr.field.Busy = 1;
568 BbpCsr.field.RegNum = Id;
569 RTUSBWriteMACRegister(pAd, BBP_CSR_CFG, BbpCsr.word);
570
571 pAd->BbpWriteLatch[Id] = Value;
572
573 return STATUS_SUCCESS;
574}
575#else
576/*
577 ========================================================================
578
579 Routine Description: Write 8-bit BBP register via firmware
580
581 Arguments:
582
583 Return Value:
584
585 IRQL =
586
587 Note:
588
589 ========================================================================
590*/
591
592NTSTATUS RTUSBWriteBBPRegister(
593 IN PRTMP_ADAPTER pAd,
594 IN UCHAR Id,
595 IN UCHAR Value)
596
597{
598 BBP_CSR_CFG_STRUC BbpCsr;
599 int BusyCnt;
600 for (BusyCnt=0; BusyCnt<MAX_BUSY_COUNT; BusyCnt++)
601 {
602 RTMP_IO_READ32(pAd, H2M_BBP_AGENT, &BbpCsr.word);
603 if (BbpCsr.field.Busy == BUSY)
604 continue;
605 BbpCsr.word = 0;
606 BbpCsr.field.fRead = 0;
607 BbpCsr.field.BBP_RW_MODE = 1;
608 BbpCsr.field.Busy = 1;
609 BbpCsr.field.Value = Value;
610 BbpCsr.field.RegNum = Id;
611 RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, BbpCsr.word);
612 AsicSendCommandToMcu(pAd, 0x80, 0xff, 0x0, 0x0);
613 pAd->BbpWriteLatch[Id] = Value;
614 break;
615 }
616 if (BusyCnt == MAX_BUSY_COUNT)
617 {
618 DBGPRINT_ERR(("BBP write R%d=0x%x fail\n", Id, BbpCsr.word));
619 return STATUS_UNSUCCESSFUL;
620 }
621 return STATUS_SUCCESS;
622}
623#endif
624/*
625 ========================================================================
626
627 Routine Description: Write RF register through MAC
628
629 Arguments:
630
631 Return Value:
632
633 IRQL =
634
635 Note:
636
637 ========================================================================
638*/
639NTSTATUS RTUSBWriteRFRegister(
640 IN PRTMP_ADAPTER pAd,
641 IN UINT32 Value)
642{
643 PHY_CSR4_STRUC PhyCsr4;
644 UINT i = 0;
645 NTSTATUS status;
646
647 NdisZeroMemory(&PhyCsr4, sizeof(PHY_CSR4_STRUC));
648 do
649 {
650 status = RTUSBReadMACRegister(pAd, RF_CSR_CFG0, &PhyCsr4.word);
651 if (status >= 0)
652 {
653 if (!(PhyCsr4.field.Busy))
654 break;
655 }
656 printk("RTUSBWriteRFRegister(RF_CSR_CFG0):retry count=%d!\n", i);
657 i++;
658 }
659 while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
660
661 if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
662 {
663 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
664 return STATUS_UNSUCCESSFUL;
665 }
666
667 RTUSBWriteMACRegister(pAd, RF_CSR_CFG0, Value);
668
669 return STATUS_SUCCESS;
670}
671
672
673/*
674 ========================================================================
675
676 Routine Description:
677
678 Arguments:
679
680 Return Value:
681
682 IRQL =
683
684 Note:
685
686 ========================================================================
687*/
688NTSTATUS RTUSBReadEEPROM(
689 IN PRTMP_ADAPTER pAd,
690 IN USHORT Offset,
691 OUT PUCHAR pData,
692 IN USHORT length)
693{
694 NTSTATUS Status = STATUS_SUCCESS;
695
696#ifdef RT30xx
697 if(pAd->bUseEfuse)
698 {
699 Status =eFuseRead(pAd, Offset, pData, length);
700 }
701 else
702#endif // RT30xx //
703 {
704 Status = RTUSB_VendorRequest(
705 pAd,
706 (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
707 DEVICE_VENDOR_REQUEST_IN,
708 0x9,
709 0,
710 Offset,
711 pData,
712 length);
713 }
714
715 return Status;
716}
717
718/*
719 ========================================================================
720
721 Routine Description:
722
723 Arguments:
724
725 Return Value:
726
727 IRQL =
728
729 Note:
730
731 ========================================================================
732*/
733NTSTATUS RTUSBWriteEEPROM(
734 IN PRTMP_ADAPTER pAd,
735 IN USHORT Offset,
736 IN PUCHAR pData,
737 IN USHORT length)
738{
739 NTSTATUS Status = STATUS_SUCCESS;
740
741#ifdef RT30xx
742 if(pAd->bUseEfuse)
743 {
744 Status = eFuseWrite(pAd, Offset, pData, length);
745 }
746 else
747#endif // RT30xx //
748 {
749 Status = RTUSB_VendorRequest(
750 pAd,
751 USBD_TRANSFER_DIRECTION_OUT,
752 DEVICE_VENDOR_REQUEST_OUT,
753 0x8,
754 0,
755 Offset,
756 pData,
757 length);
758 }
759
760 return Status;
761}
762
763/*
764 ========================================================================
765
766 Routine Description:
767
768 Arguments:
769
770 Return Value:
771
772 IRQL =
773
774 Note:
775
776 ========================================================================
777*/
778VOID RTUSBPutToSleep(
779 IN PRTMP_ADAPTER pAd)
780{
781 UINT32 value;
782
783 // Timeout 0x40 x 50us
784 value = (SLEEPCID<<16)+(OWNERMCU<<24)+ (0x40<<8)+1;
785 RTUSBWriteMACRegister(pAd, 0x7010, value);
786 RTUSBWriteMACRegister(pAd, 0x404, 0x30);
787 //RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
788 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Sleep Mailbox testvalue %x\n", value));
789
790}
791
792/*
793 ========================================================================
794
795 Routine Description:
796
797 Arguments:
798
799 Return Value:
800
801 IRQL =
802
803 Note:
804
805 ========================================================================
806*/
807NTSTATUS RTUSBWakeUp(
808 IN PRTMP_ADAPTER pAd)
809{
810 NTSTATUS Status;
811
812 Status = RTUSB_VendorRequest(
813 pAd,
814 USBD_TRANSFER_DIRECTION_OUT,
815 DEVICE_VENDOR_REQUEST_OUT,
816 0x01,
817 0x09,
818 0,
819 NULL,
820 0);
821
822 return Status;
823}
824
825/*
826 ========================================================================
827
828 Routine Description:
829
830 Arguments:
831
832 Return Value:
833
834 IRQL =
835
836 Note:
837
838 ========================================================================
839*/
840VOID RTUSBInitializeCmdQ(
841 IN PCmdQ cmdq)
842{
843 cmdq->head = NULL;
844 cmdq->tail = NULL;
845 cmdq->size = 0;
846 cmdq->CmdQState = RT2870_THREAD_INITED;
847}
848
849/*
850 ========================================================================
851
852 Routine Description:
853
854 Arguments:
855
856 Return Value:
857
858 IRQL =
859
860 Note:
861
862 ========================================================================
863*/
864NDIS_STATUS RTUSBEnqueueCmdFromNdis(
865 IN PRTMP_ADAPTER pAd,
866 IN NDIS_OID Oid,
867 IN BOOLEAN SetInformation,
868 IN PVOID pInformationBuffer,
869 IN UINT32 InformationBufferLength)
870{
871 NDIS_STATUS status;
872 PCmdQElmt cmdqelmt = NULL;
873 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
874
875
876 if (pObj->RTUSBCmdThr_pid < 0)
877 return (NDIS_STATUS_RESOURCES);
878
879 status = RTMPAllocateMemory((PVOID *)&cmdqelmt, sizeof(CmdQElmt));
880 if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL))
881 return (NDIS_STATUS_RESOURCES);
882
883 cmdqelmt->buffer = NULL;
884 if (pInformationBuffer != NULL)
885 {
886 status = RTMPAllocateMemory((PVOID *)&cmdqelmt->buffer, InformationBufferLength);
887 if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt->buffer == NULL))
888 {
889 kfree(cmdqelmt);
890 return (NDIS_STATUS_RESOURCES);
891 }
892 else
893 {
894 NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer, InformationBufferLength);
895 cmdqelmt->bufferlength = InformationBufferLength;
896 }
897 }
898 else
899 cmdqelmt->bufferlength = 0;
900
901 cmdqelmt->command = Oid;
902 cmdqelmt->CmdFromNdis = TRUE;
903 if (SetInformation == TRUE)
904 cmdqelmt->SetOperation = TRUE;
905 else
906 cmdqelmt->SetOperation = FALSE;
907
908 NdisAcquireSpinLock(&pAd->CmdQLock);
909 if (pAd->CmdQ.CmdQState & RT2870_THREAD_CAN_DO_INSERT)
910 {
911 EnqueueCmd((&pAd->CmdQ), cmdqelmt);
912 status = NDIS_STATUS_SUCCESS;
913 }
914 else
915 {
916 status = NDIS_STATUS_FAILURE;
917 }
918 NdisReleaseSpinLock(&pAd->CmdQLock);
919
920 if (status == NDIS_STATUS_FAILURE)
921 {
922 if (cmdqelmt->buffer)
923 NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
924 NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
925 }
926 else
927 RTUSBCMDUp(pAd);
928
929
930 return(NDIS_STATUS_SUCCESS);
931}
932
933/*
934 ========================================================================
935
936 Routine Description:
937
938 Arguments:
939
940 Return Value:
941
942 IRQL =
943
944 Note:
945
946 ========================================================================
947*/
948NDIS_STATUS RTUSBEnqueueInternalCmd(
949 IN PRTMP_ADAPTER pAd,
950 IN NDIS_OID Oid,
951 IN PVOID pInformationBuffer,
952 IN UINT32 InformationBufferLength)
953{
954 NDIS_STATUS status;
955 PCmdQElmt cmdqelmt = NULL;
956
957
958 status = RTMPAllocateMemory((PVOID *)&cmdqelmt, sizeof(CmdQElmt));
959 if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL))
960 return (NDIS_STATUS_RESOURCES);
961 NdisZeroMemory(cmdqelmt, sizeof(CmdQElmt));
962
963 if(InformationBufferLength > 0)
964 {
965 status = RTMPAllocateMemory((PVOID *)&cmdqelmt->buffer, InformationBufferLength);
966 if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt->buffer == NULL))
967 {
968 NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
969 return (NDIS_STATUS_RESOURCES);
970 }
971 else
972 {
973 NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer, InformationBufferLength);
974 cmdqelmt->bufferlength = InformationBufferLength;
975 }
976 }
977 else
978 {
979 cmdqelmt->buffer = NULL;
980 cmdqelmt->bufferlength = 0;
981 }
982
983 cmdqelmt->command = Oid;
984 cmdqelmt->CmdFromNdis = FALSE;
985
986 if (cmdqelmt != NULL)
987 {
988 NdisAcquireSpinLock(&pAd->CmdQLock);
989 if (pAd->CmdQ.CmdQState & RT2870_THREAD_CAN_DO_INSERT)
990 {
991 EnqueueCmd((&pAd->CmdQ), cmdqelmt);
992 status = NDIS_STATUS_SUCCESS;
993 }
994 else
995 {
996 status = NDIS_STATUS_FAILURE;
997 }
998 NdisReleaseSpinLock(&pAd->CmdQLock);
999
1000 if (status == NDIS_STATUS_FAILURE)
1001 {
1002 if (cmdqelmt->buffer)
1003 NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
1004 NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
1005 }
1006 else
1007 RTUSBCMDUp(pAd);
1008 }
1009 return(NDIS_STATUS_SUCCESS);
1010}
1011
1012/*
1013 ========================================================================
1014
1015 Routine Description:
1016
1017 Arguments:
1018
1019 Return Value:
1020
1021 IRQL =
1022
1023 Note:
1024
1025 ========================================================================
1026*/
1027VOID RTUSBDequeueCmd(
1028 IN PCmdQ cmdq,
1029 OUT PCmdQElmt *pcmdqelmt)
1030{
1031 *pcmdqelmt = cmdq->head;
1032
1033 if (*pcmdqelmt != NULL)
1034 {
1035 cmdq->head = cmdq->head->next;
1036 cmdq->size--;
1037 if (cmdq->size == 0)
1038 cmdq->tail = NULL;
1039 }
1040}
1041
1042/*
1043 ========================================================================
1044 usb_control_msg - Builds a control urb, sends it off and waits for completion
1045 @dev: pointer to the usb device to send the message to
1046 @pipe: endpoint "pipe" to send the message to
1047 @request: USB message request value
1048 @requesttype: USB message request type value
1049 @value: USB message value
1050 @index: USB message index value
1051 @data: pointer to the data to send
1052 @size: length in bytes of the data to send
1053 @timeout: time in jiffies to wait for the message to complete before
1054 timing out (if 0 the wait is forever)
1055 Context: !in_interrupt ()
1056
1057 This function sends a simple control message to a specified endpoint
1058 and waits for the message to complete, or timeout.
1059 If successful, it returns the number of bytes transferred, otherwise a negative error number.
1060
1061 Don't use this function from within an interrupt context, like a
1062 bottom half handler. If you need an asynchronous message, or need to send
1063 a message from within interrupt context, use usb_submit_urb()
1064 If a thread in your driver uses this call, make sure your disconnect()
1065 method can wait for it to complete. Since you don't have a handle on
1066 the URB used, you can't cancel the request.
1067
1068
1069 Routine Description:
1070
1071 Arguments:
1072
1073 Return Value:
1074
1075 Note:
1076
1077 ========================================================================
1078*/
1079NTSTATUS RTUSB_VendorRequest(
1080 IN PRTMP_ADAPTER pAd,
1081 IN UINT32 TransferFlags,
1082 IN UCHAR RequestType,
1083 IN UCHAR Request,
1084 IN USHORT Value,
1085 IN USHORT Index,
1086 IN PVOID TransferBuffer,
1087 IN UINT32 TransferBufferLength)
1088{
1089 int ret;
1090 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
1091
1092 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
1093 {
1094 DBGPRINT(RT_DEBUG_ERROR, ("device disconnected\n"));
1095 return -1;
1096 }
1097 else if (in_interrupt())
1098 {
1099 DBGPRINT(RT_DEBUG_ERROR, ("in_interrupt, RTUSB_VendorRequest Request%02x Value%04x Offset%04x\n",Request,Value,Index));
1100
1101 return -1;
1102 }
1103 else
1104 {
1105#define MAX_RETRY_COUNT 10
1106
1107 int retryCount = 0;
1108 void *tmpBuf = TransferBuffer;
1109
1110 // Acquire Control token
1111#ifdef INF_AMAZON_SE
1112 ret = down_interruptible(&(pAd->UsbVendorReq_semaphore));
1113 if (pAd->UsbVendorReqBuf)
1114 {
1115 ASSERT(TransferBufferLength <MAX_PARAM_BUFFER_SIZE);
1116
1117 tmpBuf = (void *)pAd->UsbVendorReqBuf;
1118 NdisZeroMemory(pAd->UsbVendorReqBuf, TransferBufferLength);
1119
1120 if (RequestType == DEVICE_VENDOR_REQUEST_OUT)
1121 NdisMoveMemory(tmpBuf, TransferBuffer, TransferBufferLength);
1122 }
1123#endif // INF_AMAZON_SE //
1124 do {
1125 if( RequestType == DEVICE_VENDOR_REQUEST_OUT)
1126 ret=usb_control_msg(pObj->pUsb_Dev, usb_sndctrlpipe( pObj->pUsb_Dev, 0 ), Request, RequestType, Value,Index, tmpBuf, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES);
1127 else if(RequestType == DEVICE_VENDOR_REQUEST_IN)
1128 ret=usb_control_msg(pObj->pUsb_Dev, usb_rcvctrlpipe( pObj->pUsb_Dev, 0 ), Request, RequestType, Value,Index, tmpBuf, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES);
1129 else
1130 {
1131 DBGPRINT(RT_DEBUG_ERROR, ("vendor request direction is failed\n"));
1132 ret = -1;
1133 }
1134
1135 retryCount++;
1136 if (ret < 0) {
1137 printk("#\n");
1138 RTMPusecDelay(5000);
1139 }
1140 } while((ret < 0) && (retryCount < MAX_RETRY_COUNT));
1141
1142#ifdef INF_AMAZON_SE
1143 if ((pAd->UsbVendorReqBuf) && (RequestType == DEVICE_VENDOR_REQUEST_IN))
1144 NdisMoveMemory(TransferBuffer, tmpBuf, TransferBufferLength);
1145 up(&(pAd->UsbVendorReq_semaphore));
1146#endif // INF_AMAZON_SE //
1147
1148 if (ret < 0) {
1149// DBGPRINT(RT_DEBUG_ERROR, ("USBVendorRequest failed ret=%d \n",ret));
1150 DBGPRINT(RT_DEBUG_ERROR, ("RTUSB_VendorRequest failed(%d),TxFlags=0x%x, ReqType=%s, Req=0x%x, Index=0x%x\n",
1151 ret, TransferFlags, (RequestType == DEVICE_VENDOR_REQUEST_OUT ? "OUT" : "IN"), Request, Index));
1152 if (Request == 0x2)
1153 DBGPRINT(RT_DEBUG_ERROR, ("\tRequest Value=0x%04x!\n", Value));
1154
1155 if ((TransferBuffer!= NULL) && (TransferBufferLength > 0))
1156 hex_dump("Failed TransferBuffer value", TransferBuffer, TransferBufferLength);
1157 }
1158 }
1159 return ret;
1160}
1161
1162/*
1163 ========================================================================
1164
1165 Routine Description:
1166 Creates an IRP to submite an IOCTL_INTERNAL_USB_RESET_PORT
1167 synchronously. Callers of this function must be running at
1168 PASSIVE LEVEL.
1169
1170 Arguments:
1171
1172 Return Value:
1173
1174 Note:
1175
1176 ========================================================================
1177*/
1178NTSTATUS RTUSB_ResetDevice(
1179 IN PRTMP_ADAPTER pAd)
1180{
1181 NTSTATUS Status = TRUE;
1182
1183 DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->USB_ResetDevice\n"));
1184 //RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS);
1185 return Status;
1186}
1187
1188VOID CMDHandler(
1189 IN PRTMP_ADAPTER pAd)
1190{
1191 PCmdQElmt cmdqelmt;
1192 PUCHAR pData;
1193 NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
1194// ULONG Now = 0;
1195 NTSTATUS ntStatus;
1196// unsigned long IrqFlags;
1197
1198 while (pAd->CmdQ.size > 0)
1199 {
1200 NdisStatus = NDIS_STATUS_SUCCESS;
1201
1202 NdisAcquireSpinLock(&pAd->CmdQLock);
1203 RTUSBDequeueCmd(&pAd->CmdQ, &cmdqelmt);
1204 NdisReleaseSpinLock(&pAd->CmdQLock);
1205
1206 if (cmdqelmt == NULL)
1207 break;
1208
1209 pData = cmdqelmt->buffer;
1210
1211 if(!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
1212 {
1213 switch (cmdqelmt->command)
1214 {
1215 case CMDTHREAD_CHECK_GPIO:
1216 {
1217#ifdef CONFIG_STA_SUPPORT
1218 UINT32 data;
1219#endif // CONFIG_STA_SUPPORT //
1220#ifdef RALINK_ATE
1221 if(ATE_ON(pAd))
1222 {
1223 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
1224 break;
1225 }
1226#endif // RALINK_ATE //
1227
1228#ifdef CONFIG_STA_SUPPORT
1229
1230
1231 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1232 {
1233 // Read GPIO pin2 as Hardware controlled radio state
1234
1235 RTUSBReadMACRegister( pAd, GPIO_CTRL_CFG, &data);
1236
1237 if (data & 0x04)
1238 {
1239 pAd->StaCfg.bHwRadio = TRUE;
1240 }
1241 else
1242 {
1243 pAd->StaCfg.bHwRadio = FALSE;
1244 }
1245
1246 if(pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
1247 {
1248 pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
1249 if(pAd->StaCfg.bRadio == TRUE)
1250 {
1251 DBGPRINT_RAW(RT_DEBUG_ERROR, ("!!! Radio On !!!\n"));
1252
1253 MlmeRadioOn(pAd);
1254 // Update extra information
1255 pAd->ExtraInfo = EXTRA_INFO_CLEAR;
1256 }
1257 else
1258 {
1259 DBGPRINT_RAW(RT_DEBUG_ERROR, ("!!! Radio Off !!!\n"));
1260
1261 MlmeRadioOff(pAd);
1262 // Update extra information
1263 pAd->ExtraInfo = HW_RADIO_OFF;
1264 }
1265 }
1266 }
1267#endif // CONFIG_STA_SUPPORT //
1268 }
1269 break;
1270
1271#ifdef CONFIG_STA_SUPPORT
1272 case CMDTHREAD_QKERIODIC_EXECUT:
1273 {
1274 StaQuickResponeForRateUpExec(NULL, pAd, NULL, NULL);
1275 }
1276 break;
1277#endif // CONFIG_STA_SUPPORT //
1278
1279 case CMDTHREAD_RESET_BULK_OUT:
1280 {
1281 UINT32 MACValue;
1282 UCHAR Index;
1283 int ret=0;
1284 PHT_TX_CONTEXT pHTTXContext;
1285// RTMP_TX_RING *pTxRing;
1286 unsigned long IrqFlags;
1287#ifdef RALINK_ATE
1288 PTX_CONTEXT pNullContext = &(pAd->NullContext);
1289#endif // RALINK_ATE //
1290 DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_OUT(ResetPipeid=0x%0x)===>\n", pAd->bulkResetPipeid));
1291 // All transfers must be aborted or cancelled before attempting to reset the pipe.
1292 //RTUSBCancelPendingBulkOutIRP(pAd);
1293 // Wait 10ms to let previous packet that are already in HW FIFO to clear. by MAXLEE 12-25-2007
1294 Index = 0;
1295 do
1296 {
1297 RTUSBReadMACRegister(pAd, TXRXQ_PCNT, &MACValue);
1298 if ((MACValue & 0xf00000/*0x800000*/) == 0)
1299 break;
1300 Index++;
1301 RTMPusecDelay(10000);
1302 }while(Index < 100);
1303 MACValue = 0;
1304 RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
1305 // To prevent Read Register error, we 2nd check the validity.
1306 if ((MACValue & 0xc00000) == 0)
1307 RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
1308 // To prevent Read Register error, we 3rd check the validity.
1309 if ((MACValue & 0xc00000) == 0)
1310 RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
1311 MACValue |= 0x80000;
1312 RTUSBWriteMACRegister(pAd, USB_DMA_CFG, MACValue);
1313
1314 // Wait 1ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007
1315 RTMPusecDelay(1000);
1316
1317 MACValue &= (~0x80000);
1318 RTUSBWriteMACRegister(pAd, USB_DMA_CFG, MACValue);
1319 DBGPRINT_RAW(RT_DEBUG_TRACE, ("\tSet 0x2a0 bit19. Clear USB DMA TX path\n"));
1320
1321 // Wait 5ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007
1322 //RTMPusecDelay(5000);
1323
1324 if ((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG)
1325 {
1326 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1327 if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE /* pMLMEContext->bWaitingBulkOut == TRUE */)
1328 {
1329 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
1330 }
1331 RTUSBKickBulkOut(pAd);
1332
1333 DBGPRINT_RAW(RT_DEBUG_TRACE, ("\tTX MGMT RECOVER Done!\n"));
1334 }
1335 else
1336 {
1337 pHTTXContext = &(pAd->TxContext[pAd->bulkResetPipeid]);
1338 //NdisAcquireSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
1339 RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1340 if ( pAd->BulkOutPending[pAd->bulkResetPipeid] == FALSE)
1341 {
1342 pAd->BulkOutPending[pAd->bulkResetPipeid] = TRUE;
1343 pHTTXContext->IRPPending = TRUE;
1344 pAd->watchDogTxPendingCnt[pAd->bulkResetPipeid] = 1;
1345
1346 // no matter what, clean the flag
1347 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1348
1349 //NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
1350 RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1351/*-----------------------------------------------------------------------------------------------*/
1352#ifdef RALINK_ATE
1353 if(ATE_ON(pAd))
1354 {
1355 pNullContext->IRPPending = TRUE;
1356 //
1357 // If driver is still in ATE TXFRAME mode,
1358 // keep on transmitting ATE frames.
1359 //
1360 DBGPRINT_RAW(RT_DEBUG_TRACE, ("pAd->ate.Mode == %d\npAd->ContinBulkOut == %d\npAd->BulkOutRemained == %d\n", pAd->ate.Mode, pAd->ContinBulkOut, atomic_read(&pAd->BulkOutRemained)));
1361 if((pAd->ate.Mode == ATE_TXFRAME) && ((pAd->ContinBulkOut == TRUE) || (atomic_read(&pAd->BulkOutRemained) > 0)))
1362 {
1363 DBGPRINT_RAW(RT_DEBUG_TRACE, ("After CMDTHREAD_RESET_BULK_OUT, continue to bulk out frames !\n"));
1364
1365 // Init Tx context descriptor
1366 RTUSBInitTxDesc(pAd, pNullContext, 0/* pAd->bulkResetPipeid */, (usb_complete_t)ATE_RTUSBBulkOutDataPacketComplete);
1367
1368 if((ret = RTUSB_SUBMIT_URB(pNullContext->pUrb))!=0)
1369 {
1370 DBGPRINT(RT_DEBUG_ERROR, ("ATE_RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret));
1371 }
1372
1373 pAd->BulkOutReq++;
1374 }
1375 }
1376 else
1377#endif // RALINK_ATE //
1378/*-----------------------------------------------------------------------------------------------*/
1379 {
1380 RTUSBInitHTTxDesc(pAd, pHTTXContext, pAd->bulkResetPipeid, pHTTXContext->BulkOutSize, (usb_complete_t)RTUSBBulkOutDataPacketComplete);
1381
1382 if((ret = RTUSB_SUBMIT_URB(pHTTXContext->pUrb))!=0)
1383 {
1384 RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1385 pAd->BulkOutPending[pAd->bulkResetPipeid] = FALSE;
1386 pHTTXContext->IRPPending = FALSE;
1387 pAd->watchDogTxPendingCnt[pAd->bulkResetPipeid] = 0;
1388 RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1389
1390 DBGPRINT(RT_DEBUG_ERROR, ("CmdThread : CMDTHREAD_RESET_BULK_OUT: Submit Tx URB failed %d\n", ret));
1391 }
1392 else
1393 {
1394 RTMP_IRQ_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1395 DBGPRINT_RAW(RT_DEBUG_TRACE,("\tCMDTHREAD_RESET_BULK_OUT: TxContext[%d]:CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, pending=%d!\n",
1396 pAd->bulkResetPipeid, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition,
1397 pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad, pAd->BulkOutPending[pAd->bulkResetPipeid]));
1398 DBGPRINT_RAW(RT_DEBUG_TRACE,("\t\tBulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n",
1399 pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther));
1400 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1401 DBGPRINT_RAW(RT_DEBUG_TRACE, ("\tCMDTHREAD_RESET_BULK_OUT: Submit Tx DATA URB for failed BulkReq(0x%lx) Done, status=%d!\n", pAd->bulkResetReq[pAd->bulkResetPipeid], pHTTXContext->pUrb->status));
1402
1403 }
1404 }
1405 }
1406 else
1407 {
1408 //NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
1409 //RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1410
1411 DBGPRINT_RAW(RT_DEBUG_ERROR, ("CmdThread : TX DATA RECOVER FAIL for BulkReq(0x%lx) because BulkOutPending[%d] is TRUE!\n", pAd->bulkResetReq[pAd->bulkResetPipeid], pAd->bulkResetPipeid));
1412 if (pAd->bulkResetPipeid == 0)
1413 {
1414 UCHAR pendingContext = 0;
1415 PHT_TX_CONTEXT pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[pAd->bulkResetPipeid ]);
1416 PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa);
1417 PTX_CONTEXT pNULLContext = (PTX_CONTEXT)(&pAd->PsPollContext);
1418 PTX_CONTEXT pPsPollContext = (PTX_CONTEXT)(&pAd->NullContext);
1419
1420 if (pHTTXContext->IRPPending)
1421 pendingContext |= 1;
1422 else if (pMLMEContext->IRPPending)
1423 pendingContext |= 2;
1424 else if (pNULLContext->IRPPending)
1425 pendingContext |= 4;
1426 else if (pPsPollContext->IRPPending)
1427 pendingContext |= 8;
1428 else
1429 pendingContext = 0;
1430
1431 DBGPRINT_RAW(RT_DEBUG_ERROR, ("\tTX Occupied by %d!\n", pendingContext));
1432 }
1433
1434 // no matter what, clean the flag
1435 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1436
1437 RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1438
1439 RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << pAd->bulkResetPipeid));
1440 }
1441
1442 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1443 //RTUSBKickBulkOut(pAd);
1444 }
1445
1446 }
1447 /*
1448 // Don't cancel BULKIN.
1449 while ((atomic_read(&pAd->PendingRx) > 0) &&
1450 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
1451 {
1452 if (atomic_read(&pAd->PendingRx) > 0)
1453 {
1454 DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!cancel it!\n"));
1455 RTUSBCancelPendingBulkInIRP(pAd);
1456 }
1457 RTMPusecDelay(100000);
1458 }
1459
1460 if ((atomic_read(&pAd->PendingRx) == 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
1461 {
1462 UCHAR i;
1463 RTUSBRxPacket(pAd);
1464 pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index
1465 pAd->NextRxBulkInIndex = 0; // Rx Bulk pointer
1466 for (i = 0; i < (RX_RING_SIZE); i++)
1467 {
1468 PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
1469
1470 pRxContext->pAd = pAd;
1471 pRxContext->InUse = FALSE;
1472 pRxContext->IRPPending = FALSE;
1473 pRxContext->Readable = FALSE;
1474 pRxContext->ReorderInUse = FALSE;
1475
1476 }
1477 RTUSBBulkReceive(pAd);
1478 DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTUSBBulkReceive\n"));
1479 }*/
1480 DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_OUT<===\n"));
1481 break;
1482
1483 case CMDTHREAD_RESET_BULK_IN:
1484 DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_IN === >\n"));
1485
1486 // All transfers must be aborted or cancelled before attempting to reset the pipe.
1487 {
1488 UINT32 MACValue;
1489/*-----------------------------------------------------------------------------------------------*/
1490#ifdef RALINK_ATE
1491 if (ATE_ON(pAd))
1492 {
1493 if((pAd->PendingRx > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
1494 {
1495 DBGPRINT_RAW(RT_DEBUG_ERROR, ("ATE : BulkIn IRP Pending!!!\n"));
1496 ATE_RTUSBCancelPendingBulkInIRP(pAd);
1497 RTMPusecDelay(100000);
1498 pAd->PendingRx = 0;
1499 }
1500 }
1501 else
1502#endif // RALINK_ATE //
1503/*-----------------------------------------------------------------------------------------------*/
1504 {
1505 //while ((atomic_read(&pAd->PendingRx) > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
1506 if((pAd->PendingRx > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
1507 {
1508 DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!!\n"));
1509 RTUSBCancelPendingBulkInIRP(pAd);
1510 RTMPusecDelay(100000);
1511 pAd->PendingRx = 0;
1512 }
1513 }
1514
1515 // Wait 10ms before reading register.
1516 RTMPusecDelay(10000);
1517 ntStatus = RTUSBReadMACRegister(pAd, MAC_CSR0, &MACValue);
1518
1519 if ((NT_SUCCESS(ntStatus) == TRUE) &&
1520 (!(RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF |
1521 fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)))))
1522 {
1523 UCHAR i;
1524
1525 if (RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF |
1526 fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)))
1527 break;
1528 pAd->NextRxBulkInPosition = pAd->RxContext[pAd->NextRxBulkInIndex].BulkInOffset;
1529 DBGPRINT(RT_DEBUG_TRACE, ("BULK_IN_RESET: NBIIdx=0x%x,NBIRIdx=0x%x, BIRPos=0x%lx. BIReq=x%lx, BIComplete=0x%lx, BICFail0x%lx\n",
1530 pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex, pAd->NextRxBulkInPosition, pAd->BulkInReq, pAd->BulkInComplete, pAd->BulkInCompleteFail));
1531 for (i = 0; i < RX_RING_SIZE; i++)
1532 {
1533 DBGPRINT(RT_DEBUG_TRACE, ("\tRxContext[%d]: IRPPending=%d, InUse=%d, Readable=%d!\n"
1534 , i, pAd->RxContext[i].IRPPending, pAd->RxContext[i].InUse, pAd->RxContext[i].Readable));
1535 }
1536 /*
1537
1538 DBGPRINT_RAW(RT_DEBUG_ERROR, ("==========================================\n"));
1539
1540 pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index
1541 pAd->NextRxBulkInIndex = 0; // Rx Bulk pointer
1542 for (i = 0; i < (RX_RING_SIZE); i++)
1543 {
1544 PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
1545
1546 pRxContext->pAd = pAd;
1547 pRxContext->InUse = FALSE;
1548 pRxContext->IRPPending = FALSE;
1549 pRxContext->Readable = FALSE;
1550 pRxContext->ReorderInUse = FALSE;
1551
1552 }*/
1553 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
1554 for (i = 0; i < pAd->CommonCfg.NumOfBulkInIRP; i++)
1555 {
1556 //RTUSBBulkReceive(pAd);
1557 PRX_CONTEXT pRxContext;
1558 PURB pUrb;
1559 int ret = 0;
1560 unsigned long IrqFlags;
1561
1562
1563 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1564 pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
1565 if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) || (pRxContext->InUse == TRUE))
1566 {
1567 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1568 break;
1569 }
1570 pRxContext->InUse = TRUE;
1571 pRxContext->IRPPending = TRUE;
1572 pAd->PendingRx++;
1573 pAd->BulkInReq++;
1574 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1575
1576 // Init Rx context descriptor
1577 RTUSBInitRxDesc(pAd, pRxContext);
1578 pUrb = pRxContext->pUrb;
1579 if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
1580 { // fail
1581
1582 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1583 pRxContext->InUse = FALSE;
1584 pRxContext->IRPPending = FALSE;
1585 pAd->PendingRx--;
1586 pAd->BulkInReq--;
1587 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1588 DBGPRINT(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB failed(%d), status=%d\n", ret, pUrb->status));
1589 }
1590 else
1591 { // success
1592 DBGPRINT_RAW(RT_DEBUG_TRACE, ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB Done, status=%d!\n", pUrb->status));
1593 ASSERT((pRxContext->InUse == pRxContext->IRPPending));
1594 }
1595 }
1596
1597 }
1598 else
1599 {
1600 // Card must be removed
1601 if (NT_SUCCESS(ntStatus) != TRUE)
1602 {
1603 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
1604 DBGPRINT_RAW(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Read Register Failed!Card must be removed!!\n\n"));
1605 }
1606 else
1607 {
1608 DBGPRINT_RAW(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Cannot do bulk in because flags(0x%lx) on !\n", pAd->Flags));
1609 }
1610 }
1611 }
1612 DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_IN <===\n"));
1613 break;
1614
1615 case CMDTHREAD_SET_ASIC_WCID:
1616 {
1617 RT_SET_ASIC_WCID SetAsicWcid;
1618 USHORT offset;
1619 UINT32 MACValue, MACRValue = 0;
1620 SetAsicWcid = *((PRT_SET_ASIC_WCID)(pData));
1621
1622 if (SetAsicWcid.WCID >= MAX_LEN_OF_MAC_TABLE)
1623 return;
1624
1625 offset = MAC_WCID_BASE + ((UCHAR)SetAsicWcid.WCID)*HW_WCID_ENTRY_SIZE;
1626
1627 DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_SET_ASIC_WCID : WCID = %ld, SetTid = %lx, DeleteTid = %lx.\n", SetAsicWcid.WCID, SetAsicWcid.SetTid, SetAsicWcid.DeleteTid));
1628 MACValue = (pAd->MacTab.Content[SetAsicWcid.WCID].Addr[3]<<24)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[2]<<16)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[1]<<8)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[0]);
1629 DBGPRINT_RAW(RT_DEBUG_TRACE, ("1-MACValue= %x,\n", MACValue));
1630 RTUSBWriteMACRegister(pAd, offset, MACValue);
1631 // Read bitmask
1632 RTUSBReadMACRegister(pAd, offset+4, &MACRValue);
1633 if ( SetAsicWcid.DeleteTid != 0xffffffff)
1634 MACRValue &= (~SetAsicWcid.DeleteTid);
1635 if (SetAsicWcid.SetTid != 0xffffffff)
1636 MACRValue |= (SetAsicWcid.SetTid);
1637 MACRValue &= 0xffff0000;
1638
1639 MACValue = (pAd->MacTab.Content[SetAsicWcid.WCID].Addr[5]<<8)+pAd->MacTab.Content[SetAsicWcid.WCID].Addr[4];
1640 MACValue |= MACRValue;
1641 RTUSBWriteMACRegister(pAd, offset+4, MACValue);
1642
1643 DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-MACValue= %x,\n", MACValue));
1644 }
1645 break;
1646
1647 case CMDTHREAD_SET_ASIC_WCID_CIPHER:
1648 {
1649#ifdef CONFIG_STA_SUPPORT
1650 RT_SET_ASIC_WCID_ATTRI SetAsicWcidAttri;
1651 USHORT offset;
1652 UINT32 MACRValue = 0;
1653 SHAREDKEY_MODE_STRUC csr1;
1654 SetAsicWcidAttri = *((PRT_SET_ASIC_WCID_ATTRI)(pData));
1655
1656 if (SetAsicWcidAttri.WCID >= MAX_LEN_OF_MAC_TABLE)
1657 return;
1658
1659 offset = MAC_WCID_ATTRIBUTE_BASE + ((UCHAR)SetAsicWcidAttri.WCID)*HW_WCID_ATTRI_SIZE;
1660
1661 DBGPRINT_RAW(RT_DEBUG_TRACE, ("Cmd : CMDTHREAD_SET_ASIC_WCID_CIPHER : WCID = %ld, Cipher = %lx.\n", SetAsicWcidAttri.WCID, SetAsicWcidAttri.Cipher));
1662 // Read bitmask
1663 RTUSBReadMACRegister(pAd, offset, &MACRValue);
1664 MACRValue = 0;
1665 MACRValue |= (((UCHAR)SetAsicWcidAttri.Cipher) << 1);
1666
1667 RTUSBWriteMACRegister(pAd, offset, MACRValue);
1668 DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-offset = %x , MACValue= %x,\n", offset, MACRValue));
1669
1670 offset = PAIRWISE_IVEIV_TABLE_BASE + ((UCHAR)SetAsicWcidAttri.WCID)*HW_IVEIV_ENTRY_SIZE;
1671 MACRValue = 0;
1672 if ( (SetAsicWcidAttri.Cipher <= CIPHER_WEP128))
1673 MACRValue |= ( pAd->StaCfg.DefaultKeyId << 30);
1674 else
1675 MACRValue |= (0x20000000);
1676 RTUSBWriteMACRegister(pAd, offset, MACRValue);
1677 DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-offset = %x , MACValue= %x,\n", offset, MACRValue));
1678
1679 //
1680 // Update cipher algorithm. WSTA always use BSS0
1681 //
1682 // for adhoc mode only ,because wep status slow than add key, when use zero config
1683 if (pAd->StaCfg.BssType == BSS_ADHOC )
1684 {
1685 offset = MAC_WCID_ATTRIBUTE_BASE;
1686
1687 RTUSBReadMACRegister(pAd, offset, &MACRValue);
1688 MACRValue &= (~0xe);
1689 MACRValue |= (((UCHAR)SetAsicWcidAttri.Cipher) << 1);
1690
1691 RTUSBWriteMACRegister(pAd, offset, MACRValue);
1692
1693 //Update group key cipher,,because wep status slow than add key, when use zero config
1694 RTUSBReadMACRegister(pAd, SHARED_KEY_MODE_BASE+4*(0/2), &csr1.word);
1695
1696 csr1.field.Bss0Key0CipherAlg = SetAsicWcidAttri.Cipher;
1697 csr1.field.Bss0Key1CipherAlg = SetAsicWcidAttri.Cipher;
1698
1699 RTUSBWriteMACRegister(pAd, SHARED_KEY_MODE_BASE+4*(0/2), csr1.word);
1700 }
1701#endif // CONFIG_STA_SUPPORT //
1702 }
1703 break;
1704
1705//Benson modified for USB interface, avoid in interrupt when write key, 20080724 -->
1706 case RT_CMD_SET_KEY_TABLE: //General call for AsicAddPairwiseKeyEntry()
1707 {
1708 RT_ADD_PAIRWISE_KEY_ENTRY KeyInfo;
1709 KeyInfo = *((PRT_ADD_PAIRWISE_KEY_ENTRY)(pData));
1710 AsicAddPairwiseKeyEntry(pAd,
1711 KeyInfo.MacAddr,
1712 (UCHAR)KeyInfo.MacTabMatchWCID,
1713 &KeyInfo.CipherKey);
1714 }
1715 break;
1716 case RT_CMD_SET_RX_WCID_TABLE: //General call for RTMPAddWcidAttributeEntry()
1717 {
1718 PMAC_TABLE_ENTRY pEntry;
1719 UCHAR KeyIdx;
1720 UCHAR CipherAlg;
1721 UCHAR ApIdx;
1722
1723 pEntry = (PMAC_TABLE_ENTRY)(pData);
1724
1725#ifdef CONFIG_STA_SUPPORT
1726#ifdef QOS_DLS_SUPPORT
1727 KeyIdx = 0;
1728 CipherAlg = pEntry->PairwiseKey.CipherAlg;
1729 ApIdx = BSS0;
1730#endif // QOS_DLS_SUPPORT //
1731#endif // CONFIG_STA_SUPPORT //
1732
1733
1734 RTMPAddWcidAttributeEntry(
1735 pAd,
1736 ApIdx,
1737 KeyIdx,
1738 CipherAlg,
1739 pEntry);
1740 }
1741 break;
1742//Benson modified for USB interface, avoid in interrupt when write key, 20080724 <--
1743
1744 case CMDTHREAD_SET_CLIENT_MAC_ENTRY:
1745 {
1746 MAC_TABLE_ENTRY *pEntry;
1747 pEntry = (MAC_TABLE_ENTRY *)pData;
1748
1749
1750#ifdef CONFIG_STA_SUPPORT
1751 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1752 {
1753 AsicRemovePairwiseKeyEntry(pAd, pEntry->apidx, (UCHAR)pEntry->Aid);
1754 if ((pEntry->AuthMode <= Ndis802_11AuthModeAutoSwitch) && (pEntry->WepStatus == Ndis802_11Encryption1Enabled))
1755 {
1756 UINT32 uIV = 0;
1757 PUCHAR ptr;
1758
1759 ptr = (PUCHAR) &uIV;
1760 *(ptr + 3) = (pAd->StaCfg.DefaultKeyId << 6);
1761 AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, uIV, 0);
1762 AsicUpdateWCIDAttribute(pAd, pEntry->Aid, BSS0, pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg, FALSE);
1763 }
1764 else if (pEntry->AuthMode == Ndis802_11AuthModeWPANone)
1765 {
1766 UINT32 uIV = 0;
1767 PUCHAR ptr;
1768
1769 ptr = (PUCHAR) &uIV;
1770 *(ptr + 3) = (pAd->StaCfg.DefaultKeyId << 6);
1771 AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, uIV, 0);
1772 AsicUpdateWCIDAttribute(pAd, pEntry->Aid, BSS0, pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg, FALSE);
1773 }
1774 else
1775 {
1776 //
1777 // Other case, disable engine.
1778 // Don't worry WPA key, we will add WPA Key after 4-Way handshaking.
1779 //
1780 USHORT offset;
1781 offset = MAC_WCID_ATTRIBUTE_BASE + (pEntry->Aid * HW_WCID_ATTRI_SIZE);
1782 // RX_PKEY_MODE:0 for no security; RX_KEY_TAB:0 for shared key table; BSS_IDX:0
1783 RTUSBWriteMACRegister(pAd, offset, 0);
1784 }
1785 }
1786#endif // CONFIG_STA_SUPPORT //
1787
1788 AsicUpdateRxWCIDTable(pAd, pEntry->Aid, pEntry->Addr);
1789 printk("UpdateRxWCIDTable(): Aid=%d, Addr=%02x:%02x:%02x:%02x:%02x:%02x!\n", pEntry->Aid,
1790 pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2], pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
1791 }
1792 break;
1793
1794// add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
1795 case CMDTHREAD_UPDATE_PROTECT:
1796 {
1797 AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT), TRUE, 0);
1798 }
1799 break;
1800// end johnli
1801
1802 case OID_802_11_ADD_WEP:
1803 {
1804#ifdef CONFIG_STA_SUPPORT
1805 UINT i;
1806 UINT32 KeyIdx;
1807 PNDIS_802_11_WEP pWepKey;
1808
1809 DBGPRINT(RT_DEBUG_TRACE, ("CmdThread::OID_802_11_ADD_WEP \n"));
1810
1811 pWepKey = (PNDIS_802_11_WEP)pData;
1812 KeyIdx = pWepKey->KeyIndex & 0x0fffffff;
1813
1814 // it is a shared key
1815 if ((KeyIdx >= 4) || ((pWepKey->KeyLength != 5) && (pWepKey->KeyLength != 13)))
1816 {
1817 NdisStatus = NDIS_STATUS_INVALID_DATA;
1818 DBGPRINT(RT_DEBUG_ERROR, ("CmdThread::OID_802_11_ADD_WEP, INVALID_DATA!!\n"));
1819 }
1820 else
1821 {
1822 UCHAR CipherAlg;
1823 pAd->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
1824 NdisMoveMemory(pAd->SharedKey[BSS0][KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
1825 CipherAlg = (pAd->SharedKey[BSS0][KeyIdx].KeyLen == 5)? CIPHER_WEP64 : CIPHER_WEP128;
1826
1827 //
1828 // Change the WEP cipher to CKIP cipher if CKIP KP on.
1829 // Funk UI or Meetinghouse UI will add ckip key from this path.
1830 //
1831
1832 if (pAd->OpMode == OPMODE_STA)
1833 {
1834 pAd->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
1835 pAd->MacTab.Content[BSSID_WCID].PairwiseKey.KeyLen = pAd->SharedKey[BSS0][KeyIdx].KeyLen;
1836 }
1837 pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CipherAlg;
1838 if (pWepKey->KeyIndex & 0x80000000)
1839 {
1840 // Default key for tx (shared key)
1841 UCHAR IVEIV[8];
1842 UINT32 WCIDAttri, Value;
1843 USHORT offset, offset2;
1844 NdisZeroMemory(IVEIV, 8);
1845 pAd->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
1846 // Add BSSID to WCTable. because this is Tx wep key.
1847 // WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:1=PAIRWISE KEY, BSSIdx is 0
1848 WCIDAttri = (CipherAlg<<1)|SHAREDKEYTABLE;
1849
1850 offset = MAC_WCID_ATTRIBUTE_BASE + (BSSID_WCID* HW_WCID_ATTRI_SIZE);
1851 RTUSBWriteMACRegister(pAd, offset, WCIDAttri);
1852 // 1. IV/EIV
1853 // Specify key index to find shared key.
1854 IVEIV[3] = (UCHAR)(KeyIdx<< 6); //WEP Eiv bit off. groupkey index is not 0
1855 offset = PAIRWISE_IVEIV_TABLE_BASE + (BSS0Mcast_WCID * HW_IVEIV_ENTRY_SIZE);
1856 offset2 = PAIRWISE_IVEIV_TABLE_BASE + (BSSID_WCID* HW_IVEIV_ENTRY_SIZE);
1857 for (i=0; i<8;)
1858 {
1859 Value = IVEIV[i];
1860 Value += (IVEIV[i+1]<<8);
1861 Value += (IVEIV[i+2]<<16);
1862 Value += (IVEIV[i+3]<<24);
1863 RTUSBWriteMACRegister(pAd, offset+i, Value);
1864 RTUSBWriteMACRegister(pAd, offset2+i, Value);
1865 i+=4;
1866 }
1867
1868 // 2. WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:use share key, BSSIdx is 0
1869 WCIDAttri = (pAd->SharedKey[BSS0][KeyIdx].CipherAlg<<1)|SHAREDKEYTABLE;
1870 offset = MAC_WCID_ATTRIBUTE_BASE + (BSS0Mcast_WCID* HW_WCID_ATTRI_SIZE);
1871 DBGPRINT(RT_DEBUG_TRACE, ("BSS0Mcast_WCID : offset = %x, WCIDAttri = %x\n", offset, WCIDAttri));
1872 RTUSBWriteMACRegister(pAd, offset, WCIDAttri);
1873
1874 }
1875 AsicAddSharedKeyEntry(pAd, BSS0, (UCHAR)KeyIdx, CipherAlg, pWepKey->KeyMaterial, NULL, NULL);
1876 DBGPRINT(RT_DEBUG_TRACE, ("CmdThread::OID_802_11_ADD_WEP (KeyIdx=%d, Len=%d-byte)\n", KeyIdx, pWepKey->KeyLength));
1877 }
1878#endif // CONFIG_STA_SUPPORT //
1879 }
1880 break;
1881
1882 case CMDTHREAD_802_11_COUNTER_MEASURE:
1883 break;
1884
1885 default:
1886 DBGPRINT(RT_DEBUG_ERROR, ("--> Control Thread !! ERROR !! Unknown(cmdqelmt->command=0x%x) !! \n", cmdqelmt->command));
1887 break;
1888 }
1889 }
1890
1891 if (cmdqelmt->CmdFromNdis == TRUE)
1892 {
1893 if (cmdqelmt->buffer != NULL)
1894 NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
1895
1896 NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
1897 }
1898 else
1899 {
1900 if ((cmdqelmt->buffer != NULL) && (cmdqelmt->bufferlength != 0))
1901 NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
1902 {
1903 NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
1904 }
1905 }
1906 } /* end of while */
1907}
1908
diff --git a/drivers/staging/rt3070/common/spectrum.c b/drivers/staging/rt3070/common/spectrum.c
new file mode 100644
index 000000000000..da57b1202d64
--- /dev/null
+++ b/drivers/staging/rt3070/common/spectrum.c
@@ -0,0 +1,1876 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 action.c
29
30 Abstract:
31 Handle association related requests either from WSTA or from local MLME
32
33 Revision History:
34 Who When What
35 --------- ---------- ----------------------------------------------
36 Fonchi Wu 2008 created for 802.11h
37 */
38
39#include "../rt_config.h"
40#include "../action.h"
41
42VOID MeasureReqTabInit(
43 IN PRTMP_ADAPTER pAd)
44{
45 NdisAllocateSpinLock(&pAd->CommonCfg.MeasureReqTabLock);
46
47 pAd->CommonCfg.pMeasureReqTab = kmalloc(sizeof(MEASURE_REQ_TAB), GFP_ATOMIC);
48 if (pAd->CommonCfg.pMeasureReqTab)
49 NdisZeroMemory(pAd->CommonCfg.pMeasureReqTab, sizeof(MEASURE_REQ_TAB));
50 else
51 DBGPRINT(RT_DEBUG_ERROR, ("%s Fail to alloc memory for pAd->CommonCfg.pMeasureReqTab.\n", __FUNCTION__));
52
53 return;
54}
55
56VOID MeasureReqTabExit(
57 IN PRTMP_ADAPTER pAd)
58{
59 NdisFreeSpinLock(pAd->CommonCfg.MeasureReqTabLock);
60
61 if (pAd->CommonCfg.pMeasureReqTab)
62 kfree(pAd->CommonCfg.pMeasureReqTab);
63 pAd->CommonCfg.pMeasureReqTab = NULL;
64
65 return;
66}
67
68static PMEASURE_REQ_ENTRY MeasureReqLookUp(
69 IN PRTMP_ADAPTER pAd,
70 IN UINT8 DialogToken)
71{
72 UINT HashIdx;
73 PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab;
74 PMEASURE_REQ_ENTRY pEntry = NULL;
75 PMEASURE_REQ_ENTRY pPrevEntry = NULL;
76
77 if (pTab == NULL)
78 {
79 DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __FUNCTION__));
80 return NULL;
81 }
82
83 RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
84
85 HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(DialogToken);
86 pEntry = pTab->Hash[HashIdx];
87
88 while (pEntry)
89 {
90 if (pEntry->DialogToken == DialogToken)
91 break;
92 else
93 {
94 pPrevEntry = pEntry;
95 pEntry = pEntry->pNext;
96 }
97 }
98
99 RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
100
101 return pEntry;
102}
103
104static PMEASURE_REQ_ENTRY MeasureReqInsert(
105 IN PRTMP_ADAPTER pAd,
106 IN UINT8 DialogToken)
107{
108 INT i;
109 ULONG HashIdx;
110 PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab;
111 PMEASURE_REQ_ENTRY pEntry = NULL, pCurrEntry;
112 ULONG Now;
113
114 if(pTab == NULL)
115 {
116 DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __FUNCTION__));
117 return NULL;
118 }
119
120 pEntry = MeasureReqLookUp(pAd, DialogToken);
121 if (pEntry == NULL)
122 {
123 RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
124 for (i = 0; i < MAX_MEASURE_REQ_TAB_SIZE; i++)
125 {
126 NdisGetSystemUpTime(&Now);
127 pEntry = &pTab->Content[i];
128
129 if ((pEntry->Valid == TRUE)
130 && RTMP_TIME_AFTER((unsigned long)Now, (unsigned long)(pEntry->lastTime + MQ_REQ_AGE_OUT)))
131 {
132 PMEASURE_REQ_ENTRY pPrevEntry = NULL;
133 ULONG HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
134 PMEASURE_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
135
136 // update Hash list
137 do
138 {
139 if (pProbeEntry == pEntry)
140 {
141 if (pPrevEntry == NULL)
142 {
143 pTab->Hash[HashIdx] = pEntry->pNext;
144 }
145 else
146 {
147 pPrevEntry->pNext = pEntry->pNext;
148 }
149 break;
150 }
151
152 pPrevEntry = pProbeEntry;
153 pProbeEntry = pProbeEntry->pNext;
154 } while (pProbeEntry);
155
156 NdisZeroMemory(pEntry, sizeof(MEASURE_REQ_ENTRY));
157 pTab->Size--;
158
159 break;
160 }
161
162 if (pEntry->Valid == FALSE)
163 break;
164 }
165
166 if (i < MAX_MEASURE_REQ_TAB_SIZE)
167 {
168 NdisGetSystemUpTime(&Now);
169 pEntry->lastTime = Now;
170 pEntry->Valid = TRUE;
171 pEntry->DialogToken = DialogToken;
172 pTab->Size++;
173 }
174 else
175 {
176 pEntry = NULL;
177 DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab tab full.\n", __FUNCTION__));
178 }
179
180 // add this Neighbor entry into HASH table
181 if (pEntry)
182 {
183 HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(DialogToken);
184 if (pTab->Hash[HashIdx] == NULL)
185 {
186 pTab->Hash[HashIdx] = pEntry;
187 }
188 else
189 {
190 pCurrEntry = pTab->Hash[HashIdx];
191 while (pCurrEntry->pNext != NULL)
192 pCurrEntry = pCurrEntry->pNext;
193 pCurrEntry->pNext = pEntry;
194 }
195 }
196
197 RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
198 }
199
200 return pEntry;
201}
202
203static VOID MeasureReqDelete(
204 IN PRTMP_ADAPTER pAd,
205 IN UINT8 DialogToken)
206{
207 PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab;
208 PMEASURE_REQ_ENTRY pEntry = NULL;
209
210 if(pTab == NULL)
211 {
212 DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __FUNCTION__));
213 return;
214 }
215
216 // if empty, return
217 if (pTab->Size == 0)
218 {
219 DBGPRINT(RT_DEBUG_ERROR, ("pMeasureReqTab empty.\n"));
220 return;
221 }
222
223 pEntry = MeasureReqLookUp(pAd, DialogToken);
224 if (pEntry != NULL)
225 {
226 PMEASURE_REQ_ENTRY pPrevEntry = NULL;
227 ULONG HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
228 PMEASURE_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
229
230 RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
231 // update Hash list
232 do
233 {
234 if (pProbeEntry == pEntry)
235 {
236 if (pPrevEntry == NULL)
237 {
238 pTab->Hash[HashIdx] = pEntry->pNext;
239 }
240 else
241 {
242 pPrevEntry->pNext = pEntry->pNext;
243 }
244 break;
245 }
246
247 pPrevEntry = pProbeEntry;
248 pProbeEntry = pProbeEntry->pNext;
249 } while (pProbeEntry);
250
251 NdisZeroMemory(pEntry, sizeof(MEASURE_REQ_ENTRY));
252 pTab->Size--;
253
254 RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
255 }
256
257 return;
258}
259
260VOID TpcReqTabInit(
261 IN PRTMP_ADAPTER pAd)
262{
263 NdisAllocateSpinLock(&pAd->CommonCfg.TpcReqTabLock);
264
265 pAd->CommonCfg.pTpcReqTab = kmalloc(sizeof(TPC_REQ_TAB), GFP_ATOMIC);
266 if (pAd->CommonCfg.pTpcReqTab)
267 NdisZeroMemory(pAd->CommonCfg.pTpcReqTab, sizeof(TPC_REQ_TAB));
268 else
269 DBGPRINT(RT_DEBUG_ERROR, ("%s Fail to alloc memory for pAd->CommonCfg.pTpcReqTab.\n", __FUNCTION__));
270
271 return;
272}
273
274VOID TpcReqTabExit(
275 IN PRTMP_ADAPTER pAd)
276{
277 NdisFreeSpinLock(pAd->CommonCfg.TpcReqTabLock);
278
279 if (pAd->CommonCfg.pTpcReqTab)
280 kfree(pAd->CommonCfg.pTpcReqTab);
281 pAd->CommonCfg.pTpcReqTab = NULL;
282
283 return;
284}
285
286static PTPC_REQ_ENTRY TpcReqLookUp(
287 IN PRTMP_ADAPTER pAd,
288 IN UINT8 DialogToken)
289{
290 UINT HashIdx;
291 PTPC_REQ_TAB pTab = pAd->CommonCfg.pTpcReqTab;
292 PTPC_REQ_ENTRY pEntry = NULL;
293 PTPC_REQ_ENTRY pPrevEntry = NULL;
294
295 if (pTab == NULL)
296 {
297 DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab doesn't exist.\n", __FUNCTION__));
298 return NULL;
299 }
300
301 RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
302
303 HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(DialogToken);
304 pEntry = pTab->Hash[HashIdx];
305
306 while (pEntry)
307 {
308 if (pEntry->DialogToken == DialogToken)
309 break;
310 else
311 {
312 pPrevEntry = pEntry;
313 pEntry = pEntry->pNext;
314 }
315 }
316
317 RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
318
319 return pEntry;
320}
321
322
323static PTPC_REQ_ENTRY TpcReqInsert(
324 IN PRTMP_ADAPTER pAd,
325 IN UINT8 DialogToken)
326{
327 INT i;
328 ULONG HashIdx;
329 PTPC_REQ_TAB pTab = pAd->CommonCfg.pTpcReqTab;
330 PTPC_REQ_ENTRY pEntry = NULL, pCurrEntry;
331 ULONG Now;
332
333 if(pTab == NULL)
334 {
335 DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab doesn't exist.\n", __FUNCTION__));
336 return NULL;
337 }
338
339 pEntry = TpcReqLookUp(pAd, DialogToken);
340 if (pEntry == NULL)
341 {
342 RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
343 for (i = 0; i < MAX_TPC_REQ_TAB_SIZE; i++)
344 {
345 NdisGetSystemUpTime(&Now);
346 pEntry = &pTab->Content[i];
347
348 if ((pEntry->Valid == TRUE)
349 && RTMP_TIME_AFTER((unsigned long)Now, (unsigned long)(pEntry->lastTime + TPC_REQ_AGE_OUT)))
350 {
351 PTPC_REQ_ENTRY pPrevEntry = NULL;
352 ULONG HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
353 PTPC_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
354
355 // update Hash list
356 do
357 {
358 if (pProbeEntry == pEntry)
359 {
360 if (pPrevEntry == NULL)
361 {
362 pTab->Hash[HashIdx] = pEntry->pNext;
363 }
364 else
365 {
366 pPrevEntry->pNext = pEntry->pNext;
367 }
368 break;
369 }
370
371 pPrevEntry = pProbeEntry;
372 pProbeEntry = pProbeEntry->pNext;
373 } while (pProbeEntry);
374
375 NdisZeroMemory(pEntry, sizeof(TPC_REQ_ENTRY));
376 pTab->Size--;
377
378 break;
379 }
380
381 if (pEntry->Valid == FALSE)
382 break;
383 }
384
385 if (i < MAX_TPC_REQ_TAB_SIZE)
386 {
387 NdisGetSystemUpTime(&Now);
388 pEntry->lastTime = Now;
389 pEntry->Valid = TRUE;
390 pEntry->DialogToken = DialogToken;
391 pTab->Size++;
392 }
393 else
394 {
395 pEntry = NULL;
396 DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab tab full.\n", __FUNCTION__));
397 }
398
399 // add this Neighbor entry into HASH table
400 if (pEntry)
401 {
402 HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(DialogToken);
403 if (pTab->Hash[HashIdx] == NULL)
404 {
405 pTab->Hash[HashIdx] = pEntry;
406 }
407 else
408 {
409 pCurrEntry = pTab->Hash[HashIdx];
410 while (pCurrEntry->pNext != NULL)
411 pCurrEntry = pCurrEntry->pNext;
412 pCurrEntry->pNext = pEntry;
413 }
414 }
415
416 RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
417 }
418
419 return pEntry;
420}
421
422static VOID TpcReqDelete(
423 IN PRTMP_ADAPTER pAd,
424 IN UINT8 DialogToken)
425{
426 PTPC_REQ_TAB pTab = pAd->CommonCfg.pTpcReqTab;
427 PTPC_REQ_ENTRY pEntry = NULL;
428
429 if(pTab == NULL)
430 {
431 DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab doesn't exist.\n", __FUNCTION__));
432 return;
433 }
434
435 // if empty, return
436 if (pTab->Size == 0)
437 {
438 DBGPRINT(RT_DEBUG_ERROR, ("pTpcReqTab empty.\n"));
439 return;
440 }
441
442 pEntry = TpcReqLookUp(pAd, DialogToken);
443 if (pEntry != NULL)
444 {
445 PTPC_REQ_ENTRY pPrevEntry = NULL;
446 ULONG HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
447 PTPC_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
448
449 RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
450 // update Hash list
451 do
452 {
453 if (pProbeEntry == pEntry)
454 {
455 if (pPrevEntry == NULL)
456 {
457 pTab->Hash[HashIdx] = pEntry->pNext;
458 }
459 else
460 {
461 pPrevEntry->pNext = pEntry->pNext;
462 }
463 break;
464 }
465
466 pPrevEntry = pProbeEntry;
467 pProbeEntry = pProbeEntry->pNext;
468 } while (pProbeEntry);
469
470 NdisZeroMemory(pEntry, sizeof(TPC_REQ_ENTRY));
471 pTab->Size--;
472
473 RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
474 }
475
476 return;
477}
478
479/*
480 ==========================================================================
481 Description:
482 Get Current TimeS tamp.
483
484 Parametrs:
485
486 Return : Current Time Stamp.
487 ==========================================================================
488 */
489static UINT64 GetCurrentTimeStamp(
490 IN PRTMP_ADAPTER pAd)
491{
492 // get current time stamp.
493 return 0;
494}
495
496/*
497 ==========================================================================
498 Description:
499 Get Current Transmit Power.
500
501 Parametrs:
502
503 Return : Current Time Stamp.
504 ==========================================================================
505 */
506static UINT8 GetCurTxPwr(
507 IN PRTMP_ADAPTER pAd,
508 IN UINT8 Wcid)
509{
510 return 16; /* 16 dBm */
511}
512
513/*
514 ==========================================================================
515 Description:
516 Insert Dialog Token into frame.
517
518 Parametrs:
519 1. frame buffer pointer.
520 2. frame length.
521 3. Dialog token.
522
523 Return : None.
524 ==========================================================================
525 */
526static VOID InsertDialogToken(
527 IN PRTMP_ADAPTER pAd,
528 OUT PUCHAR pFrameBuf,
529 OUT PULONG pFrameLen,
530 IN UINT8 DialogToken)
531{
532 ULONG TempLen;
533 MakeOutgoingFrame(pFrameBuf, &TempLen,
534 1, &DialogToken,
535 END_OF_ARGS);
536
537 *pFrameLen = *pFrameLen + TempLen;
538
539 return;
540}
541
542/*
543 ==========================================================================
544 Description:
545 Insert TPC Request IE into frame.
546
547 Parametrs:
548 1. frame buffer pointer.
549 2. frame length.
550
551 Return : None.
552 ==========================================================================
553 */
554 static VOID InsertTpcReqIE(
555 IN PRTMP_ADAPTER pAd,
556 OUT PUCHAR pFrameBuf,
557 OUT PULONG pFrameLen)
558{
559 ULONG TempLen;
560 ULONG Len = 0;
561 UINT8 ElementID = IE_TPC_REQUEST;
562
563 MakeOutgoingFrame(pFrameBuf, &TempLen,
564 1, &ElementID,
565 1, &Len,
566 END_OF_ARGS);
567
568 *pFrameLen = *pFrameLen + TempLen;
569
570 return;
571}
572
573/*
574 ==========================================================================
575 Description:
576 Insert TPC Report IE into frame.
577
578 Parametrs:
579 1. frame buffer pointer.
580 2. frame length.
581 3. Transmit Power.
582 4. Link Margin.
583
584 Return : None.
585 ==========================================================================
586 */
587 static VOID InsertTpcReportIE(
588 IN PRTMP_ADAPTER pAd,
589 OUT PUCHAR pFrameBuf,
590 OUT PULONG pFrameLen,
591 IN UINT8 TxPwr,
592 IN UINT8 LinkMargin)
593{
594 ULONG TempLen;
595 ULONG Len = sizeof(TPC_REPORT_INFO);
596 UINT8 ElementID = IE_TPC_REPORT;
597 TPC_REPORT_INFO TpcReportIE;
598
599 TpcReportIE.TxPwr = TxPwr;
600 TpcReportIE.LinkMargin = LinkMargin;
601
602 MakeOutgoingFrame(pFrameBuf, &TempLen,
603 1, &ElementID,
604 1, &Len,
605 Len, &TpcReportIE,
606 END_OF_ARGS);
607
608 *pFrameLen = *pFrameLen + TempLen;
609
610
611 return;
612}
613
614/*
615 ==========================================================================
616 Description:
617 Insert Channel Switch Announcement IE into frame.
618
619 Parametrs:
620 1. frame buffer pointer.
621 2. frame length.
622 3. channel switch announcement mode.
623 4. new selected channel.
624 5. channel switch announcement count.
625
626 Return : None.
627 ==========================================================================
628 */
629static VOID InsertChSwAnnIE(
630 IN PRTMP_ADAPTER pAd,
631 OUT PUCHAR pFrameBuf,
632 OUT PULONG pFrameLen,
633 IN UINT8 ChSwMode,
634 IN UINT8 NewChannel,
635 IN UINT8 ChSwCnt)
636{
637 ULONG TempLen;
638 ULONG Len = sizeof(CH_SW_ANN_INFO);
639 UINT8 ElementID = IE_CHANNEL_SWITCH_ANNOUNCEMENT;
640 CH_SW_ANN_INFO ChSwAnnIE;
641
642 ChSwAnnIE.ChSwMode = ChSwMode;
643 ChSwAnnIE.Channel = NewChannel;
644 ChSwAnnIE.ChSwCnt = ChSwCnt;
645
646 MakeOutgoingFrame(pFrameBuf, &TempLen,
647 1, &ElementID,
648 1, &Len,
649 Len, &ChSwAnnIE,
650 END_OF_ARGS);
651
652 *pFrameLen = *pFrameLen + TempLen;
653
654
655 return;
656}
657
658/*
659 ==========================================================================
660 Description:
661 Insert Measure Request IE into frame.
662
663 Parametrs:
664 1. frame buffer pointer.
665 2. frame length.
666 3. Measure Token.
667 4. Measure Request Mode.
668 5. Measure Request Type.
669 6. Measure Channel.
670 7. Measure Start time.
671 8. Measure Duration.
672
673
674 Return : None.
675 ==========================================================================
676 */
677static VOID InsertMeasureReqIE(
678 IN PRTMP_ADAPTER pAd,
679 OUT PUCHAR pFrameBuf,
680 OUT PULONG pFrameLen,
681 IN PMEASURE_REQ_INFO pMeasureReqIE)
682{
683 ULONG TempLen;
684 UINT8 Len = sizeof(MEASURE_REQ_INFO);
685 UINT8 ElementID = IE_MEASUREMENT_REQUEST;
686
687 MakeOutgoingFrame(pFrameBuf, &TempLen,
688 1, &ElementID,
689 1, &Len,
690 Len, pMeasureReqIE,
691 END_OF_ARGS);
692
693 *pFrameLen = *pFrameLen + TempLen;
694
695 return;
696}
697
698/*
699 ==========================================================================
700 Description:
701 Insert Measure Report IE into frame.
702
703 Parametrs:
704 1. frame buffer pointer.
705 2. frame length.
706 3. Measure Token.
707 4. Measure Request Mode.
708 5. Measure Request Type.
709 6. Length of Report Infomation
710 7. Pointer of Report Infomation Buffer.
711
712 Return : None.
713 ==========================================================================
714 */
715static VOID InsertMeasureReportIE(
716 IN PRTMP_ADAPTER pAd,
717 OUT PUCHAR pFrameBuf,
718 OUT PULONG pFrameLen,
719 IN PMEASURE_REPORT_INFO pMeasureReportIE,
720 IN UINT8 ReportLnfoLen,
721 IN PUINT8 pReportInfo)
722{
723 ULONG TempLen;
724 ULONG Len;
725 UINT8 ElementID = IE_MEASUREMENT_REPORT;
726
727 Len = sizeof(MEASURE_REPORT_INFO) + ReportLnfoLen;
728
729 MakeOutgoingFrame(pFrameBuf, &TempLen,
730 1, &ElementID,
731 1, &Len,
732 Len, pMeasureReportIE,
733 END_OF_ARGS);
734
735 *pFrameLen = *pFrameLen + TempLen;
736
737 if ((ReportLnfoLen > 0) && (pReportInfo != NULL))
738 {
739 MakeOutgoingFrame(pFrameBuf + *pFrameLen, &TempLen,
740 ReportLnfoLen, pReportInfo,
741 END_OF_ARGS);
742
743 *pFrameLen = *pFrameLen + TempLen;
744 }
745 return;
746}
747
748/*
749 ==========================================================================
750 Description:
751 Prepare Measurement request action frame and enqueue it into
752 management queue waiting for transmition.
753
754 Parametrs:
755 1. the destination mac address of the frame.
756
757 Return : None.
758 ==========================================================================
759 */
760VOID EnqueueMeasurementReq(
761 IN PRTMP_ADAPTER pAd,
762 IN PUCHAR pDA,
763 IN UINT8 MeasureToken,
764 IN UINT8 MeasureReqMode,
765 IN UINT8 MeasureReqType,
766 IN UINT8 MeasureCh,
767 IN UINT16 MeasureDuration)
768{
769 PUCHAR pOutBuffer = NULL;
770 NDIS_STATUS NStatus;
771 ULONG FrameLen;
772 HEADER_802_11 ActHdr;
773 MEASURE_REQ_INFO MeasureReqIE;
774 UINT8 RmReqDailogToken = RandomByte(pAd);
775 UINT64 MeasureStartTime = GetCurrentTimeStamp(pAd);
776
777 // build action frame header.
778 MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
779 pAd->CurrentAddress);
780
781 NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
782 if(NStatus != NDIS_STATUS_SUCCESS)
783 {
784 DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
785 return;
786 }
787 NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
788 FrameLen = sizeof(HEADER_802_11);
789
790 InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_MRQ);
791
792 // fill Dialog Token
793 InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, MeasureToken);
794
795 // prepare Measurement IE.
796 NdisZeroMemory(&MeasureReqIE, sizeof(MEASURE_REQ_INFO));
797 MeasureReqIE.Token = RmReqDailogToken;
798 MeasureReqIE.ReqMode.word = MeasureReqMode;
799 MeasureReqIE.ReqType = MeasureReqType;
800 MeasureReqIE.MeasureReq.ChNum = MeasureCh;
801 MeasureReqIE.MeasureReq.MeasureStartTime = cpu2le64(MeasureStartTime);
802 MeasureReqIE.MeasureReq.MeasureDuration = cpu2le16(MeasureDuration);
803 InsertMeasureReqIE(pAd, (pOutBuffer + FrameLen), &FrameLen, &MeasureReqIE);
804
805 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
806 MlmeFreeMemory(pAd, pOutBuffer);
807
808 return;
809}
810
811/*
812 ==========================================================================
813 Description:
814 Prepare Measurement report action frame and enqueue it into
815 management queue waiting for transmition.
816
817 Parametrs:
818 1. the destination mac address of the frame.
819
820 Return : None.
821 ==========================================================================
822 */
823VOID EnqueueMeasurementRep(
824 IN PRTMP_ADAPTER pAd,
825 IN PUCHAR pDA,
826 IN UINT8 DialogToken,
827 IN UINT8 MeasureToken,
828 IN UINT8 MeasureReqMode,
829 IN UINT8 MeasureReqType,
830 IN UINT8 ReportInfoLen,
831 IN PUINT8 pReportInfo)
832{
833 PUCHAR pOutBuffer = NULL;
834 NDIS_STATUS NStatus;
835 ULONG FrameLen;
836 HEADER_802_11 ActHdr;
837 MEASURE_REPORT_INFO MeasureRepIE;
838
839 // build action frame header.
840 MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
841 pAd->CurrentAddress);
842
843 NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
844 if(NStatus != NDIS_STATUS_SUCCESS)
845 {
846 DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
847 return;
848 }
849 NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
850 FrameLen = sizeof(HEADER_802_11);
851
852 InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_MRP);
853
854 // fill Dialog Token
855 InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
856
857 // prepare Measurement IE.
858 NdisZeroMemory(&MeasureRepIE, sizeof(MEASURE_REPORT_INFO));
859 MeasureRepIE.Token = MeasureToken;
860 MeasureRepIE.ReportMode.word = MeasureReqMode;
861 MeasureRepIE.ReportType = MeasureReqType;
862 InsertMeasureReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, &MeasureRepIE, ReportInfoLen, pReportInfo);
863
864 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
865 MlmeFreeMemory(pAd, pOutBuffer);
866
867 return;
868}
869
870/*
871 ==========================================================================
872 Description:
873 Prepare TPC Request action frame and enqueue it into
874 management queue waiting for transmition.
875
876 Parametrs:
877 1. the destination mac address of the frame.
878
879 Return : None.
880 ==========================================================================
881 */
882VOID EnqueueTPCReq(
883 IN PRTMP_ADAPTER pAd,
884 IN PUCHAR pDA,
885 IN UCHAR DialogToken)
886{
887 PUCHAR pOutBuffer = NULL;
888 NDIS_STATUS NStatus;
889 ULONG FrameLen;
890
891 HEADER_802_11 ActHdr;
892
893 // build action frame header.
894 MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
895 pAd->CurrentAddress);
896
897 NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
898 if(NStatus != NDIS_STATUS_SUCCESS)
899 {
900 DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
901 return;
902 }
903 NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
904 FrameLen = sizeof(HEADER_802_11);
905
906 InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_TPCRQ);
907
908 // fill Dialog Token
909 InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
910
911 // Insert TPC Request IE.
912 InsertTpcReqIE(pAd, (pOutBuffer + FrameLen), &FrameLen);
913
914 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
915 MlmeFreeMemory(pAd, pOutBuffer);
916
917 return;
918}
919
920/*
921 ==========================================================================
922 Description:
923 Prepare TPC Report action frame and enqueue it into
924 management queue waiting for transmition.
925
926 Parametrs:
927 1. the destination mac address of the frame.
928
929 Return : None.
930 ==========================================================================
931 */
932VOID EnqueueTPCRep(
933 IN PRTMP_ADAPTER pAd,
934 IN PUCHAR pDA,
935 IN UINT8 DialogToken,
936 IN UINT8 TxPwr,
937 IN UINT8 LinkMargin)
938{
939 PUCHAR pOutBuffer = NULL;
940 NDIS_STATUS NStatus;
941 ULONG FrameLen;
942
943 HEADER_802_11 ActHdr;
944
945 // build action frame header.
946 MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
947 pAd->CurrentAddress);
948
949 NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
950 if(NStatus != NDIS_STATUS_SUCCESS)
951 {
952 DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
953 return;
954 }
955 NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
956 FrameLen = sizeof(HEADER_802_11);
957
958 InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_TPCRP);
959
960 // fill Dialog Token
961 InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
962
963 // Insert TPC Request IE.
964 InsertTpcReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, TxPwr, LinkMargin);
965
966 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
967 MlmeFreeMemory(pAd, pOutBuffer);
968
969 return;
970}
971
972/*
973 ==========================================================================
974 Description:
975 Prepare Channel Switch Announcement action frame and enqueue it into
976 management queue waiting for transmition.
977
978 Parametrs:
979 1. the destination mac address of the frame.
980 2. Channel switch announcement mode.
981 2. a New selected channel.
982
983 Return : None.
984 ==========================================================================
985 */
986VOID EnqueueChSwAnn(
987 IN PRTMP_ADAPTER pAd,
988 IN PUCHAR pDA,
989 IN UINT8 ChSwMode,
990 IN UINT8 NewCh)
991{
992 PUCHAR pOutBuffer = NULL;
993 NDIS_STATUS NStatus;
994 ULONG FrameLen;
995
996 HEADER_802_11 ActHdr;
997
998 // build action frame header.
999 MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
1000 pAd->CurrentAddress);
1001
1002 NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
1003 if(NStatus != NDIS_STATUS_SUCCESS)
1004 {
1005 DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
1006 return;
1007 }
1008 NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
1009 FrameLen = sizeof(HEADER_802_11);
1010
1011 InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_CHANNEL_SWITCH);
1012
1013 InsertChSwAnnIE(pAd, (pOutBuffer + FrameLen), &FrameLen, ChSwMode, NewCh, 0);
1014
1015 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
1016 MlmeFreeMemory(pAd, pOutBuffer);
1017
1018 return;
1019}
1020
1021static BOOLEAN DfsRequirementCheck(
1022 IN PRTMP_ADAPTER pAd,
1023 IN UINT8 Channel)
1024{
1025 BOOLEAN Result = FALSE;
1026 INT i;
1027
1028 do
1029 {
1030 // check DFS procedure is running.
1031 // make sure DFS procedure won't start twice.
1032 if (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
1033 {
1034 Result = FALSE;
1035 break;
1036 }
1037
1038 // check the new channel carried from Channel Switch Announcemnet is valid.
1039 for (i=0; i<pAd->ChannelListNum; i++)
1040 {
1041 if ((Channel == pAd->ChannelList[i].Channel)
1042 &&(pAd->ChannelList[i].RemainingTimeForUse == 0))
1043 {
1044 // found radar signal in the channel. the channel can't use at least for 30 minutes.
1045 pAd->ChannelList[i].RemainingTimeForUse = 1800;//30 min = 1800 sec
1046 Result = TRUE;
1047 break;
1048 }
1049 }
1050 } while(FALSE);
1051
1052 return Result;
1053}
1054
1055VOID NotifyChSwAnnToPeerAPs(
1056 IN PRTMP_ADAPTER pAd,
1057 IN PUCHAR pRA,
1058 IN PUCHAR pTA,
1059 IN UINT8 ChSwMode,
1060 IN UINT8 Channel)
1061{
1062#ifdef WDS_SUPPORT
1063 if (!((pRA[0] & 0xff) == 0xff)) // is pRA a broadcase address.
1064 {
1065 INT i;
1066 // info neighbor APs that Radar signal found throgh WDS link.
1067 for (i = 0; i < MAX_WDS_ENTRY; i++)
1068 {
1069 if (ValidWdsEntry(pAd, i))
1070 {
1071 PUCHAR pDA = pAd->WdsTab.WdsEntry[i].PeerWdsAddr;
1072
1073 // DA equal to SA. have no necessary orignal AP which found Radar signal.
1074 if (MAC_ADDR_EQUAL(pTA, pDA))
1075 continue;
1076
1077 // send Channel Switch Action frame to info Neighbro APs.
1078 EnqueueChSwAnn(pAd, pDA, ChSwMode, Channel);
1079 }
1080 }
1081 }
1082#endif // WDS_SUPPORT //
1083}
1084
1085static VOID StartDFSProcedure(
1086 IN PRTMP_ADAPTER pAd,
1087 IN UCHAR Channel,
1088 IN UINT8 ChSwMode)
1089{
1090 // start DFS procedure
1091 pAd->CommonCfg.Channel = Channel;
1092#ifdef DOT11_N_SUPPORT
1093 N_ChannelCheck(pAd);
1094#endif // DOT11_N_SUPPORT //
1095 pAd->CommonCfg.RadarDetect.RDMode = RD_SWITCHING_MODE;
1096 pAd->CommonCfg.RadarDetect.CSCount = 0;
1097}
1098
1099/*
1100 ==========================================================================
1101 Description:
1102 Channel Switch Announcement action frame sanity check.
1103
1104 Parametrs:
1105 1. MLME message containing the received frame
1106 2. message length.
1107 3. Channel switch announcement infomation buffer.
1108
1109
1110 Return : None.
1111 ==========================================================================
1112 */
1113
1114/*
1115 Channel Switch Announcement IE.
1116 +----+-----+-----------+------------+-----------+
1117 | ID | Len |Ch Sw Mode | New Ch Num | Ch Sw Cnt |
1118 +----+-----+-----------+------------+-----------+
1119 1 1 1 1 1
1120*/
1121static BOOLEAN PeerChSwAnnSanity(
1122 IN PRTMP_ADAPTER pAd,
1123 IN VOID *pMsg,
1124 IN ULONG MsgLen,
1125 OUT PCH_SW_ANN_INFO pChSwAnnInfo)
1126{
1127 PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
1128 PUCHAR pFramePtr = Fr->Octet;
1129 BOOLEAN result = FALSE;
1130 PEID_STRUCT eid_ptr;
1131
1132 // skip 802.11 header.
1133 MsgLen -= sizeof(HEADER_802_11);
1134
1135 // skip category and action code.
1136 pFramePtr += 2;
1137 MsgLen -= 2;
1138
1139 if (pChSwAnnInfo == NULL)
1140 return result;
1141
1142 eid_ptr = (PEID_STRUCT)pFramePtr;
1143 while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
1144 {
1145 switch(eid_ptr->Eid)
1146 {
1147 case IE_CHANNEL_SWITCH_ANNOUNCEMENT:
1148 NdisMoveMemory(&pChSwAnnInfo->ChSwMode, eid_ptr->Octet, 1);
1149 NdisMoveMemory(&pChSwAnnInfo->Channel, eid_ptr->Octet + 1, 1);
1150 NdisMoveMemory(&pChSwAnnInfo->ChSwCnt, eid_ptr->Octet + 2, 1);
1151
1152 result = TRUE;
1153 break;
1154
1155 default:
1156 break;
1157 }
1158 eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
1159 }
1160
1161 return result;
1162}
1163
1164/*
1165 ==========================================================================
1166 Description:
1167 Measurement request action frame sanity check.
1168
1169 Parametrs:
1170 1. MLME message containing the received frame
1171 2. message length.
1172 3. Measurement request infomation buffer.
1173
1174 Return : None.
1175 ==========================================================================
1176 */
1177static BOOLEAN PeerMeasureReqSanity(
1178 IN PRTMP_ADAPTER pAd,
1179 IN VOID *pMsg,
1180 IN ULONG MsgLen,
1181 OUT PUINT8 pDialogToken,
1182 OUT PMEASURE_REQ_INFO pMeasureReqInfo)
1183{
1184 PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
1185 PUCHAR pFramePtr = Fr->Octet;
1186 BOOLEAN result = FALSE;
1187 PEID_STRUCT eid_ptr;
1188 PUCHAR ptr;
1189 UINT64 MeasureStartTime;
1190 UINT16 MeasureDuration;
1191
1192 // skip 802.11 header.
1193 MsgLen -= sizeof(HEADER_802_11);
1194
1195 // skip category and action code.
1196 pFramePtr += 2;
1197 MsgLen -= 2;
1198
1199 if (pMeasureReqInfo == NULL)
1200 return result;
1201
1202 NdisMoveMemory(pDialogToken, pFramePtr, 1);
1203 pFramePtr += 1;
1204 MsgLen -= 1;
1205
1206 eid_ptr = (PEID_STRUCT)pFramePtr;
1207 while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
1208 {
1209 switch(eid_ptr->Eid)
1210 {
1211 case IE_MEASUREMENT_REQUEST:
1212 NdisMoveMemory(&pMeasureReqInfo->Token, eid_ptr->Octet, 1);
1213 NdisMoveMemory(&pMeasureReqInfo->ReqMode.word, eid_ptr->Octet + 1, 1);
1214 NdisMoveMemory(&pMeasureReqInfo->ReqType, eid_ptr->Octet + 2, 1);
1215 ptr = eid_ptr->Octet + 3;
1216 NdisMoveMemory(&pMeasureReqInfo->MeasureReq.ChNum, ptr, 1);
1217 NdisMoveMemory(&MeasureStartTime, ptr + 1, 8);
1218 pMeasureReqInfo->MeasureReq.MeasureStartTime = SWAP64(MeasureStartTime);
1219 NdisMoveMemory(&MeasureDuration, ptr + 9, 2);
1220 pMeasureReqInfo->MeasureReq.MeasureDuration = SWAP16(MeasureDuration);
1221
1222 result = TRUE;
1223 break;
1224
1225 default:
1226 break;
1227 }
1228 eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
1229 }
1230
1231 return result;
1232}
1233
1234/*
1235 ==========================================================================
1236 Description:
1237 Measurement report action frame sanity check.
1238
1239 Parametrs:
1240 1. MLME message containing the received frame
1241 2. message length.
1242 3. Measurement report infomation buffer.
1243 4. basic report infomation buffer.
1244
1245 Return : None.
1246 ==========================================================================
1247 */
1248
1249/*
1250 Measurement Report IE.
1251 +----+-----+-------+-------------+--------------+----------------+
1252 | ID | Len | Token | Report Mode | Measure Type | Measure Report |
1253 +----+-----+-------+-------------+--------------+----------------+
1254 1 1 1 1 1 variable
1255
1256 Basic Report.
1257 +--------+------------+----------+-----+
1258 | Ch Num | Start Time | Duration | Map |
1259 +--------+------------+----------+-----+
1260 1 8 2 1
1261
1262 Map Field Bit Format.
1263 +-----+---------------+---------------------+-------+------------+----------+
1264 | Bss | OFDM Preamble | Unidentified signal | Radar | Unmeasured | Reserved |
1265 +-----+---------------+---------------------+-------+------------+----------+
1266 0 1 2 3 4 5-7
1267*/
1268static BOOLEAN PeerMeasureReportSanity(
1269 IN PRTMP_ADAPTER pAd,
1270 IN VOID *pMsg,
1271 IN ULONG MsgLen,
1272 OUT PUINT8 pDialogToken,
1273 OUT PMEASURE_REPORT_INFO pMeasureReportInfo,
1274 OUT PUINT8 pReportBuf)
1275{
1276 PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
1277 PUCHAR pFramePtr = Fr->Octet;
1278 BOOLEAN result = FALSE;
1279 PEID_STRUCT eid_ptr;
1280 PUCHAR ptr;
1281
1282 // skip 802.11 header.
1283 MsgLen -= sizeof(HEADER_802_11);
1284
1285 // skip category and action code.
1286 pFramePtr += 2;
1287 MsgLen -= 2;
1288
1289 if (pMeasureReportInfo == NULL)
1290 return result;
1291
1292 NdisMoveMemory(pDialogToken, pFramePtr, 1);
1293 pFramePtr += 1;
1294 MsgLen -= 1;
1295
1296 eid_ptr = (PEID_STRUCT)pFramePtr;
1297 while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
1298 {
1299 switch(eid_ptr->Eid)
1300 {
1301 case IE_MEASUREMENT_REPORT:
1302 NdisMoveMemory(&pMeasureReportInfo->Token, eid_ptr->Octet, 1);
1303 NdisMoveMemory(&pMeasureReportInfo->ReportMode, eid_ptr->Octet + 1, 1);
1304 NdisMoveMemory(&pMeasureReportInfo->ReportType, eid_ptr->Octet + 2, 1);
1305 if (pMeasureReportInfo->ReportType == RM_BASIC)
1306 {
1307 PMEASURE_BASIC_REPORT pReport = (PMEASURE_BASIC_REPORT)pReportBuf;
1308 ptr = eid_ptr->Octet + 3;
1309 NdisMoveMemory(&pReport->ChNum, ptr, 1);
1310 NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8);
1311 NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2);
1312 NdisMoveMemory(&pReport->Map, ptr + 11, 1);
1313
1314 }
1315 else if (pMeasureReportInfo->ReportType == RM_CCA)
1316 {
1317 PMEASURE_CCA_REPORT pReport = (PMEASURE_CCA_REPORT)pReportBuf;
1318 ptr = eid_ptr->Octet + 3;
1319 NdisMoveMemory(&pReport->ChNum, ptr, 1);
1320 NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8);
1321 NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2);
1322 NdisMoveMemory(&pReport->CCA_Busy_Fraction, ptr + 11, 1);
1323
1324 }
1325 else if (pMeasureReportInfo->ReportType == RM_RPI_HISTOGRAM)
1326 {
1327 PMEASURE_RPI_REPORT pReport = (PMEASURE_RPI_REPORT)pReportBuf;
1328 ptr = eid_ptr->Octet + 3;
1329 NdisMoveMemory(&pReport->ChNum, ptr, 1);
1330 NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8);
1331 NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2);
1332 NdisMoveMemory(&pReport->RPI_Density, ptr + 11, 8);
1333 }
1334 result = TRUE;
1335 break;
1336
1337 default:
1338 break;
1339 }
1340 eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
1341 }
1342
1343 return result;
1344}
1345
1346/*
1347 ==========================================================================
1348 Description:
1349 TPC Request action frame sanity check.
1350
1351 Parametrs:
1352 1. MLME message containing the received frame
1353 2. message length.
1354 3. Dialog Token.
1355
1356 Return : None.
1357 ==========================================================================
1358 */
1359static BOOLEAN PeerTpcReqSanity(
1360 IN PRTMP_ADAPTER pAd,
1361 IN VOID *pMsg,
1362 IN ULONG MsgLen,
1363 OUT PUINT8 pDialogToken)
1364{
1365 PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
1366 PUCHAR pFramePtr = Fr->Octet;
1367 BOOLEAN result = FALSE;
1368 PEID_STRUCT eid_ptr;
1369
1370 MsgLen -= sizeof(HEADER_802_11);
1371
1372 // skip category and action code.
1373 pFramePtr += 2;
1374 MsgLen -= 2;
1375
1376 if (pDialogToken == NULL)
1377 return result;
1378
1379 NdisMoveMemory(pDialogToken, pFramePtr, 1);
1380 pFramePtr += 1;
1381 MsgLen -= 1;
1382
1383 eid_ptr = (PEID_STRUCT)pFramePtr;
1384 while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
1385 {
1386 switch(eid_ptr->Eid)
1387 {
1388 case IE_TPC_REQUEST:
1389 result = TRUE;
1390 break;
1391
1392 default:
1393 break;
1394 }
1395 eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
1396 }
1397
1398 return result;
1399}
1400
1401/*
1402 ==========================================================================
1403 Description:
1404 TPC Report action frame sanity check.
1405
1406 Parametrs:
1407 1. MLME message containing the received frame
1408 2. message length.
1409 3. Dialog Token.
1410 4. TPC Report IE.
1411
1412 Return : None.
1413 ==========================================================================
1414 */
1415static BOOLEAN PeerTpcRepSanity(
1416 IN PRTMP_ADAPTER pAd,
1417 IN VOID *pMsg,
1418 IN ULONG MsgLen,
1419 OUT PUINT8 pDialogToken,
1420 OUT PTPC_REPORT_INFO pTpcRepInfo)
1421{
1422 PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
1423 PUCHAR pFramePtr = Fr->Octet;
1424 BOOLEAN result = FALSE;
1425 PEID_STRUCT eid_ptr;
1426
1427 MsgLen -= sizeof(HEADER_802_11);
1428
1429 // skip category and action code.
1430 pFramePtr += 2;
1431 MsgLen -= 2;
1432
1433 if (pDialogToken == NULL)
1434 return result;
1435
1436 NdisMoveMemory(pDialogToken, pFramePtr, 1);
1437 pFramePtr += 1;
1438 MsgLen -= 1;
1439
1440 eid_ptr = (PEID_STRUCT)pFramePtr;
1441 while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
1442 {
1443 switch(eid_ptr->Eid)
1444 {
1445 case IE_TPC_REPORT:
1446 NdisMoveMemory(&pTpcRepInfo->TxPwr, eid_ptr->Octet, 1);
1447 NdisMoveMemory(&pTpcRepInfo->LinkMargin, eid_ptr->Octet + 1, 1);
1448 result = TRUE;
1449 break;
1450
1451 default:
1452 break;
1453 }
1454 eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
1455 }
1456
1457 return result;
1458}
1459
1460/*
1461 ==========================================================================
1462 Description:
1463 Channel Switch Announcement action frame handler.
1464
1465 Parametrs:
1466 Elme - MLME message containing the received frame
1467
1468 Return : None.
1469 ==========================================================================
1470 */
1471static VOID PeerChSwAnnAction(
1472 IN PRTMP_ADAPTER pAd,
1473 IN MLME_QUEUE_ELEM *Elem)
1474{
1475 CH_SW_ANN_INFO ChSwAnnInfo;
1476 PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
1477#ifdef CONFIG_STA_SUPPORT
1478 UCHAR index = 0, Channel = 0, NewChannel = 0;
1479 ULONG Bssidx = 0;
1480#endif // CONFIG_STA_SUPPORT //
1481
1482 NdisZeroMemory(&ChSwAnnInfo, sizeof(CH_SW_ANN_INFO));
1483 if (! PeerChSwAnnSanity(pAd, Elem->Msg, Elem->MsgLen, &ChSwAnnInfo))
1484 {
1485 DBGPRINT(RT_DEBUG_TRACE, ("Invalid Channel Switch Action Frame.\n"));
1486 return;
1487 }
1488
1489
1490#ifdef CONFIG_STA_SUPPORT
1491 if (pAd->OpMode == OPMODE_STA)
1492 {
1493 Bssidx = BssTableSearch(&pAd->ScanTab, pFr->Hdr.Addr3, pAd->CommonCfg.Channel);
1494 if (Bssidx == BSS_NOT_FOUND)
1495 {
1496 DBGPRINT(RT_DEBUG_TRACE, ("PeerChSwAnnAction - Bssidx is not found\n"));
1497 return;
1498 }
1499
1500 DBGPRINT(RT_DEBUG_TRACE, ("\n****Bssidx is %d, Channel = %d\n", index, pAd->ScanTab.BssEntry[Bssidx].Channel));
1501 hex_dump("SSID",pAd->ScanTab.BssEntry[Bssidx].Bssid ,6);
1502
1503 Channel = pAd->CommonCfg.Channel;
1504 NewChannel = ChSwAnnInfo.Channel;
1505
1506 if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0) && (Channel != NewChannel))
1507 {
1508 // Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection).
1509 // In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results.
1510 AsicSwitchChannel(pAd, 1, FALSE);
1511 AsicLockChannel(pAd, 1);
1512 LinkDown(pAd, FALSE);
1513 MlmeQueueInit(&pAd->Mlme.Queue);
1514 BssTableInit(&pAd->ScanTab);
1515 RTMPusecDelay(1000000); // use delay to prevent STA do reassoc
1516
1517 // channel sanity check
1518 for (index = 0 ; index < pAd->ChannelListNum; index++)
1519 {
1520 if (pAd->ChannelList[index].Channel == NewChannel)
1521 {
1522 pAd->ScanTab.BssEntry[Bssidx].Channel = NewChannel;
1523 pAd->CommonCfg.Channel = NewChannel;
1524 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1525 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1526 DBGPRINT(RT_DEBUG_TRACE, ("&&&&&&&&&&&&&&&&PeerChSwAnnAction - STA receive channel switch announcement IE (New Channel =%d)\n", NewChannel));
1527 break;
1528 }
1529 }
1530
1531 if (index >= pAd->ChannelListNum)
1532 {
1533 DBGPRINT_ERR(("&&&&&&&&&&&&&&&&&&&&&&&&&&PeerChSwAnnAction(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum));
1534 }
1535 }
1536 }
1537#endif // CONFIG_STA_SUPPORT //
1538
1539 return;
1540}
1541
1542
1543/*
1544 ==========================================================================
1545 Description:
1546 Measurement Request action frame handler.
1547
1548 Parametrs:
1549 Elme - MLME message containing the received frame
1550
1551 Return : None.
1552 ==========================================================================
1553 */
1554static VOID PeerMeasureReqAction(
1555 IN PRTMP_ADAPTER pAd,
1556 IN MLME_QUEUE_ELEM *Elem)
1557{
1558 PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
1559 UINT8 DialogToken;
1560 MEASURE_REQ_INFO MeasureReqInfo;
1561 MEASURE_REPORT_MODE ReportMode;
1562
1563 if(PeerMeasureReqSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReqInfo))
1564 {
1565 ReportMode.word = 0;
1566 ReportMode.field.Incapable = 1;
1567 EnqueueMeasurementRep(pAd, pFr->Hdr.Addr2, DialogToken, MeasureReqInfo.Token, ReportMode.word, MeasureReqInfo.ReqType, 0, NULL);
1568 }
1569
1570 return;
1571}
1572
1573/*
1574 ==========================================================================
1575 Description:
1576 Measurement Report action frame handler.
1577
1578 Parametrs:
1579 Elme - MLME message containing the received frame
1580
1581 Return : None.
1582 ==========================================================================
1583 */
1584static VOID PeerMeasureReportAction(
1585 IN PRTMP_ADAPTER pAd,
1586 IN MLME_QUEUE_ELEM *Elem)
1587{
1588 MEASURE_REPORT_INFO MeasureReportInfo;
1589 PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
1590 UINT8 DialogToken;
1591 PUINT8 pMeasureReportInfo;
1592
1593// if (pAd->CommonCfg.bIEEE80211H != TRUE)
1594// return;
1595
1596 if ((pMeasureReportInfo = kmalloc(sizeof(MEASURE_RPI_REPORT), GFP_ATOMIC)) == NULL)
1597 {
1598 DBGPRINT(RT_DEBUG_ERROR, ("%s unable to alloc memory for measure report buffer (size=%d).\n", __FUNCTION__, sizeof(MEASURE_RPI_REPORT)));
1599 return;
1600 }
1601
1602 NdisZeroMemory(&MeasureReportInfo, sizeof(MEASURE_REPORT_INFO));
1603 NdisZeroMemory(pMeasureReportInfo, sizeof(MEASURE_RPI_REPORT));
1604 if (PeerMeasureReportSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReportInfo, pMeasureReportInfo))
1605 {
1606 do {
1607 PMEASURE_REQ_ENTRY pEntry = NULL;
1608
1609 // Not a autonomous measure report.
1610 // check the dialog token field. drop it if the dialog token doesn't match.
1611 if ((DialogToken != 0)
1612 && ((pEntry = MeasureReqLookUp(pAd, DialogToken)) == NULL))
1613 break;
1614
1615 if (pEntry != NULL)
1616 MeasureReqDelete(pAd, pEntry->DialogToken);
1617
1618 if (MeasureReportInfo.ReportType == RM_BASIC)
1619 {
1620 PMEASURE_BASIC_REPORT pBasicReport = (PMEASURE_BASIC_REPORT)pMeasureReportInfo;
1621 if ((pBasicReport->Map.field.Radar)
1622 && (DfsRequirementCheck(pAd, pBasicReport->ChNum) == TRUE))
1623 {
1624 NotifyChSwAnnToPeerAPs(pAd, pFr->Hdr.Addr1, pFr->Hdr.Addr2, 1, pBasicReport->ChNum);
1625 StartDFSProcedure(pAd, pBasicReport->ChNum, 1);
1626 }
1627 }
1628 } while (FALSE);
1629 }
1630 else
1631 DBGPRINT(RT_DEBUG_TRACE, ("Invalid Measurement Report Frame.\n"));
1632
1633 kfree(pMeasureReportInfo);
1634
1635 return;
1636}
1637
1638/*
1639 ==========================================================================
1640 Description:
1641 TPC Request action frame handler.
1642
1643 Parametrs:
1644 Elme - MLME message containing the received frame
1645
1646 Return : None.
1647 ==========================================================================
1648 */
1649static VOID PeerTpcReqAction(
1650 IN PRTMP_ADAPTER pAd,
1651 IN MLME_QUEUE_ELEM *Elem)
1652{
1653 PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
1654 PUCHAR pFramePtr = pFr->Octet;
1655 UINT8 DialogToken;
1656 UINT8 TxPwr = GetCurTxPwr(pAd, Elem->Wcid);
1657 UINT8 LinkMargin = 0;
1658 CHAR RealRssi;
1659
1660 // link margin: Ratio of the received signal power to the minimum desired by the station (STA). The
1661 // STA may incorporate rate information and channel conditions, including interference, into its computation
1662 // of link margin.
1663
1664 RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0),
1665 ConvertToRssi(pAd, Elem->Rssi1, RSSI_1),
1666 ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
1667
1668 // skip Category and action code.
1669 pFramePtr += 2;
1670
1671 // Dialog token.
1672 NdisMoveMemory(&DialogToken, pFramePtr, 1);
1673
1674 LinkMargin = (RealRssi / MIN_RCV_PWR);
1675 if (PeerTpcReqSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken))
1676 EnqueueTPCRep(pAd, pFr->Hdr.Addr2, DialogToken, TxPwr, LinkMargin);
1677
1678 return;
1679}
1680
1681/*
1682 ==========================================================================
1683 Description:
1684 TPC Report action frame handler.
1685
1686 Parametrs:
1687 Elme - MLME message containing the received frame
1688
1689 Return : None.
1690 ==========================================================================
1691 */
1692static VOID PeerTpcRepAction(
1693 IN PRTMP_ADAPTER pAd,
1694 IN MLME_QUEUE_ELEM *Elem)
1695{
1696 UINT8 DialogToken;
1697 TPC_REPORT_INFO TpcRepInfo;
1698 PTPC_REQ_ENTRY pEntry = NULL;
1699
1700 NdisZeroMemory(&TpcRepInfo, sizeof(TPC_REPORT_INFO));
1701 if (PeerTpcRepSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &TpcRepInfo))
1702 {
1703 if ((pEntry = TpcReqLookUp(pAd, DialogToken)) != NULL)
1704 {
1705 TpcReqDelete(pAd, pEntry->DialogToken);
1706 DBGPRINT(RT_DEBUG_TRACE, ("%s: DialogToken=%x, TxPwr=%d, LinkMargin=%d\n",
1707 __FUNCTION__, DialogToken, TpcRepInfo.TxPwr, TpcRepInfo.LinkMargin));
1708 }
1709 }
1710
1711 return;
1712}
1713
1714/*
1715 ==========================================================================
1716 Description:
1717 Spectrun action frames Handler such as channel switch annoucement,
1718 measurement report, measurement request actions frames.
1719
1720 Parametrs:
1721 Elme - MLME message containing the received frame
1722
1723 Return : None.
1724 ==========================================================================
1725 */
1726VOID PeerSpectrumAction(
1727 IN PRTMP_ADAPTER pAd,
1728 IN MLME_QUEUE_ELEM *Elem)
1729{
1730
1731 UCHAR Action = Elem->Msg[LENGTH_802_11+1];
1732
1733 if (pAd->CommonCfg.bIEEE80211H != TRUE)
1734 return;
1735
1736 switch(Action)
1737 {
1738 case SPEC_MRQ:
1739 // current rt2860 unable do such measure specified in Measurement Request.
1740 // reject all measurement request.
1741 PeerMeasureReqAction(pAd, Elem);
1742 break;
1743
1744 case SPEC_MRP:
1745 PeerMeasureReportAction(pAd, Elem);
1746 break;
1747
1748 case SPEC_TPCRQ:
1749 PeerTpcReqAction(pAd, Elem);
1750 break;
1751
1752 case SPEC_TPCRP:
1753 PeerTpcRepAction(pAd, Elem);
1754 break;
1755
1756 case SPEC_CHANNEL_SWITCH:
1757{
1758#ifdef DOT11N_DRAFT3
1759 SEC_CHA_OFFSET_IE Secondary;
1760 CHA_SWITCH_ANNOUNCE_IE ChannelSwitch;
1761
1762 // 802.11h only has Channel Switch Announcement IE.
1763 RTMPMoveMemory(&ChannelSwitch, &Elem->Msg[LENGTH_802_11+4], sizeof (CHA_SWITCH_ANNOUNCE_IE));
1764
1765 // 802.11n D3.03 adds secondary channel offset element in the end.
1766 if (Elem->MsgLen == (LENGTH_802_11 + 2 + sizeof (CHA_SWITCH_ANNOUNCE_IE) + sizeof (SEC_CHA_OFFSET_IE)))
1767 {
1768 RTMPMoveMemory(&Secondary, &Elem->Msg[LENGTH_802_11+9], sizeof (SEC_CHA_OFFSET_IE));
1769 }
1770 else
1771 {
1772 Secondary.SecondaryChannelOffset = 0;
1773 }
1774
1775 if ((Elem->Msg[LENGTH_802_11+2] == IE_CHANNEL_SWITCH_ANNOUNCEMENT) && (Elem->Msg[LENGTH_802_11+3] == 3))
1776 {
1777 ChannelSwitchAction(pAd, Elem->Wcid, ChannelSwitch.NewChannel, Secondary.SecondaryChannelOffset);
1778 }
1779#endif // DOT11N_DRAFT3 //
1780}
1781 PeerChSwAnnAction(pAd, Elem);
1782 break;
1783 }
1784
1785 return;
1786}
1787
1788/*
1789 ==========================================================================
1790 Description:
1791
1792 Parametrs:
1793
1794 Return : None.
1795 ==========================================================================
1796 */
1797INT Set_MeasureReq_Proc(
1798 IN PRTMP_ADAPTER pAd,
1799 IN PUCHAR arg)
1800{
1801 UINT Aid = 1;
1802 UINT ArgIdx;
1803 PUCHAR thisChar;
1804
1805 MEASURE_REQ_MODE MeasureReqMode;
1806 UINT8 MeasureReqToken = RandomByte(pAd);
1807 UINT8 MeasureReqType = RM_BASIC;
1808 UINT8 MeasureCh = 1;
1809
1810 ArgIdx = 1;
1811 while ((thisChar = strsep((char **)&arg, "-")) != NULL)
1812 {
1813 switch(ArgIdx)
1814 {
1815 case 1: // Aid.
1816 Aid = simple_strtol(thisChar, 0, 16);
1817 break;
1818
1819 case 2: // Measurement Request Type.
1820 MeasureReqType = simple_strtol(thisChar, 0, 16);
1821 if (MeasureReqType > 3)
1822 {
1823 DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow MeasureReqType(%d)\n", __FUNCTION__, MeasureReqType));
1824 return TRUE;
1825 }
1826 break;
1827
1828 case 3: // Measurement channel.
1829 MeasureCh = simple_strtol(thisChar, 0, 16);
1830 break;
1831 }
1832 ArgIdx++;
1833 }
1834
1835 DBGPRINT(RT_DEBUG_TRACE, ("%s::Aid = %d, MeasureReqType=%d MeasureCh=%d\n", __FUNCTION__, Aid, MeasureReqType, MeasureCh));
1836 if (!VALID_WCID(Aid))
1837 {
1838 DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow sta of Aid(%d)\n", __FUNCTION__, Aid));
1839 return TRUE;
1840 }
1841
1842 MeasureReqMode.word = 0;
1843 MeasureReqMode.field.Enable = 1;
1844
1845 MeasureReqInsert(pAd, MeasureReqToken);
1846
1847 EnqueueMeasurementReq(pAd, pAd->MacTab.Content[Aid].Addr,
1848 MeasureReqToken, MeasureReqMode.word, MeasureReqType, MeasureCh, 2000);
1849
1850 return TRUE;
1851}
1852
1853INT Set_TpcReq_Proc(
1854 IN PRTMP_ADAPTER pAd,
1855 IN PUCHAR arg)
1856{
1857 UINT Aid;
1858
1859 UINT8 TpcReqToken = RandomByte(pAd);
1860
1861 Aid = simple_strtol(arg, 0, 16);
1862
1863 DBGPRINT(RT_DEBUG_TRACE, ("%s::Aid = %d\n", __FUNCTION__, Aid));
1864 if (!VALID_WCID(Aid))
1865 {
1866 DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow sta of Aid(%d)\n", __FUNCTION__, Aid));
1867 return TRUE;
1868 }
1869
1870 TpcReqInsert(pAd, TpcReqToken);
1871
1872 EnqueueTPCReq(pAd, pAd->MacTab.Content[Aid].Addr, TpcReqToken);
1873
1874 return TRUE;
1875}
1876
diff --git a/drivers/staging/rt3070/dfs.h b/drivers/staging/rt3070/dfs.h
new file mode 100644
index 000000000000..752a6352d9dd
--- /dev/null
+++ b/drivers/staging/rt3070/dfs.h
@@ -0,0 +1,100 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 dfs.h
29
30 Abstract:
31 Support DFS function.
32
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36 Fonchi 03-12-2007 created
37*/
38
39#define RADAR_PULSE 1
40#define RADAR_WIDTH 2
41
42#define WIDTH_RD_IDLE 0
43#define WIDTH_RD_CHECK 1
44
45
46VOID BbpRadarDetectionStart(
47 IN PRTMP_ADAPTER pAd);
48
49VOID BbpRadarDetectionStop(
50 IN PRTMP_ADAPTER pAd);
51
52VOID RadarDetectionStart(
53 IN PRTMP_ADAPTER pAd,
54 IN BOOLEAN CTS_Protect,
55 IN UINT8 CTSPeriod);
56
57VOID RadarDetectionStop(
58 IN PRTMP_ADAPTER pAd);
59
60VOID RadarDetectPeriodic(
61 IN PRTMP_ADAPTER pAd);
62
63
64BOOLEAN RadarChannelCheck(
65 IN PRTMP_ADAPTER pAd,
66 IN UCHAR Ch);
67
68ULONG JapRadarType(
69 IN PRTMP_ADAPTER pAd);
70
71ULONG RTMPBbpReadRadarDuration(
72 IN PRTMP_ADAPTER pAd);
73
74ULONG RTMPReadRadarDuration(
75 IN PRTMP_ADAPTER pAd);
76
77VOID RTMPCleanRadarDuration(
78 IN PRTMP_ADAPTER pAd);
79
80VOID RTMPPrepareRDCTSFrame(
81 IN PRTMP_ADAPTER pAd,
82 IN PUCHAR pDA,
83 IN ULONG Duration,
84 IN UCHAR RTSRate,
85 IN ULONG CTSBaseAddr,
86 IN UCHAR FrameGap);
87
88VOID RTMPPrepareRadarDetectParams(
89 IN PRTMP_ADAPTER pAd);
90
91
92INT Set_ChMovingTime_Proc(
93 IN PRTMP_ADAPTER pAd,
94 IN PUCHAR arg);
95
96INT Set_LongPulseRadarTh_Proc(
97 IN PRTMP_ADAPTER pAd,
98 IN PUCHAR arg);
99
100
diff --git a/drivers/staging/rt3070/firmware.h b/drivers/staging/rt3070/firmware.h
new file mode 100644
index 000000000000..b07783ed8dd0
--- /dev/null
+++ b/drivers/staging/rt3070/firmware.h
@@ -0,0 +1,558 @@
1/*
2 Copyright (c) 2007, Ralink Technology Corporation
3 All rights reserved.
4
5 Redistribution. Redistribution and use in binary form, without
6 modification, are permitted provided that the following conditions are
7 met:
8
9 * Redistributions must reproduce the above copyright notice and the
10 following disclaimer in the documentation and/or other materials
11 provided with the distribution.
12 * Neither the name of Ralink Technology Corporation nor the names of its
13 suppliers may be used to endorse or promote products derived from this
14 software without specific prior written permission.
15 * No reverse engineering, decompilation, or disassembly of this software
16 is permitted.
17
18 Limited patent license. Ralink Technology Corporation grants a world-wide,
19 royalty-free, non-exclusive license under patents it now or hereafter
20 owns or controls to make, have made, use, import, offer to sell and
21 sell ("Utilize") this software, but solely to the extent that any
22 such patent is necessary to Utilize the software alone, or in
23 combination with an operating system licensed under an approved Open
24 Source license as listed by the Open Source Initiative at
25 http://opensource.org/licenses. The patent license shall not apply to
26 any other combinations which include this software. No hardware per
27 se is licensed hereunder.
28
29 DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
30 CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
31 BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
32 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
33 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
34 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
35 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
36 OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
37 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
38 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
39 USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
40 DAMAGE.
41*/
42/* AUTO GEN PLEASE DO NOT MODIFY IT */
43/* AUTO GEN PLEASE DO NOT MODIFY IT */
44
45
46UCHAR FirmwareImage [] = {
470xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x32, 0x02, 0x10, 0x78, 0x02, 0x12, 0x67, 0x02,
480x12, 0x68, 0x02, 0x12, 0x87, 0x02, 0x12, 0x8c, 0x12, 0x12, 0x88, 0x22, 0x02, 0x16, 0x49, 0x02,
490x17, 0x1f, 0x02, 0x13, 0x77, 0x02, 0x12, 0x8d, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x17,
500xc1, 0x22, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe3, 0x1b, 0xe5, 0x4c, 0x30, 0xe0, 0x04, 0x7f, 0x40,
510x80, 0x02, 0x7f, 0x00, 0x90, 0x10, 0x2f, 0xef, 0xf0, 0x90, 0x01, 0x8c, 0x74, 0x08, 0xf0, 0xe4,
520x90, 0x01, 0xa7, 0xf0, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe0, 0x1c, 0x90, 0x01, 0x80, 0xe0, 0xb4,
530x02, 0x15, 0xa3, 0xe0, 0xb4, 0x01, 0x10, 0x90, 0x01, 0x84, 0xe0, 0xb4, 0x81, 0x09, 0x90, 0x01,
540x8c, 0x74, 0x01, 0xf0, 0x12, 0x0d, 0xc8, 0x22, 0x90, 0x04, 0x14, 0xe0, 0x20, 0xe7, 0x03, 0x02,
550x12, 0x66, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0, 0x12, 0x0a, 0x9d, 0x10,
560xb7, 0x31, 0x10, 0xe0, 0x50, 0x11, 0x04, 0x51, 0x11, 0x0d, 0x52, 0x11, 0x0d, 0x53, 0x11, 0x0d,
570x54, 0x11, 0x4e, 0x55, 0x11, 0x7e, 0x70, 0x11, 0xa9, 0x71, 0x11, 0xd7, 0x72, 0x12, 0x1d, 0x73,
580x12, 0x3e, 0x80, 0x00, 0x00, 0x12, 0x66, 0x20, 0x02, 0x03, 0x30, 0x03, 0x1d, 0x7d, 0x02, 0xaf,
590x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5,
600x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x85, 0x56, 0x41, 0xd2, 0x02, 0x22,
610x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0x64, 0x02, 0x60, 0x03, 0x02, 0x12, 0x66, 0x90, 0x70, 0x11,
620xe0, 0x64, 0x08, 0x60, 0x08, 0xe0, 0x64, 0x20, 0x60, 0x03, 0x02, 0x12, 0x66, 0x75, 0x4e, 0x03,
630x75, 0x4f, 0x20, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92, 0x47, 0x22, 0x90, 0x04, 0x04,
640xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, 0x10, 0xe0, 0xff, 0x74, 0x47, 0x25, 0x57,
650xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, 0x74, 0x48, 0x25, 0x57, 0xf8, 0xc6, 0xef,
660xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90,
670x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0xe5, 0x47,
680x64, 0x07, 0x60, 0x0b, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0x90,
690x70, 0x11, 0xe0, 0x54, 0x0f, 0xf5, 0x3a, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0xe5, 0x3a, 0xb4, 0x03,
700x03, 0xe4, 0xf5, 0x46, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0xd2, 0x04, 0x22, 0x90, 0x70,
710x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf8, 0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56,
720x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56,
730xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70,
740x11, 0xe0, 0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b,
750x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70,
760x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x90, 0x10, 0x02, 0xe0, 0xb4, 0x70, 0x1e, 0xa3, 0xe0,
770xb4, 0x30, 0x19, 0x90, 0x05, 0x08, 0xe0, 0x44, 0x01, 0xf0, 0xfd, 0x90, 0x05, 0x05, 0xe0, 0x54,
780xfb, 0xf0, 0x44, 0x04, 0xf0, 0xed, 0x54, 0xfe, 0x90, 0x05, 0x08, 0xf0, 0xe4, 0xf5, 0x4e, 0xf5,
790x4f, 0x75, 0x3a, 0xff, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80,
800xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x4b, 0x80, 0x42, 0x90, 0x70, 0x10,
810xe0, 0x24, 0xff, 0x92, 0x93, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74,
820x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x2a, 0x80, 0x21, 0x90, 0x70,
830x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90,
840x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x07, 0x90,
850x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x22, 0xe5, 0x53, 0x70, 0x1a, 0x30, 0x60, 0x09, 0xb2,
860x4d, 0x30, 0x4d, 0x04, 0x05, 0x46, 0xc2, 0x04, 0xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f,
870x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, 0x22, 0x22, 0xc2, 0x42, 0xd3, 0x22, 0x22, 0xc2, 0x4b, 0xc2,
880x4c, 0xe5, 0x44, 0x12, 0x0a, 0x9d, 0x12, 0xaf, 0x00, 0x13, 0x42, 0x04, 0x13, 0x3e, 0x08, 0x13,
890x19, 0x10, 0x12, 0xc3, 0x20, 0x12, 0xe3, 0x60, 0x12, 0xf4, 0xa0, 0x00, 0x00, 0x13, 0x44, 0x85,
900x48, 0x43, 0x85, 0x4a, 0x42, 0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03, 0x02, 0x13,
910x44, 0x80, 0x1b, 0xe5, 0x48, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4, 0x54, 0x0f, 0xf5,
920x42, 0xe5, 0x4c, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x66, 0x53, 0x43,
930x0f, 0x80, 0x61, 0x85, 0x49, 0x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5, 0x47, 0x64, 0x06,
940x70, 0x52, 0x80, 0x1b, 0xe5, 0x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b, 0xc4, 0x54, 0x0f,
950xf5, 0x42, 0xe5, 0x4d, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x35, 0xe5,
960x43, 0x54, 0x0f, 0x44, 0x10, 0xf5, 0x43, 0x80, 0x2b, 0xe5, 0x47, 0xb4, 0x04, 0x06, 0x53, 0x5e,
970xfb, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43, 0x5e, 0x04, 0x75, 0x42, 0x09, 0xe5,
980x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30, 0xf5, 0x43, 0x80, 0x06, 0xd2, 0x4b,
990x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x25, 0xe5, 0x42, 0xc4, 0x54, 0xf0, 0xff, 0xe5, 0x43, 0x54,
1000x0f, 0x4f, 0xf5, 0x5f, 0x90, 0x70, 0x44, 0xf0, 0xa3, 0xe5, 0x5e, 0xf0, 0xa3, 0xe5, 0x4a, 0xf0,
1010xa3, 0xe5, 0x48, 0xf0, 0xa3, 0xe5, 0x4c, 0xf0, 0xa3, 0xe5, 0x44, 0xf0, 0xa3, 0xe5, 0x42, 0xf0,
1020xa3, 0xe5, 0x43, 0xf0, 0xd2, 0x60, 0x22, 0xe5, 0x47, 0x60, 0x10, 0x24, 0xc0, 0x70, 0x03, 0x12,
1030x16, 0x29, 0x12, 0x13, 0x8c, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2, 0xaf, 0x90, 0x04,
1040x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x18, 0x80, 0x08, 0xe5, 0x4e, 0x45, 0x4f, 0x24, 0xff,
1050x92, 0x18, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x19, 0x74, 0x1e, 0xf0, 0xe5,
1060x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x25, 0x70, 0x13, 0x30, 0x18, 0x05, 0xe5, 0x5f, 0x20, 0xe5,
1070x0b, 0x30, 0x19, 0x19, 0xe5, 0x5f, 0x54, 0x30, 0xff, 0xbf, 0x30, 0x11, 0xe5, 0x25, 0x70, 0x05,
1080x75, 0x25, 0x0c, 0x80, 0x02, 0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f, 0xe5, 0x5f, 0x30,
1090xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5, 0x47, 0x64, 0x03,
1100x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x25, 0x70, 0x03, 0x30,
1110x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x25, 0x70, 0x05, 0x75, 0x25, 0x07, 0x80, 0x02, 0x15, 0x25, 0xd2,
1120x6c, 0xd2, 0x6d, 0xe5, 0x47, 0xb4, 0x09, 0x14, 0xe5, 0x44, 0x20, 0xe3, 0x0b, 0xe5, 0x3a, 0x64,
1130x02, 0x60, 0x05, 0xe5, 0x3a, 0xb4, 0x03, 0x04, 0xc2, 0x6c, 0xd2, 0x6d, 0x90, 0x70, 0x46, 0xe5,
1140x2d, 0xf0, 0x20, 0x69, 0x07, 0xe5, 0x5e, 0x20, 0xe0, 0x02, 0xb2, 0x68, 0x20, 0x6b, 0x07, 0xe5,
1150x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20, 0x6d, 0x07, 0xe5, 0x5e, 0x20, 0xe2, 0x02, 0xb2, 0x6c,
1160x90, 0x70, 0x47, 0xe5, 0x2d, 0xf0, 0x75, 0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x26,
1170x30, 0x68, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01,
1180x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02,
1190x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x73, 0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80,
1200x26, 0x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f,
1210x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80,
1220x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x75, 0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c,
1230x80, 0x26, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe1, 0x04,
1240x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01,
1250x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x71, 0x92, 0x70, 0x90, 0x10, 0x00, 0xe0,
1260x90, 0x10, 0x2f, 0xf0, 0x90, 0x10, 0x03, 0xe0, 0xc3, 0x94, 0x30, 0x40, 0x14, 0xa2, 0x71, 0x92,
1270x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13, 0x54, 0x3f, 0xf5, 0x2e, 0xc2, 0x77, 0xd2,
1280x76, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x4c, 0x90, 0x02, 0x29,
1290xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f, 0x14, 0x60, 0x14, 0x24, 0xfe, 0x60, 0x23,
1300x24, 0x03, 0x60, 0x03, 0x02, 0x16, 0x18, 0x90, 0x02, 0x28, 0xe0, 0x30, 0x47, 0x0f, 0x80, 0x07,
1310x90, 0x02, 0x28, 0xe0, 0x20, 0x47, 0x06, 0x54, 0xfe, 0xf0, 0x02, 0x16, 0x18, 0x44, 0x01, 0xf0,
1320x02, 0x16, 0x18, 0xe5, 0x46, 0x30, 0xe2, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x90, 0x02,
1330x28, 0xe0, 0x54, 0xfe, 0x4f, 0xf0, 0x02, 0x16, 0x18, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x0f, 0xe5,
1340x47, 0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02, 0x16, 0x18, 0xe4, 0xf5,
1350x27, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x2d, 0x14, 0x60, 0x2e,
1360x14, 0x60, 0x36, 0x24, 0xfc, 0x60, 0x5f, 0x24, 0xf9, 0x60, 0x1f, 0x24, 0x0e, 0x70, 0x69, 0xe5,
1370x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xaf, 0xf0, 0x20, 0x47, 0x04, 0x7e, 0x01,
1380x80, 0x02, 0x7e, 0x00, 0xef, 0x6e, 0x24, 0xff, 0x80, 0x45, 0xa2, 0x47, 0x80, 0x41, 0xe5, 0x46,
1390x30, 0xe2, 0x03, 0xd3, 0x80, 0x27, 0xc3, 0x80, 0x24, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38,
1400xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0x20,
1410x47, 0x04, 0x7d, 0x01, 0x80, 0x02, 0x7d, 0x00, 0xef, 0x6d, 0x4e, 0x24, 0xff, 0x92, 0x38, 0xa2,
1420x47, 0xb3, 0x92, 0x39, 0x80, 0x19, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92,
1430x39, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x80, 0x07, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x92, 0x39, 0x90,
1440x02, 0x28, 0xe0, 0x54, 0xfc, 0x45, 0x27, 0xf0, 0x90, 0x70, 0x9c, 0xe5, 0x3a, 0xf0, 0xa3, 0xe5,
1450x47, 0xf0, 0x90, 0x70, 0x41, 0xe5, 0x3a, 0xf0, 0x22, 0xe4, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47,
1460x04, 0xaf, 0x45, 0x80, 0x04, 0xe5, 0x45, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0x8f,
1470x50, 0xd2, 0x59, 0x22, 0x8f, 0x54, 0xd2, 0x58, 0x22, 0xe4, 0xf5, 0x62, 0xc2, 0xaf, 0xe5, 0x51,
1480x14, 0x60, 0x46, 0x14, 0x60, 0x62, 0x24, 0x02, 0x60, 0x03, 0x02, 0x17, 0x03, 0xd2, 0x59, 0x75,
1490x55, 0x01, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0x7f, 0xf0, 0xa3, 0xe0, 0x20, 0xe7, 0x22, 0x90, 0x04,
1500x34, 0xe0, 0xb4, 0x02, 0x1b, 0xa3, 0xe0, 0xb4, 0x02, 0x16, 0xa3, 0xe0, 0xb4, 0x02, 0x11, 0x7f,
1510x20, 0x12, 0x16, 0x3f, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0, 0x75, 0x51, 0x01, 0x80, 0x73,
1520xe5, 0x50, 0x70, 0x05, 0x75, 0x62, 0x03, 0x80, 0x6a, 0x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70,
1530x11, 0x7f, 0x20, 0x12, 0x16, 0x3f, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0xbf, 0xf0, 0x75, 0x51, 0x02,
1540x80, 0x51, 0xe5, 0x50, 0x70, 0x02, 0x80, 0x46, 0x90, 0x02, 0xa3, 0xe0, 0x20, 0xe6, 0x3b, 0x90,
1550x04, 0x37, 0xe0, 0x64, 0x22, 0x70, 0x33, 0x90, 0x01, 0x8a, 0x74, 0x7e, 0xf0, 0x90, 0x01, 0x96,
1560xf0, 0x90, 0x12, 0x04, 0x74, 0x0a, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0,
1570x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xfa, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x54, 0xf9, 0xf0, 0x75,
1580x62, 0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70, 0x05, 0x75, 0x62,
1590x03, 0xf5, 0x51, 0xe5, 0x62, 0x60, 0x15, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2, 0x59, 0xad, 0x62,
1600xaf, 0x40, 0x12, 0x17, 0x8d, 0xe5, 0x62, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2, 0xaf, 0x22, 0xc2,
1610xaf, 0x30, 0x01, 0x12, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xf5, 0x51, 0xc2, 0x59, 0xc2, 0x01, 0x7d,
1620x02, 0xaf, 0x40, 0x12, 0x17, 0x8d, 0xe5, 0x52, 0x14, 0x60, 0x09, 0x04, 0x70, 0x4c, 0x75, 0x52,
1630x01, 0x75, 0x55, 0x03, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x44,
1640x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x12, 0x04, 0x74,
1650x03, 0xf0, 0x90, 0x02, 0xa2, 0xe0, 0x44, 0xc0, 0xf0, 0x90, 0x10, 0x04, 0xe0, 0x44, 0x0c, 0xf0,
1660xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x0b, 0xc2, 0x02, 0x7d, 0x01, 0xaf, 0x41, 0x12, 0x17,
1670x8d, 0x80, 0x02, 0xc2, 0x03, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xd2, 0xaf, 0x22, 0xef, 0xf4, 0x60,
1680x2d, 0xe4, 0xfe, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xe0, 0xb4, 0xff,
1690x19, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef, 0xf0, 0x74, 0x1c, 0x2e,
1700xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xd5, 0x22, 0x22,
1710x22, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x4d, 0xc2, 0xaf, 0x90, 0x70, 0x28, 0xe0, 0x90, 0x10,
1720x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d, 0xf0, 0x90, 0x70, 0x2a, 0xe0, 0x90, 0x10,
1730x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x62, 0x90, 0x10, 0x1e, 0xe0, 0x20, 0xe1, 0xf3, 0x90,
1740x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10, 0x1d, 0xe0, 0x90, 0x70, 0x29, 0xf0, 0x90,
1750x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0, 0x30, 0x4a, 0x07, 0x90, 0x70, 0x24, 0xe0, 0x44, 0x01,
1760xf0, 0xc2, 0x05, 0xd2, 0xaf, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1770x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1780x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1790x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1800x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1810x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1820x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1830x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1840x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1850x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1860x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1870x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1880x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1890x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1900x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1910x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1920x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1930x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1940x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1950x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1960x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1970x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1980x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1990x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2000x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2010x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2020x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2030x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2040x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2050x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2060x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2070x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2080x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2090x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2100x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2120x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2130x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2140x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2150x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2160x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2170x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2180x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2190x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2200x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2210x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2220x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2230x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2240x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2250x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2260x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2270x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2280x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2290x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2300x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2310x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2320x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2330x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2340x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2360x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2370x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2380x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2390x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2400x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2410x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2420x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2440x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2450x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2460x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2470x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2480x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2490x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2500x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2520x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2530x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2540x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2550x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2560x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2570x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2580x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2590x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2600x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2610x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2620x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2630x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2640x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2650x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2660x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2670x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2680x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2690x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2700x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2710x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2720x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2730x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2740x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2760x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2770x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2780x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2790x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2800x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2810x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2820x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2830x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2840x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2850x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2860x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2870x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2880x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2890x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2900x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2910x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2920x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2930x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2940x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2950x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2960x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2970x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2980x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2990x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3000x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3010x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3020x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x94, 0x3f,
3030xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x32, 0x02, 0x10, 0x78, 0x02, 0x12, 0x67, 0x02,
3040x12, 0x68, 0x02, 0x12, 0x87, 0x02, 0x12, 0x8c, 0x12, 0x12, 0x88, 0x22, 0x02, 0x16, 0x49, 0x02,
3050x17, 0x1f, 0x02, 0x13, 0x77, 0x02, 0x12, 0x8d, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x17,
3060xc1, 0x22, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe3, 0x1b, 0xe5, 0x4c, 0x30, 0xe0, 0x04, 0x7f, 0x40,
3070x80, 0x02, 0x7f, 0x00, 0x90, 0x10, 0x2f, 0xef, 0xf0, 0x90, 0x01, 0x8c, 0x74, 0x08, 0xf0, 0xe4,
3080x90, 0x01, 0xa7, 0xf0, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe0, 0x1c, 0x90, 0x01, 0x80, 0xe0, 0xb4,
3090x02, 0x15, 0xa3, 0xe0, 0xb4, 0x01, 0x10, 0x90, 0x01, 0x84, 0xe0, 0xb4, 0x81, 0x09, 0x90, 0x01,
3100x8c, 0x74, 0x01, 0xf0, 0x12, 0x0d, 0xdd, 0x22, 0x90, 0x04, 0x14, 0xe0, 0x20, 0xe7, 0x03, 0x02,
3110x12, 0x66, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0, 0x12, 0x0a, 0xb6, 0x10,
3120xb7, 0x31, 0x10, 0xe0, 0x50, 0x11, 0x04, 0x51, 0x11, 0x0d, 0x52, 0x11, 0x0d, 0x53, 0x11, 0x0d,
3130x54, 0x11, 0x4e, 0x55, 0x11, 0x7e, 0x70, 0x11, 0xa9, 0x71, 0x11, 0xd7, 0x72, 0x12, 0x1d, 0x73,
3140x12, 0x3e, 0x80, 0x00, 0x00, 0x12, 0x66, 0x20, 0x02, 0x03, 0x30, 0x03, 0x1d, 0x7d, 0x02, 0xaf,
3150x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5,
3160x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x85, 0x56, 0x41, 0xd2, 0x02, 0x22,
3170x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0x64, 0x02, 0x60, 0x03, 0x02, 0x12, 0x66, 0x90, 0x70, 0x11,
3180xe0, 0x64, 0x08, 0x60, 0x08, 0xe0, 0x64, 0x20, 0x60, 0x03, 0x02, 0x12, 0x66, 0x75, 0x4e, 0x03,
3190x75, 0x4f, 0x20, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92, 0x47, 0x22, 0x90, 0x04, 0x04,
3200xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, 0x10, 0xe0, 0xff, 0x74, 0x47, 0x25, 0x57,
3210xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, 0x74, 0x48, 0x25, 0x57, 0xf8, 0xc6, 0xef,
3220xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90,
3230x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0xe5, 0x47,
3240x64, 0x07, 0x60, 0x0b, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0x90,
3250x70, 0x11, 0xe0, 0x54, 0x0f, 0xf5, 0x3a, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0xe5, 0x3a, 0xb4, 0x03,
3260x03, 0xe4, 0xf5, 0x46, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0xd2, 0x04, 0x22, 0x90, 0x70,
3270x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf8, 0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56,
3280x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56,
3290xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70,
3300x11, 0xe0, 0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b,
3310xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70,
3320x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x90, 0x10, 0x02, 0xe0, 0xb4, 0x70, 0x1e, 0xa3, 0xe0,
3330xb4, 0x30, 0x19, 0x90, 0x05, 0x08, 0xe0, 0x44, 0x01, 0xf0, 0xfd, 0x90, 0x05, 0x05, 0xe0, 0x54,
3340xfb, 0xf0, 0x44, 0x04, 0xf0, 0xed, 0x54, 0xfe, 0x90, 0x05, 0x08, 0xf0, 0xe4, 0xf5, 0x4e, 0xf5,
3350x4f, 0x75, 0x3a, 0xff, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80,
3360xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x4b, 0x80, 0x42, 0x90, 0x70, 0x10,
3370xe0, 0x24, 0xff, 0x92, 0x93, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74,
3380x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x2a, 0x80, 0x21, 0x90, 0x70,
3390x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90,
3400x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x07, 0x90,
3410x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x22, 0xe5, 0x53, 0x70, 0x1a, 0x30, 0x60, 0x09, 0xb2,
3420x4d, 0x30, 0x4d, 0x04, 0x05, 0x46, 0xc2, 0x04, 0xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f,
3430x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, 0x22, 0x22, 0xc2, 0x42, 0xd3, 0x22, 0x22, 0xc2, 0x4b, 0xc2,
3440x4c, 0xe5, 0x44, 0x12, 0x0a, 0xb6, 0x12, 0xaf, 0x00, 0x13, 0x42, 0x04, 0x13, 0x3e, 0x08, 0x13,
3450x19, 0x10, 0x12, 0xc3, 0x20, 0x12, 0xe3, 0x60, 0x12, 0xf4, 0xa0, 0x00, 0x00, 0x13, 0x44, 0x85,
3460x48, 0x43, 0x85, 0x4a, 0x42, 0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03, 0x02, 0x13,
3470x44, 0x80, 0x1b, 0xe5, 0x48, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4, 0x54, 0x0f, 0xf5,
3480x42, 0xe5, 0x4c, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x66, 0x53, 0x43,
3490x0f, 0x80, 0x61, 0x85, 0x49, 0x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5, 0x47, 0x64, 0x06,
3500x70, 0x52, 0x80, 0x1b, 0xe5, 0x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b, 0xc4, 0x54, 0x0f,
3510xf5, 0x42, 0xe5, 0x4d, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x35, 0xe5,
3520x43, 0x54, 0x0f, 0x44, 0x10, 0xf5, 0x43, 0x80, 0x2b, 0xe5, 0x47, 0xb4, 0x04, 0x06, 0x53, 0x5e,
3530xfb, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43, 0x5e, 0x04, 0x75, 0x42, 0x09, 0xe5,
3540x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30, 0xf5, 0x43, 0x80, 0x06, 0xd2, 0x4b,
3550x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x25, 0xe5, 0x42, 0xc4, 0x54, 0xf0, 0xff, 0xe5, 0x43, 0x54,
3560x0f, 0x4f, 0xf5, 0x5f, 0x90, 0x70, 0x44, 0xf0, 0xa3, 0xe5, 0x5e, 0xf0, 0xa3, 0xe5, 0x4a, 0xf0,
3570xa3, 0xe5, 0x48, 0xf0, 0xa3, 0xe5, 0x4c, 0xf0, 0xa3, 0xe5, 0x44, 0xf0, 0xa3, 0xe5, 0x42, 0xf0,
3580xa3, 0xe5, 0x43, 0xf0, 0xd2, 0x60, 0x22, 0xe5, 0x47, 0x60, 0x10, 0x24, 0xc0, 0x70, 0x03, 0x12,
3590x16, 0x29, 0x12, 0x13, 0x8c, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2, 0xaf, 0x90, 0x04,
3600x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x18, 0x80, 0x08, 0xe5, 0x4e, 0x45, 0x4f, 0x24, 0xff,
3610x92, 0x18, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x19, 0x74, 0x1e, 0xf0, 0xe5,
3620x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x25, 0x70, 0x13, 0x30, 0x18, 0x05, 0xe5, 0x5f, 0x20, 0xe5,
3630x0b, 0x30, 0x19, 0x19, 0xe5, 0x5f, 0x54, 0x30, 0xff, 0xbf, 0x30, 0x11, 0xe5, 0x25, 0x70, 0x05,
3640x75, 0x25, 0x0c, 0x80, 0x02, 0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f, 0xe5, 0x5f, 0x30,
3650xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5, 0x47, 0x64, 0x03,
3660x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x25, 0x70, 0x03, 0x30,
3670x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x25, 0x70, 0x05, 0x75, 0x25, 0x07, 0x80, 0x02, 0x15, 0x25, 0xd2,
3680x6c, 0xd2, 0x6d, 0xe5, 0x47, 0xb4, 0x09, 0x14, 0xe5, 0x44, 0x20, 0xe3, 0x0b, 0xe5, 0x3a, 0x64,
3690x02, 0x60, 0x05, 0xe5, 0x3a, 0xb4, 0x03, 0x04, 0xc2, 0x6c, 0xd2, 0x6d, 0x90, 0x70, 0x46, 0xe5,
3700x2d, 0xf0, 0x20, 0x69, 0x07, 0xe5, 0x5e, 0x20, 0xe0, 0x02, 0xb2, 0x68, 0x20, 0x6b, 0x07, 0xe5,
3710x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20, 0x6d, 0x07, 0xe5, 0x5e, 0x20, 0xe2, 0x02, 0xb2, 0x6c,
3720x90, 0x70, 0x47, 0xe5, 0x2d, 0xf0, 0x75, 0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x26,
3730x30, 0x68, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01,
3740x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02,
3750x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x73, 0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80,
3760x26, 0x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f,
3770x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80,
3780x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x75, 0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c,
3790x80, 0x26, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe1, 0x04,
3800x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01,
3810x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x71, 0x92, 0x70, 0x90, 0x10, 0x00, 0xe0,
3820x90, 0x10, 0x2f, 0xf0, 0x90, 0x10, 0x03, 0xe0, 0xc3, 0x94, 0x30, 0x40, 0x14, 0xa2, 0x71, 0x92,
3830x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13, 0x54, 0x3f, 0xf5, 0x2e, 0xc2, 0x77, 0xd2,
3840x76, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x4c, 0x90, 0x02, 0x29,
3850xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f, 0x14, 0x60, 0x14, 0x24, 0xfe, 0x60, 0x23,
3860x24, 0x03, 0x60, 0x03, 0x02, 0x16, 0x18, 0x90, 0x02, 0x28, 0xe0, 0x30, 0x47, 0x0f, 0x80, 0x07,
3870x90, 0x02, 0x28, 0xe0, 0x20, 0x47, 0x06, 0x54, 0xfe, 0xf0, 0x02, 0x16, 0x18, 0x44, 0x01, 0xf0,
3880x02, 0x16, 0x18, 0xe5, 0x46, 0x30, 0xe2, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x90, 0x02,
3890x28, 0xe0, 0x54, 0xfe, 0x4f, 0xf0, 0x02, 0x16, 0x18, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x0f, 0xe5,
3900x47, 0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02, 0x16, 0x18, 0xe4, 0xf5,
3910x27, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x2d, 0x14, 0x60, 0x2e,
3920x14, 0x60, 0x36, 0x24, 0xfc, 0x60, 0x5f, 0x24, 0xf9, 0x60, 0x1f, 0x24, 0x0e, 0x70, 0x69, 0xe5,
3930x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xaf, 0xf0, 0x20, 0x47, 0x04, 0x7e, 0x01,
3940x80, 0x02, 0x7e, 0x00, 0xef, 0x6e, 0x24, 0xff, 0x80, 0x45, 0xa2, 0x47, 0x80, 0x41, 0xe5, 0x46,
3950x30, 0xe2, 0x03, 0xd3, 0x80, 0x27, 0xc3, 0x80, 0x24, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38,
3960xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0x20,
3970x47, 0x04, 0x7d, 0x01, 0x80, 0x02, 0x7d, 0x00, 0xef, 0x6d, 0x4e, 0x24, 0xff, 0x92, 0x38, 0xa2,
3980x47, 0xb3, 0x92, 0x39, 0x80, 0x19, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92,
3990x39, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x80, 0x07, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x92, 0x39, 0x90,
4000x02, 0x28, 0xe0, 0x54, 0xfc, 0x45, 0x27, 0xf0, 0x90, 0x70, 0x9c, 0xe5, 0x3a, 0xf0, 0xa3, 0xe5,
4010x47, 0xf0, 0x90, 0x70, 0x41, 0xe5, 0x3a, 0xf0, 0x22, 0xe4, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47,
4020x04, 0xaf, 0x45, 0x80, 0x04, 0xe5, 0x45, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0x8f,
4030x50, 0xd2, 0x59, 0x22, 0x8f, 0x54, 0xd2, 0x58, 0x22, 0xe4, 0xf5, 0x62, 0xc2, 0xaf, 0xe5, 0x51,
4040x14, 0x60, 0x46, 0x14, 0x60, 0x62, 0x24, 0x02, 0x60, 0x03, 0x02, 0x17, 0x03, 0xd2, 0x59, 0x75,
4050x55, 0x01, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0x7f, 0xf0, 0xa3, 0xe0, 0x20, 0xe7, 0x22, 0x90, 0x04,
4060x34, 0xe0, 0xb4, 0x02, 0x1b, 0xa3, 0xe0, 0xb4, 0x02, 0x16, 0xa3, 0xe0, 0xb4, 0x02, 0x11, 0x7f,
4070x20, 0x12, 0x16, 0x3f, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0, 0x75, 0x51, 0x01, 0x80, 0x73,
4080xe5, 0x50, 0x70, 0x05, 0x75, 0x62, 0x03, 0x80, 0x6a, 0x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70,
4090x11, 0x7f, 0x20, 0x12, 0x16, 0x3f, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0xbf, 0xf0, 0x75, 0x51, 0x02,
4100x80, 0x51, 0xe5, 0x50, 0x70, 0x02, 0x80, 0x46, 0x90, 0x02, 0xa3, 0xe0, 0x20, 0xe6, 0x3b, 0x90,
4110x04, 0x37, 0xe0, 0x64, 0x22, 0x70, 0x33, 0x90, 0x01, 0x8a, 0x74, 0x7e, 0xf0, 0x90, 0x01, 0x96,
4120xf0, 0x90, 0x12, 0x04, 0x74, 0x0a, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0,
4130x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xfa, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x54, 0xf9, 0xf0, 0x75,
4140x62, 0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70, 0x05, 0x75, 0x62,
4150x03, 0xf5, 0x51, 0xe5, 0x62, 0x60, 0x15, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2, 0x59, 0xad, 0x62,
4160xaf, 0x40, 0x12, 0x17, 0x8d, 0xe5, 0x62, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2, 0xaf, 0x22, 0xc2,
4170xaf, 0x30, 0x01, 0x12, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xf5, 0x51, 0xc2, 0x59, 0xc2, 0x01, 0x7d,
4180x02, 0xaf, 0x40, 0x12, 0x17, 0x8d, 0xe5, 0x52, 0x14, 0x60, 0x09, 0x04, 0x70, 0x4c, 0x75, 0x52,
4190x01, 0x75, 0x55, 0x03, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x44,
4200x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x12, 0x04, 0x74,
4210x03, 0xf0, 0x90, 0x02, 0xa2, 0xe0, 0x44, 0xc0, 0xf0, 0x90, 0x10, 0x04, 0xe0, 0x44, 0x0c, 0xf0,
4220xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x0b, 0xc2, 0x02, 0x7d, 0x01, 0xaf, 0x41, 0x12, 0x17,
4230x8d, 0x80, 0x02, 0xc2, 0x03, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xd2, 0xaf, 0x22, 0xef, 0xf4, 0x60,
4240x2d, 0xe4, 0xfe, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xe0, 0xb4, 0xff,
4250x19, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef, 0xf0, 0x74, 0x1c, 0x2e,
4260xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xd5, 0x22, 0x22,
4270x22, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x4d, 0xc2, 0xaf, 0x90, 0x70, 0x28, 0xe0, 0x90, 0x10,
4280x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d, 0xf0, 0x90, 0x70, 0x2a, 0xe0, 0x90, 0x10,
4290x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x62, 0x90, 0x10, 0x1e, 0xe0, 0x20, 0xe1, 0xf3, 0x90,
4300x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10, 0x1d, 0xe0, 0x90, 0x70, 0x29, 0xf0, 0x90,
4310x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0, 0x30, 0x4a, 0x07, 0x90, 0x70, 0x24, 0xe0, 0x44, 0x01,
4320xf0, 0xc2, 0x05, 0xd2, 0xaf, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4330x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4340x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4360x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4370x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4380x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4390x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4400x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4410x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4420x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4440x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4450x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4460x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4470x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4480x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4490x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4500x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4520x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4530x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4540x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4550x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4560x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4570x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4580x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4590x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4600x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4610x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4620x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4630x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4640x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4650x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4660x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4670x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4680x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4690x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4700x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4710x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4720x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4730x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4740x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4760x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4770x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4780x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4790x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4800x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4810x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4820x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4830x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4840x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4850x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4860x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4870x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4880x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4890x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4900x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4910x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4920x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4930x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4940x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4950x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4960x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4970x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4980x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4990x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5000x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5010x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5020x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5030x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5040x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5050x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5060x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5070x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5080x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5090x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5100x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5120x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5130x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5140x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5150x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5160x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5170x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5180x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5190x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5200x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5210x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5220x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5230x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5240x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5250x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5260x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5270x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5280x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5290x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5300x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5310x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5320x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5330x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5340x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5360x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5370x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5380x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5390x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5400x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5410x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5420x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5440x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5450x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5460x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5470x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5480x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5490x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5500x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5520x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5530x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5540x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5550x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5560x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5570x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5580x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x9b, 0xc0, } ;
diff --git a/drivers/staging/rt3070/leap.h b/drivers/staging/rt3070/leap.h
new file mode 100644
index 000000000000..6818c1ff4d73
--- /dev/null
+++ b/drivers/staging/rt3070/leap.h
@@ -0,0 +1,215 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 leap.h
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Name Date Modification logs
36*/
37#ifndef __LEAP_H__
38#define __LEAP_H__
39
40// Messages for Associate state machine
41#define LEAP_MACHINE_BASE 30
42
43#define LEAP_MSG_REQUEST_IDENTITY 31
44#define LEAP_MSG_REQUEST_LEAP 32
45#define LEAP_MSG_SUCCESS 33
46#define LEAP_MSG_FAILED 34
47#define LEAP_MSG_RESPONSE_LEAP 35
48#define LEAP_MSG_EAPOLKEY 36
49#define LEAP_MSG_UNKNOWN 37
50#define LEAP_MSG 38
51//! assoc state-machine states
52#define LEAP_IDLE 0
53#define LEAP_WAIT_IDENTITY_REQUEST 1
54#define LEAP_WAIT_CHANLLENGE_REQUEST 2
55#define LEAP_WAIT_SUCCESS 3
56#define LEAP_WAIT_CHANLLENGE_RESPONSE 4
57#define LEAP_WAIT_EAPOLKEY 5
58
59#define LEAP_REASON_INVALID_AUTH 0x01
60#define LEAP_REASON_AUTH_TIMEOUT 0x02
61#define LEAP_REASON_CHALLENGE_FROM_AP_FAILED 0x03
62#define LEAP_REASON_CHALLENGE_TO_AP_FAILED 0x04
63
64#define CISCO_AuthModeLEAP 0x80
65#define CISCO_AuthModeLEAPNone 0x00
66#define LEAP_AUTH_TIMEOUT 30000
67#define LEAP_CHALLENGE_RESPONSE_LENGTH 24
68#define LEAP_CHALLENGE_REQUEST_LENGTH 8
69
70typedef struct _LEAP_EAPOL_HEADER_ {
71 UCHAR Version;
72 UCHAR Type;
73 UCHAR Length[2];
74} LEAP_EAPOL_HEADER, *PLEAP_EAPOL_HEADER;
75
76typedef struct _LEAP_EAPOL_PACKET_ {
77 UCHAR Code;
78 UCHAR Identifier;
79 UCHAR Length[2];
80 UCHAR Type;
81} LEAP_EAPOL_PACKET, *PLEAP_EAPOL_PACKET;
82
83typedef struct _LEAP_EAP_CONTENTS_ {
84 UCHAR Version;
85 UCHAR Reserved;
86 UCHAR Length;
87} LEAP_EAP_CONTENTS, *PLEAP_EAP_CONTENTS;
88
89/*** EAPOL key ***/
90typedef struct _EAPOL_KEY_HEADER_ {
91 UCHAR Type;
92 UCHAR Length[2];
93 UCHAR Counter[8];
94 UCHAR IV[16];
95 UCHAR Index;
96 UCHAR Signature[16];
97} EAPOL_KEY_HEADER, *PEAPOL_KEY_HEADER;
98
99BOOLEAN LeapMsgTypeSubst(
100 IN UCHAR EAPType,
101 OUT ULONG *MsgType);
102
103VOID LeapMachinePerformAction(
104 IN PRTMP_ADAPTER pAd,
105 IN STATE_MACHINE *S,
106 IN MLME_QUEUE_ELEM *Elem);
107
108VOID LeapMacHeaderInit(
109 IN PRTMP_ADAPTER pAd,
110 IN OUT PHEADER_802_11 pHdr80211,
111 IN UCHAR wep,
112 IN PUCHAR pAddr3);
113
114VOID LeapStartAction(
115 IN PRTMP_ADAPTER pAd,
116 IN MLME_QUEUE_ELEM *Elem);
117
118VOID LeapIdentityAction(
119 IN PRTMP_ADAPTER pAd,
120 IN MLME_QUEUE_ELEM *Elem);
121
122VOID LeapPeerChallengeAction(
123 IN PRTMP_ADAPTER pAd,
124 IN MLME_QUEUE_ELEM *Elem);
125
126VOID HashPwd(
127 IN PUCHAR pwd,
128 IN INT pwdlen,
129 OUT PUCHAR hash);
130
131VOID PeerChallengeResponse(
132 IN PUCHAR szChallenge,
133 IN PUCHAR smbPasswd,
134 OUT PUCHAR szResponse);
135
136VOID ParityKey(
137 OUT PUCHAR szOut,
138 IN PUCHAR szIn);
139
140VOID DesKey(
141 OUT ULONG k[16][2],
142 IN PUCHAR key,
143 IN INT decrypt);
144
145VOID Des(
146 IN ULONG ks[16][2],
147 OUT UCHAR block[8]);
148
149VOID DesEncrypt(
150 IN PUCHAR szClear,
151 IN PUCHAR szKey,
152 OUT PUCHAR szOut);
153
154VOID LeapNetworkChallengeAction(
155 IN PRTMP_ADAPTER pAd,
156 IN MLME_QUEUE_ELEM *Elem);
157
158VOID LeapNetworkChallengeResponse(
159 IN PRTMP_ADAPTER pAd,
160 IN MLME_QUEUE_ELEM *Elem);
161
162VOID HashpwdHash(
163 IN PUCHAR hash,
164 IN PUCHAR hashhash);
165
166VOID ProcessSessionKey(
167 OUT PUCHAR SessionKey,
168 IN PUCHAR hash2,
169 IN PUCHAR ChallengeToRadius,
170 IN PUCHAR ChallengeResponseFromRadius,
171 IN PUCHAR ChallengeFromRadius,
172 IN PUCHAR ChallengeResponseToRadius);
173
174VOID LeapEapolKeyAction(
175 IN PRTMP_ADAPTER pAd,
176 IN MLME_QUEUE_ELEM *Elem);
177
178VOID RogueApTableInit(
179 IN ROGUEAP_TABLE *Tab);
180
181ULONG RogueApTableSearch(
182 IN ROGUEAP_TABLE *Tab,
183 IN PUCHAR pAddr);
184
185VOID RogueApEntrySet(
186 IN PRTMP_ADAPTER pAd,
187 OUT ROGUEAP_ENTRY *pRogueAp,
188 IN PUCHAR pAddr,
189 IN UCHAR FaileCode);
190
191ULONG RogueApTableSetEntry(
192 IN PRTMP_ADAPTER pAd,
193 OUT ROGUEAP_TABLE *Tab,
194 IN PUCHAR pAddr,
195 IN UCHAR FaileCode);
196
197VOID RogueApTableDeleteEntry(
198 IN OUT ROGUEAP_TABLE *Tab,
199 IN PUCHAR pAddr);
200
201VOID LeapAuthTimeout(
202 IN PVOID SystemSpecific1,
203 IN PVOID FunctionContext,
204 IN PVOID SystemSpecific2,
205 IN PVOID SystemSpecific3);
206
207VOID LeapSendRogueAPReport(
208 IN PRTMP_ADAPTER pAd);
209
210BOOLEAN CCKMAssocRspSanity(
211 IN PRTMP_ADAPTER pAd,
212 IN VOID *Msg,
213 IN ULONG MsgLen);
214
215#endif // __LEAP_H__
diff --git a/drivers/staging/rt3070/link_list.h b/drivers/staging/rt3070/link_list.h
new file mode 100644
index 000000000000..f6521133fd5e
--- /dev/null
+++ b/drivers/staging/rt3070/link_list.h
@@ -0,0 +1,134 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26 */
27
28#ifndef __LINK_LIST_H__
29#define __LINK_LIST_H__
30
31typedef struct _LIST_ENTRY
32{
33 struct _LIST_ENTRY *pNext;
34} LIST_ENTRY, *PLIST_ENTRY;
35
36typedef struct _LIST_HEADR
37{
38 PLIST_ENTRY pHead;
39 PLIST_ENTRY pTail;
40 UCHAR size;
41} LIST_HEADER, *PLIST_HEADER;
42
43static inline VOID initList(
44 IN PLIST_HEADER pList)
45{
46 pList->pHead = pList->pTail = NULL;
47 pList->size = 0;
48 return;
49}
50
51static inline VOID insertTailList(
52 IN PLIST_HEADER pList,
53 IN PLIST_ENTRY pEntry)
54{
55 pEntry->pNext = NULL;
56 if (pList->pTail)
57 pList->pTail->pNext = pEntry;
58 else
59 pList->pHead = pEntry;
60 pList->pTail = pEntry;
61 pList->size++;
62
63 return;
64}
65
66static inline PLIST_ENTRY removeHeadList(
67 IN PLIST_HEADER pList)
68{
69 PLIST_ENTRY pNext;
70 PLIST_ENTRY pEntry;
71
72 pEntry = pList->pHead;
73 if (pList->pHead != NULL)
74 {
75 pNext = pList->pHead->pNext;
76 pList->pHead = pNext;
77 if (pNext == NULL)
78 pList->pTail = NULL;
79 pList->size--;
80 }
81 return pEntry;
82}
83
84static inline int getListSize(
85 IN PLIST_HEADER pList)
86{
87 return pList->size;
88}
89
90static inline PLIST_ENTRY delEntryList(
91 IN PLIST_HEADER pList,
92 IN PLIST_ENTRY pEntry)
93{
94 PLIST_ENTRY pCurEntry;
95 PLIST_ENTRY pPrvEntry;
96
97 if(pList->pHead == NULL)
98 return NULL;
99
100 if(pEntry == pList->pHead)
101 {
102 pCurEntry = pList->pHead;
103 pList->pHead = pCurEntry->pNext;
104
105 if(pList->pHead == NULL)
106 pList->pTail = NULL;
107
108 pList->size--;
109 return pCurEntry;
110 }
111
112 pPrvEntry = pList->pHead;
113 pCurEntry = pPrvEntry->pNext;
114 while(pCurEntry != NULL)
115 {
116 if (pEntry == pCurEntry)
117 {
118 pPrvEntry->pNext = pCurEntry->pNext;
119
120 if(pEntry == pList->pTail)
121 pList->pTail = pPrvEntry;
122
123 pList->size--;
124 break;
125 }
126 pPrvEntry = pCurEntry;
127 pCurEntry = pPrvEntry->pNext;
128 }
129
130 return pCurEntry;
131}
132
133#endif // ___LINK_LIST_H__ //
134
diff --git a/drivers/staging/rt3070/md4.h b/drivers/staging/rt3070/md4.h
new file mode 100644
index 000000000000..f1e5b526350a
--- /dev/null
+++ b/drivers/staging/rt3070/md4.h
@@ -0,0 +1,42 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26 */
27
28#ifndef __MD4_H__
29#define __MD4_H__
30
31/* MD4 context. */
32typedef struct _MD4_CTX_ {
33 ULONG state[4]; /* state (ABCD) */
34 ULONG count[2]; /* number of bits, modulo 2^64 (lsb first) */
35 UCHAR buffer[64]; /* input buffer */
36} MD4_CTX;
37
38VOID MD4Init (MD4_CTX *);
39VOID MD4Update (MD4_CTX *, PUCHAR, UINT);
40VOID MD4Final (UCHAR [16], MD4_CTX *);
41
42#endif //__MD4_H__ \ No newline at end of file
diff --git a/drivers/staging/rt3070/md5.h b/drivers/staging/rt3070/md5.h
new file mode 100644
index 000000000000..d85db12170d5
--- /dev/null
+++ b/drivers/staging/rt3070/md5.h
@@ -0,0 +1,107 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 md5.h
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Name Date Modification logs
36 jan 10-28-03 Initial
37 Rita 11-23-04 Modify MD5 and SHA-1
38*/
39
40#ifndef uint8
41#define uint8 unsigned char
42#endif
43
44#ifndef uint32
45#define uint32 unsigned long int
46#endif
47
48
49#ifndef __MD5_H__
50#define __MD5_H__
51
52#define MD5_MAC_LEN 16
53
54typedef struct _MD5_CTX {
55 UINT32 Buf[4]; // buffers of four states
56 UCHAR Input[64]; // input message
57 UINT32 LenInBitCount[2]; // length counter for input message, 0 up to 64 bits
58} MD5_CTX;
59
60VOID MD5Init(MD5_CTX *pCtx);
61VOID MD5Update(MD5_CTX *pCtx, UCHAR *pData, UINT32 LenInBytes);
62VOID MD5Final(UCHAR Digest[16], MD5_CTX *pCtx);
63VOID MD5Transform(UINT32 Buf[4], UINT32 Mes[16]);
64
65void md5_mac(u8 *key, size_t key_len, u8 *data, size_t data_len, u8 *mac);
66void hmac_md5(u8 *key, size_t key_len, u8 *data, size_t data_len, u8 *mac);
67
68//
69// SHA context
70//
71typedef struct _SHA_CTX
72{
73 UINT32 Buf[5]; // buffers of five states
74 UCHAR Input[80]; // input message
75 UINT32 LenInBitCount[2]; // length counter for input message, 0 up to 64 bits
76
77} SHA_CTX;
78
79VOID SHAInit(SHA_CTX *pCtx);
80UCHAR SHAUpdate(SHA_CTX *pCtx, UCHAR *pData, UINT32 LenInBytes);
81VOID SHAFinal(SHA_CTX *pCtx, UCHAR Digest[20]);
82VOID SHATransform(UINT32 Buf[5], UINT32 Mes[20]);
83
84#define SHA_DIGEST_LEN 20
85#endif // __MD5_H__
86
87/******************************************************************************/
88#ifndef _AES_H
89#define _AES_H
90
91typedef struct
92{
93 uint32 erk[64]; /* encryption round keys */
94 uint32 drk[64]; /* decryption round keys */
95 int nr; /* number of rounds */
96}
97aes_context;
98
99int rtmp_aes_set_key( aes_context *ctx, uint8 *key, int nbits );
100void rtmp_aes_encrypt( aes_context *ctx, uint8 input[16], uint8 output[16] );
101void rtmp_aes_decrypt( aes_context *ctx, uint8 input[16], uint8 output[16] );
102
103void F(char *password, unsigned char *ssid, int ssidlength, int iterations, int count, unsigned char *output);
104int PasswordHash(char *password, unsigned char *ssid, int ssidlength, unsigned char *output);
105
106#endif /* aes.h */
107
diff --git a/drivers/staging/rt3070/mlme.h b/drivers/staging/rt3070/mlme.h
new file mode 100644
index 000000000000..b0035e1fa8ea
--- /dev/null
+++ b/drivers/staging/rt3070/mlme.h
@@ -0,0 +1,1468 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 mlme.h
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 John Chang 2003-08-28 Created
36 John Chang 2004-09-06 modified for RT2600
37
38*/
39#ifndef __MLME_H__
40#define __MLME_H__
41
42//extern UCHAR BROADCAST_ADDR[];
43
44// maximum supported capability information -
45// ESS, IBSS, Privacy, Short Preamble, Spectrum mgmt, Short Slot
46#define SUPPORTED_CAPABILITY_INFO 0x0533
47
48#define END_OF_ARGS -1
49#define LFSR_MASK 0x80000057
50#define MLME_TASK_EXEC_INTV 100/*200*/ //
51#define LEAD_TIME 5
52#define MLME_TASK_EXEC_MULTIPLE 10 /*5*/ // MLME_TASK_EXEC_MULTIPLE * MLME_TASK_EXEC_INTV = 1 sec
53#define REORDER_EXEC_INTV 100 // 0.1 sec
54//#define TBTT_PRELOAD_TIME 384 // usec. LomgPreamble + 24-byte at 1Mbps
55
56// The definition of Radar detection duration region
57#define CE 0
58#define FCC 1
59#define JAP 2
60#define JAP_W53 3
61#define JAP_W56 4
62#define MAX_RD_REGION 5
63
64#ifdef NDIS51_MINIPORT
65#define BEACON_LOST_TIME 4000 // 2048 msec = 2 sec
66#else
67#define BEACON_LOST_TIME 4 * OS_HZ // 2048 msec = 2 sec
68#endif
69
70#define DLS_TIMEOUT 1200 // unit: msec
71#define AUTH_TIMEOUT 300 // unit: msec
72#define ASSOC_TIMEOUT 300 // unit: msec
73#define JOIN_TIMEOUT 2 * OS_HZ // unit: msec
74#define SHORT_CHANNEL_TIME 90 // unit: msec
75#define MIN_CHANNEL_TIME 110 // unit: msec, for dual band scan
76#define MAX_CHANNEL_TIME 140 // unit: msec, for single band scan
77#define FAST_ACTIVE_SCAN_TIME 30 // Active scan waiting for probe response time
78#define CW_MIN_IN_BITS 4 // actual CwMin = 2^CW_MIN_IN_BITS - 1
79
80
81#ifdef CONFIG_STA_SUPPORT
82#ifndef CONFIG_AP_SUPPORT
83#define CW_MAX_IN_BITS 10 // actual CwMax = 2^CW_MAX_IN_BITS - 1
84#endif
85#endif // CONFIG_STA_SUPPORT //
86
87#ifdef CONFIG_APSTA_MIXED_SUPPORT
88extern UINT32 CW_MAX_IN_BITS;
89#endif // CONFIG_APSTA_MIXED_SUPPORT //
90
91// Note: RSSI_TO_DBM_OFFSET has been changed to variable for new RF (2004-0720).
92// SHould not refer to this constant anymore
93//#define RSSI_TO_DBM_OFFSET 120 // for RT2530 RSSI-115 = dBm
94#define RSSI_FOR_MID_TX_POWER -55 // -55 db is considered mid-distance
95#define RSSI_FOR_LOW_TX_POWER -45 // -45 db is considered very short distance and
96 // eligible to use a lower TX power
97#define RSSI_FOR_LOWEST_TX_POWER -30
98//#define MID_TX_POWER_DELTA 0 // 0 db from full TX power upon mid-distance to AP
99#define LOW_TX_POWER_DELTA 6 // -3 db from full TX power upon very short distance. 1 grade is 0.5 db
100#define LOWEST_TX_POWER_DELTA 16 // -8 db from full TX power upon shortest distance. 1 grade is 0.5 db
101
102#define RSSI_TRIGGERED_UPON_BELOW_THRESHOLD 0
103#define RSSI_TRIGGERED_UPON_EXCCEED_THRESHOLD 1
104#define RSSI_THRESHOLD_FOR_ROAMING 25
105#define RSSI_DELTA 5
106
107// Channel Quality Indication
108#define CQI_IS_GOOD(cqi) ((cqi) >= 50)
109//#define CQI_IS_FAIR(cqi) (((cqi) >= 20) && ((cqi) < 50))
110#define CQI_IS_POOR(cqi) (cqi < 50) //(((cqi) >= 5) && ((cqi) < 20))
111#define CQI_IS_BAD(cqi) (cqi < 5)
112#define CQI_IS_DEAD(cqi) (cqi == 0)
113
114// weighting factor to calculate Channel quality, total should be 100%
115#define RSSI_WEIGHTING 50
116#define TX_WEIGHTING 30
117#define RX_WEIGHTING 20
118
119//#define PEER_KEY_NOT_USED 0
120//#define PEER_KEY_64_BIT 64
121//#define PEER_KEY_128_BIT 128
122
123//#define PEER_KEY_64BIT_LEN 8
124//#define PEER_KEY_128BIT_LEN 16
125
126#define BSS_NOT_FOUND 0xFFFFFFFF
127
128
129#ifdef CONFIG_STA_SUPPORT
130#define MAX_LEN_OF_MLME_QUEUE 40 //10
131#endif // CONFIG_STA_SUPPORT //
132
133#define SCAN_PASSIVE 18 // scan with no probe request, only wait beacon and probe response
134#define SCAN_ACTIVE 19 // scan with probe request, and wait beacon and probe response
135#define SCAN_CISCO_PASSIVE 20 // Single channel passive scan
136#define SCAN_CISCO_ACTIVE 21 // Single channel active scan
137#define SCAN_CISCO_NOISE 22 // Single channel passive scan for noise histogram collection
138#define SCAN_CISCO_CHANNEL_LOAD 23 // Single channel passive scan for channel load collection
139#define FAST_SCAN_ACTIVE 24 // scan with probe request, and wait beacon and probe response
140
141#ifdef DOT11N_DRAFT3
142#define SCAN_2040_BSS_COEXIST 26
143#endif // DOT11N_DRAFT3 //
144
145//#define BSS_TABLE_EMPTY(x) ((x).BssNr == 0)
146#define MAC_ADDR_IS_GROUP(Addr) (((Addr[0]) & 0x01))
147#define MAC_ADDR_HASH(Addr) (Addr[0] ^ Addr[1] ^ Addr[2] ^ Addr[3] ^ Addr[4] ^ Addr[5])
148#define MAC_ADDR_HASH_INDEX(Addr) (MAC_ADDR_HASH(Addr) % HASH_TABLE_SIZE)
149#define TID_MAC_HASH(Addr,TID) (TID^Addr[0] ^ Addr[1] ^ Addr[2] ^ Addr[3] ^ Addr[4] ^ Addr[5])
150#define TID_MAC_HASH_INDEX(Addr,TID) (TID_MAC_HASH(Addr,TID) % HASH_TABLE_SIZE)
151
152// LED Control
153// assoiation ON. one LED ON. another blinking when TX, OFF when idle
154// no association, both LED off
155#define ASIC_LED_ACT_ON(pAd) RTMP_IO_WRITE32(pAd, MAC_CSR14, 0x00031e46)
156#define ASIC_LED_ACT_OFF(pAd) RTMP_IO_WRITE32(pAd, MAC_CSR14, 0x00001e46)
157
158// bit definition of the 2-byte pBEACON->Capability field
159#define CAP_IS_ESS_ON(x) (((x) & 0x0001) != 0)
160#define CAP_IS_IBSS_ON(x) (((x) & 0x0002) != 0)
161#define CAP_IS_CF_POLLABLE_ON(x) (((x) & 0x0004) != 0)
162#define CAP_IS_CF_POLL_REQ_ON(x) (((x) & 0x0008) != 0)
163#define CAP_IS_PRIVACY_ON(x) (((x) & 0x0010) != 0)
164#define CAP_IS_SHORT_PREAMBLE_ON(x) (((x) & 0x0020) != 0)
165#define CAP_IS_PBCC_ON(x) (((x) & 0x0040) != 0)
166#define CAP_IS_AGILITY_ON(x) (((x) & 0x0080) != 0)
167#define CAP_IS_SPECTRUM_MGMT(x) (((x) & 0x0100) != 0) // 802.11e d9
168#define CAP_IS_QOS(x) (((x) & 0x0200) != 0) // 802.11e d9
169#define CAP_IS_SHORT_SLOT(x) (((x) & 0x0400) != 0)
170#define CAP_IS_APSD(x) (((x) & 0x0800) != 0) // 802.11e d9
171#define CAP_IS_IMMED_BA(x) (((x) & 0x1000) != 0) // 802.11e d9
172#define CAP_IS_DSSS_OFDM(x) (((x) & 0x2000) != 0)
173#define CAP_IS_DELAY_BA(x) (((x) & 0x4000) != 0) // 802.11e d9
174
175#define CAP_GENERATE(ess,ibss,priv,s_pre,s_slot,spectrum) (((ess) ? 0x0001 : 0x0000) | ((ibss) ? 0x0002 : 0x0000) | ((priv) ? 0x0010 : 0x0000) | ((s_pre) ? 0x0020 : 0x0000) | ((s_slot) ? 0x0400 : 0x0000) | ((spectrum) ? 0x0100 : 0x0000))
176
177//#define STA_QOS_CAPABILITY 0 // 1-byte. see 802.11e d9.0 for bit definition
178
179#define ERP_IS_NON_ERP_PRESENT(x) (((x) & 0x01) != 0) // 802.11g
180#define ERP_IS_USE_PROTECTION(x) (((x) & 0x02) != 0) // 802.11g
181#define ERP_IS_USE_BARKER_PREAMBLE(x) (((x) & 0x04) != 0) // 802.11g
182
183#define DRS_TX_QUALITY_WORST_BOUND 8// 3 // just test by gary
184#define DRS_PENALTY 8
185
186#define BA_NOTUSE 2
187//BA Policy subfiled value in ADDBA frame
188#define IMMED_BA 1
189#define DELAY_BA 0
190
191// BA Initiator subfield in DELBA frame
192#define ORIGINATOR 1
193#define RECIPIENT 0
194
195// ADDBA Status Code
196#define ADDBA_RESULTCODE_SUCCESS 0
197#define ADDBA_RESULTCODE_REFUSED 37
198#define ADDBA_RESULTCODE_INVALID_PARAMETERS 38
199
200// DELBA Reason Code
201#define DELBA_REASONCODE_QSTA_LEAVING 36
202#define DELBA_REASONCODE_END_BA 37
203#define DELBA_REASONCODE_UNKNOWN_BA 38
204#define DELBA_REASONCODE_TIMEOUT 39
205
206// reset all OneSecTx counters
207#define RESET_ONE_SEC_TX_CNT(__pEntry) \
208if (((__pEntry)) != NULL) \
209{ \
210 (__pEntry)->OneSecTxRetryOkCount = 0; \
211 (__pEntry)->OneSecTxFailCount = 0; \
212 (__pEntry)->OneSecTxNoRetryOkCount = 0; \
213}
214
215//
216// 802.11 frame formats
217//
218// HT Capability INFO field in HT Cap IE .
219typedef struct PACKED {
220#ifdef RT_BIG_ENDIAN
221 USHORT LSIGTxopProSup:1;
222 USHORT Forty_Mhz_Intolerant:1;
223 USHORT PSMP:1;
224 USHORT CCKmodein40:1;
225 USHORT AMsduSize:1;
226 USHORT DelayedBA:1; //rt2860c not support
227 USHORT RxSTBC:2;
228 USHORT TxSTBC:1;
229 USHORT ShortGIfor40:1; //for40MHz
230 USHORT ShortGIfor20:1;
231 USHORT GF:1; //green field
232 USHORT MimoPs:2;//momi power safe
233 USHORT ChannelWidth:1;
234 USHORT AdvCoding:1;
235#else
236 USHORT AdvCoding:1;
237 USHORT ChannelWidth:1;
238 USHORT MimoPs:2;//momi power safe
239 USHORT GF:1; //green field
240 USHORT ShortGIfor20:1;
241 USHORT ShortGIfor40:1; //for40MHz
242 USHORT TxSTBC:1;
243 USHORT RxSTBC:2;
244 USHORT DelayedBA:1; //rt2860c not support
245 USHORT AMsduSize:1; // only support as zero
246 USHORT CCKmodein40:1;
247 USHORT PSMP:1;
248 USHORT Forty_Mhz_Intolerant:1;
249 USHORT LSIGTxopProSup:1;
250#endif /* !RT_BIG_ENDIAN */
251} HT_CAP_INFO, *PHT_CAP_INFO;
252
253// HT Capability INFO field in HT Cap IE .
254typedef struct PACKED {
255#ifdef RT_BIG_ENDIAN
256 UCHAR rsv:3;//momi power safe
257 UCHAR MpduDensity:3;
258 UCHAR MaxRAmpduFactor:2;
259#else
260 UCHAR MaxRAmpduFactor:2;
261 UCHAR MpduDensity:3;
262 UCHAR rsv:3;//momi power safe
263#endif /* !RT_BIG_ENDIAN */
264} HT_CAP_PARM, *PHT_CAP_PARM;
265
266// HT Capability INFO field in HT Cap IE .
267typedef struct PACKED {
268 UCHAR MCSSet[10];
269 UCHAR SupRate[2]; // unit : 1Mbps
270#ifdef RT_BIG_ENDIAN
271 UCHAR rsv:3;
272 UCHAR MpduDensity:1;
273 UCHAR TxStream:2;
274 UCHAR TxRxNotEqual:1;
275 UCHAR TxMCSSetDefined:1;
276#else
277 UCHAR TxMCSSetDefined:1;
278 UCHAR TxRxNotEqual:1;
279 UCHAR TxStream:2;
280 UCHAR MpduDensity:1;
281 UCHAR rsv:3;
282#endif // RT_BIG_ENDIAN //
283 UCHAR rsv3[3];
284} HT_MCS_SET, *PHT_MCS_SET;
285
286// HT Capability INFO field in HT Cap IE .
287typedef struct PACKED {
288#ifdef RT_BIG_ENDIAN
289 USHORT rsv2:4;
290 USHORT RDGSupport:1; //reverse Direction Grant support
291 USHORT PlusHTC:1; //+HTC control field support
292 USHORT MCSFeedback:2; //0:no MCS feedback, 2:unsolicited MCS feedback, 3:Full MCS feedback, 1:rsv.
293 USHORT rsv:5;//momi power safe
294 USHORT TranTime:2;
295 USHORT Pco:1;
296#else
297 USHORT Pco:1;
298 USHORT TranTime:2;
299 USHORT rsv:5;//momi power safe
300 USHORT MCSFeedback:2; //0:no MCS feedback, 2:unsolicited MCS feedback, 3:Full MCS feedback, 1:rsv.
301 USHORT PlusHTC:1; //+HTC control field support
302 USHORT RDGSupport:1; //reverse Direction Grant support
303 USHORT rsv2:4;
304#endif /* RT_BIG_ENDIAN */
305} EXT_HT_CAP_INFO, *PEXT_HT_CAP_INFO;
306
307// HT Beamforming field in HT Cap IE .
308typedef struct PACKED _HT_BF_CAP{
309#ifdef RT_BIG_ENDIAN
310 ULONG rsv:3;
311 ULONG ChanEstimation:2;
312 ULONG CSIRowBFSup:2;
313 ULONG ComSteerBFAntSup:2;
314 ULONG NoComSteerBFAntSup:2;
315 ULONG CSIBFAntSup:2;
316 ULONG MinGrouping:2;
317 ULONG ExpComBF:2;
318 ULONG ExpNoComBF:2;
319 ULONG ExpCSIFbk:2;
320 ULONG ExpComSteerCapable:1;
321 ULONG ExpNoComSteerCapable:1;
322 ULONG ExpCSICapable:1;
323 ULONG Calibration:2;
324 ULONG ImpTxBFCapable:1;
325 ULONG TxNDPCapable:1;
326 ULONG RxNDPCapable:1;
327 ULONG TxSoundCapable:1;
328 ULONG RxSoundCapable:1;
329 ULONG TxBFRecCapable:1;
330#else
331 ULONG TxBFRecCapable:1;
332 ULONG RxSoundCapable:1;
333 ULONG TxSoundCapable:1;
334 ULONG RxNDPCapable:1;
335 ULONG TxNDPCapable:1;
336 ULONG ImpTxBFCapable:1;
337 ULONG Calibration:2;
338 ULONG ExpCSICapable:1;
339 ULONG ExpNoComSteerCapable:1;
340 ULONG ExpComSteerCapable:1;
341 ULONG ExpCSIFbk:2;
342 ULONG ExpNoComBF:2;
343 ULONG ExpComBF:2;
344 ULONG MinGrouping:2;
345 ULONG CSIBFAntSup:2;
346 ULONG NoComSteerBFAntSup:2;
347 ULONG ComSteerBFAntSup:2;
348 ULONG CSIRowBFSup:2;
349 ULONG ChanEstimation:2;
350 ULONG rsv:3;
351#endif // RT_BIG_ENDIAN //
352} HT_BF_CAP, *PHT_BF_CAP;
353
354// HT antenna selection field in HT Cap IE .
355typedef struct PACKED _HT_AS_CAP{
356#ifdef RT_BIG_ENDIAN
357 UCHAR rsv:1;
358 UCHAR TxSoundPPDU:1;
359 UCHAR RxASel:1;
360 UCHAR AntIndFbk:1;
361 UCHAR ExpCSIFbk:1;
362 UCHAR AntIndFbkTxASEL:1;
363 UCHAR ExpCSIFbkTxASEL:1;
364 UCHAR AntSelect:1;
365#else
366 UCHAR AntSelect:1;
367 UCHAR ExpCSIFbkTxASEL:1;
368 UCHAR AntIndFbkTxASEL:1;
369 UCHAR ExpCSIFbk:1;
370 UCHAR AntIndFbk:1;
371 UCHAR RxASel:1;
372 UCHAR TxSoundPPDU:1;
373 UCHAR rsv:1;
374#endif // RT_BIG_ENDIAN //
375} HT_AS_CAP, *PHT_AS_CAP;
376
377// Draft 1.0 set IE length 26, but is extensible..
378#define SIZE_HT_CAP_IE 26
379// The structure for HT Capability IE.
380typedef struct PACKED _HT_CAPABILITY_IE{
381 HT_CAP_INFO HtCapInfo;
382 HT_CAP_PARM HtCapParm;
383// HT_MCS_SET HtMCSSet;
384 UCHAR MCSSet[16];
385 EXT_HT_CAP_INFO ExtHtCapInfo;
386 HT_BF_CAP TxBFCap; // beamforming cap. rt2860c not support beamforming.
387 HT_AS_CAP ASCap; //antenna selection.
388} HT_CAPABILITY_IE, *PHT_CAPABILITY_IE;
389
390
391// 802.11n draft3 related structure definitions.
392// 7.3.2.60
393#define dot11OBSSScanPassiveDwell 20 // in TU. min amount of time that the STA continously scans each channel when performing an active OBSS scan.
394#define dot11OBSSScanActiveDwell 10 // in TU.min amount of time that the STA continously scans each channel when performing an passive OBSS scan.
395#define dot11BSSWidthTriggerScanInterval 300 // in sec. max interval between scan operations to be performed to detect BSS channel width trigger events.
396#define dot11OBSSScanPassiveTotalPerChannel 200 // in TU. min total amount of time that the STA scans each channel when performing a passive OBSS scan.
397#define dot11OBSSScanActiveTotalPerChannel 20 //in TU. min total amount of time that the STA scans each channel when performing a active OBSS scan
398#define dot11BSSWidthChannelTransactionDelayFactor 5 // min ratio between the delay time in performing a switch from 20MHz BSS to 20/40 BSS operation and the maxima
399 // interval between overlapping BSS scan operations.
400#define dot11BSSScanActivityThreshold 25 // in %%, max total time that a STA may be active on the medium during a period of
401 // (dot11BSSWidthChannelTransactionDelayFactor * dot11BSSWidthTriggerScanInterval) seconds without
402 // being obligated to perform OBSS Scan operations. default is 25(== 0.25%)
403
404typedef struct PACKED _OVERLAP_BSS_SCAN_IE{
405 USHORT ScanPassiveDwell;
406 USHORT ScanActiveDwell;
407 USHORT TriggerScanInt; // Trigger scan interval
408 USHORT PassiveTalPerChannel; // passive total per channel
409 USHORT ActiveTalPerChannel; // active total per channel
410 USHORT DelayFactor; // BSS width channel transition delay factor
411 USHORT ScanActThre; // Scan Activity threshold
412}OVERLAP_BSS_SCAN_IE, *POVERLAP_BSS_SCAN_IE;
413
414
415// 7.3.2.56. 20/40 Coexistence element used in Element ID = 72 = IE_2040_BSS_COEXIST
416typedef union PACKED _BSS_2040_COEXIST_IE{
417 struct PACKED {
418 #ifdef RT_BIG_ENDIAN
419 UCHAR rsv:5;
420 UCHAR BSS20WidthReq:1;
421 UCHAR Intolerant40:1;
422 UCHAR InfoReq:1;
423 #else
424 UCHAR InfoReq:1;
425 UCHAR Intolerant40:1; // Inter-BSS. set 1 when prohibits a receiving BSS from operating as a 20/40 Mhz BSS.
426 UCHAR BSS20WidthReq:1; // Intra-BSS set 1 when prohibits a receiving AP from operating its BSS as a 20/40MHz BSS.
427 UCHAR rsv:5;
428#endif // RT_BIG_ENDIAN //
429 } field;
430 UCHAR word;
431} BSS_2040_COEXIST_IE, *PBSS_2040_COEXIST_IE;
432
433
434typedef struct _TRIGGER_EVENTA{
435 BOOLEAN bValid;
436 UCHAR BSSID[6];
437 UCHAR RegClass; // Regulatory Class
438 USHORT Channel;
439 ULONG CDCounter; // Maintain a seperate count down counter for each Event A.
440} TRIGGER_EVENTA, *PTRIGGER_EVENTA;
441
442// 20/40 trigger event table
443// If one Event A delete or created, or if Event B is detected or not detected, STA should send 2040BSSCoexistence to AP.
444#define MAX_TRIGGER_EVENT 64
445typedef struct _TRIGGER_EVENT_TAB{
446 UCHAR EventANo;
447 TRIGGER_EVENTA EventA[MAX_TRIGGER_EVENT];
448 ULONG EventBCountDown; // Count down counter for Event B.
449} TRIGGER_EVENT_TAB, *PTRIGGER_EVENT_TAB;
450
451// 7.3.27 20/40 Bss Coexistence Mgmt capability used in extended capabilities information IE( ID = 127 = IE_EXT_CAPABILITY).
452// This is the first octet and was defined in 802.11n D3.03 and 802.11yD9.0
453typedef struct PACKED _EXT_CAP_INFO_ELEMENT{
454#ifdef RT_BIG_ENDIAN
455 UCHAR rsv2:5;
456 UCHAR ExtendChannelSwitch:1;
457 UCHAR rsv:1;
458 UCHAR BssCoexistMgmtSupport:1;
459#else
460 UCHAR BssCoexistMgmtSupport:1;
461 UCHAR rsv:1;
462 UCHAR ExtendChannelSwitch:1;
463 UCHAR rsv2:5;
464#endif // RT_BIG_ENDIAN //
465}EXT_CAP_INFO_ELEMENT, *PEXT_CAP_INFO_ELEMENT;
466
467
468// 802.11n 7.3.2.61
469typedef struct PACKED _BSS_2040_COEXIST_ELEMENT{
470 UCHAR ElementID; // ID = IE_2040_BSS_COEXIST = 72
471 UCHAR Len;
472 BSS_2040_COEXIST_IE BssCoexistIe;
473}BSS_2040_COEXIST_ELEMENT, *PBSS_2040_COEXIST_ELEMENT;
474
475
476//802.11n 7.3.2.59
477typedef struct PACKED _BSS_2040_INTOLERANT_CH_REPORT{
478 UCHAR ElementID; // ID = IE_2040_BSS_INTOLERANT_REPORT = 73
479 UCHAR Len;
480 UCHAR RegulatoryClass;
481 UCHAR ChList[0];
482}BSS_2040_INTOLERANT_CH_REPORT, *PBSS_2040_INTOLERANT_CH_REPORT;
483
484
485// The structure for channel switch annoucement IE. This is in 802.11n D3.03
486typedef struct PACKED _CHA_SWITCH_ANNOUNCE_IE{
487 UCHAR SwitchMode; //channel switch mode
488 UCHAR NewChannel; //
489 UCHAR SwitchCount; //
490} CHA_SWITCH_ANNOUNCE_IE, *PCHA_SWITCH_ANNOUNCE_IE;
491
492
493// The structure for channel switch annoucement IE. This is in 802.11n D3.03
494typedef struct PACKED _SEC_CHA_OFFSET_IE{
495 UCHAR SecondaryChannelOffset; // 1: Secondary above, 3: Secondary below, 0: no Secondary
496} SEC_CHA_OFFSET_IE, *PSEC_CHA_OFFSET_IE;
497
498
499// This structure is extracted from struct RT_HT_CAPABILITY
500typedef struct {
501 BOOLEAN bHtEnable; // If we should use ht rate.
502 BOOLEAN bPreNHt; // If we should use ht rate.
503 //Substract from HT Capability IE
504 UCHAR MCSSet[16]; //only supoort MCS=0-15,32 ,
505} RT_HT_PHY_INFO, *PRT_HT_PHY_INFO;
506
507//This structure substracts ralink supports from all 802.11n-related features.
508//Features not listed here but contained in 802.11n spec are not supported in rt2860.
509typedef struct {
510#ifdef RT_BIG_ENDIAN
511 USHORT rsv:5;
512 USHORT AmsduSize:1; // Max receiving A-MSDU size
513 USHORT AmsduEnable:1; // Enable to transmit A-MSDU. Suggest disable. We should use A-MPDU to gain best benifit of 802.11n
514 USHORT RxSTBC:2; // 2 bits
515 USHORT TxSTBC:1;
516 USHORT ShortGIfor40:1; //for40MHz
517 USHORT ShortGIfor20:1;
518 USHORT GF:1; //green field
519 USHORT MimoPs:2;//mimo power safe MMPS_
520 USHORT ChannelWidth:1;
521#else
522 USHORT ChannelWidth:1;
523 USHORT MimoPs:2;//mimo power safe MMPS_
524 USHORT GF:1; //green field
525 USHORT ShortGIfor20:1;
526 USHORT ShortGIfor40:1; //for40MHz
527 USHORT TxSTBC:1;
528 USHORT RxSTBC:2; // 2 bits
529 USHORT AmsduEnable:1; // Enable to transmit A-MSDU. Suggest disable. We should use A-MPDU to gain best benifit of 802.11n
530 USHORT AmsduSize:1; // Max receiving A-MSDU size
531 USHORT rsv:5;
532#endif
533
534 //Substract from Addiont HT INFO IE
535#ifdef RT_BIG_ENDIAN
536 UCHAR RecomWidth:1;
537 UCHAR ExtChanOffset:2; // Please not the difference with following UCHAR NewExtChannelOffset; from 802.11n
538 UCHAR MpduDensity:3;
539 UCHAR MaxRAmpduFactor:2;
540#else
541 UCHAR MaxRAmpduFactor:2;
542 UCHAR MpduDensity:3;
543 UCHAR ExtChanOffset:2; // Please not the difference with following UCHAR NewExtChannelOffset; from 802.11n
544 UCHAR RecomWidth:1;
545#endif
546
547#ifdef RT_BIG_ENDIAN
548 USHORT rsv2:11;
549 USHORT OBSS_NonHTExist:1;
550 USHORT rsv3:1;
551 USHORT NonGfPresent:1;
552 USHORT OperaionMode:2;
553#else
554 USHORT OperaionMode:2;
555 USHORT NonGfPresent:1;
556 USHORT rsv3:1;
557 USHORT OBSS_NonHTExist:1;
558 USHORT rsv2:11;
559#endif
560
561 // New Extension Channel Offset IE
562 UCHAR NewExtChannelOffset;
563 // Extension Capability IE = 127
564 UCHAR BSSCoexist2040;
565} RT_HT_CAPABILITY, *PRT_HT_CAPABILITY;
566
567// field in Addtional HT Information IE .
568typedef struct PACKED {
569#ifdef RT_BIG_ENDIAN
570 UCHAR SerInterGranu:3;
571 UCHAR S_PSMPSup:1;
572 UCHAR RifsMode:1;
573 UCHAR RecomWidth:1;
574 UCHAR ExtChanOffset:2;
575#else
576 UCHAR ExtChanOffset:2;
577 UCHAR RecomWidth:1;
578 UCHAR RifsMode:1;
579 UCHAR S_PSMPSup:1; //Indicate support for scheduled PSMP
580 UCHAR SerInterGranu:3; //service interval granularity
581#endif
582} ADD_HTINFO, *PADD_HTINFO;
583
584typedef struct PACKED{
585#ifdef RT_BIG_ENDIAN
586 USHORT rsv2:11;
587 USHORT OBSS_NonHTExist:1;
588 USHORT rsv:1;
589 USHORT NonGfPresent:1;
590 USHORT OperaionMode:2;
591#else
592 USHORT OperaionMode:2;
593 USHORT NonGfPresent:1;
594 USHORT rsv:1;
595 USHORT OBSS_NonHTExist:1;
596 USHORT rsv2:11;
597#endif
598} ADD_HTINFO2, *PADD_HTINFO2;
599
600
601// TODO: Need sync with spec about the definition of StbcMcs. In Draft 3.03, it's reserved.
602typedef struct PACKED{
603#ifdef RT_BIG_ENDIAN
604 USHORT rsv:4;
605 USHORT PcoPhase:1;
606 USHORT PcoActive:1;
607 USHORT LsigTxopProt:1;
608 USHORT STBCBeacon:1;
609 USHORT DualCTSProtect:1;
610 USHORT DualBeacon:1;
611 USHORT StbcMcs:6;
612#else
613 USHORT StbcMcs:6;
614 USHORT DualBeacon:1;
615 USHORT DualCTSProtect:1;
616 USHORT STBCBeacon:1;
617 USHORT LsigTxopProt:1; // L-SIG TXOP protection full support
618 USHORT PcoActive:1;
619 USHORT PcoPhase:1;
620 USHORT rsv:4;
621#endif // RT_BIG_ENDIAN //
622} ADD_HTINFO3, *PADD_HTINFO3;
623
624#define SIZE_ADD_HT_INFO_IE 22
625typedef struct PACKED{
626 UCHAR ControlChan;
627 ADD_HTINFO AddHtInfo;
628 ADD_HTINFO2 AddHtInfo2;
629 ADD_HTINFO3 AddHtInfo3;
630 UCHAR MCSSet[16]; // Basic MCS set
631} ADD_HT_INFO_IE, *PADD_HT_INFO_IE;
632
633typedef struct PACKED{
634 UCHAR NewExtChanOffset;
635} NEW_EXT_CHAN_IE, *PNEW_EXT_CHAN_IE;
636
637
638// 4-byte HTC field. maybe included in any frame except non-QOS data frame. The Order bit must set 1.
639typedef struct PACKED {
640#ifdef RT_BIG_ENDIAN
641 UINT32 RDG:1; //RDG / More PPDU
642 UINT32 ACConstraint:1; //feedback request
643 UINT32 rsv:5; //calibration sequence
644 UINT32 ZLFAnnouce:1; // ZLF announcement
645 UINT32 CSISTEERING:2; //CSI/ STEERING
646 UINT32 FBKReq:2; //feedback request
647 UINT32 CalSeq:2; //calibration sequence
648 UINT32 CalPos:2; // calibration position
649 UINT32 MFBorASC:7; //Link adaptation feedback containing recommended MCS. 0x7f for no feedback or not available
650 UINT32 MFS:3; //SET to the received value of MRS. 0x111 for unsolicited MFB.
651 UINT32 MRSorASI:3; // MRQ Sequence identifier. unchanged during entire procedure. 0x000-0x110.
652 UINT32 MRQ:1; //MCS feedback. Request for a MCS feedback
653 UINT32 TRQ:1; //sounding request
654 UINT32 MA:1; //management action payload exist in (QoS Null+HTC)
655#else
656 UINT32 MA:1; //management action payload exist in (QoS Null+HTC)
657 UINT32 TRQ:1; //sounding request
658 UINT32 MRQ:1; //MCS feedback. Request for a MCS feedback
659 UINT32 MRSorASI:3; // MRQ Sequence identifier. unchanged during entire procedure. 0x000-0x110.
660 UINT32 MFS:3; //SET to the received value of MRS. 0x111 for unsolicited MFB.
661 UINT32 MFBorASC:7; //Link adaptation feedback containing recommended MCS. 0x7f for no feedback or not available
662 UINT32 CalPos:2; // calibration position
663 UINT32 CalSeq:2; //calibration sequence
664 UINT32 FBKReq:2; //feedback request
665 UINT32 CSISTEERING:2; //CSI/ STEERING
666 UINT32 ZLFAnnouce:1; // ZLF announcement
667 UINT32 rsv:5; //calibration sequence
668 UINT32 ACConstraint:1; //feedback request
669 UINT32 RDG:1; //RDG / More PPDU
670#endif /* !RT_BIG_ENDIAN */
671} HT_CONTROL, *PHT_CONTROL;
672
673// 2-byte QOS CONTROL field
674typedef struct PACKED {
675#ifdef RT_BIG_ENDIAN
676 USHORT Txop_QueueSize:8;
677 USHORT AMsduPresent:1;
678 USHORT AckPolicy:2; //0: normal ACK 1:No ACK 2:scheduled under MTBA/PSMP 3: BA
679 USHORT EOSP:1;
680 USHORT TID:4;
681#else
682 USHORT TID:4;
683 USHORT EOSP:1;
684 USHORT AckPolicy:2; //0: normal ACK 1:No ACK 2:scheduled under MTBA/PSMP 3: BA
685 USHORT AMsduPresent:1;
686 USHORT Txop_QueueSize:8;
687#endif /* !RT_BIG_ENDIAN */
688} QOS_CONTROL, *PQOS_CONTROL;
689
690// 2-byte Frame control field
691typedef struct PACKED {
692#ifdef RT_BIG_ENDIAN
693 USHORT Order:1; // Strict order expected
694 USHORT Wep:1; // Wep data
695 USHORT MoreData:1; // More data bit
696 USHORT PwrMgmt:1; // Power management bit
697 USHORT Retry:1; // Retry status bit
698 USHORT MoreFrag:1; // More fragment bit
699 USHORT FrDs:1; // From DS indication
700 USHORT ToDs:1; // To DS indication
701 USHORT SubType:4; // MSDU subtype
702 USHORT Type:2; // MSDU type
703 USHORT Ver:2; // Protocol version
704#else
705 USHORT Ver:2; // Protocol version
706 USHORT Type:2; // MSDU type
707 USHORT SubType:4; // MSDU subtype
708 USHORT ToDs:1; // To DS indication
709 USHORT FrDs:1; // From DS indication
710 USHORT MoreFrag:1; // More fragment bit
711 USHORT Retry:1; // Retry status bit
712 USHORT PwrMgmt:1; // Power management bit
713 USHORT MoreData:1; // More data bit
714 USHORT Wep:1; // Wep data
715 USHORT Order:1; // Strict order expected
716#endif /* !RT_BIG_ENDIAN */
717} FRAME_CONTROL, *PFRAME_CONTROL;
718
719typedef struct PACKED _HEADER_802_11 {
720 FRAME_CONTROL FC;
721 USHORT Duration;
722 UCHAR Addr1[MAC_ADDR_LEN];
723 UCHAR Addr2[MAC_ADDR_LEN];
724 UCHAR Addr3[MAC_ADDR_LEN];
725#ifdef RT_BIG_ENDIAN
726 USHORT Sequence:12;
727 USHORT Frag:4;
728#else
729 USHORT Frag:4;
730 USHORT Sequence:12;
731#endif /* !RT_BIG_ENDIAN */
732 UCHAR Octet[0];
733} HEADER_802_11, *PHEADER_802_11;
734
735typedef struct PACKED _FRAME_802_11 {
736 HEADER_802_11 Hdr;
737 UCHAR Octet[1];
738} FRAME_802_11, *PFRAME_802_11;
739
740// QoSNull embedding of management action. When HT Control MA field set to 1.
741typedef struct PACKED _MA_BODY {
742 UCHAR Category;
743 UCHAR Action;
744 UCHAR Octet[1];
745} MA_BODY, *PMA_BODY;
746
747typedef struct PACKED _HEADER_802_3 {
748 UCHAR DAAddr1[MAC_ADDR_LEN];
749 UCHAR SAAddr2[MAC_ADDR_LEN];
750 UCHAR Octet[2];
751} HEADER_802_3, *PHEADER_802_3;
752////Block ACK related format
753// 2-byte BA Parameter field in DELBA frames to terminate an already set up bA
754typedef struct PACKED{
755#ifdef RT_BIG_ENDIAN
756 USHORT TID:4; // value of TC os TS
757 USHORT Initiator:1; // 1: originator 0:recipient
758 USHORT Rsv:11; // always set to 0
759#else
760 USHORT Rsv:11; // always set to 0
761 USHORT Initiator:1; // 1: originator 0:recipient
762 USHORT TID:4; // value of TC os TS
763#endif /* !RT_BIG_ENDIAN */
764} DELBA_PARM, *PDELBA_PARM;
765
766// 2-byte BA Parameter Set field in ADDBA frames to signal parm for setting up a BA
767typedef struct PACKED {
768#ifdef RT_BIG_ENDIAN
769 USHORT BufSize:10; // number of buffe of size 2304 octetsr
770 USHORT TID:4; // value of TC os TS
771 USHORT BAPolicy:1; // 1: immediately BA 0:delayed BA
772 USHORT AMSDUSupported:1; // 0: not permitted 1: permitted
773#else
774 USHORT AMSDUSupported:1; // 0: not permitted 1: permitted
775 USHORT BAPolicy:1; // 1: immediately BA 0:delayed BA
776 USHORT TID:4; // value of TC os TS
777 USHORT BufSize:10; // number of buffe of size 2304 octetsr
778#endif /* !RT_BIG_ENDIAN */
779} BA_PARM, *PBA_PARM;
780
781// 2-byte BA Starting Seq CONTROL field
782typedef union PACKED {
783 struct PACKED {
784#ifdef RT_BIG_ENDIAN
785 USHORT StartSeq:12; // sequence number of the 1st MSDU for which this BAR is sent
786 USHORT FragNum:4; // always set to 0
787#else
788 USHORT FragNum:4; // always set to 0
789 USHORT StartSeq:12; // sequence number of the 1st MSDU for which this BAR is sent
790#endif /* RT_BIG_ENDIAN */
791 } field;
792 USHORT word;
793} BASEQ_CONTROL, *PBASEQ_CONTROL;
794
795//BAControl and BARControl are the same
796// 2-byte BA CONTROL field in BA frame
797typedef struct PACKED {
798#ifdef RT_BIG_ENDIAN
799 USHORT TID:4;
800 USHORT Rsv:9;
801 USHORT Compressed:1;
802 USHORT MTID:1; //EWC V1.24
803 USHORT ACKPolicy:1; // only related to N-Delayed BA. But not support in RT2860b. 0:NormalACK 1:No ACK
804#else
805 USHORT ACKPolicy:1; // only related to N-Delayed BA. But not support in RT2860b. 0:NormalACK 1:No ACK
806 USHORT MTID:1; //EWC V1.24
807 USHORT Compressed:1;
808 USHORT Rsv:9;
809 USHORT TID:4;
810#endif /* !RT_BIG_ENDIAN */
811} BA_CONTROL, *PBA_CONTROL;
812
813// 2-byte BAR CONTROL field in BAR frame
814typedef struct PACKED {
815#ifdef RT_BIG_ENDIAN
816 USHORT TID:4;
817 USHORT Rsv1:9;
818 USHORT Compressed:1;
819 USHORT MTID:1; //if this bit1, use FRAME_MTBA_REQ, if 0, use FRAME_BA_REQ
820 USHORT ACKPolicy:1;
821#else
822 USHORT ACKPolicy:1; // 0:normal ack, 1:no ack.
823 USHORT MTID:1; //if this bit1, use FRAME_MTBA_REQ, if 0, use FRAME_BA_REQ
824 USHORT Compressed:1;
825 USHORT Rsv1:9;
826 USHORT TID:4;
827#endif /* !RT_BIG_ENDIAN */
828} BAR_CONTROL, *PBAR_CONTROL;
829
830// BARControl in MTBAR frame
831typedef struct PACKED {
832#ifdef RT_BIG_ENDIAN
833 USHORT NumTID:4;
834 USHORT Rsv1:9;
835 USHORT Compressed:1;
836 USHORT MTID:1;
837 USHORT ACKPolicy:1;
838#else
839 USHORT ACKPolicy:1;
840 USHORT MTID:1;
841 USHORT Compressed:1;
842 USHORT Rsv1:9;
843 USHORT NumTID:4;
844#endif /* !RT_BIG_ENDIAN */
845} MTBAR_CONTROL, *PMTBAR_CONTROL;
846
847typedef struct PACKED {
848#ifdef RT_BIG_ENDIAN
849 USHORT TID:4;
850 USHORT Rsv1:12;
851#else
852 USHORT Rsv1:12;
853 USHORT TID:4;
854#endif /* !RT_BIG_ENDIAN */
855} PER_TID_INFO, *PPER_TID_INFO;
856
857typedef struct {
858 PER_TID_INFO PerTID;
859 BASEQ_CONTROL BAStartingSeq;
860} EACH_TID, *PEACH_TID;
861
862
863typedef struct PACKED _PSPOLL_FRAME {
864 FRAME_CONTROL FC;
865 USHORT Aid;
866 UCHAR Bssid[MAC_ADDR_LEN];
867 UCHAR Ta[MAC_ADDR_LEN];
868} PSPOLL_FRAME, *PPSPOLL_FRAME;
869
870typedef struct PACKED _RTS_FRAME {
871 FRAME_CONTROL FC;
872 USHORT Duration;
873 UCHAR Addr1[MAC_ADDR_LEN];
874 UCHAR Addr2[MAC_ADDR_LEN];
875}RTS_FRAME, *PRTS_FRAME;
876
877// BAREQ AND MTBAREQ have the same subtype BAR, 802.11n BAR use compressed bitmap.
878typedef struct PACKED _FRAME_BA_REQ {
879 FRAME_CONTROL FC;
880 USHORT Duration;
881 UCHAR Addr1[MAC_ADDR_LEN];
882 UCHAR Addr2[MAC_ADDR_LEN];
883 BAR_CONTROL BARControl;
884 BASEQ_CONTROL BAStartingSeq;
885} FRAME_BA_REQ, *PFRAME_BA_REQ;
886
887typedef struct PACKED _FRAME_MTBA_REQ {
888 FRAME_CONTROL FC;
889 USHORT Duration;
890 UCHAR Addr1[MAC_ADDR_LEN];
891 UCHAR Addr2[MAC_ADDR_LEN];
892 MTBAR_CONTROL MTBARControl;
893 PER_TID_INFO PerTIDInfo;
894 BASEQ_CONTROL BAStartingSeq;
895} FRAME_MTBA_REQ, *PFRAME_MTBA_REQ;
896
897// Compressed format is mandantory in HT STA
898typedef struct PACKED _FRAME_MTBA {
899 FRAME_CONTROL FC;
900 USHORT Duration;
901 UCHAR Addr1[MAC_ADDR_LEN];
902 UCHAR Addr2[MAC_ADDR_LEN];
903 BA_CONTROL BAControl;
904 BASEQ_CONTROL BAStartingSeq;
905 UCHAR BitMap[8];
906} FRAME_MTBA, *PFRAME_MTBA;
907
908typedef struct PACKED _FRAME_PSMP_ACTION {
909 HEADER_802_11 Hdr;
910 UCHAR Category;
911 UCHAR Action;
912 UCHAR Psmp; // 7.3.1.25
913} FRAME_PSMP_ACTION, *PFRAME_PSMP_ACTION;
914
915typedef struct PACKED _FRAME_ACTION_HDR {
916 HEADER_802_11 Hdr;
917 UCHAR Category;
918 UCHAR Action;
919} FRAME_ACTION_HDR, *PFRAME_ACTION_HDR;
920
921//Action Frame
922//Action Frame Category:Spectrum, Action:Channel Switch. 7.3.2.20
923typedef struct PACKED _CHAN_SWITCH_ANNOUNCE {
924 UCHAR ElementID; // ID = IE_CHANNEL_SWITCH_ANNOUNCEMENT = 37
925 UCHAR Len;
926 CHA_SWITCH_ANNOUNCE_IE CSAnnounceIe;
927} CHAN_SWITCH_ANNOUNCE, *PCHAN_SWITCH_ANNOUNCE;
928
929
930//802.11n : 7.3.2.20a
931typedef struct PACKED _SECOND_CHAN_OFFSET {
932 UCHAR ElementID; // ID = IE_SECONDARY_CH_OFFSET = 62
933 UCHAR Len;
934 SEC_CHA_OFFSET_IE SecChOffsetIe;
935} SECOND_CHAN_OFFSET, *PSECOND_CHAN_OFFSET;
936
937
938typedef struct PACKED _FRAME_SPETRUM_CS {
939 HEADER_802_11 Hdr;
940 UCHAR Category;
941 UCHAR Action;
942 CHAN_SWITCH_ANNOUNCE CSAnnounce;
943 SECOND_CHAN_OFFSET SecondChannel;
944} FRAME_SPETRUM_CS, *PFRAME_SPETRUM_CS;
945
946
947typedef struct PACKED _FRAME_ADDBA_REQ {
948 HEADER_802_11 Hdr;
949 UCHAR Category;
950 UCHAR Action;
951 UCHAR Token; // 1
952 BA_PARM BaParm; // 2 - 10
953 USHORT TimeOutValue; // 0 - 0
954 BASEQ_CONTROL BaStartSeq; // 0-0
955} FRAME_ADDBA_REQ, *PFRAME_ADDBA_REQ;
956
957typedef struct PACKED _FRAME_ADDBA_RSP {
958 HEADER_802_11 Hdr;
959 UCHAR Category;
960 UCHAR Action;
961 UCHAR Token;
962 USHORT StatusCode;
963 BA_PARM BaParm; //0 - 2
964 USHORT TimeOutValue;
965} FRAME_ADDBA_RSP, *PFRAME_ADDBA_RSP;
966
967typedef struct PACKED _FRAME_DELBA_REQ {
968 HEADER_802_11 Hdr;
969 UCHAR Category;
970 UCHAR Action;
971 DELBA_PARM DelbaParm;
972 USHORT ReasonCode;
973} FRAME_DELBA_REQ, *PFRAME_DELBA_REQ;
974
975
976//7.2.1.7
977typedef struct PACKED _FRAME_BAR {
978 FRAME_CONTROL FC;
979 USHORT Duration;
980 UCHAR Addr1[MAC_ADDR_LEN];
981 UCHAR Addr2[MAC_ADDR_LEN];
982 BAR_CONTROL BarControl;
983 BASEQ_CONTROL StartingSeq;
984} FRAME_BAR, *PFRAME_BAR;
985
986//7.2.1.7
987typedef struct PACKED _FRAME_BA {
988 FRAME_CONTROL FC;
989 USHORT Duration;
990 UCHAR Addr1[MAC_ADDR_LEN];
991 UCHAR Addr2[MAC_ADDR_LEN];
992 BAR_CONTROL BarControl;
993 BASEQ_CONTROL StartingSeq;
994 UCHAR bitmask[8];
995} FRAME_BA, *PFRAME_BA;
996
997
998// Radio Measuement Request Frame Format
999typedef struct PACKED _FRAME_RM_REQ_ACTION {
1000 HEADER_802_11 Hdr;
1001 UCHAR Category;
1002 UCHAR Action;
1003 UCHAR Token;
1004 USHORT Repetition;
1005 UCHAR data[0];
1006} FRAME_RM_REQ_ACTION, *PFRAME_RM_REQ_ACTION;
1007
1008typedef struct PACKED {
1009 UCHAR ID;
1010 UCHAR Length;
1011 UCHAR ChannelSwitchMode;
1012 UCHAR NewRegClass;
1013 UCHAR NewChannelNum;
1014 UCHAR ChannelSwitchCount;
1015} HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE, *PHT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE;
1016
1017
1018//
1019// _Limit must be the 2**n - 1
1020// _SEQ1 , _SEQ2 must be within 0 ~ _Limit
1021//
1022#define SEQ_STEPONE(_SEQ1, _SEQ2, _Limit) ((_SEQ1 == ((_SEQ2+1) & _Limit)))
1023#define SEQ_SMALLER(_SEQ1, _SEQ2, _Limit) (((_SEQ1-_SEQ2) & ((_Limit+1)>>1)))
1024#define SEQ_LARGER(_SEQ1, _SEQ2, _Limit) ((_SEQ1 != _SEQ2) && !(((_SEQ1-_SEQ2) & ((_Limit+1)>>1))))
1025#define SEQ_WITHIN_WIN(_SEQ1, _SEQ2, _WIN, _Limit) (SEQ_LARGER(_SEQ1, _SEQ2, _Limit) && \
1026 SEQ_SMALLER(_SEQ1, ((_SEQ2+_WIN+1)&_Limit), _Limit))
1027
1028//
1029// Contention-free parameter (without ID and Length)
1030//
1031typedef struct PACKED {
1032 BOOLEAN bValid; // 1: variable contains valid value
1033 UCHAR CfpCount;
1034 UCHAR CfpPeriod;
1035 USHORT CfpMaxDuration;
1036 USHORT CfpDurRemaining;
1037} CF_PARM, *PCF_PARM;
1038
1039typedef struct _CIPHER_SUITE {
1040 NDIS_802_11_ENCRYPTION_STATUS PairCipher; // Unicast cipher 1, this one has more secured cipher suite
1041 NDIS_802_11_ENCRYPTION_STATUS PairCipherAux; // Unicast cipher 2 if AP announce two unicast cipher suite
1042 NDIS_802_11_ENCRYPTION_STATUS GroupCipher; // Group cipher
1043 USHORT RsnCapability; // RSN capability from beacon
1044 BOOLEAN bMixMode; // Indicate Pair & Group cipher might be different
1045} CIPHER_SUITE, *PCIPHER_SUITE;
1046
1047// EDCA configuration from AP's BEACON/ProbeRsp
1048typedef struct {
1049 BOOLEAN bValid; // 1: variable contains valid value
1050 BOOLEAN bAdd; // 1: variable contains valid value
1051 BOOLEAN bQAck;
1052 BOOLEAN bQueueRequest;
1053 BOOLEAN bTxopRequest;
1054 BOOLEAN bAPSDCapable;
1055// BOOLEAN bMoreDataAck;
1056 UCHAR EdcaUpdateCount;
1057 UCHAR Aifsn[4]; // 0:AC_BK, 1:AC_BE, 2:AC_VI, 3:AC_VO
1058 UCHAR Cwmin[4];
1059 UCHAR Cwmax[4];
1060 USHORT Txop[4]; // in unit of 32-us
1061 BOOLEAN bACM[4]; // 1: Admission Control of AC_BK is mandattory
1062} EDCA_PARM, *PEDCA_PARM;
1063
1064// QBSS LOAD information from QAP's BEACON/ProbeRsp
1065typedef struct {
1066 BOOLEAN bValid; // 1: variable contains valid value
1067 USHORT StaNum;
1068 UCHAR ChannelUtilization;
1069 USHORT RemainingAdmissionControl; // in unit of 32-us
1070} QBSS_LOAD_PARM, *PQBSS_LOAD_PARM;
1071
1072// QBSS Info field in QSTA's assoc req
1073typedef struct PACKED {
1074#ifdef RT_BIG_ENDIAN
1075 UCHAR Rsv2:1;
1076 UCHAR MaxSPLength:2;
1077 UCHAR Rsv1:1;
1078 UCHAR UAPSD_AC_BE:1;
1079 UCHAR UAPSD_AC_BK:1;
1080 UCHAR UAPSD_AC_VI:1;
1081 UCHAR UAPSD_AC_VO:1;
1082#else
1083 UCHAR UAPSD_AC_VO:1;
1084 UCHAR UAPSD_AC_VI:1;
1085 UCHAR UAPSD_AC_BK:1;
1086 UCHAR UAPSD_AC_BE:1;
1087 UCHAR Rsv1:1;
1088 UCHAR MaxSPLength:2;
1089 UCHAR Rsv2:1;
1090#endif /* !RT_BIG_ENDIAN */
1091} QBSS_STA_INFO_PARM, *PQBSS_STA_INFO_PARM;
1092
1093// QBSS Info field in QAP's Beacon/ProbeRsp
1094typedef struct PACKED {
1095#ifdef RT_BIG_ENDIAN
1096 UCHAR UAPSD:1;
1097 UCHAR Rsv:3;
1098 UCHAR ParamSetCount:4;
1099#else
1100 UCHAR ParamSetCount:4;
1101 UCHAR Rsv:3;
1102 UCHAR UAPSD:1;
1103#endif /* !RT_BIG_ENDIAN */
1104} QBSS_AP_INFO_PARM, *PQBSS_AP_INFO_PARM;
1105
1106// QOS Capability reported in QAP's BEACON/ProbeRsp
1107// QOS Capability sent out in QSTA's AssociateReq/ReAssociateReq
1108typedef struct {
1109 BOOLEAN bValid; // 1: variable contains valid value
1110 BOOLEAN bQAck;
1111 BOOLEAN bQueueRequest;
1112 BOOLEAN bTxopRequest;
1113// BOOLEAN bMoreDataAck;
1114 UCHAR EdcaUpdateCount;
1115} QOS_CAPABILITY_PARM, *PQOS_CAPABILITY_PARM;
1116
1117#ifdef CONFIG_STA_SUPPORT
1118typedef struct {
1119 UCHAR IELen;
1120 UCHAR IE[MAX_CUSTOM_LEN];
1121} WPA_IE_;
1122#endif // CONFIG_STA_SUPPORT //
1123
1124
1125typedef struct {
1126 UCHAR Bssid[MAC_ADDR_LEN];
1127 UCHAR Channel;
1128 UCHAR CentralChannel; //Store the wide-band central channel for 40MHz. .used in 40MHz AP. Or this is the same as Channel.
1129 UCHAR BssType;
1130 USHORT AtimWin;
1131 USHORT BeaconPeriod;
1132
1133 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
1134 UCHAR SupRateLen;
1135 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
1136 UCHAR ExtRateLen;
1137 HT_CAPABILITY_IE HtCapability;
1138 UCHAR HtCapabilityLen;
1139 ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
1140 UCHAR AddHtInfoLen;
1141 UCHAR NewExtChanOffset;
1142 CHAR Rssi;
1143 UCHAR Privacy; // Indicate security function ON/OFF. Don't mess up with auth mode.
1144 UCHAR Hidden;
1145
1146 USHORT DtimPeriod;
1147 USHORT CapabilityInfo;
1148
1149 USHORT CfpCount;
1150 USHORT CfpPeriod;
1151 USHORT CfpMaxDuration;
1152 USHORT CfpDurRemaining;
1153 UCHAR SsidLen;
1154 CHAR Ssid[MAX_LEN_OF_SSID];
1155
1156 ULONG LastBeaconRxTime; // OS's timestamp
1157
1158 BOOLEAN bSES;
1159
1160 // New for WPA2
1161 CIPHER_SUITE WPA; // AP announced WPA cipher suite
1162 CIPHER_SUITE WPA2; // AP announced WPA2 cipher suite
1163
1164 // New for microsoft WPA support
1165 NDIS_802_11_FIXED_IEs FixIEs;
1166 NDIS_802_11_AUTHENTICATION_MODE AuthModeAux; // Addition mode for WPA2 / WPA capable AP
1167 NDIS_802_11_AUTHENTICATION_MODE AuthMode;
1168 NDIS_802_11_WEP_STATUS WepStatus; // Unicast Encryption Algorithm extract from VAR_IE
1169 USHORT VarIELen; // Length of next VIE include EID & Length
1170 UCHAR VarIEs[MAX_VIE_LEN];
1171
1172 // CCX Ckip information
1173 UCHAR CkipFlag;
1174
1175 // CCX 2 TSF
1176 UCHAR PTSF[4]; // Parent TSF
1177 UCHAR TTSF[8]; // Target TSF
1178
1179 // 802.11e d9, and WMM
1180 EDCA_PARM EdcaParm;
1181 QOS_CAPABILITY_PARM QosCapability;
1182 QBSS_LOAD_PARM QbssLoad;
1183#ifdef CONFIG_STA_SUPPORT
1184 WPA_IE_ WpaIE;
1185 WPA_IE_ RsnIE;
1186#ifdef EXT_BUILD_CHANNEL_LIST
1187 UCHAR CountryString[3];
1188 BOOLEAN bHasCountryIE;
1189#endif // EXT_BUILD_CHANNEL_LIST //
1190#endif // CONFIG_STA_SUPPORT //
1191} BSS_ENTRY, *PBSS_ENTRY;
1192
1193typedef struct {
1194 UCHAR BssNr;
1195 UCHAR BssOverlapNr;
1196 BSS_ENTRY BssEntry[MAX_LEN_OF_BSS_TABLE];
1197} BSS_TABLE, *PBSS_TABLE;
1198
1199
1200typedef struct _MLME_QUEUE_ELEM {
1201 ULONG Machine;
1202 ULONG MsgType;
1203 ULONG MsgLen;
1204 UCHAR Msg[MGMT_DMA_BUFFER_SIZE];
1205 LARGE_INTEGER TimeStamp;
1206 UCHAR Rssi0;
1207 UCHAR Rssi1;
1208 UCHAR Rssi2;
1209 UCHAR Signal;
1210 UCHAR Channel;
1211 UCHAR Wcid;
1212 BOOLEAN Occupied;
1213#ifdef MLME_EX
1214 USHORT Idx;
1215#endif // MLME_EX //
1216} MLME_QUEUE_ELEM, *PMLME_QUEUE_ELEM;
1217
1218typedef struct _MLME_QUEUE {
1219 ULONG Num;
1220 ULONG Head;
1221 ULONG Tail;
1222 NDIS_SPIN_LOCK Lock;
1223 MLME_QUEUE_ELEM Entry[MAX_LEN_OF_MLME_QUEUE];
1224} MLME_QUEUE, *PMLME_QUEUE;
1225
1226typedef VOID (*STATE_MACHINE_FUNC)(VOID *Adaptor, MLME_QUEUE_ELEM *Elem);
1227
1228typedef struct _STATE_MACHINE {
1229 ULONG Base;
1230 ULONG NrState;
1231 ULONG NrMsg;
1232 ULONG CurrState;
1233 STATE_MACHINE_FUNC *TransFunc;
1234} STATE_MACHINE, *PSTATE_MACHINE;
1235
1236
1237// MLME AUX data structure that hold temporarliy settings during a connection attempt.
1238// Once this attemp succeeds, all settings will be copy to pAd->StaActive.
1239// A connection attempt (user set OID, roaming, CCX fast roaming,..) consists of
1240// several steps (JOIN, AUTH, ASSOC or REASSOC) and may fail at any step. We purposely
1241// separate this under-trial settings away from pAd->StaActive so that once
1242// this new attempt failed, driver can auto-recover back to the active settings.
1243typedef struct _MLME_AUX {
1244 UCHAR BssType;
1245 UCHAR Ssid[MAX_LEN_OF_SSID];
1246 UCHAR SsidLen;
1247 UCHAR Bssid[MAC_ADDR_LEN];
1248 UCHAR AutoReconnectSsid[MAX_LEN_OF_SSID];
1249 UCHAR AutoReconnectSsidLen;
1250 USHORT Alg;
1251 UCHAR ScanType;
1252 UCHAR Channel;
1253 UCHAR CentralChannel;
1254 USHORT Aid;
1255 USHORT CapabilityInfo;
1256 USHORT BeaconPeriod;
1257 USHORT CfpMaxDuration;
1258 USHORT CfpPeriod;
1259 USHORT AtimWin;
1260
1261 // Copy supported rate from desired AP's beacon. We are trying to match
1262 // AP's supported and extended rate settings.
1263 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
1264 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
1265 UCHAR SupRateLen;
1266 UCHAR ExtRateLen;
1267 HT_CAPABILITY_IE HtCapability;
1268 UCHAR HtCapabilityLen;
1269 ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
1270 UCHAR NewExtChannelOffset;
1271 //RT_HT_CAPABILITY SupportedHtPhy;
1272
1273 // new for QOS
1274 QOS_CAPABILITY_PARM APQosCapability; // QOS capability of the current associated AP
1275 EDCA_PARM APEdcaParm; // EDCA parameters of the current associated AP
1276 QBSS_LOAD_PARM APQbssLoad; // QBSS load of the current associated AP
1277
1278 // new to keep Ralink specific feature
1279 ULONG APRalinkIe;
1280
1281 BSS_TABLE SsidBssTab; // AP list for the same SSID
1282 BSS_TABLE RoamTab; // AP list eligible for roaming
1283 ULONG BssIdx;
1284 ULONG RoamIdx;
1285
1286 BOOLEAN CurrReqIsFromNdis;
1287
1288 RALINK_TIMER_STRUCT BeaconTimer, ScanTimer;
1289 RALINK_TIMER_STRUCT AuthTimer;
1290 RALINK_TIMER_STRUCT AssocTimer, ReassocTimer, DisassocTimer;
1291} MLME_AUX, *PMLME_AUX;
1292
1293typedef struct _MLME_ADDBA_REQ_STRUCT{
1294 UCHAR Wcid; //
1295 UCHAR pAddr[MAC_ADDR_LEN];
1296 UCHAR BaBufSize;
1297 USHORT TimeOutValue;
1298 UCHAR TID;
1299 UCHAR Token;
1300 USHORT BaStartSeq;
1301} MLME_ADDBA_REQ_STRUCT, *PMLME_ADDBA_REQ_STRUCT;
1302
1303
1304typedef struct _MLME_DELBA_REQ_STRUCT{
1305 UCHAR Wcid; //
1306 UCHAR Addr[MAC_ADDR_LEN];
1307 UCHAR TID;
1308 UCHAR Initiator;
1309} MLME_DELBA_REQ_STRUCT, *PMLME_DELBA_REQ_STRUCT;
1310
1311// assoc struct is equal to reassoc
1312typedef struct _MLME_ASSOC_REQ_STRUCT{
1313 UCHAR Addr[MAC_ADDR_LEN];
1314 USHORT CapabilityInfo;
1315 USHORT ListenIntv;
1316 ULONG Timeout;
1317} MLME_ASSOC_REQ_STRUCT, *PMLME_ASSOC_REQ_STRUCT, MLME_REASSOC_REQ_STRUCT, *PMLME_REASSOC_REQ_STRUCT;
1318
1319typedef struct _MLME_DISASSOC_REQ_STRUCT{
1320 UCHAR Addr[MAC_ADDR_LEN];
1321 USHORT Reason;
1322} MLME_DISASSOC_REQ_STRUCT, *PMLME_DISASSOC_REQ_STRUCT;
1323
1324typedef struct _MLME_AUTH_REQ_STRUCT {
1325 UCHAR Addr[MAC_ADDR_LEN];
1326 USHORT Alg;
1327 ULONG Timeout;
1328} MLME_AUTH_REQ_STRUCT, *PMLME_AUTH_REQ_STRUCT;
1329
1330typedef struct _MLME_DEAUTH_REQ_STRUCT {
1331 UCHAR Addr[MAC_ADDR_LEN];
1332 USHORT Reason;
1333} MLME_DEAUTH_REQ_STRUCT, *PMLME_DEAUTH_REQ_STRUCT;
1334
1335typedef struct {
1336 ULONG BssIdx;
1337} MLME_JOIN_REQ_STRUCT;
1338
1339typedef struct _MLME_SCAN_REQ_STRUCT {
1340 UCHAR Bssid[MAC_ADDR_LEN];
1341 UCHAR BssType;
1342 UCHAR ScanType;
1343 UCHAR SsidLen;
1344 CHAR Ssid[MAX_LEN_OF_SSID];
1345} MLME_SCAN_REQ_STRUCT, *PMLME_SCAN_REQ_STRUCT;
1346
1347typedef struct _MLME_START_REQ_STRUCT {
1348 CHAR Ssid[MAX_LEN_OF_SSID];
1349 UCHAR SsidLen;
1350} MLME_START_REQ_STRUCT, *PMLME_START_REQ_STRUCT;
1351
1352#ifdef CONFIG_STA_SUPPORT
1353#ifdef QOS_DLS_SUPPORT
1354// structure for DLS
1355typedef struct _RT_802_11_DLS {
1356 USHORT TimeOut; // Use to time out while slience, unit: second , set by UI
1357 USHORT CountDownTimer; // Use to time out while slience,unit: second , used by driver only
1358 NDIS_802_11_MAC_ADDRESS MacAddr; // set by UI
1359 UCHAR Status; // 0: none , 1: wait STAkey, 2: finish DLS setup , set by driver only
1360 BOOLEAN Valid; // 1: valid , 0: invalid , set by UI, use to setup or tear down DLS link
1361 RALINK_TIMER_STRUCT Timer; // Use to time out while handshake
1362 USHORT Sequence;
1363 USHORT MacTabMatchWCID; // ASIC
1364 BOOLEAN bHTCap;
1365 PVOID pAd;
1366} RT_802_11_DLS, *PRT_802_11_DLS;
1367
1368typedef struct _MLME_DLS_REQ_STRUCT {
1369 PRT_802_11_DLS pDLS;
1370 USHORT Reason;
1371} MLME_DLS_REQ_STRUCT, *PMLME_DLS_REQ_STRUCT;
1372#endif // QOS_DLS_SUPPORT //
1373#endif // CONFIG_STA_SUPPORT //
1374
1375typedef struct PACKED {
1376 UCHAR Eid;
1377 UCHAR Len;
1378 CHAR Octet[1];
1379} EID_STRUCT,*PEID_STRUCT, BEACON_EID_STRUCT, *PBEACON_EID_STRUCT;
1380
1381typedef struct PACKED _RTMP_TX_RATE_SWITCH
1382{
1383 UCHAR ItemNo;
1384#ifdef RT_BIG_ENDIAN
1385 UCHAR Rsv2:2;
1386 UCHAR Mode:2;
1387 UCHAR Rsv1:1;
1388 UCHAR BW:1;
1389 UCHAR ShortGI:1;
1390 UCHAR STBC:1;
1391#else
1392 UCHAR STBC:1;
1393 UCHAR ShortGI:1;
1394 UCHAR BW:1;
1395 UCHAR Rsv1:1;
1396 UCHAR Mode:2;
1397 UCHAR Rsv2:2;
1398#endif
1399 UCHAR CurrMCS;
1400 UCHAR TrainUp;
1401 UCHAR TrainDown;
1402} RRTMP_TX_RATE_SWITCH, *PRTMP_TX_RATE_SWITCH;
1403
1404// ========================== AP mlme.h ===============================
1405#define TBTT_PRELOAD_TIME 384 // usec. LomgPreamble + 24-byte at 1Mbps
1406#define DEFAULT_DTIM_PERIOD 1
1407
1408// weighting factor to calculate Channel quality, total should be 100%
1409//#define RSSI_WEIGHTING 0
1410//#define TX_WEIGHTING 40
1411//#define RX_WEIGHTING 60
1412
1413#define MAC_TABLE_AGEOUT_TIME 300 // unit: sec
1414#define MAC_TABLE_ASSOC_TIMEOUT 5 // unit: sec
1415#define MAC_TABLE_FULL(Tab) ((Tab).size == MAX_LEN_OF_MAC_TABLE)
1416
1417// AP shall drop the sta if contine Tx fail count reach it.
1418#define MAC_ENTRY_LIFE_CHECK_CNT 20 // packet cnt.
1419
1420// Value domain of pMacEntry->Sst
1421typedef enum _Sst {
1422 SST_NOT_AUTH, // 0: equivalent to IEEE 802.11/1999 state 1
1423 SST_AUTH, // 1: equivalent to IEEE 802.11/1999 state 2
1424 SST_ASSOC // 2: equivalent to IEEE 802.11/1999 state 3
1425} SST;
1426
1427// value domain of pMacEntry->AuthState
1428typedef enum _AuthState {
1429 AS_NOT_AUTH,
1430 AS_AUTH_OPEN, // STA has been authenticated using OPEN SYSTEM
1431 AS_AUTH_KEY, // STA has been authenticated using SHARED KEY
1432 AS_AUTHENTICATING // STA is waiting for AUTH seq#3 using SHARED KEY
1433} AUTH_STATE;
1434
1435//for-wpa value domain of pMacEntry->WpaState 802.1i D3 p.114
1436typedef enum _ApWpaState {
1437 AS_NOTUSE, // 0
1438 AS_DISCONNECT, // 1
1439 AS_DISCONNECTED, // 2
1440 AS_INITIALIZE, // 3
1441 AS_AUTHENTICATION, // 4
1442 AS_AUTHENTICATION2, // 5
1443 AS_INITPMK, // 6
1444 AS_INITPSK, // 7
1445 AS_PTKSTART, // 8
1446 AS_PTKINIT_NEGOTIATING, // 9
1447 AS_PTKINITDONE, // 10
1448 AS_UPDATEKEYS, // 11
1449 AS_INTEGRITY_FAILURE, // 12
1450 AS_KEYUPDATE, // 13
1451} AP_WPA_STATE;
1452
1453// for-wpa value domain of pMacEntry->WpaState 802.1i D3 p.114
1454typedef enum _GTKState {
1455 REKEY_NEGOTIATING,
1456 REKEY_ESTABLISHED,
1457 KEYERROR,
1458} GTK_STATE;
1459
1460// for-wpa value domain of pMacEntry->WpaState 802.1i D3 p.114
1461typedef enum _WpaGTKState {
1462 SETKEYS,
1463 SETKEYS_DONE,
1464} WPA_GTK_STATE;
1465// ====================== end of AP mlme.h ============================
1466
1467
1468#endif // MLME_H__
diff --git a/drivers/staging/rt3070/netif_block.h b/drivers/staging/rt3070/netif_block.h
new file mode 100644
index 000000000000..6e5151c41095
--- /dev/null
+++ b/drivers/staging/rt3070/netif_block.h
@@ -0,0 +1,58 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26 */
27
28#ifndef __NET_IF_BLOCK_H__
29#define __NET_IF_BLOCK_H__
30
31//#include <linux/device.h>
32#include "link_list.h"
33#include "rtmp.h"
34
35#define FREE_NETIF_POOL_SIZE 32
36
37typedef struct _NETIF_ENTRY
38{
39 struct _NETIF_ENTRY *pNext;
40 PNET_DEV pNetDev;
41} NETIF_ENTRY, *PNETIF_ENTRY;
42
43void initblockQueueTab(
44 IN PRTMP_ADAPTER pAd);
45
46BOOLEAN blockNetIf(
47 IN PBLOCK_QUEUE_ENTRY pBlockQueueEntry,
48 IN PNET_DEV pNetDev);
49
50VOID releaseNetIf(
51 IN PBLOCK_QUEUE_ENTRY pBlockQueueEntry);
52
53VOID StopNetIfQueue(
54 IN PRTMP_ADAPTER pAd,
55 IN UCHAR QueIdx,
56 IN PNDIS_PACKET pPacket);
57#endif // __NET_IF_BLOCK_H__
58
diff --git a/drivers/staging/rt3070/oid.h b/drivers/staging/rt3070/oid.h
new file mode 100644
index 000000000000..f78bf0a5f140
--- /dev/null
+++ b/drivers/staging/rt3070/oid.h
@@ -0,0 +1,1142 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 oid.h
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Name Date Modification logs
36*/
37#ifndef _OID_H_
38#define _OID_H_
39
40//#include <linux/wireless.h>
41
42
43#define TRUE 1
44#define FALSE 0
45//
46// IEEE 802.11 Structures and definitions
47//
48#define MAX_TX_POWER_LEVEL 100 /* mW */
49#define MAX_RSSI_TRIGGER -10 /* dBm */
50#define MIN_RSSI_TRIGGER -200 /* dBm */
51#define MAX_FRAG_THRESHOLD 2346 /* byte count */
52#define MIN_FRAG_THRESHOLD 256 /* byte count */
53#define MAX_RTS_THRESHOLD 2347 /* byte count */
54
55// new types for Media Specific Indications
56// Extension channel offset
57#define EXTCHA_NONE 0
58#define EXTCHA_ABOVE 0x1
59#define EXTCHA_BELOW 0x3
60
61// BW
62#define BAND_WIDTH_20 0
63#define BAND_WIDTH_40 1
64#define BAND_WIDTH_BOTH 2
65#define BAND_WIDTH_10 3 // 802.11j has 10MHz. This definition is for internal usage. doesn't fill in the IE or other field.
66// SHORTGI
67#define GAP_INTERVAL_400 1 // only support in HT mode
68#define GAP_INTERVAL_800 0
69#define GAP_INTERVAL_BOTH 2
70
71#define NdisMediaStateConnected 1
72#define NdisMediaStateDisconnected 0
73
74#define NDIS_802_11_LENGTH_SSID 32
75#define NDIS_802_11_LENGTH_RATES 8
76#define NDIS_802_11_LENGTH_RATES_EX 16
77#define MAC_ADDR_LENGTH 6
78#define MAX_NUM_OF_CHS 49 // 14 channels @2.4G + 12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL terminationc
79#define MAX_NUMBER_OF_EVENT 10 // entry # in EVENT table
80#define MAX_NUMBER_OF_MAC 32 // if MAX_MBSSID_NUM is 8, this value can't be larger than 211
81#define MAX_NUMBER_OF_ACL 64
82#define MAX_LENGTH_OF_SUPPORT_RATES 12 // 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54
83#define MAX_NUMBER_OF_DLS_ENTRY 4
84
85
86
87#ifndef UNDER_CE
88// OID definition, since NDIS 5.0 didn't define these, we need to define for our own
89//#if _WIN32_WINNT<=0x0500
90
91#define OID_GEN_MACHINE_NAME 0x0001021A
92
93#ifdef RALINK_ATE
94#define RT_QUERY_ATE_TXDONE_COUNT 0x0401
95#endif // RALINK_ATE //
96#define RT_QUERY_SIGNAL_CONTEXT 0x0402
97#define RT_SET_IAPP_PID 0x0404
98#define RT_SET_APD_PID 0x0405
99#define RT_SET_DEL_MAC_ENTRY 0x0406
100
101//
102// IEEE 802.11 OIDs
103//
104#define OID_GET_SET_TOGGLE 0x8000
105
106#define OID_802_11_NETWORK_TYPES_SUPPORTED 0x0103
107#define OID_802_11_NETWORK_TYPE_IN_USE 0x0104
108#define OID_802_11_RSSI_TRIGGER 0x0107
109#define RT_OID_802_11_RSSI 0x0108 //rt2860 only , kathy
110#define RT_OID_802_11_RSSI_1 0x0109 //rt2860 only , kathy
111#define RT_OID_802_11_RSSI_2 0x010A //rt2860 only , kathy
112#define OID_802_11_NUMBER_OF_ANTENNAS 0x010B
113#define OID_802_11_RX_ANTENNA_SELECTED 0x010C
114#define OID_802_11_TX_ANTENNA_SELECTED 0x010D
115#define OID_802_11_SUPPORTED_RATES 0x010E
116#define OID_802_11_ADD_WEP 0x0112
117#define OID_802_11_REMOVE_WEP 0x0113
118#define OID_802_11_DISASSOCIATE 0x0114
119#define OID_802_11_PRIVACY_FILTER 0x0118
120#define OID_802_11_ASSOCIATION_INFORMATION 0x011E
121#define OID_802_11_TEST 0x011F
122#define RT_OID_802_11_COUNTRY_REGION 0x0507
123#define OID_802_11_BSSID_LIST_SCAN 0x0508
124#define OID_802_11_SSID 0x0509
125#define OID_802_11_BSSID 0x050A
126#define RT_OID_802_11_RADIO 0x050B
127#define RT_OID_802_11_PHY_MODE 0x050C
128#define RT_OID_802_11_STA_CONFIG 0x050D
129#define OID_802_11_DESIRED_RATES 0x050E
130#define RT_OID_802_11_PREAMBLE 0x050F
131#define OID_802_11_WEP_STATUS 0x0510
132#define OID_802_11_AUTHENTICATION_MODE 0x0511
133#define OID_802_11_INFRASTRUCTURE_MODE 0x0512
134#define RT_OID_802_11_RESET_COUNTERS 0x0513
135#define OID_802_11_RTS_THRESHOLD 0x0514
136#define OID_802_11_FRAGMENTATION_THRESHOLD 0x0515
137#define OID_802_11_POWER_MODE 0x0516
138#define OID_802_11_TX_POWER_LEVEL 0x0517
139#define RT_OID_802_11_ADD_WPA 0x0518
140#define OID_802_11_REMOVE_KEY 0x0519
141#define OID_802_11_ADD_KEY 0x0520
142#define OID_802_11_CONFIGURATION 0x0521
143#define OID_802_11_TX_PACKET_BURST 0x0522
144#define RT_OID_802_11_QUERY_NOISE_LEVEL 0x0523
145#define RT_OID_802_11_EXTRA_INFO 0x0524
146#ifdef DBG
147#define RT_OID_802_11_HARDWARE_REGISTER 0x0525
148#endif
149#define OID_802_11_ENCRYPTION_STATUS OID_802_11_WEP_STATUS
150#define OID_802_11_DEAUTHENTICATION 0x0526
151#define OID_802_11_DROP_UNENCRYPTED 0x0527
152#define OID_802_11_MIC_FAILURE_REPORT_FRAME 0x0528
153
154// For 802.1x daemin using to require current driver configuration
155#define OID_802_11_RADIUS_QUERY_SETTING 0x0540
156
157#define RT_OID_DEVICE_NAME 0x0607
158#define RT_OID_VERSION_INFO 0x0608
159#define OID_802_11_BSSID_LIST 0x0609
160#define OID_802_3_CURRENT_ADDRESS 0x060A
161#define OID_GEN_MEDIA_CONNECT_STATUS 0x060B
162#define RT_OID_802_11_QUERY_LINK_STATUS 0x060C
163#define OID_802_11_RSSI 0x060D
164#define OID_802_11_STATISTICS 0x060E
165#define OID_GEN_RCV_OK 0x060F
166#define OID_GEN_RCV_NO_BUFFER 0x0610
167#define RT_OID_802_11_QUERY_EEPROM_VERSION 0x0611
168#define RT_OID_802_11_QUERY_FIRMWARE_VERSION 0x0612
169#define RT_OID_802_11_QUERY_LAST_RX_RATE 0x0613
170#define RT_OID_802_11_TX_POWER_LEVEL_1 0x0614
171#define RT_OID_802_11_QUERY_PIDVID 0x0615
172//for WPA_SUPPLICANT_SUPPORT
173#define OID_SET_COUNTERMEASURES 0x0616
174#define OID_802_11_SET_IEEE8021X 0x0617
175#define OID_802_11_SET_IEEE8021X_REQUIRE_KEY 0x0618
176#define OID_802_11_PMKID 0x0620
177#define RT_OID_WPA_SUPPLICANT_SUPPORT 0x0621
178#define RT_OID_WE_VERSION_COMPILED 0x0622
179#define RT_OID_NEW_DRIVER 0x0623
180
181
182//rt2860 , kathy
183#define RT_OID_802_11_SNR_0 0x0630
184#define RT_OID_802_11_SNR_1 0x0631
185#define RT_OID_802_11_QUERY_LAST_TX_RATE 0x0632
186#define RT_OID_802_11_QUERY_HT_PHYMODE 0x0633
187#define RT_OID_802_11_SET_HT_PHYMODE 0x0634
188#define OID_802_11_RELOAD_DEFAULTS 0x0635
189#define RT_OID_802_11_QUERY_APSD_SETTING 0x0636
190#define RT_OID_802_11_SET_APSD_SETTING 0x0637
191#define RT_OID_802_11_QUERY_APSD_PSM 0x0638
192#define RT_OID_802_11_SET_APSD_PSM 0x0639
193#define RT_OID_802_11_QUERY_DLS 0x063A
194#define RT_OID_802_11_SET_DLS 0x063B
195#define RT_OID_802_11_QUERY_DLS_PARAM 0x063C
196#define RT_OID_802_11_SET_DLS_PARAM 0x063D
197#define RT_OID_802_11_QUERY_WMM 0x063E
198#define RT_OID_802_11_SET_WMM 0x063F
199#define RT_OID_802_11_QUERY_IMME_BA_CAP 0x0640
200#define RT_OID_802_11_SET_IMME_BA_CAP 0x0641
201#define RT_OID_802_11_QUERY_BATABLE 0x0642
202#define RT_OID_802_11_ADD_IMME_BA 0x0643
203#define RT_OID_802_11_TEAR_IMME_BA 0x0644
204#define RT_OID_DRIVER_DEVICE_NAME 0x0645
205#define RT_OID_802_11_QUERY_DAT_HT_PHYMODE 0x0646
206#define RT_OID_QUERY_MULTIPLE_CARD_SUPPORT 0x0647
207
208// Ralink defined OIDs
209// Dennis Lee move to platform specific
210
211#define RT_OID_802_11_BSSID (OID_GET_SET_TOGGLE | OID_802_11_BSSID)
212#define RT_OID_802_11_SSID (OID_GET_SET_TOGGLE | OID_802_11_SSID)
213#define RT_OID_802_11_INFRASTRUCTURE_MODE (OID_GET_SET_TOGGLE | OID_802_11_INFRASTRUCTURE_MODE)
214#define RT_OID_802_11_ADD_WEP (OID_GET_SET_TOGGLE | OID_802_11_ADD_WEP)
215#define RT_OID_802_11_ADD_KEY (OID_GET_SET_TOGGLE | OID_802_11_ADD_KEY)
216#define RT_OID_802_11_REMOVE_WEP (OID_GET_SET_TOGGLE | OID_802_11_REMOVE_WEP)
217#define RT_OID_802_11_REMOVE_KEY (OID_GET_SET_TOGGLE | OID_802_11_REMOVE_KEY)
218#define RT_OID_802_11_DISASSOCIATE (OID_GET_SET_TOGGLE | OID_802_11_DISASSOCIATE)
219#define RT_OID_802_11_AUTHENTICATION_MODE (OID_GET_SET_TOGGLE | OID_802_11_AUTHENTICATION_MODE)
220#define RT_OID_802_11_PRIVACY_FILTER (OID_GET_SET_TOGGLE | OID_802_11_PRIVACY_FILTER)
221#define RT_OID_802_11_BSSID_LIST_SCAN (OID_GET_SET_TOGGLE | OID_802_11_BSSID_LIST_SCAN)
222#define RT_OID_802_11_WEP_STATUS (OID_GET_SET_TOGGLE | OID_802_11_WEP_STATUS)
223#define RT_OID_802_11_RELOAD_DEFAULTS (OID_GET_SET_TOGGLE | OID_802_11_RELOAD_DEFAULTS)
224#define RT_OID_802_11_NETWORK_TYPE_IN_USE (OID_GET_SET_TOGGLE | OID_802_11_NETWORK_TYPE_IN_USE)
225#define RT_OID_802_11_TX_POWER_LEVEL (OID_GET_SET_TOGGLE | OID_802_11_TX_POWER_LEVEL)
226#define RT_OID_802_11_RSSI_TRIGGER (OID_GET_SET_TOGGLE | OID_802_11_RSSI_TRIGGER)
227#define RT_OID_802_11_FRAGMENTATION_THRESHOLD (OID_GET_SET_TOGGLE | OID_802_11_FRAGMENTATION_THRESHOLD)
228#define RT_OID_802_11_RTS_THRESHOLD (OID_GET_SET_TOGGLE | OID_802_11_RTS_THRESHOLD)
229#define RT_OID_802_11_RX_ANTENNA_SELECTED (OID_GET_SET_TOGGLE | OID_802_11_RX_ANTENNA_SELECTED)
230#define RT_OID_802_11_TX_ANTENNA_SELECTED (OID_GET_SET_TOGGLE | OID_802_11_TX_ANTENNA_SELECTED)
231#define RT_OID_802_11_SUPPORTED_RATES (OID_GET_SET_TOGGLE | OID_802_11_SUPPORTED_RATES)
232#define RT_OID_802_11_DESIRED_RATES (OID_GET_SET_TOGGLE | OID_802_11_DESIRED_RATES)
233#define RT_OID_802_11_CONFIGURATION (OID_GET_SET_TOGGLE | OID_802_11_CONFIGURATION)
234#define RT_OID_802_11_POWER_MODE (OID_GET_SET_TOGGLE | OID_802_11_POWER_MODE)
235
236
237
238typedef enum _NDIS_802_11_STATUS_TYPE
239{
240 Ndis802_11StatusType_Authentication,
241 Ndis802_11StatusType_MediaStreamMode,
242 Ndis802_11StatusType_PMKID_CandidateList,
243 Ndis802_11StatusTypeMax // not a real type, defined as an upper bound
244} NDIS_802_11_STATUS_TYPE, *PNDIS_802_11_STATUS_TYPE;
245
246typedef UCHAR NDIS_802_11_MAC_ADDRESS[6];
247
248typedef struct _NDIS_802_11_STATUS_INDICATION
249{
250 NDIS_802_11_STATUS_TYPE StatusType;
251} NDIS_802_11_STATUS_INDICATION, *PNDIS_802_11_STATUS_INDICATION;
252
253// mask for authentication/integrity fields
254#define NDIS_802_11_AUTH_REQUEST_AUTH_FIELDS 0x0f
255
256#define NDIS_802_11_AUTH_REQUEST_REAUTH 0x01
257#define NDIS_802_11_AUTH_REQUEST_KEYUPDATE 0x02
258#define NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR 0x06
259#define NDIS_802_11_AUTH_REQUEST_GROUP_ERROR 0x0E
260
261typedef struct _NDIS_802_11_AUTHENTICATION_REQUEST
262{
263 ULONG Length; // Length of structure
264 NDIS_802_11_MAC_ADDRESS Bssid;
265 ULONG Flags;
266} NDIS_802_11_AUTHENTICATION_REQUEST, *PNDIS_802_11_AUTHENTICATION_REQUEST;
267
268//Added new types for PMKID Candidate lists.
269typedef struct _PMKID_CANDIDATE {
270 NDIS_802_11_MAC_ADDRESS BSSID;
271 ULONG Flags;
272} PMKID_CANDIDATE, *PPMKID_CANDIDATE;
273
274typedef struct _NDIS_802_11_PMKID_CANDIDATE_LIST
275{
276 ULONG Version; // Version of the structure
277 ULONG NumCandidates; // No. of pmkid candidates
278 PMKID_CANDIDATE CandidateList[1];
279} NDIS_802_11_PMKID_CANDIDATE_LIST, *PNDIS_802_11_PMKID_CANDIDATE_LIST;
280
281//Flags for PMKID Candidate list structure
282#define NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01
283
284// Added new types for OFDM 5G and 2.4G
285typedef enum _NDIS_802_11_NETWORK_TYPE
286{
287 Ndis802_11FH,
288 Ndis802_11DS,
289 Ndis802_11OFDM5,
290 Ndis802_11OFDM5_N,
291 Ndis802_11OFDM24,
292 Ndis802_11OFDM24_N,
293 Ndis802_11Automode,
294 Ndis802_11NetworkTypeMax // not a real type, defined as an upper bound
295} NDIS_802_11_NETWORK_TYPE, *PNDIS_802_11_NETWORK_TYPE;
296
297typedef struct _NDIS_802_11_NETWORK_TYPE_LIST
298{
299 UINT NumberOfItems; // in list below, at least 1
300 NDIS_802_11_NETWORK_TYPE NetworkType [1];
301} NDIS_802_11_NETWORK_TYPE_LIST, *PNDIS_802_11_NETWORK_TYPE_LIST;
302
303typedef enum _NDIS_802_11_POWER_MODE
304{
305 Ndis802_11PowerModeCAM,
306 Ndis802_11PowerModeMAX_PSP,
307 Ndis802_11PowerModeFast_PSP,
308 Ndis802_11PowerModeLegacy_PSP,
309 Ndis802_11PowerModeMax // not a real mode, defined as an upper bound
310} NDIS_802_11_POWER_MODE, *PNDIS_802_11_POWER_MODE;
311
312typedef ULONG NDIS_802_11_TX_POWER_LEVEL; // in milliwatts
313
314//
315// Received Signal Strength Indication
316//
317typedef LONG NDIS_802_11_RSSI; // in dBm
318
319typedef struct _NDIS_802_11_CONFIGURATION_FH
320{
321 ULONG Length; // Length of structure
322 ULONG HopPattern; // As defined by 802.11, MSB set
323 ULONG HopSet; // to one if non-802.11
324 ULONG DwellTime; // units are Kusec
325} NDIS_802_11_CONFIGURATION_FH, *PNDIS_802_11_CONFIGURATION_FH;
326
327typedef struct _NDIS_802_11_CONFIGURATION
328{
329 ULONG Length; // Length of structure
330 ULONG BeaconPeriod; // units are Kusec
331 ULONG ATIMWindow; // units are Kusec
332 ULONG DSConfig; // Frequency, units are kHz
333 NDIS_802_11_CONFIGURATION_FH FHConfig;
334} NDIS_802_11_CONFIGURATION, *PNDIS_802_11_CONFIGURATION;
335
336typedef struct _NDIS_802_11_STATISTICS
337{
338 ULONG Length; // Length of structure
339 LARGE_INTEGER TransmittedFragmentCount;
340 LARGE_INTEGER MulticastTransmittedFrameCount;
341 LARGE_INTEGER FailedCount;
342 LARGE_INTEGER RetryCount;
343 LARGE_INTEGER MultipleRetryCount;
344 LARGE_INTEGER RTSSuccessCount;
345 LARGE_INTEGER RTSFailureCount;
346 LARGE_INTEGER ACKFailureCount;
347 LARGE_INTEGER FrameDuplicateCount;
348 LARGE_INTEGER ReceivedFragmentCount;
349 LARGE_INTEGER MulticastReceivedFrameCount;
350 LARGE_INTEGER FCSErrorCount;
351 LARGE_INTEGER TKIPLocalMICFailures;
352 LARGE_INTEGER TKIPRemoteMICErrors;
353 LARGE_INTEGER TKIPICVErrors;
354 LARGE_INTEGER TKIPCounterMeasuresInvoked;
355 LARGE_INTEGER TKIPReplays;
356 LARGE_INTEGER CCMPFormatErrors;
357 LARGE_INTEGER CCMPReplays;
358 LARGE_INTEGER CCMPDecryptErrors;
359 LARGE_INTEGER FourWayHandshakeFailures;
360} NDIS_802_11_STATISTICS, *PNDIS_802_11_STATISTICS;
361
362typedef ULONG NDIS_802_11_KEY_INDEX;
363typedef ULONGLONG NDIS_802_11_KEY_RSC;
364
365#define MAX_RADIUS_SRV_NUM 2 // 802.1x failover number
366
367typedef struct PACKED _RADIUS_SRV_INFO {
368 UINT32 radius_ip;
369 UINT32 radius_port;
370 UCHAR radius_key[64];
371 UCHAR radius_key_len;
372} RADIUS_SRV_INFO, *PRADIUS_SRV_INFO;
373
374typedef struct PACKED _RADIUS_KEY_INFO
375{
376 UCHAR radius_srv_num;
377 RADIUS_SRV_INFO radius_srv_info[MAX_RADIUS_SRV_NUM];
378 UCHAR ieee8021xWEP; // dynamic WEP
379 UCHAR key_index;
380 UCHAR key_length; // length of key in bytes
381 UCHAR key_material[13];
382} RADIUS_KEY_INFO, *PRADIUS_KEY_INFO;
383
384// It's used by 802.1x daemon to require relative configuration
385typedef struct PACKED _RADIUS_CONF
386{
387 UINT32 Length; // Length of this structure
388 UCHAR mbss_num; // indicate multiple BSS number
389 UINT32 own_ip_addr;
390 UINT32 retry_interval;
391 UINT32 session_timeout_interval;
392 UCHAR EAPifname[IFNAMSIZ];
393 UCHAR EAPifname_len;
394 UCHAR PreAuthifname[IFNAMSIZ];
395 UCHAR PreAuthifname_len;
396 RADIUS_KEY_INFO RadiusInfo[8/*MAX_MBSSID_NUM*/];
397} RADIUS_CONF, *PRADIUS_CONF;
398
399
400
401#ifdef CONFIG_STA_SUPPORT
402// Key mapping keys require a BSSID
403typedef struct _NDIS_802_11_KEY
404{
405 UINT Length; // Length of this structure
406 UINT KeyIndex;
407 UINT KeyLength; // length of key in bytes
408 NDIS_802_11_MAC_ADDRESS BSSID;
409 NDIS_802_11_KEY_RSC KeyRSC;
410 UCHAR KeyMaterial[1]; // variable length depending on above field
411} NDIS_802_11_KEY, *PNDIS_802_11_KEY;
412#endif // CONFIG_STA_SUPPORT //
413
414typedef struct _NDIS_802_11_REMOVE_KEY
415{
416 UINT Length; // Length of this structure
417 UINT KeyIndex;
418 NDIS_802_11_MAC_ADDRESS BSSID;
419} NDIS_802_11_REMOVE_KEY, *PNDIS_802_11_REMOVE_KEY;
420
421typedef struct _NDIS_802_11_WEP
422{
423 UINT Length; // Length of this structure
424 UINT KeyIndex; // 0 is the per-client key, 1-N are the
425 // global keys
426 UINT KeyLength; // length of key in bytes
427 UCHAR KeyMaterial[1];// variable length depending on above field
428} NDIS_802_11_WEP, *PNDIS_802_11_WEP;
429
430
431typedef enum _NDIS_802_11_NETWORK_INFRASTRUCTURE
432{
433 Ndis802_11IBSS,
434 Ndis802_11Infrastructure,
435 Ndis802_11AutoUnknown,
436 Ndis802_11Monitor,
437 Ndis802_11InfrastructureMax // Not a real value, defined as upper bound
438} NDIS_802_11_NETWORK_INFRASTRUCTURE, *PNDIS_802_11_NETWORK_INFRASTRUCTURE;
439
440// Add new authentication modes
441typedef enum _NDIS_802_11_AUTHENTICATION_MODE
442{
443 Ndis802_11AuthModeOpen,
444 Ndis802_11AuthModeShared,
445 Ndis802_11AuthModeAutoSwitch,
446 Ndis802_11AuthModeWPA,
447 Ndis802_11AuthModeWPAPSK,
448 Ndis802_11AuthModeWPANone,
449 Ndis802_11AuthModeWPA2,
450 Ndis802_11AuthModeWPA2PSK,
451 Ndis802_11AuthModeWPA1WPA2,
452 Ndis802_11AuthModeWPA1PSKWPA2PSK,
453 Ndis802_11AuthModeMax // Not a real mode, defined as upper bound
454} NDIS_802_11_AUTHENTICATION_MODE, *PNDIS_802_11_AUTHENTICATION_MODE;
455
456typedef UCHAR NDIS_802_11_RATES[NDIS_802_11_LENGTH_RATES]; // Set of 8 data rates
457typedef UCHAR NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX]; // Set of 16 data rates
458
459typedef struct PACKED _NDIS_802_11_SSID
460{
461 UINT SsidLength; // length of SSID field below, in bytes;
462 // this can be zero.
463 UCHAR Ssid[NDIS_802_11_LENGTH_SSID]; // SSID information field
464} NDIS_802_11_SSID, *PNDIS_802_11_SSID;
465
466
467typedef struct PACKED _NDIS_WLAN_BSSID
468{
469 ULONG Length; // Length of this structure
470 NDIS_802_11_MAC_ADDRESS MacAddress; // BSSID
471 UCHAR Reserved[2];
472 NDIS_802_11_SSID Ssid; // SSID
473 ULONG Privacy; // WEP encryption requirement
474 NDIS_802_11_RSSI Rssi; // receive signal strength in dBm
475 NDIS_802_11_NETWORK_TYPE NetworkTypeInUse;
476 NDIS_802_11_CONFIGURATION Configuration;
477 NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode;
478 NDIS_802_11_RATES SupportedRates;
479} NDIS_WLAN_BSSID, *PNDIS_WLAN_BSSID;
480
481typedef struct PACKED _NDIS_802_11_BSSID_LIST
482{
483 UINT NumberOfItems; // in list below, at least 1
484 NDIS_WLAN_BSSID Bssid[1];
485} NDIS_802_11_BSSID_LIST, *PNDIS_802_11_BSSID_LIST;
486
487// Added Capabilities, IELength and IEs for each BSSID
488typedef struct PACKED _NDIS_WLAN_BSSID_EX
489{
490 ULONG Length; // Length of this structure
491 NDIS_802_11_MAC_ADDRESS MacAddress; // BSSID
492 UCHAR Reserved[2];
493 NDIS_802_11_SSID Ssid; // SSID
494 UINT Privacy; // WEP encryption requirement
495 NDIS_802_11_RSSI Rssi; // receive signal
496 // strength in dBm
497 NDIS_802_11_NETWORK_TYPE NetworkTypeInUse;
498 NDIS_802_11_CONFIGURATION Configuration;
499 NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode;
500 NDIS_802_11_RATES_EX SupportedRates;
501 ULONG IELength;
502 UCHAR IEs[1];
503} NDIS_WLAN_BSSID_EX, *PNDIS_WLAN_BSSID_EX;
504
505typedef struct PACKED _NDIS_802_11_BSSID_LIST_EX
506{
507 UINT NumberOfItems; // in list below, at least 1
508 NDIS_WLAN_BSSID_EX Bssid[1];
509} NDIS_802_11_BSSID_LIST_EX, *PNDIS_802_11_BSSID_LIST_EX;
510
511typedef struct PACKED _NDIS_802_11_FIXED_IEs
512{
513 UCHAR Timestamp[8];
514 USHORT BeaconInterval;
515 USHORT Capabilities;
516} NDIS_802_11_FIXED_IEs, *PNDIS_802_11_FIXED_IEs;
517
518typedef struct _NDIS_802_11_VARIABLE_IEs
519{
520 UCHAR ElementID;
521 UCHAR Length; // Number of bytes in data field
522 UCHAR data[1];
523} NDIS_802_11_VARIABLE_IEs, *PNDIS_802_11_VARIABLE_IEs;
524
525typedef ULONG NDIS_802_11_FRAGMENTATION_THRESHOLD;
526
527typedef ULONG NDIS_802_11_RTS_THRESHOLD;
528
529typedef ULONG NDIS_802_11_ANTENNA;
530
531typedef enum _NDIS_802_11_PRIVACY_FILTER
532{
533 Ndis802_11PrivFilterAcceptAll,
534 Ndis802_11PrivFilter8021xWEP
535} NDIS_802_11_PRIVACY_FILTER, *PNDIS_802_11_PRIVACY_FILTER;
536
537// Added new encryption types
538// Also aliased typedef to new name
539typedef enum _NDIS_802_11_WEP_STATUS
540{
541 Ndis802_11WEPEnabled,
542 Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled,
543 Ndis802_11WEPDisabled,
544 Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled,
545 Ndis802_11WEPKeyAbsent,
546 Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent,
547 Ndis802_11WEPNotSupported,
548 Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported,
549 Ndis802_11Encryption2Enabled,
550 Ndis802_11Encryption2KeyAbsent,
551 Ndis802_11Encryption3Enabled,
552 Ndis802_11Encryption3KeyAbsent,
553 Ndis802_11Encryption4Enabled, // TKIP or AES mix
554 Ndis802_11Encryption4KeyAbsent,
555} NDIS_802_11_WEP_STATUS, *PNDIS_802_11_WEP_STATUS,
556 NDIS_802_11_ENCRYPTION_STATUS, *PNDIS_802_11_ENCRYPTION_STATUS;
557
558typedef enum _NDIS_802_11_RELOAD_DEFAULTS
559{
560 Ndis802_11ReloadWEPKeys
561} NDIS_802_11_RELOAD_DEFAULTS, *PNDIS_802_11_RELOAD_DEFAULTS;
562
563#define NDIS_802_11_AI_REQFI_CAPABILITIES 1
564#define NDIS_802_11_AI_REQFI_LISTENINTERVAL 2
565#define NDIS_802_11_AI_REQFI_CURRENTAPADDRESS 4
566
567#define NDIS_802_11_AI_RESFI_CAPABILITIES 1
568#define NDIS_802_11_AI_RESFI_STATUSCODE 2
569#define NDIS_802_11_AI_RESFI_ASSOCIATIONID 4
570
571typedef struct _NDIS_802_11_AI_REQFI
572{
573 USHORT Capabilities;
574 USHORT ListenInterval;
575 NDIS_802_11_MAC_ADDRESS CurrentAPAddress;
576} NDIS_802_11_AI_REQFI, *PNDIS_802_11_AI_REQFI;
577
578typedef struct _NDIS_802_11_AI_RESFI
579{
580 USHORT Capabilities;
581 USHORT StatusCode;
582 USHORT AssociationId;
583} NDIS_802_11_AI_RESFI, *PNDIS_802_11_AI_RESFI;
584
585typedef struct _NDIS_802_11_ASSOCIATION_INFORMATION
586{
587 ULONG Length;
588 USHORT AvailableRequestFixedIEs;
589 NDIS_802_11_AI_REQFI RequestFixedIEs;
590 ULONG RequestIELength;
591 ULONG OffsetRequestIEs;
592 USHORT AvailableResponseFixedIEs;
593 NDIS_802_11_AI_RESFI ResponseFixedIEs;
594 ULONG ResponseIELength;
595 ULONG OffsetResponseIEs;
596} NDIS_802_11_ASSOCIATION_INFORMATION, *PNDIS_802_11_ASSOCIATION_INFORMATION;
597
598typedef struct _NDIS_802_11_AUTHENTICATION_EVENT
599{
600 NDIS_802_11_STATUS_INDICATION Status;
601 NDIS_802_11_AUTHENTICATION_REQUEST Request[1];
602} NDIS_802_11_AUTHENTICATION_EVENT, *PNDIS_802_11_AUTHENTICATION_EVENT;
603
604/*
605typedef struct _NDIS_802_11_TEST
606{
607 ULONG Length;
608 ULONG Type;
609 union
610 {
611 NDIS_802_11_AUTHENTICATION_EVENT AuthenticationEvent;
612 NDIS_802_11_RSSI RssiTrigger;
613 };
614} NDIS_802_11_TEST, *PNDIS_802_11_TEST;
615 */
616
617// 802.11 Media stream constraints, associated with OID_802_11_MEDIA_STREAM_MODE
618typedef enum _NDIS_802_11_MEDIA_STREAM_MODE
619{
620 Ndis802_11MediaStreamOff,
621 Ndis802_11MediaStreamOn,
622} NDIS_802_11_MEDIA_STREAM_MODE, *PNDIS_802_11_MEDIA_STREAM_MODE;
623
624// PMKID Structures
625typedef UCHAR NDIS_802_11_PMKID_VALUE[16];
626
627#ifdef CONFIG_STA_SUPPORT
628typedef struct _BSSID_INFO
629{
630 NDIS_802_11_MAC_ADDRESS BSSID;
631 NDIS_802_11_PMKID_VALUE PMKID;
632} BSSID_INFO, *PBSSID_INFO;
633
634typedef struct _NDIS_802_11_PMKID
635{
636 UINT Length;
637 UINT BSSIDInfoCount;
638 BSSID_INFO BSSIDInfo[1];
639} NDIS_802_11_PMKID, *PNDIS_802_11_PMKID;
640#endif // CONFIG_STA_SUPPORT //
641
642
643typedef struct _NDIS_802_11_AUTHENTICATION_ENCRYPTION
644{
645 NDIS_802_11_AUTHENTICATION_MODE AuthModeSupported;
646 NDIS_802_11_ENCRYPTION_STATUS EncryptStatusSupported;
647} NDIS_802_11_AUTHENTICATION_ENCRYPTION, *PNDIS_802_11_AUTHENTICATION_ENCRYPTION;
648
649typedef struct _NDIS_802_11_CAPABILITY
650{
651 ULONG Length;
652 ULONG Version;
653 ULONG NoOfPMKIDs;
654 ULONG NoOfAuthEncryptPairsSupported;
655 NDIS_802_11_AUTHENTICATION_ENCRYPTION AuthenticationEncryptionSupported[1];
656} NDIS_802_11_CAPABILITY, *PNDIS_802_11_CAPABILITY;
657
658//#endif //of WIN 2k
659#endif //UNDER_CE
660
661#if WIRELESS_EXT <= 11
662#ifndef SIOCDEVPRIVATE
663#define SIOCDEVPRIVATE 0x8BE0
664#endif
665#define SIOCIWFIRSTPRIV SIOCDEVPRIVATE
666#endif
667
668#ifdef CONFIG_STA_SUPPORT
669#define RT_PRIV_IOCTL_EXT (SIOCIWFIRSTPRIV + 0x01) // Sync. with AP for wsc upnp daemon
670#define RTPRIV_IOCTL_SET (SIOCIWFIRSTPRIV + 0x02)
671
672#ifdef DBG
673#define RTPRIV_IOCTL_BBP (SIOCIWFIRSTPRIV + 0x03)
674#define RTPRIV_IOCTL_MAC (SIOCIWFIRSTPRIV + 0x05)
675#define RTPRIV_IOCTL_RF (SIOCIWFIRSTPRIV + 0x13)
676#define RTPRIV_IOCTL_E2P (SIOCIWFIRSTPRIV + 0x07)
677#endif
678
679#ifdef RALINK_ATE
680#ifdef RALINK_28xx_QA
681#define RTPRIV_IOCTL_ATE (SIOCIWFIRSTPRIV + 0x08)
682#endif // RALINK_28xx_QA //
683#endif // RALINK_ATE //
684
685#define RTPRIV_IOCTL_STATISTICS (SIOCIWFIRSTPRIV + 0x09)
686#define RTPRIV_IOCTL_ADD_PMKID_CACHE (SIOCIWFIRSTPRIV + 0x0A)
687#define RTPRIV_IOCTL_RADIUS_DATA (SIOCIWFIRSTPRIV + 0x0C)
688#define RTPRIV_IOCTL_GSITESURVEY (SIOCIWFIRSTPRIV + 0x0D)
689#define RT_PRIV_IOCTL (SIOCIWFIRSTPRIV + 0x0E) // Sync. with RT61 (for wpa_supplicant)
690#define RTPRIV_IOCTL_GET_MAC_TABLE (SIOCIWFIRSTPRIV + 0x0F)
691
692#define RTPRIV_IOCTL_SHOW (SIOCIWFIRSTPRIV + 0x11)
693enum {
694 SHOW_CONN_STATUS = 4,
695 SHOW_DRVIER_VERION = 5,
696 SHOW_BA_INFO = 6,
697 SHOW_DESC_INFO = 7,
698#ifdef RT2870
699 SHOW_RXBULK_INFO = 8,
700 SHOW_TXBULK_INFO = 9,
701#endif // RT2870 //
702 RAIO_OFF = 10,
703 RAIO_ON = 11,
704#ifdef QOS_DLS_SUPPORT
705 SHOW_DLS_ENTRY_INFO = 19,
706#endif // QOS_DLS_SUPPORT //
707 SHOW_CFG_VALUE = 20,
708};
709
710
711#endif // CONFIG_STA_SUPPORT //
712
713
714
715#ifdef SNMP_SUPPORT
716//SNMP ieee 802dot11, kathy , 2008_0220
717// dot11res(3)
718#define RT_OID_802_11_MANUFACTUREROUI 0x0700
719#define RT_OID_802_11_MANUFACTURERNAME 0x0701
720#define RT_OID_802_11_RESOURCETYPEIDNAME 0x0702
721
722// dot11smt(1)
723#define RT_OID_802_11_PRIVACYOPTIONIMPLEMENTED 0x0703
724#define RT_OID_802_11_POWERMANAGEMENTMODE 0x0704
725#define OID_802_11_WEPDEFAULTKEYVALUE 0x0705 // read , write
726#define OID_802_11_WEPDEFAULTKEYID 0x0706
727#define RT_OID_802_11_WEPKEYMAPPINGLENGTH 0x0707
728#define OID_802_11_SHORTRETRYLIMIT 0x0708
729#define OID_802_11_LONGRETRYLIMIT 0x0709
730#define RT_OID_802_11_PRODUCTID 0x0710
731#define RT_OID_802_11_MANUFACTUREID 0x0711
732
733// //dot11Phy(4)
734#define OID_802_11_CURRENTCHANNEL 0x0712
735
736//dot11mac
737#define RT_OID_802_11_MAC_ADDRESS 0x0713
738#endif // SNMP_SUPPORT //
739
740#define OID_802_11_BUILD_CHANNEL_EX 0x0714
741#define OID_802_11_GET_CH_LIST 0x0715
742#define OID_802_11_GET_COUNTRY_CODE 0x0716
743#define OID_802_11_GET_CHANNEL_GEOGRAPHY 0x0717
744
745//#define RT_OID_802_11_STATISTICS (OID_GET_SET_TOGGLE | OID_802_11_STATISTICS)
746
747#ifdef CONFIG_STA_SUPPORT
748#define RT_OID_WSC_SET_PASSPHRASE 0x0740 // passphrase for wpa(2)-psk
749#define RT_OID_WSC_DRIVER_AUTO_CONNECT 0x0741
750#define RT_OID_WSC_QUERY_DEFAULT_PROFILE 0x0742
751#define RT_OID_WSC_SET_CONN_BY_PROFILE_INDEX 0x0743
752#define RT_OID_WSC_SET_ACTION 0x0744
753#define RT_OID_WSC_SET_SSID 0x0745
754#define RT_OID_WSC_SET_PIN_CODE 0x0746
755#define RT_OID_WSC_SET_MODE 0x0747 // PIN or PBC
756#define RT_OID_WSC_SET_CONF_MODE 0x0748 // Enrollee or Registrar
757#define RT_OID_WSC_SET_PROFILE 0x0749
758#endif // CONFIG_STA_SUPPORT //
759#define RT_OID_802_11_WSC_QUERY_PROFILE 0x0750
760// for consistency with RT61
761#define RT_OID_WSC_QUERY_STATUS 0x0751
762#define RT_OID_WSC_PIN_CODE 0x0752
763#define RT_OID_WSC_UUID 0x0753
764#define RT_OID_WSC_SET_SELECTED_REGISTRAR 0x0754
765#define RT_OID_WSC_EAPMSG 0x0755
766#define RT_OID_WSC_MANUFACTURER 0x0756
767#define RT_OID_WSC_MODEL_NAME 0x0757
768#define RT_OID_WSC_MODEL_NO 0x0758
769#define RT_OID_WSC_SERIAL_NO 0x0759
770#define RT_OID_WSC_MAC_ADDRESS 0x0760
771
772#ifdef LLTD_SUPPORT
773// for consistency with RT61
774#define RT_OID_GET_PHY_MODE 0x761
775#endif // LLTD_SUPPORT //
776
777#ifdef NINTENDO_AP
778//#define RT_OID_NINTENDO 0x0D010770
779#define RT_OID_802_11_NINTENDO_GET_TABLE 0x0771 //((RT_OID_NINTENDO + 0x01) & 0xffff)
780#define RT_OID_802_11_NINTENDO_SET_TABLE 0x0772 //((RT_OID_NINTENDO + 0x02) & 0xffff)
781#define RT_OID_802_11_NINTENDO_CAPABLE 0x0773 //((RT_OID_NINTENDO + 0x03) & 0xffff)
782#endif // NINTENDO_AP //
783
784//Add Paul Chen for Accton
785//#define RT_OID_TX_POWER_LEVEL 0xFF020010
786//#define RT_OID_SET_TX_POWER_LEVEL (OID_GET_SET_TOGGLE | RT_OID_TX_POWER_LEVEL)
787
788// New for MeetingHouse Api support
789#define OID_MH_802_1X_SUPPORTED 0xFFEDC100
790
791// MIMO Tx parameter, ShortGI, MCS, STBC, etc. these are fields in TXWI. Don't change this definition!!!
792typedef union _HTTRANSMIT_SETTING {
793#ifdef RT_BIG_ENDIAN
794 struct {
795 USHORT MODE:2; // Use definition MODE_xxx.
796// USHORT rsv:3;
797 USHORT TxBF:1;
798 USHORT rsv:2;
799 USHORT STBC:2; //SPACE
800 USHORT ShortGI:1;
801 USHORT BW:1; //channel bandwidth 20MHz or 40 MHz
802 USHORT MCS:7; // MCS
803 } field;
804#else
805 struct {
806 USHORT MCS:7; // MCS
807 USHORT BW:1; //channel bandwidth 20MHz or 40 MHz
808 USHORT ShortGI:1;
809 USHORT STBC:2; //SPACE
810// USHORT rsv:3;
811 USHORT rsv:2;
812 USHORT TxBF:1;
813 USHORT MODE:2; // Use definition MODE_xxx.
814 } field;
815#endif
816 USHORT word;
817 } HTTRANSMIT_SETTING, *PHTTRANSMIT_SETTING;
818
819typedef enum _RT_802_11_PREAMBLE {
820 Rt802_11PreambleLong,
821 Rt802_11PreambleShort,
822 Rt802_11PreambleAuto
823} RT_802_11_PREAMBLE, *PRT_802_11_PREAMBLE;
824
825// Only for STA, need to sync with AP
826// 2005-03-08 match current RaConfig.
827typedef enum _RT_802_11_PHY_MODE {
828 PHY_11BG_MIXED = 0,
829 PHY_11B,
830 PHY_11A,
831 PHY_11ABG_MIXED,
832 PHY_11G,
833#ifdef DOT11_N_SUPPORT
834 PHY_11ABGN_MIXED, // both band 5
835 PHY_11N_2_4G, // 11n-only with 2.4G band 6
836 PHY_11GN_MIXED, // 2.4G band 7
837 PHY_11AN_MIXED, // 5G band 8
838 PHY_11BGN_MIXED, // if check 802.11b. 9
839 PHY_11AGN_MIXED, // if check 802.11b. 10
840 PHY_11N_5G, // 11n-only with 5G band 11
841#endif // DOT11_N_SUPPORT //
842} RT_802_11_PHY_MODE;
843
844// put all proprietery for-query objects here to reduce # of Query_OID
845typedef struct _RT_802_11_LINK_STATUS {
846 ULONG CurrTxRate; // in units of 0.5Mbps
847 ULONG ChannelQuality; // 0..100 %
848 ULONG TxByteCount; // both ok and fail
849 ULONG RxByteCount; // both ok and fail
850 ULONG CentralChannel; // 40MHz central channel number
851} RT_802_11_LINK_STATUS, *PRT_802_11_LINK_STATUS;
852
853typedef struct _RT_802_11_EVENT_LOG {
854 LARGE_INTEGER SystemTime; // timestammp via NdisGetCurrentSystemTime()
855 UCHAR Addr[MAC_ADDR_LENGTH];
856 USHORT Event; // EVENT_xxx
857} RT_802_11_EVENT_LOG, *PRT_802_11_EVENT_LOG;
858
859typedef struct _RT_802_11_EVENT_TABLE {
860 ULONG Num;
861 ULONG Rsv; // to align Log[] at LARGE_INEGER boundary
862 RT_802_11_EVENT_LOG Log[MAX_NUMBER_OF_EVENT];
863} RT_802_11_EVENT_TABLE, PRT_802_11_EVENT_TABLE;
864
865// MIMO Tx parameter, ShortGI, MCS, STBC, etc. these are fields in TXWI. Don't change this definition!!!
866typedef union _MACHTTRANSMIT_SETTING {
867 struct {
868 USHORT MCS:7; // MCS
869 USHORT BW:1; //channel bandwidth 20MHz or 40 MHz
870 USHORT ShortGI:1;
871 USHORT STBC:2; //SPACE
872 USHORT rsv:3;
873 USHORT MODE:2; // Use definition MODE_xxx.
874 } field;
875 USHORT word;
876 } MACHTTRANSMIT_SETTING, *PMACHTTRANSMIT_SETTING;
877
878typedef struct _RT_802_11_MAC_ENTRY {
879 UCHAR Addr[MAC_ADDR_LENGTH];
880 UCHAR Aid;
881 UCHAR Psm; // 0:PWR_ACTIVE, 1:PWR_SAVE
882 UCHAR MimoPs; // 0:MMPS_STATIC, 1:MMPS_DYNAMIC, 3:MMPS_Enabled
883 CHAR AvgRssi0;
884 CHAR AvgRssi1;
885 CHAR AvgRssi2;
886 UINT32 ConnectedTime;
887 MACHTTRANSMIT_SETTING TxRate;
888} RT_802_11_MAC_ENTRY, *PRT_802_11_MAC_ENTRY;
889
890typedef struct _RT_802_11_MAC_TABLE {
891 ULONG Num;
892 RT_802_11_MAC_ENTRY Entry[MAX_NUMBER_OF_MAC];
893} RT_802_11_MAC_TABLE, *PRT_802_11_MAC_TABLE;
894
895// structure for query/set hardware register - MAC, BBP, RF register
896typedef struct _RT_802_11_HARDWARE_REGISTER {
897 ULONG HardwareType; // 0:MAC, 1:BBP, 2:RF register, 3:EEPROM
898 ULONG Offset; // Q/S register offset addr
899 ULONG Data; // R/W data buffer
900} RT_802_11_HARDWARE_REGISTER, *PRT_802_11_HARDWARE_REGISTER;
901
902// structure to tune BBP R17 "RX AGC VGC init"
903//typedef struct _RT_802_11_RX_AGC_VGC_TUNING {
904// UCHAR FalseCcaLowerThreshold; // 0-255, def 10
905// UCHAR FalseCcaUpperThreshold; // 0-255, def 100
906// UCHAR VgcDelta; // R17 +-= VgcDelta whenever flase CCA over UpprThreshold
907// // or lower than LowerThresholdupper threshold
908// UCHAR VgcUpperBound; // max value of R17
909//} RT_802_11_RX_AGC_VGC_TUNING, *PRT_802_11_RX_AGC_VGC_TUNING;
910
911typedef struct _RT_802_11_AP_CONFIG {
912 ULONG EnableTxBurst; // 0-disable, 1-enable
913 ULONG EnableTurboRate; // 0-disable, 1-enable 72/100mbps turbo rate
914 ULONG IsolateInterStaTraffic; // 0-disable, 1-enable isolation
915 ULONG HideSsid; // 0-disable, 1-enable hiding
916 ULONG UseBGProtection; // 0-AUTO, 1-always ON, 2-always OFF
917 ULONG UseShortSlotTime; // 0-no use, 1-use 9-us short slot time
918 ULONG Rsv1; // must be 0
919 ULONG SystemErrorBitmap; // ignore upon SET, return system error upon QUERY
920} RT_802_11_AP_CONFIG, *PRT_802_11_AP_CONFIG;
921
922// structure to query/set STA_CONFIG
923typedef struct _RT_802_11_STA_CONFIG {
924 ULONG EnableTxBurst; // 0-disable, 1-enable
925 ULONG EnableTurboRate; // 0-disable, 1-enable 72/100mbps turbo rate
926 ULONG UseBGProtection; // 0-AUTO, 1-always ON, 2-always OFF
927 ULONG UseShortSlotTime; // 0-no use, 1-use 9-us short slot time when applicable
928 ULONG AdhocMode; // 0-11b rates only (WIFI spec), 1 - b/g mixed, 2 - g only
929 ULONG HwRadioStatus; // 0-OFF, 1-ON, default is 1, Read-Only
930 ULONG Rsv1; // must be 0
931 ULONG SystemErrorBitmap; // ignore upon SET, return system error upon QUERY
932} RT_802_11_STA_CONFIG, *PRT_802_11_STA_CONFIG;
933
934//
935// For OID Query or Set about BA structure
936//
937typedef struct _OID_BACAP_STRUC {
938 UCHAR RxBAWinLimit;
939 UCHAR TxBAWinLimit;
940 UCHAR Policy; // 0: DELAY_BA 1:IMMED_BA (//BA Policy subfiled value in ADDBA frame) 2:BA-not use. other value invalid
941 UCHAR MpduDensity; // 0: DELAY_BA 1:IMMED_BA (//BA Policy subfiled value in ADDBA frame) 2:BA-not use. other value invalid
942 UCHAR AmsduEnable; //Enable AMSDU transmisstion
943 UCHAR AmsduSize; // 0:3839, 1:7935 bytes. UINT MSDUSizeToBytes[] = { 3839, 7935};
944 UCHAR MMPSmode; // MIMO power save more, 0:static, 1:dynamic, 2:rsv, 3:mimo enable
945 BOOLEAN AutoBA; // Auto BA will automatically
946} OID_BACAP_STRUC, *POID_BACAP_STRUC;
947
948typedef struct _RT_802_11_ACL_ENTRY {
949 UCHAR Addr[MAC_ADDR_LENGTH];
950 USHORT Rsv;
951} RT_802_11_ACL_ENTRY, *PRT_802_11_ACL_ENTRY;
952
953typedef struct PACKED _RT_802_11_ACL {
954 ULONG Policy; // 0-disable, 1-positive list, 2-negative list
955 ULONG Num;
956 RT_802_11_ACL_ENTRY Entry[MAX_NUMBER_OF_ACL];
957} RT_802_11_ACL, *PRT_802_11_ACL;
958
959typedef struct _RT_802_11_WDS {
960 ULONG Num;
961 NDIS_802_11_MAC_ADDRESS Entry[24/*MAX_NUM_OF_WDS_LINK*/];
962 ULONG KeyLength;
963 UCHAR KeyMaterial[32];
964} RT_802_11_WDS, *PRT_802_11_WDS;
965
966typedef struct _RT_802_11_TX_RATES_ {
967 UCHAR SupRateLen;
968 UCHAR SupRate[MAX_LENGTH_OF_SUPPORT_RATES];
969 UCHAR ExtRateLen;
970 UCHAR ExtRate[MAX_LENGTH_OF_SUPPORT_RATES];
971} RT_802_11_TX_RATES, *PRT_802_11_TX_RATES;
972
973
974// Definition of extra information code
975#define GENERAL_LINK_UP 0x0 // Link is Up
976#define GENERAL_LINK_DOWN 0x1 // Link is Down
977#define HW_RADIO_OFF 0x2 // Hardware radio off
978#define SW_RADIO_OFF 0x3 // Software radio off
979#define AUTH_FAIL 0x4 // Open authentication fail
980#define AUTH_FAIL_KEYS 0x5 // Shared authentication fail
981#define ASSOC_FAIL 0x6 // Association failed
982#define EAP_MIC_FAILURE 0x7 // Deauthencation because MIC failure
983#define EAP_4WAY_TIMEOUT 0x8 // Deauthencation on 4-way handshake timeout
984#define EAP_GROUP_KEY_TIMEOUT 0x9 // Deauthencation on group key handshake timeout
985#define EAP_SUCCESS 0xa // EAP succeed
986#define DETECT_RADAR_SIGNAL 0xb // Radar signal occur in current channel
987#define EXTRA_INFO_MAX 0xb // Indicate Last OID
988
989#define EXTRA_INFO_CLEAR 0xffffffff
990
991// This is OID setting structure. So only GF or MM as Mode. This is valid when our wirelss mode has 802.11n in use.
992typedef struct {
993 RT_802_11_PHY_MODE PhyMode; //
994 UCHAR TransmitNo;
995 UCHAR HtMode; //HTMODE_GF or HTMODE_MM
996 UCHAR ExtOffset; //extension channel above or below
997 UCHAR MCS;
998 UCHAR BW;
999 UCHAR STBC;
1000 UCHAR SHORTGI;
1001 UCHAR rsv;
1002} OID_SET_HT_PHYMODE, *POID_SET_HT_PHYMODE;
1003
1004#ifdef NINTENDO_AP
1005#define NINTENDO_MAX_ENTRY 16
1006#define NINTENDO_SSID_NAME_LN 8
1007#define NINTENDO_SSID_NAME "NWCUSBAP"
1008#define NINTENDO_PROBE_REQ_FLAG_MASK 0x03
1009#define NINTENDO_PROBE_REQ_ON 0x01
1010#define NINTENDO_PROBE_REQ_SIGNAL 0x02
1011#define NINTENDO_PROBE_RSP_ON 0x01
1012#define NINTENDO_SSID_NICKNAME_LN 20
1013
1014#define NINTENDO_WEPKEY_LN 13
1015
1016typedef struct _NINTENDO_SSID
1017{
1018 UCHAR NINTENDOFixChar[NINTENDO_SSID_NAME_LN];
1019 UCHAR zero1;
1020 UCHAR registe;
1021 UCHAR ID;
1022 UCHAR zero2;
1023 UCHAR NICKname[NINTENDO_SSID_NICKNAME_LN];
1024} RT_NINTENDO_SSID, *PRT_NINTENDO_SSID;
1025
1026typedef struct _NINTENDO_ENTRY
1027{
1028 UCHAR NICKname[NINTENDO_SSID_NICKNAME_LN];
1029 UCHAR DS_Addr[ETH_LENGTH_OF_ADDRESS];
1030 UCHAR registe;
1031 UCHAR UserSpaceAck;
1032} RT_NINTENDO_ENTRY, *PRT_NINTENDO_ENTRY;
1033
1034//RTPRIV_IOCTL_NINTENDO_GET_TABLE
1035//RTPRIV_IOCTL_NINTENDO_SET_TABLE
1036typedef struct _NINTENDO_TABLE
1037{
1038 UINT number;
1039 RT_NINTENDO_ENTRY entry[NINTENDO_MAX_ENTRY];
1040} RT_NINTENDO_TABLE, *PRT_NINTENDO_TABLE;
1041
1042//RTPRIV_IOCTL_NINTENDO_SEED_WEPKEY
1043typedef struct _NINTENDO_SEED_WEPKEY
1044{
1045 UCHAR seed[NINTENDO_SSID_NICKNAME_LN];
1046 UCHAR wepkey[16];//use 13 for 104 bits wep key
1047} RT_NINTENDO_SEED_WEPKEY, *PRT_NINTENDO_SEED_WEPKEY;
1048#endif // NINTENDO_AP //
1049
1050#ifdef LLTD_SUPPORT
1051typedef struct _RT_LLTD_ASSOICATION_ENTRY {
1052 UCHAR Addr[ETH_LENGTH_OF_ADDRESS];
1053 unsigned short MOR; // maximum operational rate
1054 UCHAR phyMode;
1055} RT_LLTD_ASSOICATION_ENTRY, *PRT_LLTD_ASSOICATION_ENTRY;
1056
1057typedef struct _RT_LLTD_ASSOICATION_TABLE {
1058 unsigned int Num;
1059 RT_LLTD_ASSOICATION_ENTRY Entry[MAX_NUMBER_OF_MAC];
1060} RT_LLTD_ASSOICATION_TABLE, *PRT_LLTD_ASSOICATION_TABLE;
1061#endif // LLTD_SUPPORT //
1062
1063#ifdef CONFIG_STA_SUPPORT
1064#ifdef QOS_DLS_SUPPORT
1065//rt2860, kathy 2007-0118
1066// structure for DLS
1067typedef struct _RT_802_11_DLS_UI {
1068 USHORT TimeOut; // unit: second , set by UI
1069 USHORT CountDownTimer; // unit: second , used by driver only
1070 NDIS_802_11_MAC_ADDRESS MacAddr; // set by UI
1071 UCHAR Status; // 0: none , 1: wait STAkey, 2: finish DLS setup , set by driver only
1072 BOOLEAN Valid; // 1: valid , 0: invalid , set by UI, use to setup or tear down DLS link
1073} RT_802_11_DLS_UI, *PRT_802_11_DLS_UI;
1074
1075typedef struct _RT_802_11_DLS_INFO {
1076 RT_802_11_DLS_UI Entry[MAX_NUMBER_OF_DLS_ENTRY];
1077 UCHAR num;
1078} RT_802_11_DLS_INFO, *PRT_802_11_DLS_INFO;
1079
1080typedef enum _RT_802_11_DLS_MODE {
1081 DLS_NONE,
1082 DLS_WAIT_KEY,
1083 DLS_FINISH
1084} RT_802_11_DLS_MODE;
1085#endif // QOS_DLS_SUPPORT //
1086
1087#ifdef WPA_SUPPLICANT_SUPPORT
1088#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
1089#define RT_ASSOC_EVENT_FLAG 0x0101
1090#define RT_DISASSOC_EVENT_FLAG 0x0102
1091#define RT_REQIE_EVENT_FLAG 0x0103
1092#define RT_RESPIE_EVENT_FLAG 0x0104
1093#define RT_ASSOCINFO_EVENT_FLAG 0x0105
1094#define RT_PMKIDCAND_FLAG 0x0106
1095#define RT_INTERFACE_DOWN 0x0107
1096#define RT_INTERFACE_UP 0x0108
1097#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1098#endif // WPA_SUPPLICANT_SUPPORT //
1099#endif // CONFIG_STA_SUPPORT //
1100
1101
1102#define MAX_CUSTOM_LEN 128
1103
1104#ifdef CONFIG_STA_SUPPORT
1105typedef enum _RT_802_11_D_CLIENT_MODE
1106{
1107 Rt802_11_D_None,
1108 Rt802_11_D_Flexible,
1109 Rt802_11_D_Strict,
1110} RT_802_11_D_CLIENT_MODE, *PRT_802_11_D_CLIENT_MODE;
1111#endif // CONFIG_STA_SUPPORT //
1112
1113typedef struct _RT_CHANNEL_LIST_INFO
1114{
1115 UCHAR ChannelList[MAX_NUM_OF_CHS]; // list all supported channels for site survey
1116 UCHAR ChannelListNum; // number of channel in ChannelList[]
1117} RT_CHANNEL_LIST_INFO, *PRT_CHANNEL_LIST_INFO;
1118
1119// WSC configured credential
1120typedef struct _WSC_CREDENTIAL
1121{
1122 NDIS_802_11_SSID SSID; // mandatory
1123 USHORT AuthType; // mandatory, 1: open, 2: wpa-psk, 4: shared, 8:wpa, 0x10: wpa2, 0x20: wpa2-psk
1124 USHORT EncrType; // mandatory, 1: none, 2: wep, 4: tkip, 8: aes
1125 UCHAR Key[64]; // mandatory, Maximum 64 byte
1126 USHORT KeyLength;
1127 UCHAR MacAddr[6]; // mandatory, AP MAC address
1128 UCHAR KeyIndex; // optional, default is 1
1129 UCHAR Rsvd[3]; // Make alignment
1130} WSC_CREDENTIAL, *PWSC_CREDENTIAL;
1131
1132// WSC configured profiles
1133typedef struct _WSC_PROFILE
1134{
1135 UINT ProfileCnt;
1136 WSC_CREDENTIAL Profile[8]; // Support up to 8 profiles
1137} WSC_PROFILE, *PWSC_PROFILE;
1138
1139
1140
1141#endif // _OID_H_
1142
diff --git a/drivers/staging/rt3070/rt2870.h b/drivers/staging/rt3070/rt2870.h
new file mode 100644
index 000000000000..d32a2bf1d040
--- /dev/null
+++ b/drivers/staging/rt3070/rt2870.h
@@ -0,0 +1,756 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26 */
27
28#ifndef __RT2870_H__
29#define __RT2870_H__
30
31//usb header files
32#include <linux/usb.h>
33
34/* rtmp_def.h */
35//
36#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
37#define BULKAGGRE_ZISE 100
38#define RT28XX_DRVDATA_SET(_a) usb_set_intfdata(_a, pAd);
39#define RT28XX_PUT_DEVICE usb_put_dev
40#define RTUSB_ALLOC_URB(iso) usb_alloc_urb(iso, GFP_ATOMIC)
41#define RTUSB_SUBMIT_URB(pUrb) usb_submit_urb(pUrb, GFP_ATOMIC)
42#define RTUSB_URB_ALLOC_BUFFER(pUsb_Dev, BufSize, pDma_addr) usb_buffer_alloc(pUsb_Dev, BufSize, GFP_ATOMIC, pDma_addr)
43#define RTUSB_URB_FREE_BUFFER(pUsb_Dev, BufSize, pTransferBuf, Dma_addr) usb_buffer_free(pUsb_Dev, BufSize, pTransferBuf, Dma_addr)
44#else
45#define BULKAGGRE_ZISE 60
46#define RT28XX_DRVDATA_SET(_a)
47#define RT28XX_PUT_DEVICE(dev_p)
48#define RTUSB_ALLOC_URB(iso) usb_alloc_urb(iso)
49#define RTUSB_SUBMIT_URB(pUrb) usb_submit_urb(pUrb)
50#define RTUSB_URB_ALLOC_BUFFER(pUsb_Dev, BufSize, pDma_addr) kmalloc(BufSize, GFP_ATOMIC)
51#define RTUSB_URB_FREE_BUFFER(pUsb_Dev, BufSize, pTransferBuf, Dma_addr) kfree(pTransferBuf)
52#endif
53
54#define RXBULKAGGRE_ZISE 12
55#define MAX_TXBULK_LIMIT (LOCAL_TXBUF_SIZE*(BULKAGGRE_ZISE-1))
56#define MAX_TXBULK_SIZE (LOCAL_TXBUF_SIZE*BULKAGGRE_ZISE)
57#define MAX_RXBULK_SIZE (LOCAL_TXBUF_SIZE*RXBULKAGGRE_ZISE)
58#define MAX_MLME_HANDLER_MEMORY 20
59#define BUFFER_SIZE 2400 //2048
60#define TX_RING 0xa
61#define PRIO_RING 0xc
62
63
64// Flags for Bulkflags control for bulk out data
65//
66#define fRTUSB_BULK_OUT_DATA_NULL 0x00000001
67#define fRTUSB_BULK_OUT_RTS 0x00000002
68#define fRTUSB_BULK_OUT_MLME 0x00000004
69
70#define fRTUSB_BULK_OUT_DATA_NORMAL 0x00010000
71#define fRTUSB_BULK_OUT_DATA_NORMAL_2 0x00020000
72#define fRTUSB_BULK_OUT_DATA_NORMAL_3 0x00040000
73#define fRTUSB_BULK_OUT_DATA_NORMAL_4 0x00080000
74#define fRTUSB_BULK_OUT_DATA_NORMAL_5 0x00100000
75
76#define fRTUSB_BULK_OUT_PSPOLL 0x00000020
77#define fRTUSB_BULK_OUT_DATA_FRAG 0x00000040
78#define fRTUSB_BULK_OUT_DATA_FRAG_2 0x00000080
79#define fRTUSB_BULK_OUT_DATA_FRAG_3 0x00000100
80#define fRTUSB_BULK_OUT_DATA_FRAG_4 0x00000200
81
82#ifdef RALINK_ATE
83#define fRTUSB_BULK_OUT_DATA_ATE 0x00100000
84#endif // RALINK_ATE //
85
86#define RT2870_USB_DEVICES \
87{ \
88 {USB_DEVICE(0x148F,0x2770)}, /* Ralink */ \
89 {USB_DEVICE(0x148F,0x2870)}, /* Ralink */ \
90 {USB_DEVICE(0x148F,0x3070)}, /* Ralink 3070 */ \
91 {USB_DEVICE(0x148F,0x3071)}, /* Ralink 3071 */ \
92 {USB_DEVICE(0x148F,0x3072)}, /* Ralink 3072 */ \
93 {USB_DEVICE(0x0B05,0x1731)}, /* Asus */ \
94 {USB_DEVICE(0x0B05,0x1732)}, /* Asus */ \
95 {USB_DEVICE(0x0B05,0x1742)}, /* Asus */ \
96 {USB_DEVICE(0x0DF6,0x0017)}, /* Sitecom */ \
97 {USB_DEVICE(0x0DF6,0x002B)}, /* Sitecom */ \
98 {USB_DEVICE(0x0DF6,0x002C)}, /* Sitecom */ \
99 {USB_DEVICE(0x0DF6,0x003E)}, /* Sitecom 3070 */ \
100 {USB_DEVICE(0x0DF6,0x002D)}, /* Sitecom */ \
101 {USB_DEVICE(0x0DF6,0x0039)}, /* Sitecom 2770 */ \
102 {USB_DEVICE(0x14B2,0x3C06)}, /* Conceptronic */ \
103 {USB_DEVICE(0x14B2,0x3C28)}, /* Conceptronic */ \
104 {USB_DEVICE(0x2019,0xED06)}, /* Planex Communications, Inc. */ \
105 {USB_DEVICE(0x2019,0xAB25)}, /* Planex Communications, Inc. RT3070 */ \
106 {USB_DEVICE(0x07D1,0x3C09)}, /* D-Link */ \
107 {USB_DEVICE(0x07D1,0x3C11)}, /* D-Link */ \
108 {USB_DEVICE(0x2001,0x3C09)}, /* D-Link */ \
109 {USB_DEVICE(0x2001,0x3C0A)}, /* D-Link 3072*/ \
110 {USB_DEVICE(0x14B2,0x3C07)}, /* AL */ \
111 {USB_DEVICE(0x14B2,0x3C12)}, /* AL 3070 */ \
112 {USB_DEVICE(0x050D,0x8053)}, /* Belkin */ \
113 {USB_DEVICE(0x14B2,0x3C23)}, /* Airlink */ \
114 {USB_DEVICE(0x14B2,0x3C27)}, /* Airlink */ \
115 {USB_DEVICE(0x07AA,0x002F)}, /* Corega */ \
116 {USB_DEVICE(0x07AA,0x003C)}, /* Corega */ \
117 {USB_DEVICE(0x07AA,0x003F)}, /* Corega */ \
118 {USB_DEVICE(0x18C5,0x0012)}, /* Corega 3070 */ \
119 {USB_DEVICE(0x1044,0x800B)}, /* Gigabyte */ \
120 {USB_DEVICE(0x1044,0x800D)}, /* Gigabyte GN-WB32L 3070 */ \
121 {USB_DEVICE(0x15A9,0x0006)}, /* Sparklan */ \
122 {USB_DEVICE(0x083A,0xB522)}, /* SMC */ \
123 {USB_DEVICE(0x083A,0xA618)}, /* SMC */ \
124 {USB_DEVICE(0x083A,0x8522)}, /* Arcadyan */ \
125 {USB_DEVICE(0x083A,0x7512)}, /* Arcadyan 2770 */ \
126 {USB_DEVICE(0x083A,0x7522)}, /* Arcadyan */ \
127 {USB_DEVICE(0x083A,0x7511)}, /* Arcadyan 3070 */ \
128 {USB_DEVICE(0x0CDE,0x0022)}, /* ZCOM */ \
129 {USB_DEVICE(0x0586,0x3416)}, /* Zyxel */ \
130 {USB_DEVICE(0x0CDE,0x0025)}, /* Zyxel */ \
131 {USB_DEVICE(0x1740,0x9701)}, /* EnGenius */ \
132 {USB_DEVICE(0x1740,0x9702)}, /* EnGenius */ \
133 {USB_DEVICE(0x1740,0x9703)}, /* EnGenius 3070 */ \
134 {USB_DEVICE(0x0471,0x200f)}, /* Philips */ \
135 {USB_DEVICE(0x14B2,0x3C25)}, /* Draytek */ \
136 {USB_DEVICE(0x13D3,0x3247)}, /* AzureWave */ \
137 {USB_DEVICE(0x13D3,0x3273)}, /* AzureWave 3070*/ \
138 {USB_DEVICE(0x083A,0x6618)}, /* Accton */ \
139 {USB_DEVICE(0x15c5,0x0008)}, /* Amit */ \
140 {USB_DEVICE(0x0E66,0x0001)}, /* Hawking */ \
141 {USB_DEVICE(0x0E66,0x0003)}, /* Hawking */ \
142 {USB_DEVICE(0x129B,0x1828)}, /* Siemens */ \
143 {USB_DEVICE(0x157E,0x300E)}, /* U-Media */ \
144 {USB_DEVICE(0x050d,0x805c)}, \
145 {USB_DEVICE(0x1482,0x3C09)}, /* Abocom*/ \
146 {USB_DEVICE(0x14B2,0x3C09)}, /* Alpha */ \
147 {USB_DEVICE(0x04E8,0x2018)}, /* samsung */ \
148 {USB_DEVICE(0x07B8,0x3070)}, /* AboCom 3070 */ \
149 {USB_DEVICE(0x07B8,0x3071)}, /* AboCom 3071 */ \
150 {USB_DEVICE(0x07B8,0x3072)}, /* Abocom 3072 */ \
151 {USB_DEVICE(0x7392,0x7711)}, /* Edimax 3070 */ \
152 {USB_DEVICE(0x5A57,0x0280)}, /* Zinwell */ \
153 {USB_DEVICE(0x5A57,0x0282)}, /* Zinwell */ \
154 {USB_DEVICE(0x1A32,0x0304)}, /* Quanta 3070 */ \
155 {USB_DEVICE(0x0789,0x0162)}, /* Logitec 2870 */ \
156 {USB_DEVICE(0x0789,0x0163)}, /* Logitec 2870 */ \
157 {USB_DEVICE(0x0789,0x0164)}, /* Logitec 2870 */ \
158 {USB_DEVICE(0x1EDA,0x2310)}, /* AirTies 3070 */ \
159 { }/* Terminating entry */ \
160}
161
162#define FREE_HTTX_RING(_p, _b, _t) \
163{ \
164 if ((_t)->ENextBulkOutPosition == (_t)->CurWritePosition) \
165 { \
166 (_t)->bRingEmpty = TRUE; \
167 } \
168 /*NdisInterlockedDecrement(&(_p)->TxCount); */\
169}
170
171//
172// RXINFO appends at the end of each rx packet.
173//
174#ifdef RT_BIG_ENDIAN
175typedef struct PACKED _RXINFO_STRUC {
176 UINT32 PlcpSignal:12;
177 UINT32 LastAMSDU:1;
178 UINT32 CipherAlg:1;
179 UINT32 PlcpRssil:1;
180 UINT32 Decrypted:1;
181 UINT32 AMPDU:1; // To be moved
182 UINT32 L2PAD:1;
183 UINT32 RSSI:1;
184 UINT32 HTC:1;
185 UINT32 AMSDU:1; // rx with 802.3 header, not 802.11 header.
186 UINT32 CipherErr:2; // 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid
187 UINT32 Crc:1; // 1: CRC error
188 UINT32 MyBss:1; // 1: this frame belongs to the same BSSID
189 UINT32 Bcast:1; // 1: this is a broadcast frame
190 UINT32 Mcast:1; // 1: this is a multicast frame
191 UINT32 U2M:1; // 1: this RX frame is unicast to me
192 UINT32 FRAG:1;
193 UINT32 NULLDATA:1;
194 UINT32 DATA:1;
195 UINT32 BA:1;
196} RXINFO_STRUC, *PRXINFO_STRUC, RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC;
197#else
198typedef struct PACKED _RXINFO_STRUC {
199 UINT32 BA:1;
200 UINT32 DATA:1;
201 UINT32 NULLDATA:1;
202 UINT32 FRAG:1;
203 UINT32 U2M:1; // 1: this RX frame is unicast to me
204 UINT32 Mcast:1; // 1: this is a multicast frame
205 UINT32 Bcast:1; // 1: this is a broadcast frame
206 UINT32 MyBss:1; // 1: this frame belongs to the same BSSID
207 UINT32 Crc:1; // 1: CRC error
208 UINT32 CipherErr:2; // 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid
209 UINT32 AMSDU:1; // rx with 802.3 header, not 802.11 header.
210 UINT32 HTC:1;
211 UINT32 RSSI:1;
212 UINT32 L2PAD:1;
213 UINT32 AMPDU:1; // To be moved
214 UINT32 Decrypted:1;
215 UINT32 PlcpRssil:1;
216 UINT32 CipherAlg:1;
217 UINT32 LastAMSDU:1;
218 UINT32 PlcpSignal:12;
219} RXINFO_STRUC, *PRXINFO_STRUC, RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC;
220#endif
221
222
223//
224// TXINFO
225//
226#ifdef RT_BIG_ENDIAN
227typedef struct _TXINFO_STRUC {
228 // Word 0
229 UINT32 USBDMATxburst:1;//used ONLY in USB bulk Aggre. Force USB DMA transmit frame from current selected endpoint
230 UINT32 USBDMANextVLD:1; //used ONLY in USB bulk Aggregation, NextValid
231 UINT32 rsv2:2; // Software use.
232 UINT32 SwUseLastRound:1; // Software use.
233 UINT32 QSEL:2; // select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA
234 UINT32 WIV:1; // Wireless Info Valid. 1 if Driver already fill WI, o if DMA needs to copy WI to correctposition
235 UINT32 rsv:8;
236 UINT32 USBDMATxPktLen:16; //used ONLY in USB bulk Aggregation, Total byte counts of all sub-frame.
237} TXINFO_STRUC, *PTXINFO_STRUC;
238#else
239typedef struct _TXINFO_STRUC {
240 // Word 0
241 UINT32 USBDMATxPktLen:16; //used ONLY in USB bulk Aggregation, Total byte counts of all sub-frame.
242 UINT32 rsv:8;
243 UINT32 WIV:1; // Wireless Info Valid. 1 if Driver already fill WI, o if DMA needs to copy WI to correctposition
244 UINT32 QSEL:2; // select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA
245 UINT32 SwUseLastRound:1; // Software use.
246 UINT32 rsv2:2; // Software use.
247 UINT32 USBDMANextVLD:1; //used ONLY in USB bulk Aggregation, NextValid
248 UINT32 USBDMATxburst:1;//used ONLY in USB bulk Aggre. Force USB DMA transmit frame from current selected endpoint
249} TXINFO_STRUC, *PTXINFO_STRUC;
250#endif
251
252#define TXINFO_SIZE 4
253#define RXINFO_SIZE 4
254#define TXPADDING_SIZE 11
255
256//
257// Management ring buffer format
258//
259typedef struct _MGMT_STRUC {
260 BOOLEAN Valid;
261 PUCHAR pBuffer;
262 ULONG Length;
263} MGMT_STRUC, *PMGMT_STRUC;
264
265
266/* ----------------- EEPROM Related MACRO ----------------- */
267#ifdef RT30xx
268#define RT28xx_EEPROM_READ16(pAd, offset, var) \
269 do { \
270 RTUSBReadEEPROM(pAd, offset, (PUCHAR)&(var), 2); \
271 if(!pAd->bUseEfuse) \
272 var = le2cpu16(var); \
273 }while(0)
274
275#define RT28xx_EEPROM_WRITE16(pAd, offset, var) \
276 do{ \
277 USHORT _tmpVar=var; \
278 if(!pAd->bUseEfuse) \
279 _tmpVar = cpu2le16(var); \
280 RTUSBWriteEEPROM(pAd, offset, (PUCHAR)&(_tmpVar), 2); \
281 }while(0)
282#endif // RT30xx //
283#ifndef RT30xx
284#define RT28xx_EEPROM_READ16(pAd, offset, var) \
285 do { \
286 RTUSBReadEEPROM(pAd, offset, (PUCHAR)&(var), 2); \
287 var = le2cpu16(var); \
288 }while(0)
289
290#define RT28xx_EEPROM_WRITE16(pAd, offset, var) \
291 do{ \
292 USHORT _tmpVar=var; \
293 _tmpVar = cpu2le16(var); \
294 RTUSBWriteEEPROM(pAd, offset, (PUCHAR)&(_tmpVar), 2); \
295 }while(0)
296#endif // RT30xx //
297
298/* ----------------- TASK/THREAD Related MACRO ----------------- */
299#define RT28XX_TASK_THREAD_INIT(pAd, Status) \
300 Status = CreateThreads(net_dev);
301
302
303/* ----------------- Frimware Related MACRO ----------------- */
304#define RT28XX_WRITE_FIRMWARE(_pAd, _pFwImage, _FwLen) \
305 RTUSBFirmwareWrite(_pAd, _pFwImage, _FwLen)
306
307/* ----------------- TX Related MACRO ----------------- */
308#define RT28XX_START_DEQUEUE(pAd, QueIdx, irqFlags) \
309 { \
310 RTMP_IRQ_LOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \
311 if (pAd->DeQueueRunning[QueIdx]) \
312 { \
313 RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);\
314 printk("DeQueueRunning[%d]= TRUE!\n", QueIdx); \
315 continue; \
316 } \
317 else \
318 { \
319 pAd->DeQueueRunning[QueIdx] = TRUE; \
320 RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);\
321 } \
322 }
323#define RT28XX_STOP_DEQUEUE(pAd, QueIdx, irqFlags) \
324 do{ \
325 RTMP_IRQ_LOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \
326 pAd->DeQueueRunning[QueIdx] = FALSE; \
327 RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \
328 }while(0)
329
330
331#define RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, freeNum, pPacket) \
332 (RTUSBFreeDescriptorRequest(pAd, pTxBlk->QueIdx, (pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket))) == NDIS_STATUS_SUCCESS)
333
334#define RT28XX_RELEASE_DESC_RESOURCE(pAd, QueIdx) \
335 do{}while(0)
336
337#define NEED_QUEUE_BACK_FOR_AGG(_pAd, _QueIdx, _freeNum, _TxFrameType) \
338 ((_TxFrameType == TX_RALINK_FRAME) && (RTUSBNeedQueueBackForAgg(_pAd, _QueIdx)))
339
340
341
342#define fRTMP_ADAPTER_NEED_STOP_TX \
343 (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
344 fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_BULKOUT_RESET | \
345 fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_REMOVE_IN_PROGRESS)
346
347
348#define HAL_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) \
349 RtmpUSB_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)
350
351#define HAL_WriteTxResource(pAd, pTxBlk,bIsLast, pFreeNumber) \
352 RtmpUSB_WriteSingleTxResource(pAd, pTxBlk,bIsLast, pFreeNumber)
353
354#define HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) \
355 RtmpUSB_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber)
356
357#define HAL_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber) \
358 RtmpUSB_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber)
359
360#define HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, TxIdx) \
361 RtmpUSB_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, TxIdx)
362
363#define HAL_LastTxIdx(pAd, QueIdx,TxIdx) \
364 /*RtmpUSBDataLastTxIdx(pAd, QueIdx,TxIdx)*/
365
366#define HAL_KickOutTx(pAd, pTxBlk, QueIdx) \
367 RtmpUSBDataKickOut(pAd, pTxBlk, QueIdx)
368
369
370#define HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen) \
371 RtmpUSBMgmtKickOut(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen)
372
373#define HAL_KickOutNullFrameTx(_pAd, _QueIdx, _pNullFrame, _frameLen) \
374 RtmpUSBNullFrameKickOut(_pAd, _QueIdx, _pNullFrame, _frameLen)
375
376#define RTMP_PKT_TAIL_PADDING 11 // 3(max 4 byte padding) + 4 (last packet padding) + 4 (MaxBulkOutsize align padding)
377
378extern UCHAR EpToQueue[6];
379
380
381#ifdef RT2870
382#define GET_TXRING_FREENO(_pAd, _QueIdx) (_QueIdx) //(_pAd->TxRing[_QueIdx].TxSwFreeIdx)
383#define GET_MGMTRING_FREENO(_pAd) (_pAd->MgmtRing.TxSwFreeIdx)
384#endif // RT2870 //
385
386
387/* ----------------- RX Related MACRO ----------------- */
388//#define RT28XX_RX_ERROR_CHECK RTMPCheckRxWI
389
390#define RT28XX_RV_ALL_BUF_END(bBulkReceive) \
391 /* We return STATUS_MORE_PROCESSING_REQUIRED so that the completion */ \
392 /* routine (IofCompleteRequest) will stop working on the irp. */ \
393 if (bBulkReceive == TRUE) RTUSBBulkReceive(pAd);
394
395
396/* ----------------- ASIC Related MACRO ----------------- */
397// reset MAC of a station entry to 0xFFFFFFFFFFFF
398#define RT28XX_STA_ENTRY_MAC_RESET(pAd, Wcid) \
399 { RT_SET_ASIC_WCID SetAsicWcid; \
400 SetAsicWcid.WCID = Wcid; \
401 SetAsicWcid.SetTid = 0xffffffff; \
402 SetAsicWcid.DeleteTid = 0xffffffff; \
403 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_ASIC_WCID, \
404 &SetAsicWcid, sizeof(RT_SET_ASIC_WCID)); }
405
406// add this entry into ASIC RX WCID search table
407#define RT28XX_STA_ENTRY_ADD(pAd, pEntry) \
408 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_CLIENT_MAC_ENTRY, \
409 pEntry, sizeof(MAC_TABLE_ENTRY));
410
411// add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
412// Set MAC register value according operation mode
413#define RT28XX_UPDATE_PROTECT(pAd) \
414 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_UPDATE_PROTECT, NULL, 0);
415// end johnli
416
417// remove Pair-wise key material from ASIC
418// yet implement
419#define RT28XX_STA_ENTRY_KEY_DEL(pAd, BssIdx, Wcid)
420
421// add Client security information into ASIC WCID table and IVEIV table
422#define RT28XX_STA_SECURITY_INFO_ADD(pAd, apidx, KeyID, pEntry) \
423 { RT28XX_STA_ENTRY_MAC_RESET(pAd, pEntry->Aid); \
424 if (pEntry->Aid >= 1) { \
425 RT_SET_ASIC_WCID_ATTRI SetAsicWcidAttri; \
426 SetAsicWcidAttri.WCID = pEntry->Aid; \
427 if ((pEntry->AuthMode <= Ndis802_11AuthModeAutoSwitch) && \
428 (pEntry->WepStatus == Ndis802_11Encryption1Enabled)) \
429 { \
430 SetAsicWcidAttri.Cipher = pAd->SharedKey[apidx][KeyID].CipherAlg; \
431 } \
432 else if (pEntry->AuthMode == Ndis802_11AuthModeWPANone) \
433 { \
434 SetAsicWcidAttri.Cipher = pAd->SharedKey[apidx][KeyID].CipherAlg; \
435 } \
436 else SetAsicWcidAttri.Cipher = 0; \
437 DBGPRINT(RT_DEBUG_TRACE, ("aid cipher = %ld\n",SetAsicWcidAttri.Cipher)); \
438 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_ASIC_WCID_CIPHER, \
439 &SetAsicWcidAttri, sizeof(RT_SET_ASIC_WCID_ATTRI)); } }
440
441// Insert the BA bitmap to ASIC for the Wcid entry
442#define RT28XX_ADD_BA_SESSION_TO_ASIC(_pAd, _Aid, _TID) \
443 do{ \
444 RT_SET_ASIC_WCID SetAsicWcid; \
445 SetAsicWcid.WCID = (_Aid); \
446 SetAsicWcid.SetTid = (0x10000<<(_TID)); \
447 SetAsicWcid.DeleteTid = 0xffffffff; \
448 RTUSBEnqueueInternalCmd((_pAd), CMDTHREAD_SET_ASIC_WCID, &SetAsicWcid, sizeof(RT_SET_ASIC_WCID)); \
449 }while(0)
450
451// Remove the BA bitmap from ASIC for the Wcid entry
452#define RT28XX_DEL_BA_SESSION_FROM_ASIC(_pAd, _Wcid, _TID) \
453 do{ \
454 RT_SET_ASIC_WCID SetAsicWcid; \
455 SetAsicWcid.WCID = (_Wcid); \
456 SetAsicWcid.SetTid = (0xffffffff); \
457 SetAsicWcid.DeleteTid = (0x10000<<(_TID) ); \
458 RTUSBEnqueueInternalCmd((_pAd), CMDTHREAD_SET_ASIC_WCID, &SetAsicWcid, sizeof(RT_SET_ASIC_WCID)); \
459 }while(0)
460
461
462/* ----------------- PCI/USB Related MACRO ----------------- */
463#define RT28XX_HANDLE_DEV_ASSIGN(handle, dev_p) \
464 ((POS_COOKIE)handle)->pUsb_Dev = dev_p;
465
466// no use
467#define RT28XX_UNMAP()
468#define RT28XX_IRQ_REQUEST(net_dev)
469#define RT28XX_IRQ_RELEASE(net_dev)
470#define RT28XX_IRQ_INIT(pAd)
471#define RT28XX_IRQ_ENABLE(pAd)
472
473
474/* ----------------- MLME Related MACRO ----------------- */
475#define RT28XX_MLME_HANDLER(pAd) RTUSBMlmeUp(pAd)
476
477#define RT28XX_MLME_PRE_SANITY_CHECK(pAd) \
478 { if ((pAd->CommonCfg.bHardwareRadio == TRUE) && \
479 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && \
480 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))) { \
481 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_CHECK_GPIO, NULL, 0); } }
482
483#define RT28XX_MLME_STA_QUICK_RSP_WAKE_UP(pAd) \
484 { RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_QKERIODIC_EXECUT, NULL, 0); \
485 RTUSBMlmeUp(pAd); }
486
487#define RT28XX_MLME_RESET_STATE_MACHINE(pAd) \
488 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_RESET_CONF, 0, NULL); \
489 RTUSBMlmeUp(pAd);
490
491#define RT28XX_HANDLE_COUNTER_MEASURE(_pAd, _pEntry) \
492 { RTUSBEnqueueInternalCmd(_pAd, CMDTHREAD_802_11_COUNTER_MEASURE, _pEntry, sizeof(MAC_TABLE_ENTRY)); \
493 RTUSBMlmeUp(_pAd); \
494 }
495
496
497/* ----------------- Power Save Related MACRO ----------------- */
498#define RT28XX_PS_POLL_ENQUEUE(pAd) \
499 { RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL); \
500 RTUSBKickBulkOut(pAd); }
501
502#define RT28xx_CHIP_NAME "RT2870"
503#define USB_CYC_CFG 0x02a4
504#define NT_SUCCESS(status) (((status) > 0) ? (1):(0))
505#define InterlockedIncrement atomic_inc
506#define NdisInterlockedIncrement atomic_inc
507#define InterlockedDecrement atomic_dec
508#define NdisInterlockedDecrement atomic_dec
509#define InterlockedExchange atomic_set
510//#define NdisMSendComplete RTMP_SendComplete
511#define NdisMCancelTimer RTMPCancelTimer
512#define NdisAllocMemory(_ptr, _size, _flag) \
513 do{_ptr = kmalloc((_size),(_flag));}while(0)
514#define NdisFreeMemory(a, b, c) kfree((a))
515#define NdisMSleep RTMPusecDelay /* unit: microsecond */
516
517
518#define USBD_TRANSFER_DIRECTION_OUT 0
519#define USBD_TRANSFER_DIRECTION_IN 0
520#define USBD_SHORT_TRANSFER_OK 0
521#define PURB purbb_t
522
523#define RTUSB_FREE_URB(pUrb) usb_free_urb(pUrb)
524
525//#undef MlmeAllocateMemory
526//#undef MlmeFreeMemory
527
528typedef struct usb_device * PUSB_DEV;
529
530/* MACRO for linux usb */
531typedef struct urb *purbb_t;
532typedef struct usb_ctrlrequest devctrlrequest;
533#define PIRP PVOID
534#define PMDL PVOID
535#define NDIS_OID UINT
536#ifndef USB_ST_NOERROR
537#define USB_ST_NOERROR 0
538#endif
539
540// vendor-specific control operations
541#define CONTROL_TIMEOUT_JIFFIES ( (100 * HZ) / 1000)
542#define UNLINK_TIMEOUT_MS 3
543
544/* unlink urb */
545#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,7)
546#define RTUSB_UNLINK_URB(pUrb) usb_kill_urb(pUrb)
547#else
548#define RTUSB_UNLINK_URB(pUrb) usb_unlink_urb(pUrb)
549#endif
550
551// Prototypes of completion funuc.
552#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
553#define RTUSBBulkOutDataPacketComplete(purb, pt_regs) RTUSBBulkOutDataPacketComplete(purb)
554#define RTUSBBulkOutMLMEPacketComplete(pUrb, pt_regs) RTUSBBulkOutMLMEPacketComplete(pUrb)
555#define RTUSBBulkOutNullFrameComplete(pUrb, pt_regs) RTUSBBulkOutNullFrameComplete(pUrb)
556#define RTUSBBulkOutRTSFrameComplete(pUrb, pt_regs) RTUSBBulkOutRTSFrameComplete(pUrb)
557#define RTUSBBulkOutPsPollComplete(pUrb, pt_regs) RTUSBBulkOutPsPollComplete(pUrb)
558#define RTUSBBulkRxComplete(pUrb, pt_regs) RTUSBBulkRxComplete(pUrb)
559#endif
560
561
562VOID RTUSBBulkOutDataPacketComplete(purbb_t purb, struct pt_regs *pt_regs);
563VOID RTUSBBulkOutMLMEPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs);
564VOID RTUSBBulkOutNullFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs);
565VOID RTUSBBulkOutRTSFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs);
566VOID RTUSBBulkOutPsPollComplete(purbb_t pUrb, struct pt_regs *pt_regs);
567VOID RTUSBBulkRxComplete(purbb_t pUrb, struct pt_regs *pt_regs);
568
569
570#define RTUSBMlmeUp(pAd) \
571{ \
572 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; \
573 if(pObj->MLMEThr_pid>0) \
574 up(&(pAd->mlme_semaphore)); \
575}
576
577#define RTUSBCMDUp(pAd) \
578{ \
579 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; \
580 if(pObj->RTUSBCmdThr_pid>0) \
581 up(&(pAd->RTUSBCmd_semaphore)); \
582}
583
584
585static inline NDIS_STATUS RTMPAllocateMemory(
586 OUT PVOID *ptr,
587 IN size_t size)
588{
589 *ptr = kmalloc(size, GFP_ATOMIC);
590 if(*ptr)
591 return NDIS_STATUS_SUCCESS;
592 else
593 return NDIS_STATUS_RESOURCES;
594}
595
596/* rtmp.h */
597#define BEACON_RING_SIZE 2
598#define DEVICE_VENDOR_REQUEST_OUT 0x40
599#define DEVICE_VENDOR_REQUEST_IN 0xc0
600#define INTERFACE_VENDOR_REQUEST_OUT 0x41
601#define INTERFACE_VENDOR_REQUEST_IN 0xc1
602#define MGMTPIPEIDX 0 // EP6 is highest priority
603
604#define BULKOUT_MGMT_RESET_FLAG 0x80
605
606#define RTUSB_SET_BULK_FLAG(_M, _F) ((_M)->BulkFlags |= (_F))
607#define RTUSB_CLEAR_BULK_FLAG(_M, _F) ((_M)->BulkFlags &= ~(_F))
608#define RTUSB_TEST_BULK_FLAG(_M, _F) (((_M)->BulkFlags & (_F)) != 0)
609
610#define EnqueueCmd(cmdq, cmdqelmt) \
611{ \
612 if (cmdq->size == 0) \
613 cmdq->head = cmdqelmt; \
614 else \
615 cmdq->tail->next = cmdqelmt; \
616 cmdq->tail = cmdqelmt; \
617 cmdqelmt->next = NULL; \
618 cmdq->size++; \
619}
620
621typedef struct _RT_SET_ASIC_WCID {
622 ULONG WCID; // mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based
623 ULONG SetTid; // time-based: seconds, packet-based: kilo-packets
624 ULONG DeleteTid; // time-based: seconds, packet-based: kilo-packets
625} RT_SET_ASIC_WCID,*PRT_SET_ASIC_WCID;
626
627typedef struct _RT_SET_ASIC_WCID_ATTRI {
628 ULONG WCID; // mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based
629 ULONG Cipher; // ASIC Cipher definition
630 UCHAR Addr[ETH_LENGTH_OF_ADDRESS];
631} RT_SET_ASIC_WCID_ATTRI,*PRT_SET_ASIC_WCID_ATTRI;
632
633typedef struct _MLME_MEMORY_STRUCT {
634 PVOID AllocVa; //Pointer to the base virtual address of the allocated memory
635 struct _MLME_MEMORY_STRUCT *Next; //Pointer to the next virtual address of the allocated memory
636} MLME_MEMORY_STRUCT, *PMLME_MEMORY_STRUCT;
637
638typedef struct _MLME_MEMORY_HANDLER {
639 BOOLEAN MemRunning; //The flag of the Mlme memory handler's status
640 UINT MemoryCount; //Total nonpaged system-space memory not size
641 UINT InUseCount; //Nonpaged system-space memory in used counts
642 UINT UnUseCount; //Nonpaged system-space memory available counts
643 INT PendingCount; //Nonpaged system-space memory for free counts
644 PMLME_MEMORY_STRUCT pInUseHead; //Pointer to the first nonpaed memory not used
645 PMLME_MEMORY_STRUCT pInUseTail; //Pointer to the last nonpaged memory not used
646 PMLME_MEMORY_STRUCT pUnUseHead; //Pointer to the first nonpaged memory in used
647 PMLME_MEMORY_STRUCT pUnUseTail; //Pointer to the last nonpaged memory in used
648 PULONG MemFreePending[MAX_MLME_HANDLER_MEMORY]; //an array to keep pending free-memory's pointer (32bits)
649} MLME_MEMORY_HANDLER, *PMLME_MEMORY_HANDLER;
650
651typedef struct _CmdQElmt {
652 UINT command;
653 PVOID buffer;
654 ULONG bufferlength;
655 BOOLEAN CmdFromNdis;
656 BOOLEAN SetOperation;
657 struct _CmdQElmt *next;
658} CmdQElmt, *PCmdQElmt;
659
660typedef struct _CmdQ {
661 UINT size;
662 CmdQElmt *head;
663 CmdQElmt *tail;
664 UINT32 CmdQState;
665}CmdQ, *PCmdQ;
666
667//
668// For WPA SUPPLICANT: WIRELESS EXT support wireless events: v14 or newer
669//
670#if WIRELESS_EXT >= 14
671//#define WPA_SUPPLICANT_SUPPORT 1
672#endif
673
674/* oid.h */
675// Cipher suite type for mixed mode group cipher, P802.11i-2004
676typedef enum _RT_802_11_CIPHER_SUITE_TYPE {
677 Cipher_Type_NONE,
678 Cipher_Type_WEP40,
679 Cipher_Type_TKIP,
680 Cipher_Type_RSVD,
681 Cipher_Type_CCMP,
682 Cipher_Type_WEP104
683} RT_802_11_CIPHER_SUITE_TYPE, *PRT_802_11_CIPHER_SUITE_TYPE;
684
685//CMDTHREAD_MULTI_READ_MAC
686//CMDTHREAD_MULTI_WRITE_MAC
687//CMDTHREAD_VENDOR_EEPROM_READ
688//CMDTHREAD_VENDOR_EEPROM_WRITE
689typedef struct _CMDHandler_TLV {
690 USHORT Offset;
691 USHORT Length;
692 UCHAR DataFirst;
693} CMDHandler_TLV, *PCMDHandler_TLV;
694
695// New for MeetingHouse Api support
696#define CMDTHREAD_VENDOR_RESET 0x0D730101 // cmd
697#define CMDTHREAD_VENDOR_UNPLUG 0x0D730102 // cmd
698#define CMDTHREAD_VENDOR_SWITCH_FUNCTION 0x0D730103 // cmd
699#define CMDTHREAD_MULTI_WRITE_MAC 0x0D730107 // cmd
700#define CMDTHREAD_MULTI_READ_MAC 0x0D730108 // cmd
701#define CMDTHREAD_VENDOR_EEPROM_WRITE 0x0D73010A // cmd
702#define CMDTHREAD_VENDOR_EEPROM_READ 0x0D73010B // cmd
703#define CMDTHREAD_VENDOR_ENTER_TESTMODE 0x0D73010C // cmd
704#define CMDTHREAD_VENDOR_EXIT_TESTMODE 0x0D73010D // cmd
705#define CMDTHREAD_VENDOR_WRITE_BBP 0x0D730119 // cmd
706#define CMDTHREAD_VENDOR_READ_BBP 0x0D730118 // cmd
707#define CMDTHREAD_VENDOR_WRITE_RF 0x0D73011A // cmd
708#define CMDTHREAD_VENDOR_FLIP_IQ 0x0D73011D // cmd
709#define CMDTHREAD_RESET_BULK_OUT 0x0D730210 // cmd
710#define CMDTHREAD_RESET_BULK_IN 0x0D730211 // cmd
711#define CMDTHREAD_SET_PSM_BIT_SAVE 0x0D730212 // cmd
712#define CMDTHREAD_SET_RADIO 0x0D730214 // cmd
713#define CMDTHREAD_UPDATE_TX_RATE 0x0D730216 // cmd
714#define CMDTHREAD_802_11_ADD_KEY_WEP 0x0D730218 // cmd
715#define CMDTHREAD_RESET_FROM_ERROR 0x0D73021A // cmd
716#define CMDTHREAD_LINK_DOWN 0x0D73021B // cmd
717#define CMDTHREAD_RESET_FROM_NDIS 0x0D73021C // cmd
718#define CMDTHREAD_CHECK_GPIO 0x0D730215 // cmd
719#define CMDTHREAD_FORCE_WAKE_UP 0x0D730222 // cmd
720#define CMDTHREAD_SET_BW 0x0D730225 // cmd
721#define CMDTHREAD_SET_ASIC_WCID 0x0D730226 // cmd
722#define CMDTHREAD_SET_ASIC_WCID_CIPHER 0x0D730227 // cmd
723#define CMDTHREAD_QKERIODIC_EXECUT 0x0D73023D // cmd
724#define RT_CMD_SET_KEY_TABLE 0x0D730228 // cmd
725#define RT_CMD_SET_RX_WCID_TABLE 0x0D730229 // cmd
726#define CMDTHREAD_SET_CLIENT_MAC_ENTRY 0x0D73023E // cmd
727#define CMDTHREAD_802_11_QUERY_HARDWARE_REGISTER 0x0D710105 // cmd
728#define CMDTHREAD_802_11_SET_PHY_MODE 0x0D79010C // cmd
729#define CMDTHREAD_802_11_SET_STA_CONFIG 0x0D790111 // cmd
730#define CMDTHREAD_802_11_SET_PREAMBLE 0x0D790101 // cmd
731#define CMDTHREAD_802_11_COUNTER_MEASURE 0x0D790102 // cmd
732// add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
733#define CMDTHREAD_UPDATE_PROTECT 0x0D790103 // cmd
734// end johnli
735
736#define WPA1AKMBIT 0x01
737#define WPA2AKMBIT 0x02
738#define WPA1PSKAKMBIT 0x04
739#define WPA2PSKAKMBIT 0x08
740#define TKIPBIT 0x01
741#define CCMPBIT 0x02
742
743
744#define RT28XX_STA_FORCE_WAKEUP(pAd, bFromTx) \
745 RT28xxUsbStaAsicForceWakeup(pAd, bFromTx);
746
747#define RT28XX_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp) \
748 RT28xxUsbStaAsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
749
750#define RT28XX_MLME_RADIO_ON(pAd) \
751 RT28xxUsbMlmeRadioOn(pAd);
752
753#define RT28XX_MLME_RADIO_OFF(pAd) \
754 RT28xxUsbMlmeRadioOFF(pAd);
755
756#endif //__RT2870_H__
diff --git a/drivers/staging/rt3070/rt28xx.h b/drivers/staging/rt3070/rt28xx.h
new file mode 100644
index 000000000000..b637c4ee6096
--- /dev/null
+++ b/drivers/staging/rt3070/rt28xx.h
@@ -0,0 +1,2725 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 rt28xx.h
29
30 Abstract:
31 RT28xx ASIC related definition & structures
32
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36 Jan Lee Jan-3-2006 created for RT2860c
37*/
38
39#ifndef __RT28XX_H__
40#define __RT28XX_H__
41
42
43//
44// PCI registers - base address 0x0000
45//
46#define PCI_CFG 0x0000
47#define PCI_EECTRL 0x0004
48#define PCI_MCUCTRL 0x0008
49
50#define OPT_14 0x114
51
52typedef int NTSTATUS;
53#define RETRY_LIMIT 10
54#define STATUS_SUCCESS 0x00
55#define STATUS_UNSUCCESSFUL 0x01
56
57//
58// SCH/DMA registers - base address 0x0200
59//
60// INT_SOURCE_CSR: Interrupt source register. Write one to clear corresponding bit
61//
62#define DMA_CSR0 0x200
63#define INT_SOURCE_CSR 0x200
64#ifdef RT_BIG_ENDIAN
65typedef union _INT_SOURCE_CSR_STRUC {
66 struct {
67 UINT32 :14;
68 UINT32 TxCoherent:1;
69 UINT32 RxCoherent:1;
70 UINT32 GPTimer:1;
71 UINT32 AutoWakeup:1;//bit14
72 UINT32 TXFifoStatusInt:1;//FIFO Statistics is full, sw should read 0x171c
73 UINT32 PreTBTT:1;
74 UINT32 TBTTInt:1;
75 UINT32 RxTxCoherent:1;
76 UINT32 MCUCommandINT:1;
77 UINT32 MgmtDmaDone:1;
78 UINT32 HccaDmaDone:1;
79 UINT32 Ac3DmaDone:1;
80 UINT32 Ac2DmaDone:1;
81 UINT32 Ac1DmaDone:1;
82 UINT32 Ac0DmaDone:1;
83 UINT32 RxDone:1;
84 UINT32 TxDelayINT:1; //delayed interrupt, not interrupt until several int or time limit hit
85 UINT32 RxDelayINT:1; //dealyed interrupt
86 } field;
87 UINT32 word;
88} INT_SOURCE_CSR_STRUC, *PINT_SOURCE_CSR_STRUC;
89#else
90typedef union _INT_SOURCE_CSR_STRUC {
91 struct {
92 UINT32 RxDelayINT:1;
93 UINT32 TxDelayINT:1;
94 UINT32 RxDone:1;
95 UINT32 Ac0DmaDone:1;//4
96 UINT32 Ac1DmaDone:1;
97 UINT32 Ac2DmaDone:1;
98 UINT32 Ac3DmaDone:1;
99 UINT32 HccaDmaDone:1; // bit7
100 UINT32 MgmtDmaDone:1;
101 UINT32 MCUCommandINT:1;//bit 9
102 UINT32 RxTxCoherent:1;
103 UINT32 TBTTInt:1;
104 UINT32 PreTBTT:1;
105 UINT32 TXFifoStatusInt:1;//FIFO Statistics is full, sw should read 0x171c
106 UINT32 AutoWakeup:1;//bit14
107 UINT32 GPTimer:1;
108 UINT32 RxCoherent:1;//bit16
109 UINT32 TxCoherent:1;
110 UINT32 :14;
111 } field;
112 UINT32 word;
113} INT_SOURCE_CSR_STRUC, *PINT_SOURCE_CSR_STRUC;
114#endif
115
116//
117// INT_MASK_CSR: Interrupt MASK register. 1: the interrupt is mask OFF
118//
119#define INT_MASK_CSR 0x204
120#ifdef RT_BIG_ENDIAN
121typedef union _INT_MASK_CSR_STRUC {
122 struct {
123 UINT32 TxCoherent:1;
124 UINT32 RxCoherent:1;
125 UINT32 :20;
126 UINT32 MCUCommandINT:1;
127 UINT32 MgmtDmaDone:1;
128 UINT32 HccaDmaDone:1;
129 UINT32 Ac3DmaDone:1;
130 UINT32 Ac2DmaDone:1;
131 UINT32 Ac1DmaDone:1;
132 UINT32 Ac0DmaDone:1;
133 UINT32 RxDone:1;
134 UINT32 TxDelay:1;
135 UINT32 RXDelay_INT_MSK:1;
136 } field;
137 UINT32 word;
138}INT_MASK_CSR_STRUC, *PINT_MASK_CSR_STRUC;
139#else
140typedef union _INT_MASK_CSR_STRUC {
141 struct {
142 UINT32 RXDelay_INT_MSK:1;
143 UINT32 TxDelay:1;
144 UINT32 RxDone:1;
145 UINT32 Ac0DmaDone:1;
146 UINT32 Ac1DmaDone:1;
147 UINT32 Ac2DmaDone:1;
148 UINT32 Ac3DmaDone:1;
149 UINT32 HccaDmaDone:1;
150 UINT32 MgmtDmaDone:1;
151 UINT32 MCUCommandINT:1;
152 UINT32 :20;
153 UINT32 RxCoherent:1;
154 UINT32 TxCoherent:1;
155 } field;
156 UINT32 word;
157} INT_MASK_CSR_STRUC, *PINT_MASK_CSR_STRUC;
158#endif
159#define WPDMA_GLO_CFG 0x208
160#ifdef RT_BIG_ENDIAN
161typedef union _WPDMA_GLO_CFG_STRUC {
162 struct {
163 UINT32 HDR_SEG_LEN:16;
164 UINT32 RXHdrScater:8;
165 UINT32 BigEndian:1;
166 UINT32 EnTXWriteBackDDONE:1;
167 UINT32 WPDMABurstSIZE:2;
168 UINT32 RxDMABusy:1;
169 UINT32 EnableRxDMA:1;
170 UINT32 TxDMABusy:1;
171 UINT32 EnableTxDMA:1;
172 } field;
173 UINT32 word;
174}WPDMA_GLO_CFG_STRUC, *PWPDMA_GLO_CFG_STRUC;
175#else
176typedef union _WPDMA_GLO_CFG_STRUC {
177 struct {
178 UINT32 EnableTxDMA:1;
179 UINT32 TxDMABusy:1;
180 UINT32 EnableRxDMA:1;
181 UINT32 RxDMABusy:1;
182 UINT32 WPDMABurstSIZE:2;
183 UINT32 EnTXWriteBackDDONE:1;
184 UINT32 BigEndian:1;
185 UINT32 RXHdrScater:8;
186 UINT32 HDR_SEG_LEN:16;
187 } field;
188 UINT32 word;
189} WPDMA_GLO_CFG_STRUC, *PWPDMA_GLO_CFG_STRUC;
190#endif
191#define WPDMA_RST_IDX 0x20c
192#ifdef RT_BIG_ENDIAN
193typedef union _WPDMA_RST_IDX_STRUC {
194 struct {
195 UINT32 :15;
196 UINT32 RST_DRX_IDX0:1;
197 UINT32 rsv:10;
198 UINT32 RST_DTX_IDX5:1;
199 UINT32 RST_DTX_IDX4:1;
200 UINT32 RST_DTX_IDX3:1;
201 UINT32 RST_DTX_IDX2:1;
202 UINT32 RST_DTX_IDX1:1;
203 UINT32 RST_DTX_IDX0:1;
204 } field;
205 UINT32 word;
206}WPDMA_RST_IDX_STRUC, *PWPDMA_RST_IDX_STRUC;
207#else
208typedef union _WPDMA_RST_IDX_STRUC {
209 struct {
210 UINT32 RST_DTX_IDX0:1;
211 UINT32 RST_DTX_IDX1:1;
212 UINT32 RST_DTX_IDX2:1;
213 UINT32 RST_DTX_IDX3:1;
214 UINT32 RST_DTX_IDX4:1;
215 UINT32 RST_DTX_IDX5:1;
216 UINT32 rsv:10;
217 UINT32 RST_DRX_IDX0:1;
218 UINT32 :15;
219 } field;
220 UINT32 word;
221} WPDMA_RST_IDX_STRUC, *PWPDMA_RST_IDX_STRUC;
222#endif
223#define DELAY_INT_CFG 0x0210
224#ifdef RT_BIG_ENDIAN
225typedef union _DELAY_INT_CFG_STRUC {
226 struct {
227 UINT32 TXDLY_INT_EN:1;
228 UINT32 TXMAX_PINT:7;
229 UINT32 TXMAX_PTIME:8;
230 UINT32 RXDLY_INT_EN:1;
231 UINT32 RXMAX_PINT:7;
232 UINT32 RXMAX_PTIME:8;
233 } field;
234 UINT32 word;
235}DELAY_INT_CFG_STRUC, *PDELAY_INT_CFG_STRUC;
236#else
237typedef union _DELAY_INT_CFG_STRUC {
238 struct {
239 UINT32 RXMAX_PTIME:8;
240 UINT32 RXMAX_PINT:7;
241 UINT32 RXDLY_INT_EN:1;
242 UINT32 TXMAX_PTIME:8;
243 UINT32 TXMAX_PINT:7;
244 UINT32 TXDLY_INT_EN:1;
245 } field;
246 UINT32 word;
247} DELAY_INT_CFG_STRUC, *PDELAY_INT_CFG_STRUC;
248#endif
249#define WMM_AIFSN_CFG 0x0214
250#ifdef RT_BIG_ENDIAN
251typedef union _AIFSN_CSR_STRUC {
252 struct {
253 UINT32 Rsv:16;
254 UINT32 Aifsn3:4; // for AC_VO
255 UINT32 Aifsn2:4; // for AC_VI
256 UINT32 Aifsn1:4; // for AC_BK
257 UINT32 Aifsn0:4; // for AC_BE
258 } field;
259 UINT32 word;
260} AIFSN_CSR_STRUC, *PAIFSN_CSR_STRUC;
261#else
262typedef union _AIFSN_CSR_STRUC {
263 struct {
264 UINT32 Aifsn0:4; // for AC_BE
265 UINT32 Aifsn1:4; // for AC_BK
266 UINT32 Aifsn2:4; // for AC_VI
267 UINT32 Aifsn3:4; // for AC_VO
268 UINT32 Rsv:16;
269 } field;
270 UINT32 word;
271} AIFSN_CSR_STRUC, *PAIFSN_CSR_STRUC;
272#endif
273//
274// CWMIN_CSR: CWmin for each EDCA AC
275//
276#define WMM_CWMIN_CFG 0x0218
277#ifdef RT_BIG_ENDIAN
278typedef union _CWMIN_CSR_STRUC {
279 struct {
280 UINT32 Rsv:16;
281 UINT32 Cwmin3:4; // for AC_VO
282 UINT32 Cwmin2:4; // for AC_VI
283 UINT32 Cwmin1:4; // for AC_BK
284 UINT32 Cwmin0:4; // for AC_BE
285 } field;
286 UINT32 word;
287} CWMIN_CSR_STRUC, *PCWMIN_CSR_STRUC;
288#else
289typedef union _CWMIN_CSR_STRUC {
290 struct {
291 UINT32 Cwmin0:4; // for AC_BE
292 UINT32 Cwmin1:4; // for AC_BK
293 UINT32 Cwmin2:4; // for AC_VI
294 UINT32 Cwmin3:4; // for AC_VO
295 UINT32 Rsv:16;
296 } field;
297 UINT32 word;
298} CWMIN_CSR_STRUC, *PCWMIN_CSR_STRUC;
299#endif
300
301//
302// CWMAX_CSR: CWmin for each EDCA AC
303//
304#define WMM_CWMAX_CFG 0x021c
305#ifdef RT_BIG_ENDIAN
306typedef union _CWMAX_CSR_STRUC {
307 struct {
308 UINT32 Rsv:16;
309 UINT32 Cwmax3:4; // for AC_VO
310 UINT32 Cwmax2:4; // for AC_VI
311 UINT32 Cwmax1:4; // for AC_BK
312 UINT32 Cwmax0:4; // for AC_BE
313 } field;
314 UINT32 word;
315} CWMAX_CSR_STRUC, *PCWMAX_CSR_STRUC;
316#else
317typedef union _CWMAX_CSR_STRUC {
318 struct {
319 UINT32 Cwmax0:4; // for AC_BE
320 UINT32 Cwmax1:4; // for AC_BK
321 UINT32 Cwmax2:4; // for AC_VI
322 UINT32 Cwmax3:4; // for AC_VO
323 UINT32 Rsv:16;
324 } field;
325 UINT32 word;
326} CWMAX_CSR_STRUC, *PCWMAX_CSR_STRUC;
327#endif
328
329
330//
331// AC_TXOP_CSR0: AC_BK/AC_BE TXOP register
332//
333#define WMM_TXOP0_CFG 0x0220
334#ifdef RT_BIG_ENDIAN
335typedef union _AC_TXOP_CSR0_STRUC {
336 struct {
337 USHORT Ac1Txop; // for AC_BE, in unit of 32us
338 USHORT Ac0Txop; // for AC_BK, in unit of 32us
339 } field;
340 UINT32 word;
341} AC_TXOP_CSR0_STRUC, *PAC_TXOP_CSR0_STRUC;
342#else
343typedef union _AC_TXOP_CSR0_STRUC {
344 struct {
345 USHORT Ac0Txop; // for AC_BK, in unit of 32us
346 USHORT Ac1Txop; // for AC_BE, in unit of 32us
347 } field;
348 UINT32 word;
349} AC_TXOP_CSR0_STRUC, *PAC_TXOP_CSR0_STRUC;
350#endif
351
352//
353// AC_TXOP_CSR1: AC_VO/AC_VI TXOP register
354//
355#define WMM_TXOP1_CFG 0x0224
356#ifdef RT_BIG_ENDIAN
357typedef union _AC_TXOP_CSR1_STRUC {
358 struct {
359 USHORT Ac3Txop; // for AC_VO, in unit of 32us
360 USHORT Ac2Txop; // for AC_VI, in unit of 32us
361 } field;
362 UINT32 word;
363} AC_TXOP_CSR1_STRUC, *PAC_TXOP_CSR1_STRUC;
364#else
365typedef union _AC_TXOP_CSR1_STRUC {
366 struct {
367 USHORT Ac2Txop; // for AC_VI, in unit of 32us
368 USHORT Ac3Txop; // for AC_VO, in unit of 32us
369 } field;
370 UINT32 word;
371} AC_TXOP_CSR1_STRUC, *PAC_TXOP_CSR1_STRUC;
372#endif
373#define RINGREG_DIFF 0x10
374#define GPIO_CTRL_CFG 0x0228 //MAC_CSR13
375#define MCU_CMD_CFG 0x022c
376#define TX_BASE_PTR0 0x0230 //AC_BK base address
377#define TX_MAX_CNT0 0x0234
378#define TX_CTX_IDX0 0x0238
379#define TX_DTX_IDX0 0x023c
380#define TX_BASE_PTR1 0x0240 //AC_BE base address
381#define TX_MAX_CNT1 0x0244
382#define TX_CTX_IDX1 0x0248
383#define TX_DTX_IDX1 0x024c
384#define TX_BASE_PTR2 0x0250 //AC_VI base address
385#define TX_MAX_CNT2 0x0254
386#define TX_CTX_IDX2 0x0258
387#define TX_DTX_IDX2 0x025c
388#define TX_BASE_PTR3 0x0260 //AC_VO base address
389#define TX_MAX_CNT3 0x0264
390#define TX_CTX_IDX3 0x0268
391#define TX_DTX_IDX3 0x026c
392#define TX_BASE_PTR4 0x0270 //HCCA base address
393#define TX_MAX_CNT4 0x0274
394#define TX_CTX_IDX4 0x0278
395#define TX_DTX_IDX4 0x027c
396#define TX_BASE_PTR5 0x0280 //MGMT base address
397#define TX_MAX_CNT5 0x0284
398#define TX_CTX_IDX5 0x0288
399#define TX_DTX_IDX5 0x028c
400#define TX_MGMTMAX_CNT TX_MAX_CNT5
401#define TX_MGMTCTX_IDX TX_CTX_IDX5
402#define TX_MGMTDTX_IDX TX_DTX_IDX5
403#define RX_BASE_PTR 0x0290 //RX base address
404#define RX_MAX_CNT 0x0294
405#define RX_CRX_IDX 0x0298
406#define RX_DRX_IDX 0x029c
407#define USB_DMA_CFG 0x02a0
408#ifdef RT_BIG_ENDIAN
409typedef union _USB_DMA_CFG_STRUC {
410 struct {
411 UINT32 TxBusy:1; //USB DMA TX FSM busy . debug only
412 UINT32 RxBusy:1; //USB DMA RX FSM busy . debug only
413 UINT32 EpoutValid:6; //OUT endpoint data valid. debug only
414 UINT32 TxBulkEn:1; //Enable USB DMA Tx
415 UINT32 RxBulkEn:1; //Enable USB DMA Rx
416 UINT32 RxBulkAggEn:1; //Enable Rx Bulk Aggregation
417 UINT32 TxopHalt:1; //Halt TXOP count down when TX buffer is full.
418 UINT32 TxClear:1; //Clear USB DMA TX path
419 UINT32 rsv:2;
420 UINT32 phyclear:1; //phy watch dog enable. write 1
421 UINT32 RxBulkAggLmt:8; //Rx Bulk Aggregation Limit in unit of 1024 bytes
422 UINT32 RxBulkAggTOut:8; //Rx Bulk Aggregation TimeOut in unit of 33ns
423 } field;
424 UINT32 word;
425} USB_DMA_CFG_STRUC, *PUSB_DMA_CFG_STRUC;
426#else
427typedef union _USB_DMA_CFG_STRUC {
428 struct {
429 UINT32 RxBulkAggTOut:8; //Rx Bulk Aggregation TimeOut in unit of 33ns
430 UINT32 RxBulkAggLmt:8; //Rx Bulk Aggregation Limit in unit of 256 bytes
431 UINT32 phyclear:1; //phy watch dog enable. write 1
432 UINT32 rsv:2;
433 UINT32 TxClear:1; //Clear USB DMA TX path
434 UINT32 TxopHalt:1; //Halt TXOP count down when TX buffer is full.
435 UINT32 RxBulkAggEn:1; //Enable Rx Bulk Aggregation
436 UINT32 RxBulkEn:1; //Enable USB DMA Rx
437 UINT32 TxBulkEn:1; //Enable USB DMA Tx
438 UINT32 EpoutValid:6; //OUT endpoint data valid
439 UINT32 RxBusy:1; //USB DMA RX FSM busy
440 UINT32 TxBusy:1; //USB DMA TX FSM busy
441 } field;
442 UINT32 word;
443} USB_DMA_CFG_STRUC, *PUSB_DMA_CFG_STRUC;
444#endif
445
446//
447// 3 PBF registers
448//
449//
450// Most are for debug. Driver doesn't touch PBF register.
451#define PBF_SYS_CTRL 0x0400
452#define PBF_CFG 0x0408
453#define PBF_MAX_PCNT 0x040C
454#define PBF_CTRL 0x0410
455#define PBF_INT_STA 0x0414
456#define PBF_INT_ENA 0x0418
457#define TXRXQ_PCNT 0x0438
458#define PBF_DBG 0x043c
459#define PBF_CAP_CTRL 0x0440
460
461
462// eFuse registers
463#define EFUSE_CTRL 0x0580
464#define EFUSE_DATA0 0x0590
465#define EFUSE_DATA1 0x0594
466#define EFUSE_DATA2 0x0598
467#define EFUSE_DATA3 0x059c
468#define EFUSE_USAGE_MAP_START 0x2d0
469#define EFUSE_USAGE_MAP_END 0x2fc
470#define EFUSE_TAG 0x2fe
471#define EFUSE_USAGE_MAP_SIZE 45
472
473#ifdef RT_BIG_ENDIAN
474typedef union _EFUSE_CTRL_STRUC {
475 struct {
476 UINT32 SEL_EFUSE:1;
477 UINT32 EFSROM_KICK:1;
478 UINT32 RESERVED:4;
479 UINT32 EFSROM_AIN:10;
480 UINT32 EFSROM_LDO_ON_TIME:2;
481 UINT32 EFSROM_LDO_OFF_TIME:6;
482 UINT32 EFSROM_MODE:2;
483 UINT32 EFSROM_AOUT:6;
484 } field;
485 UINT32 word;
486} EFUSE_CTRL_STRUC, *PEFUSE_CTRL_STRUC;
487#else
488typedef union _EFUSE_CTRL_STRUC {
489 struct {
490 UINT32 EFSROM_AOUT:6;
491 UINT32 EFSROM_MODE:2;
492 UINT32 EFSROM_LDO_OFF_TIME:6;
493 UINT32 EFSROM_LDO_ON_TIME:2;
494 UINT32 EFSROM_AIN:10;
495 UINT32 RESERVED:4;
496 UINT32 EFSROM_KICK:1;
497 UINT32 SEL_EFUSE:1;
498 } field;
499 UINT32 word;
500} EFUSE_CTRL_STRUC, *PEFUSE_CTRL_STRUC;
501#endif // RT_BIG_ENDIAN //
502
503#define LDO_CFG0 0x05d4
504#define GPIO_SWITCH 0x05dc
505
506//
507// 4 MAC registers
508//
509//
510// 4.1 MAC SYSTEM configuration registers (offset:0x1000)
511//
512#define MAC_CSR0 0x1000
513#ifdef RT_BIG_ENDIAN
514typedef union _ASIC_VER_ID_STRUC {
515 struct {
516 USHORT ASICVer; // version : 2860
517 USHORT ASICRev; // reversion : 0
518 } field;
519 UINT32 word;
520} ASIC_VER_ID_STRUC, *PASIC_VER_ID_STRUC;
521#else
522typedef union _ASIC_VER_ID_STRUC {
523 struct {
524 USHORT ASICRev; // reversion : 0
525 USHORT ASICVer; // version : 2860
526 } field;
527 UINT32 word;
528} ASIC_VER_ID_STRUC, *PASIC_VER_ID_STRUC;
529#endif
530#define MAC_SYS_CTRL 0x1004 //MAC_CSR1
531#define MAC_ADDR_DW0 0x1008 // MAC ADDR DW0
532#define MAC_ADDR_DW1 0x100c // MAC ADDR DW1
533//
534// MAC_CSR2: STA MAC register 0
535//
536#ifdef RT_BIG_ENDIAN
537typedef union _MAC_DW0_STRUC {
538 struct {
539 UCHAR Byte3; // MAC address byte 3
540 UCHAR Byte2; // MAC address byte 2
541 UCHAR Byte1; // MAC address byte 1
542 UCHAR Byte0; // MAC address byte 0
543 } field;
544 UINT32 word;
545} MAC_DW0_STRUC, *PMAC_DW0_STRUC;
546#else
547typedef union _MAC_DW0_STRUC {
548 struct {
549 UCHAR Byte0; // MAC address byte 0
550 UCHAR Byte1; // MAC address byte 1
551 UCHAR Byte2; // MAC address byte 2
552 UCHAR Byte3; // MAC address byte 3
553 } field;
554 UINT32 word;
555} MAC_DW0_STRUC, *PMAC_DW0_STRUC;
556#endif
557
558//
559// MAC_CSR3: STA MAC register 1
560//
561#ifdef RT_BIG_ENDIAN
562typedef union _MAC_DW1_STRUC {
563 struct {
564 UCHAR Rsvd1;
565 UCHAR U2MeMask;
566 UCHAR Byte5; // MAC address byte 5
567 UCHAR Byte4; // MAC address byte 4
568 } field;
569 UINT32 word;
570} MAC_DW1_STRUC, *PMAC_DW1_STRUC;
571#else
572typedef union _MAC_DW1_STRUC {
573 struct {
574 UCHAR Byte4; // MAC address byte 4
575 UCHAR Byte5; // MAC address byte 5
576 UCHAR U2MeMask;
577 UCHAR Rsvd1;
578 } field;
579 UINT32 word;
580} MAC_DW1_STRUC, *PMAC_DW1_STRUC;
581#endif
582
583#define MAC_BSSID_DW0 0x1010 // MAC BSSID DW0
584#define MAC_BSSID_DW1 0x1014 // MAC BSSID DW1
585
586//
587// MAC_CSR5: BSSID register 1
588//
589#ifdef RT_BIG_ENDIAN
590typedef union _MAC_CSR5_STRUC {
591 struct {
592 USHORT Rsvd:11;
593 USHORT MBssBcnNum:3;
594 USHORT BssIdMode:2; // 0: one BSSID, 10: 4 BSSID, 01: 2 BSSID , 11: 8BSSID
595 UCHAR Byte5; // BSSID byte 5
596 UCHAR Byte4; // BSSID byte 4
597 } field;
598 UINT32 word;
599} MAC_CSR5_STRUC, *PMAC_CSR5_STRUC;
600#else
601typedef union _MAC_CSR5_STRUC {
602 struct {
603 UCHAR Byte4; // BSSID byte 4
604 UCHAR Byte5; // BSSID byte 5
605 USHORT BssIdMask:2; // 0: one BSSID, 10: 4 BSSID, 01: 2 BSSID , 11: 8BSSID
606 USHORT MBssBcnNum:3;
607 USHORT Rsvd:11;
608 } field;
609 UINT32 word;
610} MAC_CSR5_STRUC, *PMAC_CSR5_STRUC;
611#endif
612
613#define MAX_LEN_CFG 0x1018 // rt2860b max 16k bytes. bit12:13 Maximum PSDU length (power factor) 0:2^13, 1:2^14, 2:2^15, 3:2^16
614#define BBP_CSR_CFG 0x101c //
615//
616// BBP_CSR_CFG: BBP serial control register
617//
618#ifdef RT_BIG_ENDIAN
619typedef union _BBP_CSR_CFG_STRUC {
620 struct {
621 UINT32 :12;
622 UINT32 BBP_RW_MODE:1; // 0: use serial mode 1:parallel
623 UINT32 BBP_PAR_DUR:1; // 0: 4 MAC clock cycles 1: 8 MAC clock cycles
624 UINT32 Busy:1; // 1: ASIC is busy execute BBP programming.
625 UINT32 fRead:1; // 0: Write BBP, 1: Read BBP
626 UINT32 RegNum:8; // Selected BBP register
627 UINT32 Value:8; // Register value to program into BBP
628 } field;
629 UINT32 word;
630} BBP_CSR_CFG_STRUC, *PBBP_CSR_CFG_STRUC;
631#else
632typedef union _BBP_CSR_CFG_STRUC {
633 struct {
634 UINT32 Value:8; // Register value to program into BBP
635 UINT32 RegNum:8; // Selected BBP register
636 UINT32 fRead:1; // 0: Write BBP, 1: Read BBP
637 UINT32 Busy:1; // 1: ASIC is busy execute BBP programming.
638 UINT32 BBP_PAR_DUR:1; // 0: 4 MAC clock cycles 1: 8 MAC clock cycles
639 UINT32 BBP_RW_MODE:1; // 0: use serial mode 1:parallel
640 UINT32 :12;
641 } field;
642 UINT32 word;
643} BBP_CSR_CFG_STRUC, *PBBP_CSR_CFG_STRUC;
644#endif
645#define RF_CSR_CFG0 0x1020
646//
647// RF_CSR_CFG: RF control register
648//
649#ifdef RT_BIG_ENDIAN
650typedef union _RF_CSR_CFG0_STRUC {
651 struct {
652 UINT32 Busy:1; // 0: idle 1: 8busy
653 UINT32 Sel:1; // 0:RF_LE0 activate 1:RF_LE1 activate
654 UINT32 StandbyMode:1; // 0: high when stand by 1: low when standby
655 UINT32 bitwidth:5; // Selected BBP register
656 UINT32 RegIdAndContent:24; // Register value to program into BBP
657 } field;
658 UINT32 word;
659} RF_CSR_CFG0_STRUC, *PRF_CSR_CFG0_STRUC;
660#else
661typedef union _RF_CSR_CFG0_STRUC {
662 struct {
663 UINT32 RegIdAndContent:24; // Register value to program into BBP
664 UINT32 bitwidth:5; // Selected BBP register
665 UINT32 StandbyMode:1; // 0: high when stand by 1: low when standby
666 UINT32 Sel:1; // 0:RF_LE0 activate 1:RF_LE1 activate
667 UINT32 Busy:1; // 0: idle 1: 8busy
668 } field;
669 UINT32 word;
670} RF_CSR_CFG0_STRUC, *PRF_CSR_CFG0_STRUC;
671#endif
672#define RF_CSR_CFG1 0x1024
673#ifdef RT_BIG_ENDIAN
674typedef union _RF_CSR_CFG1_STRUC {
675 struct {
676 UINT32 rsv:7; // 0: idle 1: 8busy
677 UINT32 RFGap:5; // Gap between BB_CONTROL_RF and RF_LE. 0: 3 system clock cycle (37.5usec) 1: 5 system clock cycle (62.5usec)
678 UINT32 RegIdAndContent:24; // Register value to program into BBP
679 } field;
680 UINT32 word;
681} RF_CSR_CFG1_STRUC, *PRF_CSR_CFG1_STRUC;
682#else
683typedef union _RF_CSR_CFG1_STRUC {
684 struct {
685 UINT32 RegIdAndContent:24; // Register value to program into BBP
686 UINT32 RFGap:5; // Gap between BB_CONTROL_RF and RF_LE. 0: 3 system clock cycle (37.5usec) 1: 5 system clock cycle (62.5usec)
687 UINT32 rsv:7; // 0: idle 1: 8busy
688 } field;
689 UINT32 word;
690} RF_CSR_CFG1_STRUC, *PRF_CSR_CFG1_STRUC;
691#endif
692#define RF_CSR_CFG2 0x1028 //
693#ifdef RT_BIG_ENDIAN
694typedef union _RF_CSR_CFG2_STRUC {
695 struct {
696 UINT32 rsv:8; // 0: idle 1: 8busy
697 UINT32 RegIdAndContent:24; // Register value to program into BBP
698 } field;
699 UINT32 word;
700} RF_CSR_CFG2_STRUC, *PRF_CSR_CFG2_STRUC;
701#else
702typedef union _RF_CSR_CFG2_STRUC {
703 struct {
704 UINT32 RegIdAndContent:24; // Register value to program into BBP
705 UINT32 rsv:8; // 0: idle 1: 8busy
706 } field;
707 UINT32 word;
708} RF_CSR_CFG2_STRUC, *PRF_CSR_CFG2_STRUC;
709#endif
710#define LED_CFG 0x102c // MAC_CSR14
711#ifdef RT_BIG_ENDIAN
712typedef union _LED_CFG_STRUC {
713 struct {
714 UINT32 :1;
715 UINT32 LedPolar:1; // Led Polarity. 0: active low1: active high
716 UINT32 YLedMode:2; // yellow Led Mode
717 UINT32 GLedMode:2; // green Led Mode
718 UINT32 RLedMode:2; // red Led Mode 0: off1: blinking upon TX2: periodic slow blinking3: always on
719 UINT32 rsv:2;
720 UINT32 SlowBlinkPeriod:6; // slow blinking period. unit:1ms
721 UINT32 OffPeriod:8; // blinking off period unit 1ms
722 UINT32 OnPeriod:8; // blinking on period unit 1ms
723 } field;
724 UINT32 word;
725} LED_CFG_STRUC, *PLED_CFG_STRUC;
726#else
727typedef union _LED_CFG_STRUC {
728 struct {
729 UINT32 OnPeriod:8; // blinking on period unit 1ms
730 UINT32 OffPeriod:8; // blinking off period unit 1ms
731 UINT32 SlowBlinkPeriod:6; // slow blinking period. unit:1ms
732 UINT32 rsv:2;
733 UINT32 RLedMode:2; // red Led Mode 0: off1: blinking upon TX2: periodic slow blinking3: always on
734 UINT32 GLedMode:2; // green Led Mode
735 UINT32 YLedMode:2; // yellow Led Mode
736 UINT32 LedPolar:1; // Led Polarity. 0: active low1: active high
737 UINT32 :1;
738 } field;
739 UINT32 word;
740} LED_CFG_STRUC, *PLED_CFG_STRUC;
741#endif
742//
743// 4.2 MAC TIMING configuration registers (offset:0x1100)
744//
745#define XIFS_TIME_CFG 0x1100 // MAC_CSR8 MAC_CSR9
746#ifdef RT_BIG_ENDIAN
747typedef union _IFS_SLOT_CFG_STRUC {
748 struct {
749 UINT32 rsv:2;
750 UINT32 BBRxendEnable:1; // reference RXEND signal to begin XIFS defer
751 UINT32 EIFS:9; // unit 1us
752 UINT32 OfdmXifsTime:4; //OFDM SIFS. unit 1us. Applied after OFDM RX when MAC doesn't reference BBP signal BBRXEND
753 UINT32 OfdmSifsTime:8; // unit 1us. Applied after OFDM RX/TX
754 UINT32 CckmSifsTime:8; // unit 1us. Applied after CCK RX/TX
755 } field;
756 UINT32 word;
757} IFS_SLOT_CFG_STRUC, *PIFS_SLOT_CFG_STRUC;
758#else
759typedef union _IFS_SLOT_CFG_STRUC {
760 struct {
761 UINT32 CckmSifsTime:8; // unit 1us. Applied after CCK RX/TX
762 UINT32 OfdmSifsTime:8; // unit 1us. Applied after OFDM RX/TX
763 UINT32 OfdmXifsTime:4; //OFDM SIFS. unit 1us. Applied after OFDM RX when MAC doesn't reference BBP signal BBRXEND
764 UINT32 EIFS:9; // unit 1us
765 UINT32 BBRxendEnable:1; // reference RXEND signal to begin XIFS defer
766 UINT32 rsv:2;
767 } field;
768 UINT32 word;
769} IFS_SLOT_CFG_STRUC, *PIFS_SLOT_CFG_STRUC;
770#endif
771
772#define BKOFF_SLOT_CFG 0x1104 // mac_csr9 last 8 bits
773#define NAV_TIME_CFG 0x1108 // NAV (MAC_CSR15)
774#define CH_TIME_CFG 0x110C // Count as channel busy
775#define PBF_LIFE_TIMER 0x1110 //TX/RX MPDU timestamp timer (free run)Unit: 1us
776#define BCN_TIME_CFG 0x1114 // TXRX_CSR9
777
778#define BCN_OFFSET0 0x042C
779#define BCN_OFFSET1 0x0430
780
781//
782// BCN_TIME_CFG : Synchronization control register
783//
784#ifdef RT_BIG_ENDIAN
785typedef union _BCN_TIME_CFG_STRUC {
786 struct {
787 UINT32 TxTimestampCompensate:8;
788 UINT32 :3;
789 UINT32 bBeaconGen:1; // Enable beacon generator
790 UINT32 bTBTTEnable:1;
791 UINT32 TsfSyncMode:2; // Enable TSF sync, 00: disable, 01: infra mode, 10: ad-hoc mode
792 UINT32 bTsfTicking:1; // Enable TSF auto counting
793 UINT32 BeaconInterval:16; // in unit of 1/16 TU
794 } field;
795 UINT32 word;
796} BCN_TIME_CFG_STRUC, *PBCN_TIME_CFG_STRUC;
797#else
798typedef union _BCN_TIME_CFG_STRUC {
799 struct {
800 UINT32 BeaconInterval:16; // in unit of 1/16 TU
801 UINT32 bTsfTicking:1; // Enable TSF auto counting
802 UINT32 TsfSyncMode:2; // Enable TSF sync, 00: disable, 01: infra mode, 10: ad-hoc mode
803 UINT32 bTBTTEnable:1;
804 UINT32 bBeaconGen:1; // Enable beacon generator
805 UINT32 :3;
806 UINT32 TxTimestampCompensate:8;
807 } field;
808 UINT32 word;
809} BCN_TIME_CFG_STRUC, *PBCN_TIME_CFG_STRUC;
810#endif
811#define TBTT_SYNC_CFG 0x1118 // txrx_csr10
812#define TSF_TIMER_DW0 0x111C // Local TSF timer lsb 32 bits. Read-only
813#define TSF_TIMER_DW1 0x1120 // msb 32 bits. Read-only.
814#define TBTT_TIMER 0x1124 // TImer remains till next TBTT. Read-only. TXRX_CSR14
815#define INT_TIMER_CFG 0x1128 //
816#define INT_TIMER_EN 0x112c // GP-timer and pre-tbtt Int enable
817#define CH_IDLE_STA 0x1130 // channel idle time
818#define CH_BUSY_STA 0x1134 // channle busy time
819//
820// 4.2 MAC POWER configuration registers (offset:0x1200)
821//
822#define MAC_STATUS_CFG 0x1200 // old MAC_CSR12
823#define PWR_PIN_CFG 0x1204 // old MAC_CSR12
824#define AUTO_WAKEUP_CFG 0x1208 // old MAC_CSR10
825//
826// AUTO_WAKEUP_CFG: Manual power control / status register
827//
828#ifdef RT_BIG_ENDIAN
829typedef union _AUTO_WAKEUP_STRUC {
830 struct {
831 UINT32 :16;
832 UINT32 EnableAutoWakeup:1; // 0:sleep, 1:awake
833 UINT32 NumofSleepingTbtt:7; // ForceWake has high privilege than PutToSleep when both set
834 UINT32 AutoLeadTime:8;
835 } field;
836 UINT32 word;
837} AUTO_WAKEUP_STRUC, *PAUTO_WAKEUP_STRUC;
838#else
839typedef union _AUTO_WAKEUP_STRUC {
840 struct {
841 UINT32 AutoLeadTime:8;
842 UINT32 NumofSleepingTbtt:7; // ForceWake has high privilege than PutToSleep when both set
843 UINT32 EnableAutoWakeup:1; // 0:sleep, 1:awake
844 UINT32 :16;
845 } field;
846 UINT32 word;
847} AUTO_WAKEUP_STRUC, *PAUTO_WAKEUP_STRUC;
848#endif
849//
850// 4.3 MAC TX configuration registers (offset:0x1300)
851//
852
853#define EDCA_AC0_CFG 0x1300 //AC_TXOP_CSR0 0x3474
854#define EDCA_AC1_CFG 0x1304
855#define EDCA_AC2_CFG 0x1308
856#define EDCA_AC3_CFG 0x130c
857#ifdef RT_BIG_ENDIAN
858typedef union _EDCA_AC_CFG_STRUC {
859 struct {
860 UINT32 :12; //
861 UINT32 Cwmax:4; //unit power of 2
862 UINT32 Cwmin:4; //
863 UINT32 Aifsn:4; // # of slot time
864 UINT32 AcTxop:8; // in unit of 32us
865 } field;
866 UINT32 word;
867} EDCA_AC_CFG_STRUC, *PEDCA_AC_CFG_STRUC;
868#else
869typedef union _EDCA_AC_CFG_STRUC {
870 struct {
871 UINT32 AcTxop:8; // in unit of 32us
872 UINT32 Aifsn:4; // # of slot time
873 UINT32 Cwmin:4; //
874 UINT32 Cwmax:4; //unit power of 2
875 UINT32 :12; //
876 } field;
877 UINT32 word;
878} EDCA_AC_CFG_STRUC, *PEDCA_AC_CFG_STRUC;
879#endif
880
881#define EDCA_TID_AC_MAP 0x1310
882#define TX_PWR_CFG_0 0x1314
883#define TX_PWR_CFG_1 0x1318
884#define TX_PWR_CFG_2 0x131C
885#define TX_PWR_CFG_3 0x1320
886#define TX_PWR_CFG_4 0x1324
887#define TX_PIN_CFG 0x1328
888#define TX_BAND_CFG 0x132c // 0x1 use upper 20MHz. 0 juse lower 20MHz
889#define TX_SW_CFG0 0x1330
890#define TX_SW_CFG1 0x1334
891#define TX_SW_CFG2 0x1338
892#define TXOP_THRES_CFG 0x133c
893#define TXOP_CTRL_CFG 0x1340
894#define TX_RTS_CFG 0x1344
895
896#ifdef RT_BIG_ENDIAN
897typedef union _TX_RTS_CFG_STRUC {
898 struct {
899 UINT32 rsv:7;
900 UINT32 RtsFbkEn:1; // enable rts rate fallback
901 UINT32 RtsThres:16; // unit:byte
902 UINT32 AutoRtsRetryLimit:8;
903 } field;
904 UINT32 word;
905} TX_RTS_CFG_STRUC, *PTX_RTS_CFG_STRUC;
906#else
907typedef union _TX_RTS_CFG_STRUC {
908 struct {
909 UINT32 AutoRtsRetryLimit:8;
910 UINT32 RtsThres:16; // unit:byte
911 UINT32 RtsFbkEn:1; // enable rts rate fallback
912 UINT32 rsv:7; // 1: HT non-STBC control frame enable
913 } field;
914 UINT32 word;
915} TX_RTS_CFG_STRUC, *PTX_RTS_CFG_STRUC;
916#endif
917#define TX_TIMEOUT_CFG 0x1348
918#ifdef RT_BIG_ENDIAN
919typedef union _TX_TIMEOUT_CFG_STRUC {
920 struct {
921 UINT32 rsv2:8;
922 UINT32 TxopTimeout:8; //TXOP timeout value for TXOP truncation. It is recommended that (SLOT_TIME) > (TX_OP_TIMEOUT) > (RX_ACK_TIMEOUT)
923 UINT32 RxAckTimeout:8; // unit:slot. Used for TX precedure
924 UINT32 MpduLifeTime:4; // expiration time = 2^(9+MPDU LIFE TIME) us
925 UINT32 rsv:4;
926 } field;
927 UINT32 word;
928} TX_TIMEOUT_CFG_STRUC, *PTX_TIMEOUT_CFG_STRUC;
929#else
930typedef union _TX_TIMEOUT_CFG_STRUC {
931 struct {
932 UINT32 rsv:4;
933 UINT32 MpduLifeTime:4; // expiration time = 2^(9+MPDU LIFE TIME) us
934 UINT32 RxAckTimeout:8; // unit:slot. Used for TX precedure
935 UINT32 TxopTimeout:8; //TXOP timeout value for TXOP truncation. It is recommended that (SLOT_TIME) > (TX_OP_TIMEOUT) > (RX_ACK_TIMEOUT)
936 UINT32 rsv2:8; // 1: HT non-STBC control frame enable
937 } field;
938 UINT32 word;
939} TX_TIMEOUT_CFG_STRUC, *PTX_TIMEOUT_CFG_STRUC;
940#endif
941#define TX_RTY_CFG 0x134c
942#ifdef RT_BIG_ENDIAN
943typedef union PACKED _TX_RTY_CFG_STRUC {
944 struct {
945 UINT32 rsv:1;
946 UINT32 TxautoFBEnable:1; // Tx retry PHY rate auto fallback enable
947 UINT32 AggRtyMode:1; // Aggregate MPDU retry mode. 0:expired by retry limit, 1: expired by mpdu life timer
948 UINT32 NonAggRtyMode:1; // Non-Aggregate MPDU retry mode. 0:expired by retry limit, 1: expired by mpdu life timer
949 UINT32 LongRtyThre:12; // Long retry threshoold
950 UINT32 LongRtyLimit:8; //long retry limit
951 UINT32 ShortRtyLimit:8; // short retry limit
952
953 } field;
954 UINT32 word;
955} TX_RTY_CFG_STRUC, *PTX_RTY_CFG_STRUC;
956#else
957typedef union PACKED _TX_RTY_CFG_STRUC {
958 struct {
959 UINT32 ShortRtyLimit:8; // short retry limit
960 UINT32 LongRtyLimit:8; //long retry limit
961 UINT32 LongRtyThre:12; // Long retry threshoold
962 UINT32 NonAggRtyMode:1; // Non-Aggregate MPDU retry mode. 0:expired by retry limit, 1: expired by mpdu life timer
963 UINT32 AggRtyMode:1; // Aggregate MPDU retry mode. 0:expired by retry limit, 1: expired by mpdu life timer
964 UINT32 TxautoFBEnable:1; // Tx retry PHY rate auto fallback enable
965 UINT32 rsv:1; // 1: HT non-STBC control frame enable
966 } field;
967 UINT32 word;
968} TX_RTY_CFG_STRUC, *PTX_RTY_CFG_STRUC;
969#endif
970#define TX_LINK_CFG 0x1350
971#ifdef RT_BIG_ENDIAN
972typedef union PACKED _TX_LINK_CFG_STRUC {
973 struct PACKED {
974 UINT32 RemotMFS:8; //remote MCS feedback sequence number
975 UINT32 RemotMFB:8; // remote MCS feedback
976 UINT32 rsv:3; //
977 UINT32 TxCFAckEn:1; // Piggyback CF-ACK enable
978 UINT32 TxRDGEn:1; // RDG TX enable
979 UINT32 TxMRQEn:1; // MCS request TX enable
980 UINT32 RemoteUMFSEnable:1; // remote unsolicit MFB enable. 0: not apply remote remote unsolicit (MFS=7)
981 UINT32 MFBEnable:1; // TX apply remote MFB 1:enable
982 UINT32 RemoteMFBLifeTime:8; //remote MFB life time. unit : 32us
983 } field;
984 UINT32 word;
985} TX_LINK_CFG_STRUC, *PTX_LINK_CFG_STRUC;
986#else
987typedef union PACKED _TX_LINK_CFG_STRUC {
988 struct PACKED {
989 UINT32 RemoteMFBLifeTime:8; //remote MFB life time. unit : 32us
990 UINT32 MFBEnable:1; // TX apply remote MFB 1:enable
991 UINT32 RemoteUMFSEnable:1; // remote unsolicit MFB enable. 0: not apply remote remote unsolicit (MFS=7)
992 UINT32 TxMRQEn:1; // MCS request TX enable
993 UINT32 TxRDGEn:1; // RDG TX enable
994 UINT32 TxCFAckEn:1; // Piggyback CF-ACK enable
995 UINT32 rsv:3; //
996 UINT32 RemotMFB:8; // remote MCS feedback
997 UINT32 RemotMFS:8; //remote MCS feedback sequence number
998 } field;
999 UINT32 word;
1000} TX_LINK_CFG_STRUC, *PTX_LINK_CFG_STRUC;
1001#endif
1002#define HT_FBK_CFG0 0x1354
1003#ifdef RT_BIG_ENDIAN
1004typedef union PACKED _HT_FBK_CFG0_STRUC {
1005 struct {
1006 UINT32 HTMCS7FBK:4;
1007 UINT32 HTMCS6FBK:4;
1008 UINT32 HTMCS5FBK:4;
1009 UINT32 HTMCS4FBK:4;
1010 UINT32 HTMCS3FBK:4;
1011 UINT32 HTMCS2FBK:4;
1012 UINT32 HTMCS1FBK:4;
1013 UINT32 HTMCS0FBK:4;
1014 } field;
1015 UINT32 word;
1016} HT_FBK_CFG0_STRUC, *PHT_FBK_CFG0_STRUC;
1017#else
1018typedef union PACKED _HT_FBK_CFG0_STRUC {
1019 struct {
1020 UINT32 HTMCS0FBK:4;
1021 UINT32 HTMCS1FBK:4;
1022 UINT32 HTMCS2FBK:4;
1023 UINT32 HTMCS3FBK:4;
1024 UINT32 HTMCS4FBK:4;
1025 UINT32 HTMCS5FBK:4;
1026 UINT32 HTMCS6FBK:4;
1027 UINT32 HTMCS7FBK:4;
1028 } field;
1029 UINT32 word;
1030} HT_FBK_CFG0_STRUC, *PHT_FBK_CFG0_STRUC;
1031#endif
1032#define HT_FBK_CFG1 0x1358
1033#ifdef RT_BIG_ENDIAN
1034typedef union _HT_FBK_CFG1_STRUC {
1035 struct {
1036 UINT32 HTMCS15FBK:4;
1037 UINT32 HTMCS14FBK:4;
1038 UINT32 HTMCS13FBK:4;
1039 UINT32 HTMCS12FBK:4;
1040 UINT32 HTMCS11FBK:4;
1041 UINT32 HTMCS10FBK:4;
1042 UINT32 HTMCS9FBK:4;
1043 UINT32 HTMCS8FBK:4;
1044 } field;
1045 UINT32 word;
1046} HT_FBK_CFG1_STRUC, *PHT_FBK_CFG1_STRUC;
1047#else
1048typedef union _HT_FBK_CFG1_STRUC {
1049 struct {
1050 UINT32 HTMCS8FBK:4;
1051 UINT32 HTMCS9FBK:4;
1052 UINT32 HTMCS10FBK:4;
1053 UINT32 HTMCS11FBK:4;
1054 UINT32 HTMCS12FBK:4;
1055 UINT32 HTMCS13FBK:4;
1056 UINT32 HTMCS14FBK:4;
1057 UINT32 HTMCS15FBK:4;
1058 } field;
1059 UINT32 word;
1060} HT_FBK_CFG1_STRUC, *PHT_FBK_CFG1_STRUC;
1061#endif
1062#define LG_FBK_CFG0 0x135c
1063#ifdef RT_BIG_ENDIAN
1064typedef union _LG_FBK_CFG0_STRUC {
1065 struct {
1066 UINT32 OFDMMCS7FBK:4; //initial value is 6
1067 UINT32 OFDMMCS6FBK:4; //initial value is 5
1068 UINT32 OFDMMCS5FBK:4; //initial value is 4
1069 UINT32 OFDMMCS4FBK:4; //initial value is 3
1070 UINT32 OFDMMCS3FBK:4; //initial value is 2
1071 UINT32 OFDMMCS2FBK:4; //initial value is 1
1072 UINT32 OFDMMCS1FBK:4; //initial value is 0
1073 UINT32 OFDMMCS0FBK:4; //initial value is 0
1074 } field;
1075 UINT32 word;
1076} LG_FBK_CFG0_STRUC, *PLG_FBK_CFG0_STRUC;
1077#else
1078typedef union _LG_FBK_CFG0_STRUC {
1079 struct {
1080 UINT32 OFDMMCS0FBK:4; //initial value is 0
1081 UINT32 OFDMMCS1FBK:4; //initial value is 0
1082 UINT32 OFDMMCS2FBK:4; //initial value is 1
1083 UINT32 OFDMMCS3FBK:4; //initial value is 2
1084 UINT32 OFDMMCS4FBK:4; //initial value is 3
1085 UINT32 OFDMMCS5FBK:4; //initial value is 4
1086 UINT32 OFDMMCS6FBK:4; //initial value is 5
1087 UINT32 OFDMMCS7FBK:4; //initial value is 6
1088 } field;
1089 UINT32 word;
1090} LG_FBK_CFG0_STRUC, *PLG_FBK_CFG0_STRUC;
1091#endif
1092#define LG_FBK_CFG1 0x1360
1093#ifdef RT_BIG_ENDIAN
1094typedef union _LG_FBK_CFG1_STRUC {
1095 struct {
1096 UINT32 rsv:16;
1097 UINT32 CCKMCS3FBK:4; //initial value is 2
1098 UINT32 CCKMCS2FBK:4; //initial value is 1
1099 UINT32 CCKMCS1FBK:4; //initial value is 0
1100 UINT32 CCKMCS0FBK:4; //initial value is 0
1101 } field;
1102 UINT32 word;
1103} LG_FBK_CFG1_STRUC, *PLG_FBK_CFG1_STRUC;
1104#else
1105typedef union _LG_FBK_CFG1_STRUC {
1106 struct {
1107 UINT32 CCKMCS0FBK:4; //initial value is 0
1108 UINT32 CCKMCS1FBK:4; //initial value is 0
1109 UINT32 CCKMCS2FBK:4; //initial value is 1
1110 UINT32 CCKMCS3FBK:4; //initial value is 2
1111 UINT32 rsv:16;
1112 } field;
1113 UINT32 word;
1114} LG_FBK_CFG1_STRUC, *PLG_FBK_CFG1_STRUC;
1115#endif
1116
1117//=======================================================
1118//================ Protection Paramater================================
1119//=======================================================
1120#define CCK_PROT_CFG 0x1364 //CCK Protection
1121#define ASIC_SHORTNAV 1
1122#define ASIC_LONGNAV 2
1123#define ASIC_RTS 1
1124#define ASIC_CTS 2
1125#ifdef RT_BIG_ENDIAN
1126typedef union _PROT_CFG_STRUC {
1127 struct {
1128 UINT32 rsv:5;
1129 UINT32 RTSThEn:1; //RTS threshold enable on CCK TX
1130 UINT32 TxopAllowGF40:1; //CCK TXOP allowance.0:disallow.
1131 UINT32 TxopAllowGF20:1; //CCK TXOP allowance.0:disallow.
1132 UINT32 TxopAllowMM40:1; //CCK TXOP allowance.0:disallow.
1133 UINT32 TxopAllowMM20:1; //CCK TXOP allowance. 0:disallow.
1134 UINT32 TxopAllowOfdm:1; //CCK TXOP allowance.0:disallow.
1135 UINT32 TxopAllowCck:1; //CCK TXOP allowance.0:disallow.
1136 UINT32 ProtectNav:2; //TXOP protection type for CCK TX. 0:None, 1:ShortNAVprotect, 2:LongNAVProtect, 3:rsv
1137 UINT32 ProtectCtrl:2; //Protection control frame type for CCK TX. 1:RTS/CTS, 2:CTS-to-self, 0:None, 3:rsv
1138 UINT32 ProtectRate:16; //Protection control frame rate for CCK TX(RTS/CTS/CFEnd).
1139 } field;
1140 UINT32 word;
1141} PROT_CFG_STRUC, *PPROT_CFG_STRUC;
1142#else
1143typedef union _PROT_CFG_STRUC {
1144 struct {
1145 UINT32 ProtectRate:16; //Protection control frame rate for CCK TX(RTS/CTS/CFEnd).
1146 UINT32 ProtectCtrl:2; //Protection control frame type for CCK TX. 1:RTS/CTS, 2:CTS-to-self, 0:None, 3:rsv
1147 UINT32 ProtectNav:2; //TXOP protection type for CCK TX. 0:None, 1:ShortNAVprotect, 2:LongNAVProtect, 3:rsv
1148 UINT32 TxopAllowCck:1; //CCK TXOP allowance.0:disallow.
1149 UINT32 TxopAllowOfdm:1; //CCK TXOP allowance.0:disallow.
1150 UINT32 TxopAllowMM20:1; //CCK TXOP allowance. 0:disallow.
1151 UINT32 TxopAllowMM40:1; //CCK TXOP allowance.0:disallow.
1152 UINT32 TxopAllowGF20:1; //CCK TXOP allowance.0:disallow.
1153 UINT32 TxopAllowGF40:1; //CCK TXOP allowance.0:disallow.
1154 UINT32 RTSThEn:1; //RTS threshold enable on CCK TX
1155 UINT32 rsv:5;
1156 } field;
1157 UINT32 word;
1158} PROT_CFG_STRUC, *PPROT_CFG_STRUC;
1159#endif
1160
1161#define OFDM_PROT_CFG 0x1368 //OFDM Protection
1162#define MM20_PROT_CFG 0x136C //MM20 Protection
1163#define MM40_PROT_CFG 0x1370 //MM40 Protection
1164#define GF20_PROT_CFG 0x1374 //GF20 Protection
1165#define GF40_PROT_CFG 0x1378 //GR40 Protection
1166#define EXP_CTS_TIME 0x137C //
1167#define EXP_ACK_TIME 0x1380 //
1168
1169//
1170// 4.4 MAC RX configuration registers (offset:0x1400)
1171//
1172#define RX_FILTR_CFG 0x1400 //TXRX_CSR0
1173#define AUTO_RSP_CFG 0x1404 //TXRX_CSR4
1174//
1175// TXRX_CSR4: Auto-Responder/
1176//
1177#ifdef RT_BIG_ENDIAN
1178typedef union _AUTO_RSP_CFG_STRUC {
1179 struct {
1180 UINT32 :24;
1181 UINT32 AckCtsPsmBit:1; // Power bit value in conrtrol frame
1182 UINT32 DualCTSEn:1; // Power bit value in conrtrol frame
1183 UINT32 rsv:1; // Power bit value in conrtrol frame
1184 UINT32 AutoResponderPreamble:1; // 0:long, 1:short preamble
1185 UINT32 CTS40MRef:1; // Response CTS 40MHz duplicate mode
1186 UINT32 CTS40MMode:1; // Response CTS 40MHz duplicate mode
1187 UINT32 BACAckPolicyEnable:1; // 0:long, 1:short preamble
1188 UINT32 AutoResponderEnable:1;
1189 } field;
1190 UINT32 word;
1191} AUTO_RSP_CFG_STRUC, *PAUTO_RSP_CFG_STRUC;
1192#else
1193typedef union _AUTO_RSP_CFG_STRUC {
1194 struct {
1195 UINT32 AutoResponderEnable:1;
1196 UINT32 BACAckPolicyEnable:1; // 0:long, 1:short preamble
1197 UINT32 CTS40MMode:1; // Response CTS 40MHz duplicate mode
1198 UINT32 CTS40MRef:1; // Response CTS 40MHz duplicate mode
1199 UINT32 AutoResponderPreamble:1; // 0:long, 1:short preamble
1200 UINT32 rsv:1; // Power bit value in conrtrol frame
1201 UINT32 DualCTSEn:1; // Power bit value in conrtrol frame
1202 UINT32 AckCtsPsmBit:1; // Power bit value in conrtrol frame
1203 UINT32 :24;
1204 } field;
1205 UINT32 word;
1206} AUTO_RSP_CFG_STRUC, *PAUTO_RSP_CFG_STRUC;
1207#endif
1208
1209#define LEGACY_BASIC_RATE 0x1408 // TXRX_CSR5 0x3054
1210#define HT_BASIC_RATE 0x140c
1211#define HT_CTRL_CFG 0x1410
1212#define SIFS_COST_CFG 0x1414
1213#define RX_PARSER_CFG 0x1418 //Set NAV for all received frames
1214
1215//
1216// 4.5 MAC Security configuration (offset:0x1500)
1217//
1218#define TX_SEC_CNT0 0x1500 //
1219#define RX_SEC_CNT0 0x1504 //
1220#define CCMP_FC_MUTE 0x1508 //
1221//
1222// 4.6 HCCA/PSMP (offset:0x1600)
1223//
1224#define TXOP_HLDR_ADDR0 0x1600
1225#define TXOP_HLDR_ADDR1 0x1604
1226#define TXOP_HLDR_ET 0x1608
1227#define QOS_CFPOLL_RA_DW0 0x160c
1228#define QOS_CFPOLL_A1_DW1 0x1610
1229#define QOS_CFPOLL_QC 0x1614
1230//
1231// 4.7 MAC Statistis registers (offset:0x1700)
1232//
1233#define RX_STA_CNT0 0x1700 //
1234#define RX_STA_CNT1 0x1704 //
1235#define RX_STA_CNT2 0x1708 //
1236
1237//
1238// RX_STA_CNT0_STRUC: RX PLCP error count & RX CRC error count
1239//
1240#ifdef RT_BIG_ENDIAN
1241typedef union _RX_STA_CNT0_STRUC {
1242 struct {
1243 USHORT PhyErr;
1244 USHORT CrcErr;
1245 } field;
1246 UINT32 word;
1247} RX_STA_CNT0_STRUC, *PRX_STA_CNT0_STRUC;
1248#else
1249typedef union _RX_STA_CNT0_STRUC {
1250 struct {
1251 USHORT CrcErr;
1252 USHORT PhyErr;
1253 } field;
1254 UINT32 word;
1255} RX_STA_CNT0_STRUC, *PRX_STA_CNT0_STRUC;
1256#endif
1257
1258//
1259// RX_STA_CNT1_STRUC: RX False CCA count & RX LONG frame count
1260//
1261#ifdef RT_BIG_ENDIAN
1262typedef union _RX_STA_CNT1_STRUC {
1263 struct {
1264 USHORT PlcpErr;
1265 USHORT FalseCca;
1266 } field;
1267 UINT32 word;
1268} RX_STA_CNT1_STRUC, *PRX_STA_CNT1_STRUC;
1269#else
1270typedef union _RX_STA_CNT1_STRUC {
1271 struct {
1272 USHORT FalseCca;
1273 USHORT PlcpErr;
1274 } field;
1275 UINT32 word;
1276} RX_STA_CNT1_STRUC, *PRX_STA_CNT1_STRUC;
1277#endif
1278
1279//
1280// RX_STA_CNT2_STRUC:
1281//
1282#ifdef RT_BIG_ENDIAN
1283typedef union _RX_STA_CNT2_STRUC {
1284 struct {
1285 USHORT RxFifoOverflowCount;
1286 USHORT RxDupliCount;
1287 } field;
1288 UINT32 word;
1289} RX_STA_CNT2_STRUC, *PRX_STA_CNT2_STRUC;
1290#else
1291typedef union _RX_STA_CNT2_STRUC {
1292 struct {
1293 USHORT RxDupliCount;
1294 USHORT RxFifoOverflowCount;
1295 } field;
1296 UINT32 word;
1297} RX_STA_CNT2_STRUC, *PRX_STA_CNT2_STRUC;
1298#endif
1299#define TX_STA_CNT0 0x170C //
1300//
1301// STA_CSR3: TX Beacon count
1302//
1303#ifdef RT_BIG_ENDIAN
1304typedef union _TX_STA_CNT0_STRUC {
1305 struct {
1306 USHORT TxBeaconCount;
1307 USHORT TxFailCount;
1308 } field;
1309 UINT32 word;
1310} TX_STA_CNT0_STRUC, *PTX_STA_CNT0_STRUC;
1311#else
1312typedef union _TX_STA_CNT0_STRUC {
1313 struct {
1314 USHORT TxFailCount;
1315 USHORT TxBeaconCount;
1316 } field;
1317 UINT32 word;
1318} TX_STA_CNT0_STRUC, *PTX_STA_CNT0_STRUC;
1319#endif
1320#define TX_STA_CNT1 0x1710 //
1321//
1322// TX_STA_CNT1: TX tx count
1323//
1324#ifdef RT_BIG_ENDIAN
1325typedef union _TX_STA_CNT1_STRUC {
1326 struct {
1327 USHORT TxRetransmit;
1328 USHORT TxSuccess;
1329 } field;
1330 UINT32 word;
1331} TX_STA_CNT1_STRUC, *PTX_STA_CNT1_STRUC;
1332#else
1333typedef union _TX_STA_CNT1_STRUC {
1334 struct {
1335 USHORT TxSuccess;
1336 USHORT TxRetransmit;
1337 } field;
1338 UINT32 word;
1339} TX_STA_CNT1_STRUC, *PTX_STA_CNT1_STRUC;
1340#endif
1341#define TX_STA_CNT2 0x1714 //
1342//
1343// TX_STA_CNT2: TX tx count
1344//
1345#ifdef RT_BIG_ENDIAN
1346typedef union _TX_STA_CNT2_STRUC {
1347 struct {
1348 USHORT TxUnderFlowCount;
1349 USHORT TxZeroLenCount;
1350 } field;
1351 UINT32 word;
1352} TX_STA_CNT2_STRUC, *PTX_STA_CNT2_STRUC;
1353#else
1354typedef union _TX_STA_CNT2_STRUC {
1355 struct {
1356 USHORT TxZeroLenCount;
1357 USHORT TxUnderFlowCount;
1358 } field;
1359 UINT32 word;
1360} TX_STA_CNT2_STRUC, *PTX_STA_CNT2_STRUC;
1361#endif
1362#define TX_STA_FIFO 0x1718 //
1363//
1364// TX_STA_FIFO_STRUC: TX Result for specific PID status fifo register
1365//
1366#ifdef RT_BIG_ENDIAN
1367typedef union PACKED _TX_STA_FIFO_STRUC {
1368 struct {
1369 UINT32 Reserve:2;
1370 UINT32 TxBF:1; // 3*3
1371 UINT32 SuccessRate:13; //include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16.
1372// UINT32 SuccessRate:16; //include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16.
1373 UINT32 wcid:8; //wireless client index
1374 UINT32 TxAckRequired:1; // ack required
1375 UINT32 TxAggre:1; // Tx is aggregated
1376 UINT32 TxSuccess:1; // Tx success. whether success or not
1377 UINT32 PidType:4;
1378 UINT32 bValid:1; // 1:This register contains a valid TX result
1379 } field;
1380 UINT32 word;
1381} TX_STA_FIFO_STRUC, *PTX_STA_FIFO_STRUC;
1382#else
1383typedef union PACKED _TX_STA_FIFO_STRUC {
1384 struct {
1385 UINT32 bValid:1; // 1:This register contains a valid TX result
1386 UINT32 PidType:4;
1387 UINT32 TxSuccess:1; // Tx No retry success
1388 UINT32 TxAggre:1; // Tx Retry Success
1389 UINT32 TxAckRequired:1; // Tx fail
1390 UINT32 wcid:8; //wireless client index
1391// UINT32 SuccessRate:16; //include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16.
1392 UINT32 SuccessRate:13; //include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16.
1393 UINT32 TxBF:1;
1394 UINT32 Reserve:2;
1395 } field;
1396 UINT32 word;
1397} TX_STA_FIFO_STRUC, *PTX_STA_FIFO_STRUC;
1398#endif
1399// Debug counter
1400#define TX_AGG_CNT 0x171c
1401#ifdef RT_BIG_ENDIAN
1402typedef union _TX_AGG_CNT_STRUC {
1403 struct {
1404 USHORT AggTxCount;
1405 USHORT NonAggTxCount;
1406 } field;
1407 UINT32 word;
1408} TX_AGG_CNT_STRUC, *PTX_AGG_CNT_STRUC;
1409#else
1410typedef union _TX_AGG_CNT_STRUC {
1411 struct {
1412 USHORT NonAggTxCount;
1413 USHORT AggTxCount;
1414 } field;
1415 UINT32 word;
1416} TX_AGG_CNT_STRUC, *PTX_AGG_CNT_STRUC;
1417#endif
1418// Debug counter
1419#define TX_AGG_CNT0 0x1720
1420#ifdef RT_BIG_ENDIAN
1421typedef union _TX_AGG_CNT0_STRUC {
1422 struct {
1423 USHORT AggSize2Count;
1424 USHORT AggSize1Count;
1425 } field;
1426 UINT32 word;
1427} TX_AGG_CNT0_STRUC, *PTX_AGG_CNT0_STRUC;
1428#else
1429typedef union _TX_AGG_CNT0_STRUC {
1430 struct {
1431 USHORT AggSize1Count;
1432 USHORT AggSize2Count;
1433 } field;
1434 UINT32 word;
1435} TX_AGG_CNT0_STRUC, *PTX_AGG_CNT0_STRUC;
1436#endif
1437// Debug counter
1438#define TX_AGG_CNT1 0x1724
1439#ifdef RT_BIG_ENDIAN
1440typedef union _TX_AGG_CNT1_STRUC {
1441 struct {
1442 USHORT AggSize4Count;
1443 USHORT AggSize3Count;
1444 } field;
1445 UINT32 word;
1446} TX_AGG_CNT1_STRUC, *PTX_AGG_CNT1_STRUC;
1447#else
1448typedef union _TX_AGG_CNT1_STRUC {
1449 struct {
1450 USHORT AggSize3Count;
1451 USHORT AggSize4Count;
1452 } field;
1453 UINT32 word;
1454} TX_AGG_CNT1_STRUC, *PTX_AGG_CNT1_STRUC;
1455#endif
1456#define TX_AGG_CNT2 0x1728
1457#ifdef RT_BIG_ENDIAN
1458typedef union _TX_AGG_CNT2_STRUC {
1459 struct {
1460 USHORT AggSize6Count;
1461 USHORT AggSize5Count;
1462 } field;
1463 UINT32 word;
1464} TX_AGG_CNT2_STRUC, *PTX_AGG_CNT2_STRUC;
1465#else
1466typedef union _TX_AGG_CNT2_STRUC {
1467 struct {
1468 USHORT AggSize5Count;
1469 USHORT AggSize6Count;
1470 } field;
1471 UINT32 word;
1472} TX_AGG_CNT2_STRUC, *PTX_AGG_CNT2_STRUC;
1473#endif
1474// Debug counter
1475#define TX_AGG_CNT3 0x172c
1476#ifdef RT_BIG_ENDIAN
1477typedef union _TX_AGG_CNT3_STRUC {
1478 struct {
1479 USHORT AggSize8Count;
1480 USHORT AggSize7Count;
1481 } field;
1482 UINT32 word;
1483} TX_AGG_CNT3_STRUC, *PTX_AGG_CNT3_STRUC;
1484#else
1485typedef union _TX_AGG_CNT3_STRUC {
1486 struct {
1487 USHORT AggSize7Count;
1488 USHORT AggSize8Count;
1489 } field;
1490 UINT32 word;
1491} TX_AGG_CNT3_STRUC, *PTX_AGG_CNT3_STRUC;
1492#endif
1493// Debug counter
1494#define TX_AGG_CNT4 0x1730
1495#ifdef RT_BIG_ENDIAN
1496typedef union _TX_AGG_CNT4_STRUC {
1497 struct {
1498 USHORT AggSize10Count;
1499 USHORT AggSize9Count;
1500 } field;
1501 UINT32 word;
1502} TX_AGG_CNT4_STRUC, *PTX_AGG_CNT4_STRUC;
1503#else
1504typedef union _TX_AGG_CNT4_STRUC {
1505 struct {
1506 USHORT AggSize9Count;
1507 USHORT AggSize10Count;
1508 } field;
1509 UINT32 word;
1510} TX_AGG_CNT4_STRUC, *PTX_AGG_CNT4_STRUC;
1511#endif
1512#define TX_AGG_CNT5 0x1734
1513#ifdef RT_BIG_ENDIAN
1514typedef union _TX_AGG_CNT5_STRUC {
1515 struct {
1516 USHORT AggSize12Count;
1517 USHORT AggSize11Count;
1518 } field;
1519 UINT32 word;
1520} TX_AGG_CNT5_STRUC, *PTX_AGG_CNT5_STRUC;
1521#else
1522typedef union _TX_AGG_CNT5_STRUC {
1523 struct {
1524 USHORT AggSize11Count;
1525 USHORT AggSize12Count;
1526 } field;
1527 UINT32 word;
1528} TX_AGG_CNT5_STRUC, *PTX_AGG_CNT5_STRUC;
1529#endif
1530#define TX_AGG_CNT6 0x1738
1531#ifdef RT_BIG_ENDIAN
1532typedef union _TX_AGG_CNT6_STRUC {
1533 struct {
1534 USHORT AggSize14Count;
1535 USHORT AggSize13Count;
1536 } field;
1537 UINT32 word;
1538} TX_AGG_CNT6_STRUC, *PTX_AGG_CNT6_STRUC;
1539#else
1540typedef union _TX_AGG_CNT6_STRUC {
1541 struct {
1542 USHORT AggSize13Count;
1543 USHORT AggSize14Count;
1544 } field;
1545 UINT32 word;
1546} TX_AGG_CNT6_STRUC, *PTX_AGG_CNT6_STRUC;
1547#endif
1548#define TX_AGG_CNT7 0x173c
1549#ifdef RT_BIG_ENDIAN
1550typedef union _TX_AGG_CNT7_STRUC {
1551 struct {
1552 USHORT AggSize16Count;
1553 USHORT AggSize15Count;
1554 } field;
1555 UINT32 word;
1556} TX_AGG_CNT7_STRUC, *PTX_AGG_CNT7_STRUC;
1557#else
1558typedef union _TX_AGG_CNT7_STRUC {
1559 struct {
1560 USHORT AggSize15Count;
1561 USHORT AggSize16Count;
1562 } field;
1563 UINT32 word;
1564} TX_AGG_CNT7_STRUC, *PTX_AGG_CNT7_STRUC;
1565#endif
1566#define MPDU_DENSITY_CNT 0x1740
1567#ifdef RT_BIG_ENDIAN
1568typedef union _MPDU_DEN_CNT_STRUC {
1569 struct {
1570 USHORT RXZeroDelCount; //RX zero length delimiter count
1571 USHORT TXZeroDelCount; //TX zero length delimiter count
1572 } field;
1573 UINT32 word;
1574} MPDU_DEN_CNT_STRUC, *PMPDU_DEN_CNT_STRUC;
1575#else
1576typedef union _MPDU_DEN_CNT_STRUC {
1577 struct {
1578 USHORT TXZeroDelCount; //TX zero length delimiter count
1579 USHORT RXZeroDelCount; //RX zero length delimiter count
1580 } field;
1581 UINT32 word;
1582} MPDU_DEN_CNT_STRUC, *PMPDU_DEN_CNT_STRUC;
1583#endif
1584//
1585// TXRX control registers - base address 0x3000
1586//
1587// rt2860b UNKNOWN reg use R/O Reg Addr 0x77d0 first..
1588#define TXRX_CSR1 0x77d0
1589
1590//
1591// Security key table memory, base address = 0x1000
1592//
1593#define MAC_WCID_BASE 0x1800 //8-bytes(use only 6-bytes) * 256 entry =
1594#define HW_WCID_ENTRY_SIZE 8
1595#define PAIRWISE_KEY_TABLE_BASE 0x4000 // 32-byte * 256-entry = -byte
1596#define HW_KEY_ENTRY_SIZE 0x20
1597#define PAIRWISE_IVEIV_TABLE_BASE 0x6000 // 8-byte * 256-entry = -byte
1598#define MAC_IVEIV_TABLE_BASE 0x6000 // 8-byte * 256-entry = -byte
1599#define HW_IVEIV_ENTRY_SIZE 8
1600#define MAC_WCID_ATTRIBUTE_BASE 0x6800 // 4-byte * 256-entry = -byte
1601#define HW_WCID_ATTRI_SIZE 4
1602#define WCID_RESERVED 0x6bfc
1603#define SHARED_KEY_TABLE_BASE 0x6c00 // 32-byte * 16-entry = 512-byte
1604#define SHARED_KEY_MODE_BASE 0x7000 // 32-byte * 16-entry = 512-byte
1605#define HW_SHARED_KEY_MODE_SIZE 4
1606#define SHAREDKEYTABLE 0
1607#define PAIRWISEKEYTABLE 1
1608
1609
1610#ifdef RT_BIG_ENDIAN
1611typedef union _SHAREDKEY_MODE_STRUC {
1612 struct {
1613 UINT32 :1;
1614 UINT32 Bss1Key3CipherAlg:3;
1615 UINT32 :1;
1616 UINT32 Bss1Key2CipherAlg:3;
1617 UINT32 :1;
1618 UINT32 Bss1Key1CipherAlg:3;
1619 UINT32 :1;
1620 UINT32 Bss1Key0CipherAlg:3;
1621 UINT32 :1;
1622 UINT32 Bss0Key3CipherAlg:3;
1623 UINT32 :1;
1624 UINT32 Bss0Key2CipherAlg:3;
1625 UINT32 :1;
1626 UINT32 Bss0Key1CipherAlg:3;
1627 UINT32 :1;
1628 UINT32 Bss0Key0CipherAlg:3;
1629 } field;
1630 UINT32 word;
1631} SHAREDKEY_MODE_STRUC, *PSHAREDKEY_MODE_STRUC;
1632#else
1633typedef union _SHAREDKEY_MODE_STRUC {
1634 struct {
1635 UINT32 Bss0Key0CipherAlg:3;
1636 UINT32 :1;
1637 UINT32 Bss0Key1CipherAlg:3;
1638 UINT32 :1;
1639 UINT32 Bss0Key2CipherAlg:3;
1640 UINT32 :1;
1641 UINT32 Bss0Key3CipherAlg:3;
1642 UINT32 :1;
1643 UINT32 Bss1Key0CipherAlg:3;
1644 UINT32 :1;
1645 UINT32 Bss1Key1CipherAlg:3;
1646 UINT32 :1;
1647 UINT32 Bss1Key2CipherAlg:3;
1648 UINT32 :1;
1649 UINT32 Bss1Key3CipherAlg:3;
1650 UINT32 :1;
1651 } field;
1652 UINT32 word;
1653} SHAREDKEY_MODE_STRUC, *PSHAREDKEY_MODE_STRUC;
1654#endif
1655// 64-entry for pairwise key table
1656typedef struct _HW_WCID_ENTRY { // 8-byte per entry
1657 UCHAR Address[6];
1658 UCHAR Rsv[2];
1659} HW_WCID_ENTRY, PHW_WCID_ENTRY;
1660
1661
1662
1663//
1664// Other on-chip shared memory space, base = 0x2000
1665//
1666
1667// CIS space - base address = 0x2000
1668#define HW_CIS_BASE 0x2000
1669
1670// Carrier-sense CTS frame base address. It's where mac stores carrier-sense frame for carrier-sense function.
1671#define HW_CS_CTS_BASE 0x7700
1672// DFS CTS frame base address. It's where mac stores CTS frame for DFS.
1673#define HW_DFS_CTS_BASE 0x7780
1674#define HW_CTS_FRAME_SIZE 0x80
1675
1676// 2004-11-08 john - since NULL frame won't be that long (256 byte). We steal 16 tail bytes
1677// to save debugging settings
1678#define HW_DEBUG_SETTING_BASE 0x77f0 // 0x77f0~0x77ff total 16 bytes
1679#define HW_DEBUG_SETTING_BASE2 0x7770 // 0x77f0~0x77ff total 16 bytes
1680
1681// In order to support maximum 8 MBSS and its maximum length is 512 for each beacon
1682// Three section discontinue memory segments will be used.
1683// 1. The original region for BCN 0~3
1684// 2. Extract memory from FCE table for BCN 4~5
1685// 3. Extract memory from Pair-wise key table for BCN 6~7
1686// It occupied those memory of wcid 238~253 for BCN 6
1687// and wcid 222~237 for BCN 7
1688#define HW_BEACON_MAX_SIZE 0x1000 /* unit: byte */
1689#define HW_BEACON_BASE0 0x7800
1690#define HW_BEACON_BASE1 0x7A00
1691#define HW_BEACON_BASE2 0x7C00
1692#define HW_BEACON_BASE3 0x7E00
1693#define HW_BEACON_BASE4 0x7200
1694#define HW_BEACON_BASE5 0x7400
1695#define HW_BEACON_BASE6 0x5DC0
1696#define HW_BEACON_BASE7 0x5BC0
1697
1698#define HW_BEACON_MAX_COUNT 8
1699#define HW_BEACON_OFFSET 0x0200
1700#define HW_BEACON_CONTENT_LEN (HW_BEACON_OFFSET - TXWI_SIZE)
1701
1702// HOST-MCU shared memory - base address = 0x2100
1703#define HOST_CMD_CSR 0x404
1704#define H2M_MAILBOX_CSR 0x7010
1705#define H2M_MAILBOX_CID 0x7014
1706#define H2M_MAILBOX_STATUS 0x701c
1707#define H2M_INT_SRC 0x7024
1708#define H2M_BBP_AGENT 0x7028
1709#define M2H_CMD_DONE_CSR 0x000c
1710#define MCU_TXOP_ARRAY_BASE 0x000c // TODO: to be provided by Albert
1711#define MCU_TXOP_ENTRY_SIZE 32 // TODO: to be provided by Albert
1712#define MAX_NUM_OF_TXOP_ENTRY 16 // TODO: must be same with 8051 firmware
1713#define MCU_MBOX_VERSION 0x01 // TODO: to be confirmed by Albert
1714#define MCU_MBOX_VERSION_OFFSET 5 // TODO: to be provided by Albert
1715
1716//
1717// Host DMA registers - base address 0x200 . TX0-3=EDCAQid0-3, TX4=HCCA, TX5=MGMT,
1718//
1719//
1720// DMA RING DESCRIPTOR
1721//
1722#define E2PROM_CSR 0x0004
1723#define IO_CNTL_CSR 0x77d0
1724
1725#ifdef RT2870
1726// 8051 firmware image for usb - use last-half base address = 0x3000
1727#define FIRMWARE_IMAGE_BASE 0x3000
1728#define MAX_FIRMWARE_IMAGE_SIZE 0x1000 // 4kbyte
1729#endif // RT2870 //
1730
1731// TODO: ????? old RT2560 registers. to keep them or remove them?
1732//#define MCAST0 0x0178 // multicast filter register 0
1733//#define MCAST1 0x017c // multicast filter register 1
1734
1735
1736// ================================================================
1737// Tx / Rx / Mgmt ring descriptor definition
1738// ================================================================
1739
1740// the following PID values are used to mark outgoing frame type in TXD->PID so that
1741// proper TX statistics can be collected based on these categories
1742// b3-2 of PID field -
1743#define PID_MGMT 0x05
1744#define PID_BEACON 0x0c
1745#define PID_DATA_NORMALUCAST 0x02
1746#define PID_DATA_AMPDU 0x04
1747#define PID_DATA_NO_ACK 0x08
1748#define PID_DATA_NOT_NORM_ACK 0x03
1749// value domain of pTxD->HostQId (4-bit: 0~15)
1750#define QID_AC_BK 1 // meet ACI definition in 802.11e
1751#define QID_AC_BE 0 // meet ACI definition in 802.11e
1752#define QID_AC_VI 2
1753#define QID_AC_VO 3
1754#define QID_HCCA 4
1755#define NUM_OF_TX_RING 5
1756#define QID_MGMT 13
1757#define QID_RX 14
1758#define QID_OTHER 15
1759
1760
1761// ------------------------------------------------------
1762// BBP & RF definition
1763// ------------------------------------------------------
1764#define BUSY 1
1765#define IDLE 0
1766
1767#define RF_R00 0
1768#define RF_R01 1
1769#define RF_R02 2
1770#define RF_R03 3
1771#define RF_R04 4
1772#define RF_R05 5
1773#define RF_R06 6
1774#define RF_R07 7
1775#define RF_R08 8
1776#define RF_R09 9
1777#define RF_R10 10
1778#define RF_R11 11
1779#define RF_R12 12
1780#define RF_R13 13
1781#define RF_R14 14
1782#define RF_R15 15
1783#define RF_R16 16
1784#define RF_R17 17
1785#define RF_R18 18
1786#define RF_R19 19
1787#define RF_R20 20
1788#define RF_R21 21
1789#define RF_R22 22
1790#define RF_R23 23
1791#define RF_R24 24
1792#define RF_R25 25
1793#define RF_R26 26
1794#define RF_R27 27
1795#define RF_R28 28
1796#define RF_R29 29
1797#define RF_R30 30
1798#define RF_R31 31
1799
1800#define BBP_R0 0 // version
1801#define BBP_R1 1 // TSSI
1802#define BBP_R2 2 // TX configure
1803#define BBP_R3 3
1804#define BBP_R4 4
1805#define BBP_R5 5
1806#define BBP_R6 6
1807#define BBP_R14 14 // RX configure
1808#define BBP_R16 16
1809#define BBP_R17 17 // RX sensibility
1810#define BBP_R18 18
1811#define BBP_R21 21
1812#define BBP_R22 22
1813#define BBP_R24 24
1814#define BBP_R25 25
1815#define BBP_R31 31
1816#define BBP_R49 49 //TSSI
1817#define BBP_R50 50
1818#define BBP_R51 51
1819#define BBP_R52 52
1820#define BBP_R55 55
1821#define BBP_R62 62 // Rx SQ0 Threshold HIGH
1822#define BBP_R63 63
1823#define BBP_R64 64
1824#define BBP_R65 65
1825#define BBP_R66 66
1826#define BBP_R67 67
1827#define BBP_R68 68
1828#define BBP_R69 69
1829#define BBP_R70 70 // Rx AGC SQ CCK Xcorr threshold
1830#define BBP_R73 73
1831#define BBP_R75 75
1832#define BBP_R77 77
1833#define BBP_R79 79
1834#define BBP_R80 80
1835#define BBP_R81 81
1836#define BBP_R82 82
1837#define BBP_R83 83
1838#define BBP_R84 84
1839#define BBP_R86 86
1840#define BBP_R91 91
1841#define BBP_R92 92
1842#define BBP_R94 94 // Tx Gain Control
1843#define BBP_R103 103
1844#define BBP_R105 105
1845#define BBP_R113 113
1846#define BBP_R114 114
1847#define BBP_R115 115
1848#define BBP_R116 116
1849#define BBP_R117 117
1850#define BBP_R118 118
1851#define BBP_R119 119
1852#define BBP_R120 120
1853#define BBP_R121 121
1854#define BBP_R122 122
1855#define BBP_R123 123
1856#ifdef RT30xx
1857#define BBP_R138 138 // add by johnli, RF power sequence setup, ADC dynamic on/off control
1858#endif // RT30xx //
1859
1860
1861#define BBPR94_DEFAULT 0x06 // Add 1 value will gain 1db
1862
1863//#define PHY_TR_SWITCH_TIME 5 // usec
1864
1865//#define BBP_R17_LOW_SENSIBILITY 0x50
1866//#define BBP_R17_MID_SENSIBILITY 0x41
1867//#define BBP_R17_DYNAMIC_UP_BOUND 0x40
1868#define RSSI_FOR_VERY_LOW_SENSIBILITY -35
1869#define RSSI_FOR_LOW_SENSIBILITY -58
1870#define RSSI_FOR_MID_LOW_SENSIBILITY -80
1871#define RSSI_FOR_MID_SENSIBILITY -90
1872
1873//-------------------------------------------------------------------------
1874// EEPROM definition
1875//-------------------------------------------------------------------------
1876#define EEDO 0x08
1877#define EEDI 0x04
1878#define EECS 0x02
1879#define EESK 0x01
1880#define EERL 0x80
1881
1882#define EEPROM_WRITE_OPCODE 0x05
1883#define EEPROM_READ_OPCODE 0x06
1884#define EEPROM_EWDS_OPCODE 0x10
1885#define EEPROM_EWEN_OPCODE 0x13
1886
1887#define NUM_EEPROM_BBP_PARMS 19 // Include NIC Config 0, 1, CR, TX ALC step, BBPs
1888#define NUM_EEPROM_TX_G_PARMS 7
1889#define EEPROM_NIC1_OFFSET 0x34 // The address is from NIC config 0, not BBP register ID
1890#define EEPROM_NIC2_OFFSET 0x36 // The address is from NIC config 0, not BBP register ID
1891#define EEPROM_BBP_BASE_OFFSET 0xf0 // The address is from NIC config 0, not BBP register ID
1892#define EEPROM_G_TX_PWR_OFFSET 0x52
1893#define EEPROM_G_TX2_PWR_OFFSET 0x60
1894#define EEPROM_LED1_OFFSET 0x3c
1895#define EEPROM_LED2_OFFSET 0x3e
1896#define EEPROM_LED3_OFFSET 0x40
1897#define EEPROM_LNA_OFFSET 0x44
1898#define EEPROM_RSSI_BG_OFFSET 0x46
1899#define EEPROM_RSSI_A_OFFSET 0x4a
1900#define EEPROM_DEFINE_MAX_TXPWR 0x4e
1901#define EEPROM_TXPOWER_BYRATE_20MHZ_2_4G 0xde // 20MHZ 2.4G tx power.
1902#define EEPROM_TXPOWER_BYRATE_40MHZ_2_4G 0xee // 40MHZ 2.4G tx power.
1903#define EEPROM_TXPOWER_BYRATE_20MHZ_5G 0xfa // 20MHZ 5G tx power.
1904#define EEPROM_TXPOWER_BYRATE_40MHZ_5G 0x10a // 40MHZ 5G tx power.
1905#define EEPROM_A_TX_PWR_OFFSET 0x78
1906#define EEPROM_A_TX2_PWR_OFFSET 0xa6
1907//#define EEPROM_Japan_TX_PWR_OFFSET 0x90 // 802.11j
1908//#define EEPROM_Japan_TX2_PWR_OFFSET 0xbe
1909//#define EEPROM_TSSI_REF_OFFSET 0x54
1910//#define EEPROM_TSSI_DELTA_OFFSET 0x24
1911//#define EEPROM_CCK_TX_PWR_OFFSET 0x62
1912//#define EEPROM_CALIBRATE_OFFSET 0x7c
1913#define EEPROM_VERSION_OFFSET 0x02
1914#define EEPROM_FREQ_OFFSET 0x3a
1915#define EEPROM_TXPOWER_BYRATE 0xde // 20MHZ power.
1916#define EEPROM_TXPOWER_DELTA 0x50 // 20MHZ AND 40 MHZ use different power. This is delta in 40MHZ.
1917#define VALID_EEPROM_VERSION 1
1918
1919// PairKeyMode definition
1920#define PKMODE_NONE 0
1921#define PKMODE_WEP64 1
1922#define PKMODE_WEP128 2
1923#define PKMODE_TKIP 3
1924#define PKMODE_AES 4
1925#define PKMODE_CKIP64 5
1926#define PKMODE_CKIP128 6
1927#define PKMODE_TKIP_NO_MIC 7 // MIC appended by driver: not a valid value in hardware key table
1928
1929// =================================================================================
1930// WCID format
1931// =================================================================================
1932//7.1 WCID ENTRY format : 8bytes
1933typedef struct _WCID_ENTRY_STRUC {
1934 UCHAR RXBABitmap7; // bit0 for TID8, bit7 for TID 15
1935 UCHAR RXBABitmap0; // bit0 for TID0, bit7 for TID 7
1936 UCHAR MAC[6]; // 0 for shared key table. 1 for pairwise key table
1937} WCID_ENTRY_STRUC, *PWCID_ENTRY_STRUC;
1938
1939//8.1.1 SECURITY KEY format : 8DW
1940// 32-byte per entry, total 16-entry for shared key table, 64-entry for pairwise key table
1941typedef struct _HW_KEY_ENTRY { // 32-byte per entry
1942 UCHAR Key[16];
1943 UCHAR TxMic[8];
1944 UCHAR RxMic[8];
1945} HW_KEY_ENTRY, *PHW_KEY_ENTRY;
1946
1947//8.1.2 IV/EIV format : 2DW
1948
1949//8.1.3 RX attribute entry format : 1DW
1950#ifdef RT_BIG_ENDIAN
1951typedef struct _MAC_ATTRIBUTE_STRUC {
1952 UINT32 rsv:22;
1953 UINT32 RXWIUDF:3;
1954 UINT32 BSSIDIdx:3; //multipleBSS index for the WCID
1955 UINT32 PairKeyMode:3;
1956 UINT32 KeyTab:1; // 0 for shared key table. 1 for pairwise key table
1957} MAC_ATTRIBUTE_STRUC, *PMAC_ATTRIBUTE_STRUC;
1958#else
1959typedef struct _MAC_ATTRIBUTE_STRUC {
1960 UINT32 KeyTab:1; // 0 for shared key table. 1 for pairwise key table
1961 UINT32 PairKeyMode:3;
1962 UINT32 BSSIDIdx:3; //multipleBSS index for the WCID
1963 UINT32 RXWIUDF:3;
1964 UINT32 rsv:22;
1965} MAC_ATTRIBUTE_STRUC, *PMAC_ATTRIBUTE_STRUC;
1966#endif
1967
1968
1969// =================================================================================
1970// TX / RX ring descriptor format
1971// =================================================================================
1972
1973// the first 24-byte in TXD is called TXINFO and will be DMAed to MAC block through TXFIFO.
1974// MAC block use this TXINFO to control the transmission behavior of this frame.
1975#define FIFO_MGMT 0
1976#define FIFO_HCCA 1
1977#define FIFO_EDCA 2
1978
1979//
1980// TX descriptor format, Tx ring, Mgmt Ring
1981//
1982#ifdef RT_BIG_ENDIAN
1983typedef struct PACKED _TXD_STRUC {
1984 // Word 0
1985 UINT32 SDPtr0;
1986 // Word 1
1987 UINT32 DMADONE:1;
1988 UINT32 LastSec0:1;
1989 UINT32 SDLen0:14;
1990 UINT32 Burst:1;
1991 UINT32 LastSec1:1;
1992 UINT32 SDLen1:14;
1993 // Word 2
1994 UINT32 SDPtr1;
1995 // Word 3
1996 UINT32 ICO:1;
1997 UINT32 UCO:1;
1998 UINT32 TCO:1;
1999 UINT32 rsv:2;
2000 UINT32 QSEL:2; // select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA
2001 UINT32 WIV:1; // Wireless Info Valid. 1 if Driver already fill WI, o if DMA needs to copy WI to correctposition
2002 UINT32 rsv2:24;
2003} TXD_STRUC, *PTXD_STRUC;
2004#else
2005typedef struct PACKED _TXD_STRUC {
2006 // Word 0
2007 UINT32 SDPtr0;
2008 // Word 1
2009 UINT32 SDLen1:14;
2010 UINT32 LastSec1:1;
2011 UINT32 Burst:1;
2012 UINT32 SDLen0:14;
2013 UINT32 LastSec0:1;
2014 UINT32 DMADONE:1;
2015 //Word2
2016 UINT32 SDPtr1;
2017 //Word3
2018 UINT32 rsv2:24;
2019 UINT32 WIV:1; // Wireless Info Valid. 1 if Driver already fill WI, o if DMA needs to copy WI to correctposition
2020 UINT32 QSEL:2; // select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA
2021 UINT32 rsv:2;
2022 UINT32 TCO:1; //
2023 UINT32 UCO:1; //
2024 UINT32 ICO:1; //
2025} TXD_STRUC, *PTXD_STRUC;
2026#endif
2027
2028
2029//
2030// TXD Wireless Information format for Tx ring and Mgmt Ring
2031//
2032//txop : for txop mode
2033// 0:txop for the MPDU frame will be handles by ASIC by register
2034// 1/2/3:the MPDU frame is send after PIFS/backoff/SIFS
2035#ifdef RT_BIG_ENDIAN
2036typedef struct PACKED _TXWI_STRUC {
2037 // Word 0
2038 UINT32 PHYMODE:2;
2039 UINT32 TxBF:1; // 3*3
2040 UINT32 rsv2:1;
2041// UINT32 rsv2:2;
2042 UINT32 Ifs:1; //
2043 UINT32 STBC:2; //channel bandwidth 20MHz or 40 MHz
2044 UINT32 ShortGI:1;
2045 UINT32 BW:1; //channel bandwidth 20MHz or 40 MHz
2046 UINT32 MCS:7;
2047
2048 UINT32 rsv:6;
2049 UINT32 txop:2; //tx back off mode 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs only when previous frame exchange is successful.
2050 UINT32 MpduDensity:3;
2051 UINT32 AMPDU:1;
2052
2053 UINT32 TS:1;
2054 UINT32 CFACK:1;
2055 UINT32 MIMOps:1; // the remote peer is in dynamic MIMO-PS mode
2056 UINT32 FRAG:1; // 1 to inform TKIP engine this is a fragment.
2057 // Word 1
2058 UINT32 PacketId:4;
2059 UINT32 MPDUtotalByteCount:12;
2060 UINT32 WirelessCliID:8;
2061 UINT32 BAWinSize:6;
2062 UINT32 NSEQ:1;
2063 UINT32 ACK:1;
2064 // Word 2
2065 UINT32 IV;
2066 // Word 3
2067 UINT32 EIV;
2068} TXWI_STRUC, *PTXWI_STRUC;
2069#else
2070typedef struct PACKED _TXWI_STRUC {
2071 // Word 0
2072 UINT32 FRAG:1; // 1 to inform TKIP engine this is a fragment.
2073 UINT32 MIMOps:1; // the remote peer is in dynamic MIMO-PS mode
2074 UINT32 CFACK:1;
2075 UINT32 TS:1;
2076
2077 UINT32 AMPDU:1;
2078 UINT32 MpduDensity:3;
2079 UINT32 txop:2; //FOR "THIS" frame. 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs only when previous frame exchange is successful.
2080 UINT32 rsv:6;
2081
2082 UINT32 MCS:7;
2083 UINT32 BW:1; //channel bandwidth 20MHz or 40 MHz
2084 UINT32 ShortGI:1;
2085 UINT32 STBC:2; // 1: STBC support MCS =0-7, 2,3 : RESERVE
2086 UINT32 Ifs:1; //
2087// UINT32 rsv2:2; //channel bandwidth 20MHz or 40 MHz
2088 UINT32 rsv2:1;
2089 UINT32 TxBF:1; // 3*3
2090 UINT32 PHYMODE:2;
2091 // Word 1
2092 UINT32 ACK:1;
2093 UINT32 NSEQ:1;
2094 UINT32 BAWinSize:6;
2095 UINT32 WirelessCliID:8;
2096 UINT32 MPDUtotalByteCount:12;
2097 UINT32 PacketId:4;
2098 //Word2
2099 UINT32 IV;
2100 //Word3
2101 UINT32 EIV;
2102} TXWI_STRUC, *PTXWI_STRUC;
2103#endif
2104//
2105// Rx descriptor format, Rx Ring
2106//
2107//
2108// RXWI wireless information format, in PBF. invisible in driver.
2109//
2110#ifdef RT_BIG_ENDIAN
2111typedef struct PACKED _RXWI_STRUC {
2112 // Word 0
2113 UINT32 TID:4;
2114 UINT32 MPDUtotalByteCount:12;
2115 UINT32 UDF:3;
2116 UINT32 BSSID:3;
2117 UINT32 KeyIndex:2;
2118 UINT32 WirelessCliID:8;
2119 // Word 1
2120 UINT32 PHYMODE:2; // 1: this RX frame is unicast to me
2121 UINT32 rsv:3;
2122 UINT32 STBC:2;
2123 UINT32 ShortGI:1;
2124 UINT32 BW:1;
2125 UINT32 MCS:7;
2126 UINT32 SEQUENCE:12;
2127 UINT32 FRAG:4;
2128 // Word 2
2129 UINT32 rsv1:8;
2130 UINT32 RSSI2:8;
2131 UINT32 RSSI1:8;
2132 UINT32 RSSI0:8;
2133 // Word 3
2134 UINT32 rsv2:16;
2135 UINT32 SNR1:8;
2136 UINT32 SNR0:8;
2137} RXWI_STRUC, *PRXWI_STRUC;
2138#else
2139typedef struct PACKED _RXWI_STRUC {
2140 // Word 0
2141 UINT32 WirelessCliID:8;
2142 UINT32 KeyIndex:2;
2143 UINT32 BSSID:3;
2144 UINT32 UDF:3;
2145 UINT32 MPDUtotalByteCount:12;
2146 UINT32 TID:4;
2147 // Word 1
2148 UINT32 FRAG:4;
2149 UINT32 SEQUENCE:12;
2150 UINT32 MCS:7;
2151 UINT32 BW:1;
2152 UINT32 ShortGI:1;
2153 UINT32 STBC:2;
2154 UINT32 rsv:3;
2155 UINT32 PHYMODE:2; // 1: this RX frame is unicast to me
2156 //Word2
2157 UINT32 RSSI0:8;
2158 UINT32 RSSI1:8;
2159 UINT32 RSSI2:8;
2160 UINT32 rsv1:8;
2161 //Word3
2162 UINT32 SNR0:8;
2163 UINT32 SNR1:8;
2164 UINT32 rsv2:16;
2165} RXWI_STRUC, *PRXWI_STRUC;
2166#endif
2167
2168
2169// =================================================================================
2170// HOST-MCU communication data structure
2171// =================================================================================
2172
2173//
2174// H2M_MAILBOX_CSR: Host-to-MCU Mailbox
2175//
2176#ifdef RT_BIG_ENDIAN
2177typedef union _H2M_MAILBOX_STRUC {
2178 struct {
2179 UINT32 Owner:8;
2180 UINT32 CmdToken:8; // 0xff tells MCU not to report CmdDoneInt after excuting the command
2181 UINT32 HighByte:8;
2182 UINT32 LowByte:8;
2183 } field;
2184 UINT32 word;
2185} H2M_MAILBOX_STRUC, *PH2M_MAILBOX_STRUC;
2186#else
2187typedef union _H2M_MAILBOX_STRUC {
2188 struct {
2189 UINT32 LowByte:8;
2190 UINT32 HighByte:8;
2191 UINT32 CmdToken:8;
2192 UINT32 Owner:8;
2193 } field;
2194 UINT32 word;
2195} H2M_MAILBOX_STRUC, *PH2M_MAILBOX_STRUC;
2196#endif
2197
2198//
2199// M2H_CMD_DONE_CSR: MCU-to-Host command complete indication
2200//
2201#ifdef RT_BIG_ENDIAN
2202typedef union _M2H_CMD_DONE_STRUC {
2203 struct {
2204 UINT32 CmdToken3;
2205 UINT32 CmdToken2;
2206 UINT32 CmdToken1;
2207 UINT32 CmdToken0;
2208 } field;
2209 UINT32 word;
2210} M2H_CMD_DONE_STRUC, *PM2H_CMD_DONE_STRUC;
2211#else
2212typedef union _M2H_CMD_DONE_STRUC {
2213 struct {
2214 UINT32 CmdToken0;
2215 UINT32 CmdToken1;
2216 UINT32 CmdToken2;
2217 UINT32 CmdToken3;
2218 } field;
2219 UINT32 word;
2220} M2H_CMD_DONE_STRUC, *PM2H_CMD_DONE_STRUC;
2221#endif
2222
2223
2224
2225//
2226// MCU_LEDCS: MCU LED Control Setting.
2227//
2228#ifdef RT_BIG_ENDIAN
2229typedef union _MCU_LEDCS_STRUC {
2230 struct {
2231 UCHAR Polarity:1;
2232 UCHAR LedMode:7;
2233 } field;
2234 UCHAR word;
2235} MCU_LEDCS_STRUC, *PMCU_LEDCS_STRUC;
2236#else
2237typedef union _MCU_LEDCS_STRUC {
2238 struct {
2239 UCHAR LedMode:7;
2240 UCHAR Polarity:1;
2241 } field;
2242 UCHAR word;
2243} MCU_LEDCS_STRUC, *PMCU_LEDCS_STRUC;
2244#endif
2245// =================================================================================
2246// Register format
2247// =================================================================================
2248
2249
2250
2251//NAV_TIME_CFG :NAV
2252#ifdef RT_BIG_ENDIAN
2253typedef union _NAV_TIME_CFG_STRUC {
2254 struct {
2255 USHORT rsv:6;
2256 USHORT ZeroSifs:1; // Applied zero SIFS timer after OFDM RX 0: disable
2257 USHORT Eifs:9; // in unit of 1-us
2258 UCHAR SlotTime; // in unit of 1-us
2259 UCHAR Sifs; // in unit of 1-us
2260 } field;
2261 UINT32 word;
2262} NAV_TIME_CFG_STRUC, *PNAV_TIME_CFG_STRUC;
2263#else
2264typedef union _NAV_TIME_CFG_STRUC {
2265 struct {
2266 UCHAR Sifs; // in unit of 1-us
2267 UCHAR SlotTime; // in unit of 1-us
2268 USHORT Eifs:9; // in unit of 1-us
2269 USHORT ZeroSifs:1; // Applied zero SIFS timer after OFDM RX 0: disable
2270 USHORT rsv:6;
2271 } field;
2272 UINT32 word;
2273} NAV_TIME_CFG_STRUC, *PNAV_TIME_CFG_STRUC;
2274#endif
2275
2276
2277
2278
2279
2280//
2281// RX_FILTR_CFG: /RX configuration register
2282//
2283#ifdef RT_BIG_ENDIAN
2284typedef union RX_FILTR_CFG_STRUC {
2285 struct {
2286 UINT32 :15;
2287 UINT32 DropRsvCntlType:1;
2288
2289 UINT32 DropBAR:1; //
2290 UINT32 DropBA:1; //
2291 UINT32 DropPsPoll:1; // Drop Ps-Poll
2292 UINT32 DropRts:1; // Drop Ps-Poll
2293
2294 UINT32 DropCts:1; // Drop Ps-Poll
2295 UINT32 DropAck:1; // Drop Ps-Poll
2296 UINT32 DropCFEnd:1; // Drop Ps-Poll
2297 UINT32 DropCFEndAck:1; // Drop Ps-Poll
2298
2299 UINT32 DropDuplicate:1; // Drop duplicate frame
2300 UINT32 DropBcast:1; // Drop broadcast frames
2301 UINT32 DropMcast:1; // Drop multicast frames
2302 UINT32 DropVerErr:1; // Drop version error frame
2303
2304 UINT32 DropNotMyBSSID:1; // Drop fram ToDs bit is true
2305 UINT32 DropNotToMe:1; // Drop not to me unicast frame
2306 UINT32 DropPhyErr:1; // Drop physical error
2307 UINT32 DropCRCErr:1; // Drop CRC error
2308 } field;
2309 UINT32 word;
2310} RX_FILTR_CFG_STRUC, *PRX_FILTR_CFG_STRUC;
2311#else
2312typedef union _RX_FILTR_CFG_STRUC {
2313 struct {
2314 UINT32 DropCRCErr:1; // Drop CRC error
2315 UINT32 DropPhyErr:1; // Drop physical error
2316 UINT32 DropNotToMe:1; // Drop not to me unicast frame
2317 UINT32 DropNotMyBSSID:1; // Drop fram ToDs bit is true
2318
2319 UINT32 DropVerErr:1; // Drop version error frame
2320 UINT32 DropMcast:1; // Drop multicast frames
2321 UINT32 DropBcast:1; // Drop broadcast frames
2322 UINT32 DropDuplicate:1; // Drop duplicate frame
2323
2324 UINT32 DropCFEndAck:1; // Drop Ps-Poll
2325 UINT32 DropCFEnd:1; // Drop Ps-Poll
2326 UINT32 DropAck:1; // Drop Ps-Poll
2327 UINT32 DropCts:1; // Drop Ps-Poll
2328
2329 UINT32 DropRts:1; // Drop Ps-Poll
2330 UINT32 DropPsPoll:1; // Drop Ps-Poll
2331 UINT32 DropBA:1; //
2332 UINT32 DropBAR:1; //
2333
2334 UINT32 DropRsvCntlType:1;
2335 UINT32 :15;
2336 } field;
2337 UINT32 word;
2338} RX_FILTR_CFG_STRUC, *PRX_FILTR_CFG_STRUC;
2339#endif
2340
2341
2342
2343
2344//
2345// PHY_CSR4: RF serial control register
2346//
2347#ifdef RT_BIG_ENDIAN
2348typedef union _PHY_CSR4_STRUC {
2349 struct {
2350 UINT32 Busy:1; // 1: ASIC is busy execute RF programming.
2351 UINT32 PLL_LD:1; // RF PLL_LD status
2352 UINT32 IFSelect:1; // 1: select IF to program, 0: select RF to program
2353 UINT32 NumberOfBits:5; // Number of bits used in RFRegValue (I:20, RFMD:22)
2354 UINT32 RFRegValue:24; // Register value (include register id) serial out to RF/IF chip.
2355 } field;
2356 UINT32 word;
2357} PHY_CSR4_STRUC, *PPHY_CSR4_STRUC;
2358#else
2359typedef union _PHY_CSR4_STRUC {
2360 struct {
2361 UINT32 RFRegValue:24; // Register value (include register id) serial out to RF/IF chip.
2362 UINT32 NumberOfBits:5; // Number of bits used in RFRegValue (I:20, RFMD:22)
2363 UINT32 IFSelect:1; // 1: select IF to program, 0: select RF to program
2364 UINT32 PLL_LD:1; // RF PLL_LD status
2365 UINT32 Busy:1; // 1: ASIC is busy execute RF programming.
2366 } field;
2367 UINT32 word;
2368} PHY_CSR4_STRUC, *PPHY_CSR4_STRUC;
2369#endif
2370
2371
2372//
2373// SEC_CSR5: shared key table security mode register
2374//
2375#ifdef RT_BIG_ENDIAN
2376typedef union _SEC_CSR5_STRUC {
2377 struct {
2378 UINT32 :1;
2379 UINT32 Bss3Key3CipherAlg:3;
2380 UINT32 :1;
2381 UINT32 Bss3Key2CipherAlg:3;
2382 UINT32 :1;
2383 UINT32 Bss3Key1CipherAlg:3;
2384 UINT32 :1;
2385 UINT32 Bss3Key0CipherAlg:3;
2386 UINT32 :1;
2387 UINT32 Bss2Key3CipherAlg:3;
2388 UINT32 :1;
2389 UINT32 Bss2Key2CipherAlg:3;
2390 UINT32 :1;
2391 UINT32 Bss2Key1CipherAlg:3;
2392 UINT32 :1;
2393 UINT32 Bss2Key0CipherAlg:3;
2394 } field;
2395 UINT32 word;
2396} SEC_CSR5_STRUC, *PSEC_CSR5_STRUC;
2397#else
2398typedef union _SEC_CSR5_STRUC {
2399 struct {
2400 UINT32 Bss2Key0CipherAlg:3;
2401 UINT32 :1;
2402 UINT32 Bss2Key1CipherAlg:3;
2403 UINT32 :1;
2404 UINT32 Bss2Key2CipherAlg:3;
2405 UINT32 :1;
2406 UINT32 Bss2Key3CipherAlg:3;
2407 UINT32 :1;
2408 UINT32 Bss3Key0CipherAlg:3;
2409 UINT32 :1;
2410 UINT32 Bss3Key1CipherAlg:3;
2411 UINT32 :1;
2412 UINT32 Bss3Key2CipherAlg:3;
2413 UINT32 :1;
2414 UINT32 Bss3Key3CipherAlg:3;
2415 UINT32 :1;
2416 } field;
2417 UINT32 word;
2418} SEC_CSR5_STRUC, *PSEC_CSR5_STRUC;
2419#endif
2420
2421
2422//
2423// HOST_CMD_CSR: For HOST to interrupt embedded processor
2424//
2425#ifdef RT_BIG_ENDIAN
2426typedef union _HOST_CMD_CSR_STRUC {
2427 struct {
2428 UINT32 Rsv:24;
2429 UINT32 HostCommand:8;
2430 } field;
2431 UINT32 word;
2432} HOST_CMD_CSR_STRUC, *PHOST_CMD_CSR_STRUC;
2433#else
2434typedef union _HOST_CMD_CSR_STRUC {
2435 struct {
2436 UINT32 HostCommand:8;
2437 UINT32 Rsv:24;
2438 } field;
2439 UINT32 word;
2440} HOST_CMD_CSR_STRUC, *PHOST_CMD_CSR_STRUC;
2441#endif
2442
2443
2444//
2445// AIFSN_CSR: AIFSN for each EDCA AC
2446//
2447
2448
2449
2450//
2451// E2PROM_CSR: EEPROM control register
2452//
2453#ifdef RT_BIG_ENDIAN
2454typedef union _E2PROM_CSR_STRUC {
2455 struct {
2456 UINT32 Rsvd:25;
2457 UINT32 LoadStatus:1; // 1:loading, 0:done
2458 UINT32 Type:1; // 1: 93C46, 0:93C66
2459 UINT32 EepromDO:1;
2460 UINT32 EepromDI:1;
2461 UINT32 EepromCS:1;
2462 UINT32 EepromSK:1;
2463 UINT32 Reload:1; // Reload EEPROM content, write one to reload, self-cleared.
2464 } field;
2465 UINT32 word;
2466} E2PROM_CSR_STRUC, *PE2PROM_CSR_STRUC;
2467#else
2468typedef union _E2PROM_CSR_STRUC {
2469 struct {
2470 UINT32 Reload:1; // Reload EEPROM content, write one to reload, self-cleared.
2471 UINT32 EepromSK:1;
2472 UINT32 EepromCS:1;
2473 UINT32 EepromDI:1;
2474 UINT32 EepromDO:1;
2475 UINT32 Type:1; // 1: 93C46, 0:93C66
2476 UINT32 LoadStatus:1; // 1:loading, 0:done
2477 UINT32 Rsvd:25;
2478 } field;
2479 UINT32 word;
2480} E2PROM_CSR_STRUC, *PE2PROM_CSR_STRUC;
2481#endif
2482
2483
2484// -------------------------------------------------------------------
2485// E2PROM data layout
2486// -------------------------------------------------------------------
2487
2488//
2489// EEPROM antenna select format
2490//
2491#ifdef RT_BIG_ENDIAN
2492typedef union _EEPROM_ANTENNA_STRUC {
2493 struct {
2494 USHORT Rsv:4;
2495 USHORT RfIcType:4; // see E2PROM document
2496 USHORT TxPath:4; // 1: 1T, 2: 2T
2497 USHORT RxPath:4; // 1: 1R, 2: 2R, 3: 3R
2498 } field;
2499 USHORT word;
2500} EEPROM_ANTENNA_STRUC, *PEEPROM_ANTENNA_STRUC;
2501#else
2502typedef union _EEPROM_ANTENNA_STRUC {
2503 struct {
2504 USHORT RxPath:4; // 1: 1R, 2: 2R, 3: 3R
2505 USHORT TxPath:4; // 1: 1T, 2: 2T
2506 USHORT RfIcType:4; // see E2PROM document
2507 USHORT Rsv:4;
2508 } field;
2509 USHORT word;
2510} EEPROM_ANTENNA_STRUC, *PEEPROM_ANTENNA_STRUC;
2511#endif
2512
2513#ifdef RT_BIG_ENDIAN
2514typedef union _EEPROM_NIC_CINFIG2_STRUC {
2515 struct {
2516 USHORT DACTestBit:1; // control if driver should patch the DAC issue
2517 USHORT Rsv2:3; // must be 0
2518 USHORT AntDiversity:1; // Antenna diversity
2519 USHORT Rsv1:1; // must be 0
2520 USHORT BW40MAvailForA:1; // 0:enable, 1:disable
2521 USHORT BW40MAvailForG:1; // 0:enable, 1:disable
2522 USHORT EnableWPSPBC:1; // WPS PBC Control bit
2523 USHORT BW40MSidebandForA:1;
2524 USHORT BW40MSidebandForG:1;
2525 USHORT CardbusAcceleration:1; // !!! NOTE: 0 - enable, 1 - disable
2526 USHORT ExternalLNAForA:1; // external LNA enable for 5G
2527 USHORT ExternalLNAForG:1; // external LNA enable for 2.4G
2528 USHORT DynamicTxAgcControl:1; //
2529 USHORT HardwareRadioControl:1; // Whether RF is controlled by driver or HW. 1:enable hw control, 0:disable
2530 } field;
2531 USHORT word;
2532} EEPROM_NIC_CONFIG2_STRUC, *PEEPROM_NIC_CONFIG2_STRUC;
2533#else
2534typedef union _EEPROM_NIC_CINFIG2_STRUC {
2535 struct {
2536 USHORT HardwareRadioControl:1; // 1:enable, 0:disable
2537 USHORT DynamicTxAgcControl:1; //
2538 USHORT ExternalLNAForG:1; //
2539 USHORT ExternalLNAForA:1; // external LNA enable for 2.4G
2540 USHORT CardbusAcceleration:1; // !!! NOTE: 0 - enable, 1 - disable
2541 USHORT BW40MSidebandForG:1;
2542 USHORT BW40MSidebandForA:1;
2543 USHORT EnableWPSPBC:1; // WPS PBC Control bit
2544 USHORT BW40MAvailForG:1; // 0:enable, 1:disable
2545 USHORT BW40MAvailForA:1; // 0:enable, 1:disable
2546 USHORT Rsv1:1; // must be 0
2547 USHORT AntDiversity:1; // Antenna diversity
2548 USHORT Rsv2:3; // must be 0
2549 USHORT DACTestBit:1; // control if driver should patch the DAC issue
2550 } field;
2551 USHORT word;
2552} EEPROM_NIC_CONFIG2_STRUC, *PEEPROM_NIC_CONFIG2_STRUC;
2553#endif
2554
2555//
2556// TX_PWR Value valid range 0xFA(-6) ~ 0x24(36)
2557//
2558#ifdef RT_BIG_ENDIAN
2559typedef union _EEPROM_TX_PWR_STRUC {
2560 struct {
2561 CHAR Byte1; // High Byte
2562 CHAR Byte0; // Low Byte
2563 } field;
2564 USHORT word;
2565} EEPROM_TX_PWR_STRUC, *PEEPROM_TX_PWR_STRUC;
2566#else
2567typedef union _EEPROM_TX_PWR_STRUC {
2568 struct {
2569 CHAR Byte0; // Low Byte
2570 CHAR Byte1; // High Byte
2571 } field;
2572 USHORT word;
2573} EEPROM_TX_PWR_STRUC, *PEEPROM_TX_PWR_STRUC;
2574#endif
2575
2576#ifdef RT_BIG_ENDIAN
2577typedef union _EEPROM_VERSION_STRUC {
2578 struct {
2579 UCHAR Version; // High Byte
2580 UCHAR FaeReleaseNumber; // Low Byte
2581 } field;
2582 USHORT word;
2583} EEPROM_VERSION_STRUC, *PEEPROM_VERSION_STRUC;
2584#else
2585typedef union _EEPROM_VERSION_STRUC {
2586 struct {
2587 UCHAR FaeReleaseNumber; // Low Byte
2588 UCHAR Version; // High Byte
2589 } field;
2590 USHORT word;
2591} EEPROM_VERSION_STRUC, *PEEPROM_VERSION_STRUC;
2592#endif
2593
2594#ifdef RT_BIG_ENDIAN
2595typedef union _EEPROM_LED_STRUC {
2596 struct {
2597 USHORT Rsvd:3; // Reserved
2598 USHORT LedMode:5; // Led mode.
2599 USHORT PolarityGPIO_4:1; // Polarity GPIO#4 setting.
2600 USHORT PolarityGPIO_3:1; // Polarity GPIO#3 setting.
2601 USHORT PolarityGPIO_2:1; // Polarity GPIO#2 setting.
2602 USHORT PolarityGPIO_1:1; // Polarity GPIO#1 setting.
2603 USHORT PolarityGPIO_0:1; // Polarity GPIO#0 setting.
2604 USHORT PolarityACT:1; // Polarity ACT setting.
2605 USHORT PolarityRDY_A:1; // Polarity RDY_A setting.
2606 USHORT PolarityRDY_G:1; // Polarity RDY_G setting.
2607 } field;
2608 USHORT word;
2609} EEPROM_LED_STRUC, *PEEPROM_LED_STRUC;
2610#else
2611typedef union _EEPROM_LED_STRUC {
2612 struct {
2613 USHORT PolarityRDY_G:1; // Polarity RDY_G setting.
2614 USHORT PolarityRDY_A:1; // Polarity RDY_A setting.
2615 USHORT PolarityACT:1; // Polarity ACT setting.
2616 USHORT PolarityGPIO_0:1; // Polarity GPIO#0 setting.
2617 USHORT PolarityGPIO_1:1; // Polarity GPIO#1 setting.
2618 USHORT PolarityGPIO_2:1; // Polarity GPIO#2 setting.
2619 USHORT PolarityGPIO_3:1; // Polarity GPIO#3 setting.
2620 USHORT PolarityGPIO_4:1; // Polarity GPIO#4 setting.
2621 USHORT LedMode:5; // Led mode.
2622 USHORT Rsvd:3; // Reserved
2623 } field;
2624 USHORT word;
2625} EEPROM_LED_STRUC, *PEEPROM_LED_STRUC;
2626#endif
2627
2628#ifdef RT_BIG_ENDIAN
2629typedef union _EEPROM_TXPOWER_DELTA_STRUC {
2630 struct {
2631 UCHAR TxPowerEnable:1;// Enable
2632 UCHAR Type:1; // 1: plus the delta value, 0: minus the delta value
2633 UCHAR DeltaValue:6; // Tx Power dalta value (MAX=4)
2634 } field;
2635 UCHAR value;
2636} EEPROM_TXPOWER_DELTA_STRUC, *PEEPROM_TXPOWER_DELTA_STRUC;
2637#else
2638typedef union _EEPROM_TXPOWER_DELTA_STRUC {
2639 struct {
2640 UCHAR DeltaValue:6; // Tx Power dalta value (MAX=4)
2641 UCHAR Type:1; // 1: plus the delta value, 0: minus the delta value
2642 UCHAR TxPowerEnable:1;// Enable
2643 } field;
2644 UCHAR value;
2645} EEPROM_TXPOWER_DELTA_STRUC, *PEEPROM_TXPOWER_DELTA_STRUC;
2646#endif
2647
2648//
2649// QOS_CSR0: TXOP holder address0 register
2650//
2651#ifdef RT_BIG_ENDIAN
2652typedef union _QOS_CSR0_STRUC {
2653 struct {
2654 UCHAR Byte3; // MAC address byte 3
2655 UCHAR Byte2; // MAC address byte 2
2656 UCHAR Byte1; // MAC address byte 1
2657 UCHAR Byte0; // MAC address byte 0
2658 } field;
2659 UINT32 word;
2660} QOS_CSR0_STRUC, *PQOS_CSR0_STRUC;
2661#else
2662typedef union _QOS_CSR0_STRUC {
2663 struct {
2664 UCHAR Byte0; // MAC address byte 0
2665 UCHAR Byte1; // MAC address byte 1
2666 UCHAR Byte2; // MAC address byte 2
2667 UCHAR Byte3; // MAC address byte 3
2668 } field;
2669 UINT32 word;
2670} QOS_CSR0_STRUC, *PQOS_CSR0_STRUC;
2671#endif
2672
2673//
2674// QOS_CSR1: TXOP holder address1 register
2675//
2676#ifdef RT_BIG_ENDIAN
2677typedef union _QOS_CSR1_STRUC {
2678 struct {
2679 UCHAR Rsvd1;
2680 UCHAR Rsvd0;
2681 UCHAR Byte5; // MAC address byte 5
2682 UCHAR Byte4; // MAC address byte 4
2683 } field;
2684 UINT32 word;
2685} QOS_CSR1_STRUC, *PQOS_CSR1_STRUC;
2686#else
2687typedef union _QOS_CSR1_STRUC {
2688 struct {
2689 UCHAR Byte4; // MAC address byte 4
2690 UCHAR Byte5; // MAC address byte 5
2691 UCHAR Rsvd0;
2692 UCHAR Rsvd1;
2693 } field;
2694 UINT32 word;
2695} QOS_CSR1_STRUC, *PQOS_CSR1_STRUC;
2696#endif
2697
2698#define RF_CSR_CFG 0x500
2699#ifdef RT_BIG_ENDIAN
2700typedef union _RF_CSR_CFG_STRUC {
2701 struct {
2702 UINT Rsvd1:14; // Reserved
2703 UINT RF_CSR_KICK:1; // kick RF register read/write
2704 UINT RF_CSR_WR:1; // 0: read 1: write
2705 UINT Rsvd2:3; // Reserved
2706 UINT TESTCSR_RFACC_REGNUM:5; // RF register ID
2707 UINT RF_CSR_DATA:8; // DATA
2708 } field;
2709 UINT word;
2710} RF_CSR_CFG_STRUC, *PRF_CSR_CFG_STRUC;
2711#else
2712typedef union _RF_CSR_CFG_STRUC {
2713 struct {
2714 UINT RF_CSR_DATA:8; // DATA
2715 UINT TESTCSR_RFACC_REGNUM:5; // RF register ID
2716 UINT Rsvd2:3; // Reserved
2717 UINT RF_CSR_WR:1; // 0: read 1: write
2718 UINT RF_CSR_KICK:1; // kick RF register read/write
2719 UINT Rsvd1:14; // Reserved
2720 } field;
2721 UINT word;
2722} RF_CSR_CFG_STRUC, *PRF_CSR_CFG_STRUC;
2723#endif
2724
2725#endif // __RT28XX_H__
diff --git a/drivers/staging/rt3070/rt_ate.c b/drivers/staging/rt3070/rt_ate.c
new file mode 100644
index 000000000000..9238d960121c
--- /dev/null
+++ b/drivers/staging/rt3070/rt_ate.c
@@ -0,0 +1,6506 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26 */
27
28#include "rt_config.h"
29
30#ifdef UCOS
31INT IoctlResponse(PUCHAR payload, PUCHAR msg, INT len);
32#endif // UCOS //
33
34#define ATE_BBP_REG_NUM 168
35UCHAR restore_BBP[ATE_BBP_REG_NUM]={0};
36
37#ifdef RALINK_ATE
38UCHAR TemplateFrame[24] = {0x08/* Data type */,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0xAA,0xBB,0x12,0x34,0x56,0x00,0x11,0x22,0xAA,0xBB,0xCC,0x00,0x00}; // 802.11 MAC Header, Type:Data, Length:24bytes
39extern RTMP_RF_REGS RF2850RegTable[];
40extern UCHAR NUM_OF_2850_CHNL;
41
42#ifdef RT2870
43extern UCHAR EpToQueue[];
44extern VOID RTUSBRejectPendingPackets( IN PRTMP_ADAPTER pAd);
45#endif // RT2870 //
46
47#ifdef RT30xx
48//2008/07/10:KH adds to support 3070 ATE<--
49extern FREQUENCY_ITEM FreqItems3020[];
50extern UCHAR NUM_OF_3020_CHNL;
51//2008/07/10:KH adds to support 3070 ATE-->
52#endif // RT30xx //
53
54#ifdef UCOS
55extern INT ConsoleResponse(IN PUCHAR buff);
56extern int (*remote_display)(char *);
57#endif // UCOS //
58
59static CHAR CCKRateTable[] = {0, 1, 2, 3, 8, 9, 10, 11, -1}; /* CCK Mode. */
60static CHAR OFDMRateTable[] = {0, 1, 2, 3, 4, 5, 6, 7, -1}; /* OFDM Mode. */
61static CHAR HTMIXRateTable[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1}; /* HT Mix Mode. */
62
63static INT TxDmaBusy(
64 IN PRTMP_ADAPTER pAd);
65
66static INT RxDmaBusy(
67 IN PRTMP_ADAPTER pAd);
68
69static VOID RtmpDmaEnable(
70 IN PRTMP_ADAPTER pAd,
71 IN INT Enable);
72
73static VOID BbpSoftReset(
74 IN PRTMP_ADAPTER pAd);
75
76static VOID RtmpRfIoWrite(
77 IN PRTMP_ADAPTER pAd);
78
79static INT ATESetUpFrame(
80 IN PRTMP_ADAPTER pAd,
81 IN UINT32 TxIdx);
82
83static INT ATETxPwrHandler(
84 IN PRTMP_ADAPTER pAd,
85 IN char index);
86
87static INT ATECmdHandler(
88 IN PRTMP_ADAPTER pAd,
89 IN PUCHAR arg);
90
91static int CheckMCSValid(
92 IN UCHAR Mode,
93 IN UCHAR Mcs);
94
95
96#ifdef RT2870
97static VOID ATEWriteTxInfo(
98 IN PRTMP_ADAPTER pAd,
99 IN PTXINFO_STRUC pTxInfo,
100 IN USHORT USBDMApktLen,
101 IN BOOLEAN bWiv,
102 IN UCHAR QueueSel,
103 IN UCHAR NextValid,
104 IN UCHAR TxBurst);
105
106static VOID ATEWriteTxWI(
107 IN PRTMP_ADAPTER pAd,
108 IN PTXWI_STRUC pTxWI,
109 IN BOOLEAN FRAG,
110 IN BOOLEAN InsTimestamp,
111 IN BOOLEAN AMPDU,
112 IN BOOLEAN Ack,
113 IN BOOLEAN NSeq, // HW new a sequence.
114 IN UCHAR BASize,
115 IN UCHAR WCID,
116 IN ULONG Length,
117 IN UCHAR PID,
118 IN UCHAR MIMOps,
119 IN UCHAR Txopmode,
120 IN BOOLEAN CfAck,
121 IN HTTRANSMIT_SETTING Transmit);
122
123#endif // RT2870 //
124
125static VOID SetJapanFilter(
126 IN PRTMP_ADAPTER pAd);
127
128/*=========================end of prototype=========================*/
129
130
131#ifdef RT2870
132static INT TxDmaBusy(
133 IN PRTMP_ADAPTER pAd)
134{
135 INT result;
136 USB_DMA_CFG_STRUC UsbCfg;
137
138 RTMP_IO_READ32(pAd, USB_DMA_CFG, &UsbCfg.word); // disable DMA
139 if (UsbCfg.field.TxBusy)
140 result = 1;
141 else
142 result = 0;
143
144 return result;
145}
146
147static INT RxDmaBusy(
148 IN PRTMP_ADAPTER pAd)
149{
150 INT result;
151 USB_DMA_CFG_STRUC UsbCfg;
152
153 RTMP_IO_READ32(pAd, USB_DMA_CFG, &UsbCfg.word); // disable DMA
154 if (UsbCfg.field.RxBusy)
155 result = 1;
156 else
157 result = 0;
158
159 return result;
160}
161
162static VOID RtmpDmaEnable(
163 IN PRTMP_ADAPTER pAd,
164 IN INT Enable)
165{
166 BOOLEAN value;
167 ULONG WaitCnt;
168 USB_DMA_CFG_STRUC UsbCfg;
169
170 value = Enable > 0 ? 1 : 0;
171
172 // check DMA is in busy mode.
173 WaitCnt = 0;
174 while (TxDmaBusy(pAd) || RxDmaBusy(pAd))
175 {
176 RTMPusecDelay(10);
177 if (WaitCnt++ > 100)
178 break;
179 }
180
181 //Why not to clear USB DMA TX path first ???
182 RTMP_IO_READ32(pAd, USB_DMA_CFG, &UsbCfg.word); // disable DMA
183 UsbCfg.field.TxBulkEn = value;
184 UsbCfg.field.RxBulkEn = value;
185 RTMP_IO_WRITE32(pAd, USB_DMA_CFG, UsbCfg.word); // abort all TX rings
186 RTMPusecDelay(5000);
187
188 return;
189}
190#endif // RT2870 //
191
192static VOID BbpSoftReset(
193 IN PRTMP_ADAPTER pAd)
194{
195 UCHAR BbpData = 0;
196
197 // Soft reset, set BBP R21 bit0=1->0
198 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R21, &BbpData);
199 BbpData |= 0x00000001; //set bit0=1
200 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R21, BbpData);
201
202 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R21, &BbpData);
203 BbpData &= ~(0x00000001); //set bit0=0
204 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R21, BbpData);
205
206 return;
207}
208
209static VOID RtmpRfIoWrite(
210 IN PRTMP_ADAPTER pAd)
211{
212 // Set RF value 1's set R3[bit2] = [0]
213 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
214 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
215 RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
216 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
217
218 RTMPusecDelay(200);
219
220 // Set RF value 2's set R3[bit2] = [1]
221 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
222 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
223 RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 | 0x04));
224 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
225
226 RTMPusecDelay(200);
227
228 // Set RF value 3's set R3[bit2] = [0]
229 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
230 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
231 RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
232 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
233
234 return;
235}
236
237static int CheckMCSValid(
238 UCHAR Mode,
239 UCHAR Mcs)
240{
241 int i;
242 PCHAR pRateTab;
243
244 switch(Mode)
245 {
246 case 0:
247 pRateTab = CCKRateTable;
248 break;
249 case 1:
250 pRateTab = OFDMRateTable;
251 break;
252 case 2:
253 case 3:
254 pRateTab = HTMIXRateTable;
255 break;
256 default:
257 ATEDBGPRINT(RT_DEBUG_ERROR, ("unrecognizable Tx Mode %d\n", Mode));
258 return -1;
259 break;
260 }
261
262 i = 0;
263 while(pRateTab[i] != -1)
264 {
265 if (pRateTab[i] == Mcs)
266 return 0;
267 i++;
268 }
269
270 return -1;
271}
272
273#if 1
274static INT ATETxPwrHandler(
275 IN PRTMP_ADAPTER pAd,
276 IN char index)
277{
278 ULONG R;
279 CHAR TxPower;
280 UCHAR Bbp94 = 0;
281 BOOLEAN bPowerReduce = FALSE;
282#ifdef RT30xx
283 UCHAR RFValue;
284#endif // RT30xx //
285#ifdef RALINK_28xx_QA
286 if ((pAd->ate.bQATxStart == TRUE) || (pAd->ate.bQARxStart == TRUE))
287 {
288 /* When QA is used for Tx, pAd->ate.TxPower0/1 and real tx power
289 ** are not synchronized.
290 */
291/*
292 pAd->ate.TxPower0 = pAd->LatchRfRegs.xxx;
293 pAd->ate.TxPower1 = pAd->LatchRfRegs.xxx;
294*/
295 return 0;
296 }
297 else
298#endif // RALINK_28xx_QA //
299 {
300 TxPower = index == 0 ? pAd->ate.TxPower0 : pAd->ate.TxPower1;
301
302 if (pAd->ate.Channel <= 14)
303 {
304 if (TxPower > 31)
305 {
306 //
307 // R3, R4 can't large than 31 (0x24), 31 ~ 36 used by BBP 94
308 //
309 R = 31;
310 if (TxPower <= 36)
311 Bbp94 = BBPR94_DEFAULT + (UCHAR)(TxPower - 31);
312 }
313 else if (TxPower < 0)
314 {
315 //
316 // R3, R4 can't less than 0, -1 ~ -6 used by BBP 94
317 //
318 R = 0;
319 if (TxPower >= -6)
320 Bbp94 = BBPR94_DEFAULT + TxPower;
321 }
322 else
323 {
324 // 0 ~ 31
325 R = (ULONG) TxPower;
326 Bbp94 = BBPR94_DEFAULT;
327 }
328
329 ATEDBGPRINT(RT_DEBUG_TRACE, ("%s (TxPower=%d, R=%ld, BBP_R94=%d)\n", __FUNCTION__, TxPower, R, Bbp94));
330 }
331 else// 5.5 GHz
332 {
333 if (TxPower > 15)
334 {
335 //
336 // R3, R4 can't large than 15 (0x0F)
337 //
338 R = 15;
339 }
340 else if (TxPower < 0)
341 {
342 //
343 // R3, R4 can't less than 0
344 //
345 // -1 ~ -7
346 ASSERT((TxPower >= -7));
347 R = (ULONG)(TxPower + 7);
348 bPowerReduce = TRUE;
349 }
350 else
351 {
352 // 0 ~ 15
353 R = (ULONG) TxPower;
354 }
355
356 ATEDBGPRINT(RT_DEBUG_TRACE, ("%s (TxPower=%d, R=%lu)\n", __FUNCTION__, TxPower, R));
357 }
358//2008/09/10:KH adds to support 3070 ATE TX Power tunning real time<--
359#ifdef RT30xx
360 if(IS_RT30xx(pAd))
361 {
362 // Set Tx Power
363
364 RT30xxReadRFRegister(pAd, RF_R12, (PUCHAR)&RFValue);
365 RFValue = (RFValue & 0xE0) | TxPower;
366 RT30xxWriteRFRegister(pAd, RF_R12, (UCHAR)RFValue);
367 ATEDBGPRINT(RT_DEBUG_TRACE, ("3070 or 2070:%s (TxPower=%d, RFValue=%x)\n", __FUNCTION__, TxPower, RFValue));
368
369 }
370 else
371#endif // RT30xx //
372 {
373 if (pAd->ate.Channel <= 14)
374 {
375 if (index == 0)
376 {
377 R = R << 9; // shift TX power control to correct RF(R3) register bit position
378 R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
379 pAd->LatchRfRegs.R3 = R;
380 }
381 else
382 {
383 R = R << 6; // shift TX power control to correct RF(R4) register bit position
384 R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
385 pAd->LatchRfRegs.R4 = R;
386 }
387 }
388 else// 5.5GHz
389 {
390 if (bPowerReduce == FALSE)
391 {
392 if (index == 0)
393 {
394 R = (R << 10) | (1 << 9); // shift TX power control to correct RF(R3) register bit position
395 R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
396 pAd->LatchRfRegs.R3 = R;
397 }
398 else
399 {
400 R = (R << 7) | (1 << 6); // shift TX power control to correct RF(R4) register bit position
401 R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
402 pAd->LatchRfRegs.R4 = R;
403 }
404 }
405 else
406 {
407 if (index == 0)
408 {
409 R = (R << 10); // shift TX power control to correct RF(R3) register bit position
410 R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
411
412 /* Clear bit 9 of R3 to reduce 7dB. */
413 pAd->LatchRfRegs.R3 = (R & (~(1 << 9)));
414 }
415 else
416 {
417 R = (R << 7); // shift TX power control to correct RF(R4) register bit position
418 R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
419
420 /* Clear bit 6 of R4 to reduce 7dB. */
421 pAd->LatchRfRegs.R4 = (R & (~(1 << 6)));
422 }
423 }
424 }
425 RtmpRfIoWrite(pAd);
426 }
427//2008/09/10:KH adds to support 3070 ATE TX Power tunning real time-->
428
429 return 0;
430 }
431}
432#else// 1 //
433static INT ATETxPwrHandler(
434 IN PRTMP_ADAPTER pAd,
435 IN char index)
436{
437 ULONG R;
438 CHAR TxPower;
439 UCHAR Bbp94 = 0;
440
441#ifdef RALINK_28xx_QA
442 if ((pAd->ate.bQATxStart == TRUE) || (pAd->ate.bQARxStart == TRUE))
443 {
444 // TODO: how to get current TxPower0/1 from pAd->LatchRfRegs ?
445 /* When QA is used for Tx, pAd->ate.TxPower0/1 and real tx power
446 ** are not synchronized.
447 */
448/*
449 pAd->ate.TxPower0 = pAd->LatchRfRegs.xxx;
450 pAd->ate.TxPower1 = pAd->LatchRfRegs.xxx;
451*/
452 return 0;
453 }
454 else
455#endif // RALINK_28xx_QA //
456 {
457 TxPower = index == 0 ? pAd->ate.TxPower0 : pAd->ate.TxPower1;
458
459 if (TxPower > 31)
460 {
461 //
462 // R3, R4 can't large than 36 (0x24), 31 ~ 36 used by BBP 94
463 //
464 R = 31;
465 if (TxPower <= 36)
466 Bbp94 = BBPR94_DEFAULT + (UCHAR)(TxPower - 31);
467 }
468 else if (TxPower < 0)
469 {
470 //
471 // R3, R4 can't less than 0, -1 ~ -6 used by BBP 94
472 //
473 R = 0;
474 if (TxPower >= -6)
475 Bbp94 = BBPR94_DEFAULT + TxPower;
476 }
477 else
478 {
479 // 0 ~ 31
480 R = (ULONG) TxPower;
481 Bbp94 = BBPR94_DEFAULT;
482 }
483
484 ATEDBGPRINT(RT_DEBUG_TRACE, ("%s (TxPower=%d, R3=%ld, BBP_R94=%d)\n", __FUNCTION__, TxPower, R, Bbp94));
485
486 if (pAd->ate.Channel <= 14)
487 {
488 if (index == 0)
489 {
490 R = R << 9; // shift TX power control to correct RF(R3) register bit position
491 R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
492 pAd->LatchRfRegs.R3 = R;
493 }
494 else
495 {
496 R = R << 6; // shift TX power control to correct RF(R4) register bit position
497 R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
498 pAd->LatchRfRegs.R4 = R;
499 }
500 }
501 else
502 {
503 if (index == 0)
504 {
505 R = (R << 10) | (1 << 9); // shift TX power control to correct RF(R3) register bit position
506 R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
507 pAd->LatchRfRegs.R3 = R;
508 }
509 else
510 {
511 R = (R << 7) | (1 << 6); // shift TX power control to correct RF(R4) register bit position
512 R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
513 pAd->LatchRfRegs.R4 = R;
514 }
515 }
516
517 RtmpRfIoWrite(pAd);
518
519 return 0;
520 }
521}
522#endif // 1 //
523/*
524 ==========================================================================
525 Description:
526 Set ATE operation mode to
527 0. ATESTART = Start ATE Mode
528 1. ATESTOP = Stop ATE Mode
529 2. TXCONT = Continuous Transmit
530 3. TXCARR = Transmit Carrier
531 4. TXFRAME = Transmit Frames
532 5. RXFRAME = Receive Frames
533#ifdef RALINK_28xx_QA
534 6. TXSTOP = Stop Any Type of Transmition
535 7. RXSTOP = Stop Receiving Frames
536#endif // RALINK_28xx_QA //
537 Return:
538 TRUE if all parameters are OK, FALSE otherwise
539 ==========================================================================
540*/
541/* */
542/* */
543/*=======================End of RT2860=======================*/
544
545
546/*======================Start of RT2870======================*/
547/* */
548/* */
549
550#ifdef RT2870
551static INT ATECmdHandler(
552 IN PRTMP_ADAPTER pAd,
553 IN PUCHAR arg)
554{
555 UINT32 Value;
556 UCHAR BbpData;
557 UINT32 MacData;
558 UINT i=0, atemode;
559 //NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
560 //PUCHAR pDest;
561 UINT32 temp;
562 ULONG IrqFlags;
563
564 ATEDBGPRINT(RT_DEBUG_TRACE, ("===> ATECmdHandler()\n"));
565 ATEAsicSwitchChannel(pAd);
566 /* AsicLockChannel() is empty function so far in fact */
567 AsicLockChannel(pAd, pAd->ate.Channel);
568
569 RTMPusecDelay(5000);
570
571 // Default value in BBP R22 is 0x0.
572 BbpData = 0;
573
574 /* Enter ATE mode and set Tx/Rx Idle */
575 if (!strcmp(arg, "ATESTART"))
576 {
577#ifdef CONFIG_STA_SUPPORT
578 BOOLEAN Cancelled;
579#endif // CONFIG_STA_SUPPORT //
580 ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: ATESTART\n"));
581
582 netif_stop_queue(pAd->net_dev);
583
584 atemode = pAd->ate.Mode;
585 pAd->ate.Mode = ATE_START;
586// pAd->ate.TxDoneCount = pAd->ate.TxCount;
587 // Disable Rx
588 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
589 Value &= ~(1 << 3);
590 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
591
592 // Disable auto responder
593 RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &temp);
594 temp = temp & 0xFFFFFFFE;
595 RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, temp);
596
597 // read MAC_SYS_CTRL and backup MAC_SYS_CTRL value.
598 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
599 // clean bit4 to stop continuous Tx production test.
600 MacData &= 0xFFFFFFEF;
601 // Stop continuous TX production test.
602 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);//disable or cancel pending irp first ???
603
604 if (atemode & ATE_TXCARR
605#ifdef RT30xx
606 || atemode & ATE_TXCONT
607#endif // RT30xx //
608)
609 {
610#ifdef RT30xx
611 //Hardware Reset BBP
612 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &temp);
613 temp = temp |0x00000002;
614 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, temp);
615 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &temp);
616 temp = temp & ~(0x00000002);
617 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, temp);
618 //Restore All BBP Value
619 for(i=0;i<ATE_BBP_REG_NUM;i++)
620 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd,i,restore_BBP[i]);
621#endif // RT30xx //
622
623 // No Carrier Test set BBP R22 bit7=0, bit6=0, bit[5~0]=0x0
624 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
625 BbpData &= 0xFFFFFF00; //clear bit7, bit6, bit[5~0]
626 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
627 }
628 else if (atemode & ATE_TXCARRSUPP)
629 {
630#ifdef RT30xx
631 //Hardware Reset BBP
632 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &temp);
633 temp = temp |0x00000002;
634 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, temp);
635 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &temp);
636 temp = temp & ~(0x00000002);
637 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, temp);
638 //Restore All BBP Value
639 for(i=0;i<ATE_BBP_REG_NUM;i++)
640 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd,i,restore_BBP[i]);
641#endif // RT30xx //
642
643 // No Cont. TX set BBP R22 bit7=0
644 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
645 BbpData &= ~(1 << 7); //set bit7=0
646 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
647
648 // No Carrier Suppression set BBP R24 bit0=0
649 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R24, &BbpData);
650 BbpData &= 0xFFFFFFFE; //clear bit0
651 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, BbpData);
652 }
653 // We should free some resource which allocate when ATE_TXFRAME , ATE_STOP, and ATE_TXCONT.
654 // TODO:Should we free some resource which was allocated when LoopBack and ATE_STOP ?
655 else if ((atemode & ATE_TXFRAME) || (atemode == ATE_STOP))
656 {
657 if (atemode & ATE_TXCONT)
658 {
659 // Not Cont. TX anymore, so set BBP R22 bit7=0
660 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
661 BbpData &= ~(1 << 7); //set bit7=0
662 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
663 }
664 // Abort Tx, Rx DMA.
665 RtmpDmaEnable(pAd, 0);
666
667 {
668 // It seems nothing to free,
669 // because we didn't allocate any resource when we entered ATE_TXFRAME mode latestly.
670 }
671
672 // Start Tx, RX DMA
673 RtmpDmaEnable(pAd, 1);
674 }
675
676 RTUSBRejectPendingPackets(pAd);
677 RTUSBCleanUpDataBulkOutQueue(pAd);
678
679#ifdef CONFIG_STA_SUPPORT
680 //
681 // It will be called in MlmeSuspend().
682 //
683 // Cancel pending timers
684 RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled);
685 RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled);
686 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
687 RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled);
688 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled);
689 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
690#endif // CONFIG_STA_SUPPORT //
691
692 //RTUSBCleanUpMLMEWaitQueue(pAd); /* not used in RT28xx */
693 RTUSBCleanUpMLMEBulkOutQueue(pAd);
694
695 // Sometimes kernel will hang on, so we avoid calling MlmeSuspend().
696// MlmeSuspend(pAd, TRUE);
697 //RTMPCancelTimer(&pAd->Mlme.PeriodicTimer, &Cancelled);
698
699 // Disable Rx
700 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
701 Value &= ~(1 << 3);
702 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
703
704 // Abort Tx, RX DMA.
705 RtmpDmaEnable(pAd, 0);
706
707 // Disable Tx
708 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
709 Value &= ~(1 << 2);
710 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
711
712 // Make sure there are no pending bulk in/out IRPs before we go on.
713/*=========================================================================*/
714 /* pAd->PendingRx is not of type atomic_t anymore in 28xx */
715// while ((atomic_read(&pAd->PendingRx) > 0)) //pAd->BulkFlags != 0 wait bulk out finish
716 while ((pAd->PendingRx > 0)) //pAd->BulkFlags != 0 wait bulk out finish
717 {
718#if 1
719 ATE_RTUSBCancelPendingBulkInIRP(pAd);
720#else
721 NdisInterlockedDecrement(&pAd->PendingRx);
722#endif
723 /* delay 0.5 seconds */
724 RTMPusecDelay(500000);
725 pAd->PendingRx = 0;
726 }
727 /* peter : why don't we have to get BulkOutLock first ? */
728 while (((pAd->BulkOutPending[0] == TRUE) ||
729 (pAd->BulkOutPending[1] == TRUE) ||
730 (pAd->BulkOutPending[2] == TRUE) ||
731 (pAd->BulkOutPending[3] == TRUE)) && (pAd->BulkFlags != 0)) //pAd->BulkFlags != 0 wait bulk out finish
732 {
733 do
734 {
735 /* pAd->BulkOutPending[y] will be set to FALSE in RTUSBCancelPendingBulkOutIRP(pAd) */
736 RTUSBCancelPendingBulkOutIRP(pAd);
737 } while (FALSE);
738
739 /* we have enough time delay in RTUSBCancelPendingBulkOutIRP(pAd)
740 ** so this is not necessary
741 */
742// RTMPusecDelay(500000);
743 }
744
745 /* pAd->PendingRx is not of type atomic_t anymore in 28xx */
746// ASSERT(atomic_read(&pAd->PendingRx) == 0);
747 ASSERT(pAd->PendingRx == 0);
748/*=========================================================================*/
749
750 // reset Rx statistics.
751 pAd->ate.LastSNR0 = 0;
752 pAd->ate.LastSNR1 = 0;
753 pAd->ate.LastRssi0 = 0;
754 pAd->ate.LastRssi1 = 0;
755 pAd->ate.LastRssi2 = 0;
756 pAd->ate.AvgRssi0 = 0;
757 pAd->ate.AvgRssi1 = 0;
758 pAd->ate.AvgRssi2 = 0;
759 pAd->ate.AvgRssi0X8 = 0;
760 pAd->ate.AvgRssi1X8 = 0;
761 pAd->ate.AvgRssi2X8 = 0;
762 pAd->ate.NumOfAvgRssiSample = 0;
763
764#ifdef RALINK_28xx_QA
765 // Tx frame
766 pAd->ate.bQATxStart = FALSE;
767 pAd->ate.bQARxStart = FALSE;
768 pAd->ate.seq = 0;
769
770 // counters
771 pAd->ate.U2M = 0;
772 pAd->ate.OtherData = 0;
773 pAd->ate.Beacon = 0;
774 pAd->ate.OtherCount = 0;
775 pAd->ate.TxAc0 = 0;
776 pAd->ate.TxAc1 = 0;
777 pAd->ate.TxAc2 = 0;
778 pAd->ate.TxAc3 = 0;
779 pAd->ate.TxHCCA = 0;
780 pAd->ate.TxMgmt = 0;
781 pAd->ate.RSSI0 = 0;
782 pAd->ate.RSSI1 = 0;
783 pAd->ate.RSSI2 = 0;
784 pAd->ate.SNR0 = 0;
785 pAd->ate.SNR1 = 0;
786
787 // control
788 pAd->ate.TxDoneCount = 0;
789 pAd->ate.TxStatus = 0; // task Tx status // 0 --> task is idle, 1 --> task is running
790#endif // RALINK_28xx_QA //
791
792 // Soft reset BBP.
793 BbpSoftReset(pAd);
794
795
796#ifdef CONFIG_STA_SUPPORT
797 AsicDisableSync(pAd);
798
799 /*
800 ** If we skip "LinkDown()", we should disable protection
801 ** to prevent from sending out RTS or CTS-to-self.
802 */
803 ATEDisableAsicProtect(pAd);
804 RTMPStationStop(pAd);
805#endif // CONFIG_STA_SUPPORT //
806
807 // Default value in BBP R22 is 0x0.
808 BbpData = 0;
809 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
810
811 // Clean bit4 to stop continuous Tx production test.
812 MacData &= 0xFFFFFFEF;
813 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
814 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
815 //Clean ATE Bulk in/out counter and continue setup
816 InterlockedExchange(&pAd->BulkOutRemained, 0);
817
818 /* NdisAcquireSpinLock()/NdisReleaseSpinLock() need only one argument in RT28xx */
819 NdisAcquireSpinLock(&pAd->GenericLock);
820 pAd->ContinBulkOut = FALSE;
821 pAd->ContinBulkIn = FALSE;
822 NdisReleaseSpinLock(&pAd->GenericLock);
823
824 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
825 }
826 else if (!strcmp(arg, "ATESTOP"))
827 {
828 ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE : ATESTOP ===>\n"));
829
830 // Default value in BBP R22 is 0x0.
831 BbpData = 0;
832 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);//0820
833 // Clean bit4 to stop continuous Tx production test.
834 MacData &= 0xFFFFFFEF;
835 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
836 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); // recover the MAC_SYS_CTRL register back.
837
838 // Disable Rx
839 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
840 Value &= ~(1 << 3);
841 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
842
843 /*
844 ** Abort Tx, RX DMA.
845 ** Q : How to do the following I/O if Tx, Rx DMA is aborted ?
846 ** Ans : Bulk endpoints are aborted, while the control endpoint is not.
847 */
848 RtmpDmaEnable(pAd, 0);
849
850 // Disable Tx
851 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
852 Value &= ~(1 << 2);
853 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
854
855 /* Make sure there are no pending bulk in/out IRPs before we go on. */
856/*=========================================================================*/
857// while ((atomic_read(&pAd->PendingRx) > 0)) //pAd->BulkFlags != 0 wait bulk out finish
858 while (pAd->PendingRx > 0)
859 {
860#if 1
861 ATE_RTUSBCancelPendingBulkInIRP(pAd);
862#else
863// NdisInterlockedDecrement(&pAd->PendingRx);
864 pAd->PendingRx--;
865#endif
866 RTMPusecDelay(500000);
867 }
868
869 while (((pAd->BulkOutPending[0] == TRUE) ||
870 (pAd->BulkOutPending[1] == TRUE) ||
871 (pAd->BulkOutPending[2] == TRUE) ||
872 (pAd->BulkOutPending[3] == TRUE)) && (pAd->BulkFlags != 0)) //pAd->BulkFlags != 0 wait bulk out finish
873 {
874 do
875 {
876 RTUSBCancelPendingBulkOutIRP(pAd);
877 } while (FALSE);
878
879 RTMPusecDelay(500000);
880 }
881
882// ASSERT(atomic_read(&pAd->PendingRx) == 0);
883 ASSERT(pAd->PendingRx == 0);
884/*=========================================================================*/
885/* Reset Rx RING */
886/*=========================================================================*/
887// InterlockedExchange(&pAd->PendingRx, 0);
888 pAd->PendingRx = 0;
889 pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index
890 pAd->NextRxBulkInIndex = RX_RING_SIZE - 1; // Rx Bulk pointer
891 pAd->NextRxBulkInPosition = 0;
892 for (i = 0; i < (RX_RING_SIZE); i++)
893 {
894 PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
895 NdisZeroMemory(pRxContext->TransferBuffer, MAX_RXBULK_SIZE);
896 /* peter : why don't we have to get BulkInLock first ? */
897 pRxContext->pAd = pAd;
898 pRxContext->pIrp = NULL;
899 /* peter debug ++ */
900 pRxContext->BulkInOffset = 0;
901 pRxContext->bRxHandling = FALSE;
902 /* peter debug -- */
903 pRxContext->InUse = FALSE;
904 pRxContext->IRPPending = FALSE;
905 pRxContext->Readable = FALSE;
906// pRxContext->ReorderInUse = FALSE;
907// pRxContext->ReadPosOffset = 0;
908 }
909
910/*=========================================================================*/
911/* Reset Tx RING */
912/*=========================================================================*/
913 do
914 {
915 RTUSBCancelPendingBulkOutIRP(pAd);
916 } while (FALSE);
917
918/*=========================================================================*/
919 // Enable auto responder.
920 RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &temp);
921 temp = temp | (0x01);
922 RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, temp);
923
924/*================================================*/
925 AsicEnableBssSync(pAd);
926
927 /* Soft reset BBP.*/
928 /* In 2870 chipset, ATE_BBP_IO_READ8_BY_REG_ID() == RTMP_BBP_IO_READ8_BY_REG_ID() */
929 /* Both rt2870ap and rt2870sta use BbpSoftReset(pAd) to do BBP soft reset */
930 BbpSoftReset(pAd);
931/*================================================*/
932 {
933#ifdef CONFIG_STA_SUPPORT
934 // Set all state machines back IDLE
935 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
936 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
937 pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
938 pAd->Mlme.AuthRspMachine.CurrState = AUTH_RSP_IDLE;
939 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
940 pAd->Mlme.ActMachine.CurrState = ACT_IDLE;
941#endif // CONFIG_STA_SUPPORT //
942
943 //
944 // ===> refer to MlmeRestartStateMachine().
945 // When we entered ATE_START mode, PeriodicTimer was not cancelled.
946 // So we don't have to set it here.
947 //
948 //RTMPSetTimer(pAd, &pAd->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV);
949
950 ASSERT(pAd->CommonCfg.Channel != 0);
951
952 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
953 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
954
955
956#ifdef CONFIG_STA_SUPPORT
957 RTMPStationStart(pAd);
958#endif // CONFIG_STA_SUPPORT //
959 }
960//
961// These two steps have been done when entering ATE_STOP mode.
962//
963 // Clean ATE Bulk in/out counter and continue setup.
964 InterlockedExchange(&pAd->BulkOutRemained, 0);
965 NdisAcquireSpinLock(&pAd->GenericLock);
966 pAd->ContinBulkOut = FALSE;
967 pAd->ContinBulkIn = FALSE;
968 NdisReleaseSpinLock(&pAd->GenericLock);
969
970 /* Wait 50ms to prevent next URB to bulkout during HW reset. */
971 /* todo : remove this if not necessary */
972 NdisMSleep(50000);
973
974 pAd->ate.Mode = ATE_STOP;
975
976 // Enable Tx
977 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
978 Value |= (1 << 2);
979 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
980
981/*=========================================================================*/
982 /* restore RX_FILTR_CFG */
983#ifdef CONFIG_STA_SUPPORT
984 /* restore RX_FILTR_CFG in order that QA maybe set it to 0x3 */
985 RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL);
986#endif // CONFIG_STA_SUPPORT //
987/*=========================================================================*/
988
989 // Enable Tx, RX DMA.
990 RtmpDmaEnable(pAd, 1);
991
992 // Enable Rx
993 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
994 Value |= (1 << 3);
995 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
996
997 // Wait 10ms to wait all of the bulk-in URBs to complete.
998 /* todo : remove this if not necessary */
999 NdisMSleep(10000);
1000
1001 // Everything is ready to start normal Tx/Rx.
1002 RTUSBBulkReceive(pAd);
1003 netif_start_queue(pAd->net_dev);
1004
1005 ATEDBGPRINT(RT_DEBUG_TRACE, ("<=== ATE : ATESTOP \n"));
1006 }
1007 else if (!strcmp(arg, "TXCARR")) // Tx Carrier
1008 {
1009 ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: TXCARR\n"));
1010 pAd->ate.Mode |= ATE_TXCARR;
1011
1012#ifdef RT30xx
1013 for(i=0;i<ATE_BBP_REG_NUM;i++)
1014 restore_BBP[i]=0;
1015 //Record All BBP Value
1016 for(i=0;i<ATE_BBP_REG_NUM;i++)
1017 ATE_BBP_IO_READ8_BY_REG_ID(pAd,i,&restore_BBP[i]);
1018#endif // RT30xx //
1019
1020 // Disable Rx
1021 // May be we need not to do this, because these have been done in ATE_START mode ???
1022 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1023 Value &= ~(1 << 3);
1024 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1025
1026 // QA has done the following steps if it is used.
1027 if (pAd->ate.bQATxStart == FALSE)
1028 {
1029 // Soft reset BBP.
1030 BbpSoftReset(pAd);
1031
1032 // Carrier Test set BBP R22 bit7=1, bit6=1, bit[5~0]=0x01
1033 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
1034 BbpData &= 0xFFFFFF00; //clear bit7, bit6, bit[5~0]
1035 BbpData |= 0x000000C1; //set bit7=1, bit6=1, bit[5~0]=0x01
1036 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
1037
1038 // set MAC_SYS_CTRL(0x1004) Continuous Tx Production Test (bit4) = 1
1039 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1040 Value = Value | 0x00000010;
1041 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1042 }
1043 }
1044 else if (!strcmp(arg, "TXCONT")) // Tx Continue
1045 {
1046 if (pAd->ate.bQATxStart == TRUE)
1047 {
1048 /* set MAC_SYS_CTRL(0x1004) bit4(Continuous Tx Production Test)
1049 and bit2(MAC TX enable) back to zero. */
1050 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
1051 MacData &= 0xFFFFFFEB;
1052 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
1053
1054 // set BBP R22 bit7=0
1055 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
1056 BbpData &= 0xFFFFFF7F; //set bit7=0
1057 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
1058 }
1059
1060 /* for TxCont mode.
1061 ** Step 1: Send 50 packets first then wait for a moment.
1062 ** Step 2: Send more 50 packet then start continue mode.
1063 */
1064 ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: TXCONT\n"));
1065
1066#ifdef RT30xx
1067 for(i=0;i<ATE_BBP_REG_NUM;i++)
1068 restore_BBP[i]=0;
1069 //Record All BBP Value
1070 for(i=0;i<ATE_BBP_REG_NUM;i++)
1071 ATE_BBP_IO_READ8_BY_REG_ID(pAd,i,&restore_BBP[i]);
1072#endif // RT30xx //
1073
1074 // Step 1: send 50 packets first.
1075 pAd->ate.Mode |= ATE_TXCONT;
1076 pAd->ate.TxCount = 50;
1077 pAd->ate.TxDoneCount = 0;
1078
1079 // Soft reset BBP.
1080 BbpSoftReset(pAd);
1081
1082 // Abort Tx, RX DMA.
1083 RtmpDmaEnable(pAd, 0);
1084
1085
1086 /* Only needed if we have to send some normal frames. */
1087 SetJapanFilter(pAd);
1088
1089 // Setup frame format.
1090 ATESetUpFrame(pAd, 0);
1091
1092 // Enable Tx
1093 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1094 Value |= (1 << 2);
1095 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1096
1097 // Disable Rx
1098 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1099 Value &= ~(1 << 3);
1100 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1101
1102 // Start Tx, RX DMA.
1103 RtmpDmaEnable(pAd, 1);
1104
1105 InterlockedExchange(&pAd->BulkOutRemained, pAd->ate.TxCount);
1106
1107#ifdef RALINK_28xx_QA
1108 if (pAd->ate.bQATxStart == TRUE)
1109 {
1110 pAd->ate.TxStatus = 1;
1111 //pAd->ate.Repeat = 0;
1112 }
1113#endif // RALINK_28xx_QA //
1114
1115 NdisAcquireSpinLock(&pAd->GenericLock);//0820
1116 pAd->ContinBulkOut = FALSE;
1117 NdisReleaseSpinLock(&pAd->GenericLock);
1118
1119 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
1120
1121 // Kick bulk out
1122 RTUSBKickBulkOut(pAd);
1123
1124 /* To make sure all the 50 frames have been bulk out before executing step 2 */
1125 while (atomic_read(&pAd->BulkOutRemained) > 0)
1126 {
1127 RTMPusecDelay(5000);
1128 }
1129
1130 // Step 2: send more 50 packets then start continue mode.
1131 // Abort Tx, RX DMA.
1132 RtmpDmaEnable(pAd, 0);
1133
1134 // Cont. TX set BBP R22 bit7=1
1135 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
1136 BbpData |= 0x00000080; //set bit7=1
1137 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
1138
1139 pAd->ate.TxCount = 50;
1140 pAd->ate.TxDoneCount = 0;
1141
1142 SetJapanFilter(pAd);
1143
1144 // Setup frame format.
1145 ATESetUpFrame(pAd, 0);
1146
1147 // Enable Tx
1148 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1149 Value |= (1 << 2);
1150 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1151
1152 // Disable Rx
1153 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1154 Value &= ~(1 << 3);
1155
1156 // Start Tx, RX DMA.
1157 RtmpDmaEnable(pAd, 1);
1158
1159 InterlockedExchange(&pAd->BulkOutRemained, pAd->ate.TxCount);
1160
1161#ifdef RALINK_28xx_QA
1162 if (pAd->ate.bQATxStart == TRUE)
1163 {
1164 pAd->ate.TxStatus = 1;
1165 //pAd->ate.Repeat = 0;
1166 }
1167#endif // RALINK_28xx_QA //
1168
1169 NdisAcquireSpinLock(&pAd->GenericLock);//0820
1170 pAd->ContinBulkOut = FALSE;
1171 NdisReleaseSpinLock(&pAd->GenericLock);
1172
1173 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
1174 // Kick bulk out
1175 RTUSBKickBulkOut(pAd);
1176
1177#if 1
1178 RTMPusecDelay(500);
1179#else
1180 while (atomic_read(&pAd->BulkOutRemained) > 0)
1181 {
1182 RTMPusecDelay(5000);
1183 }
1184#endif // 1 //
1185
1186 // Set MAC_SYS_CTRL(0x1004) Continuous Tx Production Test (bit4) = 1.
1187 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
1188 MacData |= 0x00000010;
1189 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
1190 }
1191 else if (!strcmp(arg, "TXFRAME")) // Tx Frames
1192 {
1193 ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: TXFRAME(Count=0x%08x)\n", pAd->ate.TxCount));
1194 pAd->ate.Mode |= ATE_TXFRAME;
1195
1196 // Soft reset BBP.
1197 BbpSoftReset(pAd);
1198
1199 // Default value in BBP R22 is 0x0.
1200 BbpData = 0;
1201
1202 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
1203
1204 // Clean bit4 to stop continuous Tx production test.
1205 MacData &= 0xFFFFFFEF;
1206
1207 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
1208 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
1209
1210#ifdef RALINK_28xx_QA
1211 // add this for LoopBack mode
1212 if (pAd->ate.bQARxStart == FALSE)
1213 {
1214 // Disable Rx
1215 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1216 Value &= ~(1 << 3);
1217 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1218 }
1219
1220 if (pAd->ate.bQATxStart == TRUE)
1221 {
1222 pAd->ate.TxStatus = 1;
1223 //pAd->ate.Repeat = 0;
1224 }
1225#else
1226 // Disable Rx
1227 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1228 Value &= ~(1 << 3);
1229 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1230#endif // RALINK_28xx_QA //
1231
1232 // Enable Tx
1233 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1234 Value |= (1 << 2);
1235 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1236
1237 SetJapanFilter(pAd);
1238
1239 // Abort Tx, RX DMA.
1240 RtmpDmaEnable(pAd, 0);
1241
1242 pAd->ate.TxDoneCount = 0;
1243
1244 // Setup frame format
1245 ATESetUpFrame(pAd, 0);
1246
1247 // Start Tx, RX DMA.
1248 RtmpDmaEnable(pAd, 1);
1249
1250 // Check count is continuous or not yet.
1251 //
1252 // Due to the type mismatch between "pAd->BulkOutRemained"(atomic_t) and "pAd->ate.TxCount"(UINT32)
1253 //
1254 if (pAd->ate.TxCount == 0)
1255 {
1256 InterlockedExchange(&pAd->BulkOutRemained, 0);
1257 }
1258 else
1259 {
1260 InterlockedExchange(&pAd->BulkOutRemained, pAd->ate.TxCount);
1261 }
1262 ATEDBGPRINT(RT_DEBUG_TRACE, ("bulk out count = %d\n", atomic_read(&pAd->BulkOutRemained)));
1263 ASSERT((atomic_read(&pAd->BulkOutRemained) >= 0));
1264
1265 if (atomic_read(&pAd->BulkOutRemained) == 0)
1266 {
1267 ATEDBGPRINT(RT_DEBUG_TRACE, ("Send packet countinuously\n"));
1268
1269 /* In 28xx, NdisAcquireSpinLock() == spin_lock_bh() */
1270 /* NdisAcquireSpinLock only need one argument in 28xx. */
1271 NdisAcquireSpinLock(&pAd->GenericLock);
1272 pAd->ContinBulkOut = TRUE;
1273 NdisReleaseSpinLock(&pAd->GenericLock);
1274
1275 /* In 28xx, BULK_OUT_LOCK() == spin_lock_irqsave() */
1276 BULK_OUT_LOCK(&pAd->BulkOutLock[0], IrqFlags);// peter : NdisAcquireSpinLock ==> BULK_OUT_LOCK
1277 pAd->BulkOutPending[0] = FALSE;
1278 BULK_OUT_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);// peter : NdisAcquireSpinLock ==> BULK_OUT_LOCK
1279 }
1280 else
1281 {
1282 ATEDBGPRINT(RT_DEBUG_TRACE, ("Send packets depend on counter\n"));
1283
1284 NdisAcquireSpinLock(&pAd->GenericLock);
1285 pAd->ContinBulkOut = FALSE;
1286 NdisReleaseSpinLock(&pAd->GenericLock);
1287
1288 BULK_OUT_LOCK(&pAd->BulkOutLock[0], IrqFlags);
1289 pAd->BulkOutPending[0] = FALSE;
1290 BULK_OUT_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
1291 }
1292
1293 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
1294
1295 // Kick bulk out
1296 RTUSBKickBulkOut(pAd);
1297 }
1298#ifdef RALINK_28xx_QA
1299 else if (!strcmp(arg, "TXSTOP")) //Enter ATE mode and set Tx/Rx Idle
1300 {
1301 ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: TXSTOP\n"));
1302
1303 atemode = pAd->ate.Mode;
1304 pAd->ate.Mode &= ATE_TXSTOP;
1305 pAd->ate.bQATxStart = FALSE;
1306// pAd->ate.TxDoneCount = pAd->ate.TxCount;
1307
1308/*=========================================================================*/
1309 if (atemode & ATE_TXCARR)
1310 {
1311 // No Carrier Test set BBP R22 bit7=0, bit6=0, bit[5~0]=0x0
1312 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
1313 BbpData &= 0xFFFFFF00; //clear bit7, bit6, bit[5~0]
1314 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
1315 }
1316 else if (atemode & ATE_TXCARRSUPP)
1317 {
1318 // No Cont. TX set BBP R22 bit7=0
1319 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
1320 BbpData &= ~(1 << 7); //set bit7=0
1321 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
1322
1323 // No Carrier Suppression set BBP R24 bit0=0
1324 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R24, &BbpData);
1325 BbpData &= 0xFFFFFFFE; //clear bit0
1326 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, BbpData);
1327 }
1328 else if ((atemode & ATE_TXFRAME) || (atemode == ATE_STOP))
1329 {
1330 if (atemode & ATE_TXCONT)
1331 {
1332 // No Cont. TX set BBP R22 bit7=0
1333 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
1334 BbpData &= ~(1 << 7); //set bit7=0
1335 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
1336 }
1337 }
1338
1339/*=========================================================================*/
1340 RTUSBRejectPendingPackets(pAd);
1341 RTUSBCleanUpDataBulkOutQueue(pAd);
1342
1343 /* not used in RT28xx */
1344 //RTUSBCleanUpMLMEWaitQueue(pAd);
1345 /* empty function so far */
1346 RTUSBCleanUpMLMEBulkOutQueue(pAd);
1347/*=========================================================================*/
1348 // Abort Tx, RX DMA.
1349 RtmpDmaEnable(pAd, 0);
1350/*=========================================================================*/
1351
1352 /* In 28xx, pAd->PendingRx is not of type atomic_t anymore */
1353// while ((atomic_read(&pAd->PendingRx) > 0)) //pAd->BulkFlags != 0 wait bulk out finish
1354 /* peter todo : BulkInLock */
1355 while (pAd->PendingRx > 0)
1356 {
1357#if 1
1358 ATE_RTUSBCancelPendingBulkInIRP(pAd);
1359#else
1360// NdisInterlockedDecrement(&pAd->PendingRx);
1361 pAd->PendingRx--;
1362#endif
1363 RTMPusecDelay(500000);
1364 }
1365
1366 while (((pAd->BulkOutPending[0] == TRUE) ||
1367 (pAd->BulkOutPending[1] == TRUE) ||
1368 (pAd->BulkOutPending[2] == TRUE) ||
1369 (pAd->BulkOutPending[3] == TRUE)) && (pAd->BulkFlags != 0)) //pAd->BulkFlags != 0 wait bulk out finish
1370 {
1371 do
1372 {
1373 RTUSBCancelPendingBulkOutIRP(pAd);
1374 } while (FALSE);
1375
1376 RTMPusecDelay(500000);
1377 }
1378
1379 ASSERT(pAd->PendingRx == 0);
1380/*=========================================================================*/
1381 // Enable Tx, Rx DMA.
1382 RtmpDmaEnable(pAd, 1);
1383
1384 /* task Tx status : 0 --> task is idle, 1 --> task is running */
1385 pAd->ate.TxStatus = 0;
1386
1387 // Soft reset BBP.
1388 BbpSoftReset(pAd);
1389
1390 // Disable Tx
1391 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
1392 MacData &= (0xfffffffb);
1393 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
1394
1395 //Clean ATE Bulk in/out counter and continue setup
1396 InterlockedExchange(&pAd->BulkOutRemained, 0);
1397
1398 pAd->ContinBulkOut = FALSE;
1399 }
1400 else if (!strcmp(arg, "RXSTOP"))
1401 {
1402 ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: RXSTOP\n"));
1403 atemode = pAd->ate.Mode;
1404
1405 // Disable Rx
1406 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1407 Value &= ~(1 << 3);
1408 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1409
1410 pAd->ate.Mode &= ATE_RXSTOP;
1411 pAd->ate.bQARxStart = FALSE;
1412// pAd->ate.TxDoneCount = pAd->ate.TxCount;
1413
1414/*=========================================================================*/
1415 RTUSBRejectPendingPackets(pAd);
1416 RTUSBCleanUpDataBulkOutQueue(pAd);
1417
1418 /* not used in RT28xx */
1419 //RTUSBCleanUpMLMEWaitQueue(pAd);
1420 RTUSBCleanUpMLMEBulkOutQueue(pAd);
1421/*=========================================================================*/
1422
1423 // Abort Tx, RX DMA.
1424 RtmpDmaEnable(pAd, 0);
1425/*=========================================================================*/
1426// while ((atomic_read(&pAd->PendingRx) > 0))
1427 while (pAd->PendingRx > 0)
1428 {
1429#if 1
1430 ATE_RTUSBCancelPendingBulkInIRP(pAd);
1431#else
1432// NdisInterlockedDecrement(&pAd->PendingRx);
1433 pAd->PendingRx--;
1434#endif
1435 RTMPusecDelay(500000);
1436 }
1437
1438 while (((pAd->BulkOutPending[0] == TRUE) ||
1439 (pAd->BulkOutPending[1] == TRUE) ||
1440 (pAd->BulkOutPending[2] == TRUE) ||
1441 (pAd->BulkOutPending[3] == TRUE)) && (pAd->BulkFlags != 0)) //pAd->BulkFlags != 0 wait bulk out finish
1442 {
1443 do
1444 {
1445 RTUSBCancelPendingBulkOutIRP(pAd);
1446 } while (FALSE);
1447
1448 RTMPusecDelay(500000);
1449 }
1450
1451 ASSERT(pAd->PendingRx == 0);
1452/*=========================================================================*/
1453
1454 // Soft reset BBP.
1455 BbpSoftReset(pAd);
1456 pAd->ContinBulkIn = FALSE;
1457 }
1458#endif // RALINK_28xx_QA //
1459 else if (!strcmp(arg, "RXFRAME")) // Rx Frames
1460 {
1461 ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: RXFRAME\n"));
1462
1463 // Disable Rx of MAC block
1464 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1465 Value &= ~(1 << 3);
1466 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1467
1468 // Default value in BBP R22 is 0x0.
1469 BbpData = 0;
1470
1471 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
1472 // Clean bit4 to stop continuous Tx production test.
1473 MacData &= 0xFFFFFFEF;
1474
1475 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
1476 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
1477
1478 pAd->ate.Mode |= ATE_RXFRAME;
1479
1480 // Abort Tx, RX DMA.
1481 RtmpDmaEnable(pAd, 0);
1482
1483 // Disable TX of MAC block
1484 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1485 Value &= ~(1 << 2);
1486 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1487
1488 // Reset Rx RING.
1489 for ( i = 0; i < (RX_RING_SIZE); i++)
1490 {
1491 PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
1492
1493 pRxContext->InUse = FALSE;
1494 pRxContext->IRPPending = FALSE;
1495 pRxContext->Readable = FALSE;
1496
1497 //
1498 // Get the urb from kernel back to driver.
1499 //
1500 RTUSB_UNLINK_URB(pRxContext->pUrb);
1501
1502 /* Sleep 200 microsecs to give cancellation time to work. */
1503 NdisMSleep(200);
1504 pAd->BulkInReq = 0;
1505
1506// InterlockedExchange(&pAd->PendingRx, 0);
1507 pAd->PendingRx = 0;
1508 pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index
1509 pAd->NextRxBulkInIndex = RX_RING_SIZE - 1; // Rx Bulk pointer
1510 pAd->NextRxBulkInPosition = 0;
1511 }
1512
1513 // read to clear counters
1514 RTUSBReadMACRegister(pAd, RX_STA_CNT0, &temp); //RX PHY & RX CRC count
1515 RTUSBReadMACRegister(pAd, RX_STA_CNT1, &temp); //RX PLCP error count & CCA false alarm count
1516 RTUSBReadMACRegister(pAd, RX_STA_CNT2, &temp); //RX FIFO overflow frame count & RX duplicated filtered frame count
1517
1518 pAd->ContinBulkIn = TRUE;
1519
1520 // Enable Tx, RX DMA.
1521 RtmpDmaEnable(pAd, 1);
1522
1523 // Enable RX of MAC block
1524 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1525 Value |= (1 << 3);
1526 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1527
1528 // Kick bulk in
1529 RTUSBBulkReceive(pAd);
1530 }
1531 else
1532 {
1533 ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: Invalid arg!\n"));
1534 return FALSE;
1535 }
1536 RTMPusecDelay(5000);
1537
1538 ATEDBGPRINT(RT_DEBUG_TRACE, ("<=== ATECmdHandler()\n"));
1539
1540 return TRUE;
1541}
1542#endif // RT2870 //
1543
1544INT Set_ATE_Proc(
1545 IN PRTMP_ADAPTER pAd,
1546 IN PUCHAR arg)
1547{
1548 if (ATECmdHandler(pAd, arg))
1549 {
1550 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_Proc Success\n"));
1551
1552
1553 return TRUE;
1554 }
1555 else
1556 {
1557 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_Proc Failed\n"));
1558 return FALSE;
1559 }
1560}
1561
1562/*
1563 ==========================================================================
1564 Description:
1565 Set ATE ADDR1=DA for TxFrame(AP : To DS = 0 ; From DS = 1)
1566 or
1567 Set ATE ADDR3=DA for TxFrame(STA : To DS = 1 ; From DS = 0)
1568
1569 Return:
1570 TRUE if all parameters are OK, FALSE otherwise
1571 ==========================================================================
1572*/
1573INT Set_ATE_DA_Proc(
1574 IN PRTMP_ADAPTER pAd,
1575 IN PUCHAR arg)
1576{
1577 CHAR *value;
1578 INT i;
1579
1580 if(strlen(arg) != 17) //Mac address acceptable format 01:02:03:04:05:06 length 17
1581 return FALSE;
1582
1583 for (i=0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":"))
1584 {
1585 if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
1586 return FALSE; //Invalid
1587
1588
1589#ifdef CONFIG_STA_SUPPORT
1590 AtoH(value, &pAd->ate.Addr3[i++], 1);
1591#endif // CONFIG_STA_SUPPORT //
1592 }
1593
1594 if(i != 6)
1595 return FALSE; //Invalid
1596
1597
1598#ifdef CONFIG_STA_SUPPORT
1599 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_DA_Proc (DA = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAd->ate.Addr3[0],
1600 pAd->ate.Addr3[1], pAd->ate.Addr3[2], pAd->ate.Addr3[3], pAd->ate.Addr3[4], pAd->ate.Addr3[5]));
1601#endif // CONFIG_STA_SUPPORT //
1602
1603 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_DA_Proc Success\n"));
1604
1605 return TRUE;
1606}
1607
1608/*
1609 ==========================================================================
1610 Description:
1611 Set ATE ADDR3=SA for TxFrame(AP : To DS = 0 ; From DS = 1)
1612 or
1613 Set ATE ADDR2=SA for TxFrame(STA : To DS = 1 ; From DS = 0)
1614
1615 Return:
1616 TRUE if all parameters are OK, FALSE otherwise
1617 ==========================================================================
1618*/
1619INT Set_ATE_SA_Proc(
1620 IN PRTMP_ADAPTER pAd,
1621 IN PUCHAR arg)
1622{
1623 CHAR *value;
1624 INT i;
1625
1626 if(strlen(arg) != 17) //Mac address acceptable format 01:02:03:04:05:06 length 17
1627 return FALSE;
1628
1629 for (i=0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":"))
1630 {
1631 if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
1632 return FALSE; //Invalid
1633
1634
1635#ifdef CONFIG_STA_SUPPORT
1636 AtoH(value, &pAd->ate.Addr2[i++], 1);
1637#endif // CONFIG_STA_SUPPORT //
1638 }
1639
1640 if(i != 6)
1641 return FALSE; //Invalid
1642
1643
1644#ifdef CONFIG_STA_SUPPORT
1645 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_SA_Proc (SA = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAd->ate.Addr2[0],
1646 pAd->ate.Addr2[1], pAd->ate.Addr2[2], pAd->ate.Addr2[3], pAd->ate.Addr2[4], pAd->ate.Addr2[5]));
1647#endif // CONFIG_STA_SUPPORT //
1648
1649 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_SA_Proc Success\n"));
1650
1651 return TRUE;
1652}
1653
1654/*
1655 ==========================================================================
1656 Description:
1657 Set ATE ADDR2=BSSID for TxFrame(AP : To DS = 0 ; From DS = 1)
1658 or
1659 Set ATE ADDR1=BSSID for TxFrame(STA : To DS = 1 ; From DS = 0)
1660
1661 Return:
1662 TRUE if all parameters are OK, FALSE otherwise
1663 ==========================================================================
1664*/
1665INT Set_ATE_BSSID_Proc(
1666 IN PRTMP_ADAPTER pAd,
1667 IN PUCHAR arg)
1668{
1669 CHAR *value;
1670 INT i;
1671
1672 if(strlen(arg) != 17) //Mac address acceptable format 01:02:03:04:05:06 length 17
1673 return FALSE;
1674
1675 for (i=0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":"))
1676 {
1677 if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
1678 return FALSE; //Invalid
1679
1680
1681#ifdef CONFIG_STA_SUPPORT
1682 AtoH(value, &pAd->ate.Addr1[i++], 1);
1683#endif // CONFIG_STA_SUPPORT //
1684 }
1685
1686 if(i != 6)
1687 return FALSE; //Invalid
1688
1689
1690#ifdef CONFIG_STA_SUPPORT
1691 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_BSSID_Proc (BSSID = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAd->ate.Addr1[0],
1692 pAd->ate.Addr1[1], pAd->ate.Addr1[2], pAd->ate.Addr1[3], pAd->ate.Addr1[4], pAd->ate.Addr1[5]));
1693#endif // CONFIG_STA_SUPPORT //
1694
1695 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_BSSID_Proc Success\n"));
1696
1697 return TRUE;
1698}
1699
1700/*
1701 ==========================================================================
1702 Description:
1703 Set ATE Tx Channel
1704
1705 Return:
1706 TRUE if all parameters are OK, FALSE otherwise
1707 ==========================================================================
1708*/
1709INT Set_ATE_CHANNEL_Proc(
1710 IN PRTMP_ADAPTER pAd,
1711 IN PUCHAR arg)
1712{
1713 UCHAR channel;
1714
1715 channel = simple_strtol(arg, 0, 10);
1716
1717 if ((channel < 1) || (channel > 216))// to allow A band channel : ((channel < 1) || (channel > 14))
1718 {
1719 ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_CHANNEL_Proc::Out of range, it should be in range of 1~14.\n"));
1720 return FALSE;
1721 }
1722 pAd->ate.Channel = channel;
1723
1724 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_CHANNEL_Proc (ATE Channel = %d)\n", pAd->ate.Channel));
1725 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_CHANNEL_Proc Success\n"));
1726
1727
1728 return TRUE;
1729}
1730
1731/*
1732 ==========================================================================
1733 Description:
1734 Set ATE Tx Power0
1735
1736 Return:
1737 TRUE if all parameters are OK, FALSE otherwise
1738 ==========================================================================
1739*/
1740INT Set_ATE_TX_POWER0_Proc(
1741 IN PRTMP_ADAPTER pAd,
1742 IN PUCHAR arg)
1743{
1744 CHAR TxPower;
1745
1746 TxPower = simple_strtol(arg, 0, 10);
1747
1748 if (pAd->ate.Channel <= 14)
1749 {
1750 if ((TxPower > 31) || (TxPower < 0))
1751 {
1752 ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER0_Proc::Out of range (Value=%d)\n", TxPower));
1753 return FALSE;
1754 }
1755 }
1756 else// 5.5GHz
1757 {
1758 if ((TxPower > 15) || (TxPower < -7))
1759 {
1760 ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER0_Proc::Out of range (Value=%d)\n", TxPower));
1761 return FALSE;
1762 }
1763 }
1764
1765 pAd->ate.TxPower0 = TxPower;
1766 ATETxPwrHandler(pAd, 0);
1767 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_POWER0_Proc Success\n"));
1768
1769
1770 return TRUE;
1771}
1772
1773/*
1774 ==========================================================================
1775 Description:
1776 Set ATE Tx Power1
1777
1778 Return:
1779 TRUE if all parameters are OK, FALSE otherwise
1780 ==========================================================================
1781*/
1782INT Set_ATE_TX_POWER1_Proc(
1783 IN PRTMP_ADAPTER pAd,
1784 IN PUCHAR arg)
1785{
1786 CHAR TxPower;
1787
1788 TxPower = simple_strtol(arg, 0, 10);
1789
1790 if (pAd->ate.Channel <= 14)
1791 {
1792 if ((TxPower > 31) || (TxPower < 0))
1793 {
1794 ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER1_Proc::Out of range (Value=%d)\n", TxPower));
1795 return FALSE;
1796 }
1797 }
1798 else
1799 {
1800 if ((TxPower > 15) || (TxPower < -7))
1801 {
1802 ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER1_Proc::Out of range (Value=%d)\n", TxPower));
1803 return FALSE;
1804 }
1805 }
1806
1807 pAd->ate.TxPower1 = TxPower;
1808 ATETxPwrHandler(pAd, 1);
1809 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_POWER1_Proc Success\n"));
1810
1811
1812 return TRUE;
1813}
1814
1815/*
1816 ==========================================================================
1817 Description:
1818 Set ATE Tx Antenna
1819
1820 Return:
1821 TRUE if all parameters are OK, FALSE otherwise
1822 ==========================================================================
1823*/
1824INT Set_ATE_TX_Antenna_Proc(
1825 IN PRTMP_ADAPTER pAd,
1826 IN PUCHAR arg)
1827{
1828 CHAR value;
1829
1830 value = simple_strtol(arg, 0, 10);
1831
1832 if ((value > 2) || (value < 0))
1833 {
1834 ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_Antenna_Proc::Out of range (Value=%d)\n", value));
1835 return FALSE;
1836 }
1837
1838 pAd->ate.TxAntennaSel = value;
1839
1840 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_Antenna_Proc (Antenna = %d)\n", pAd->ate.TxAntennaSel));
1841 ATEDBGPRINT(RT_DEBUG_TRACE,("Ralink: Set_ATE_TX_Antenna_Proc Success\n"));
1842
1843
1844 return TRUE;
1845}
1846
1847/*
1848 ==========================================================================
1849 Description:
1850 Set ATE Rx Antenna
1851
1852 Return:
1853 TRUE if all parameters are OK, FALSE otherwise
1854 ==========================================================================
1855*/
1856INT Set_ATE_RX_Antenna_Proc(
1857 IN PRTMP_ADAPTER pAd,
1858 IN PUCHAR arg)
1859{
1860 CHAR value;
1861
1862 value = simple_strtol(arg, 0, 10);
1863
1864 if ((value > 3) || (value < 0))
1865 {
1866 ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_RX_Antenna_Proc::Out of range (Value=%d)\n", value));
1867 return FALSE;
1868 }
1869
1870 pAd->ate.RxAntennaSel = value;
1871
1872 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_RX_Antenna_Proc (Antenna = %d)\n", pAd->ate.RxAntennaSel));
1873 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_RX_Antenna_Proc Success\n"));
1874
1875
1876 return TRUE;
1877}
1878
1879/*
1880 ==========================================================================
1881 Description:
1882 Set ATE RF frequence offset
1883
1884 Return:
1885 TRUE if all parameters are OK, FALSE otherwise
1886 ==========================================================================
1887*/
1888INT Set_ATE_TX_FREQOFFSET_Proc(
1889 IN PRTMP_ADAPTER pAd,
1890 IN PUCHAR arg)
1891{
1892 UCHAR RFFreqOffset;
1893 ULONG R4;
1894
1895 RFFreqOffset = simple_strtol(arg, 0, 10);
1896#ifndef RT30xx
1897 if(RFFreqOffset >= 64)
1898#endif // RT30xx //
1899#ifdef RT30xx
1900//2008/08/06: KH modified the limit of offset value from 65 to 95(0x5F)
1901 if(RFFreqOffset >= 95)
1902#endif // RT30xx //
1903 {
1904 ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_FREQOFFSET_Proc::Out of range, it should be in range of 0~63.\n"));
1905 return FALSE;
1906 }
1907
1908 pAd->ate.RFFreqOffset = RFFreqOffset;
1909#ifdef RT30xx
1910 if(IS_RT30xx(pAd))
1911 {
1912 // Set RF offset
1913 UCHAR RFValue;
1914 RT30xxReadRFRegister(pAd, RF_R23, (PUCHAR)&RFValue);
1915 //2008/08/06: KH modified "pAd->RFFreqOffset" to "pAd->ate.RFFreqOffset"
1916 RFValue = (RFValue & 0x80) | pAd->ate.RFFreqOffset;
1917 RT30xxWriteRFRegister(pAd, RF_R23, (UCHAR)RFValue);
1918 }
1919 else
1920#endif // RT30xx //
1921 {
1922
1923 R4 = pAd->ate.RFFreqOffset << 15; // shift TX power control to correct RF register bit position
1924 R4 |= (pAd->LatchRfRegs.R4 & ((~0x001f8000)));
1925 pAd->LatchRfRegs.R4 = R4;
1926
1927 RtmpRfIoWrite(pAd);
1928 }
1929 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_FREQOFFSET_Proc (RFFreqOffset = %d)\n", pAd->ate.RFFreqOffset));
1930 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_FREQOFFSET_Proc Success\n"));
1931
1932
1933 return TRUE;
1934}
1935
1936/*
1937 ==========================================================================
1938 Description:
1939 Set ATE RF BW
1940
1941 Return:
1942 TRUE if all parameters are OK, FALSE otherwise
1943 ==========================================================================
1944*/
1945INT Set_ATE_TX_BW_Proc(
1946 IN PRTMP_ADAPTER pAd,
1947 IN PUCHAR arg)
1948{
1949 int i;
1950 UCHAR value = 0;
1951 UCHAR BBPCurrentBW;
1952
1953 BBPCurrentBW = simple_strtol(arg, 0, 10);
1954
1955 if(BBPCurrentBW == 0)
1956 pAd->ate.TxWI.BW = BW_20;
1957 else
1958 pAd->ate.TxWI.BW = BW_40;
1959
1960 if(pAd->ate.TxWI.BW == BW_20)
1961 {
1962 if(pAd->ate.Channel <= 14)
1963 {
1964 for (i=0; i<5; i++)
1965 {
1966 if (pAd->Tx20MPwrCfgGBand[i] != 0xffffffff)
1967 {
1968 RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, pAd->Tx20MPwrCfgGBand[i]);
1969 RTMPusecDelay(5000);
1970 }
1971 }
1972 }
1973 else
1974 {
1975 for (i=0; i<5; i++)
1976 {
1977 if (pAd->Tx20MPwrCfgABand[i] != 0xffffffff)
1978 {
1979 RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, pAd->Tx20MPwrCfgABand[i]);
1980 RTMPusecDelay(5000);
1981 }
1982 }
1983 }
1984
1985 //Set BBP R4 bit[4:3]=0:0
1986 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &value);
1987 value &= (~0x18);
1988 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, value);
1989
1990 //Set BBP R66=0x3C
1991 value = 0x3C;
1992 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, value);
1993 //Set BBP R68=0x0B
1994 //to improve Rx sensitivity.
1995 value = 0x0B;
1996 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R68, value);
1997 //Set BBP R69=0x16
1998 value = 0x16;
1999 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, value);
2000 //Set BBP R70=0x08
2001 value = 0x08;
2002 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, value);
2003 //Set BBP R73=0x11
2004 value = 0x11;
2005 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, value);
2006
2007 // If Channel=14, Bandwidth=20M and Mode=CCK, Set BBP R4 bit5=1
2008 // (Japan filter coefficients)
2009 // This segment of code will only works when ATETXMODE and ATECHANNEL
2010 // were set to MODE_CCK and 14 respectively before ATETXBW is set to 0.
2011 //=====================================================================
2012 if (pAd->ate.Channel == 14)
2013 {
2014 int TxMode = pAd->ate.TxWI.PHYMODE;
2015 if (TxMode == MODE_CCK)
2016 {
2017 // when Channel==14 && Mode==CCK && BandWidth==20M, BBP R4 bit5=1
2018 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &value);
2019 value |= 0x20; //set bit5=1
2020 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, value);
2021 }
2022 }
2023
2024 //=====================================================================
2025 // If bandwidth != 40M, RF Reg4 bit 21 = 0.
2026#ifdef RT30xx
2027 // Set BW
2028 if(IS_RT30xx(pAd))
2029 RT30xxWriteRFRegister(pAd, RF_R24, (UCHAR) pAd->Mlme.CaliBW20RfR24);
2030 else
2031#endif // RT30xx //
2032 {
2033 pAd->LatchRfRegs.R4 &= ~0x00200000;
2034 RtmpRfIoWrite(pAd);
2035 }
2036
2037 }
2038 else if(pAd->ate.TxWI.BW == BW_40)
2039 {
2040 if(pAd->ate.Channel <= 14)
2041 {
2042 for (i=0; i<5; i++)
2043 {
2044 if (pAd->Tx40MPwrCfgGBand[i] != 0xffffffff)
2045 {
2046 RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, pAd->Tx40MPwrCfgGBand[i]);
2047 RTMPusecDelay(5000);
2048 }
2049 }
2050 }
2051 else
2052 {
2053 for (i=0; i<5; i++)
2054 {
2055 if (pAd->Tx40MPwrCfgABand[i] != 0xffffffff)
2056 {
2057 RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, pAd->Tx40MPwrCfgABand[i]);
2058 RTMPusecDelay(5000);
2059 }
2060 }
2061#ifdef DOT11_N_SUPPORT
2062 if ((pAd->ate.TxWI.PHYMODE >= MODE_HTMIX) && (pAd->ate.TxWI.MCS == 7))
2063 {
2064 value = 0x28;
2065 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R67, value);
2066 }
2067#endif // DOT11_N_SUPPORT //
2068 }
2069
2070 //Set BBP R4 bit[4:3]=1:0
2071 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &value);
2072 value &= (~0x18);
2073 value |= 0x10;
2074 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, value);
2075
2076 //Set BBP R66=0x3C
2077 value = 0x3C;
2078 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, value);
2079 //Set BBP R68=0x0C
2080 //to improve Rx sensitivity.
2081 value = 0x0C;
2082 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R68, value);
2083 //Set BBP R69=0x1A
2084 value = 0x1A;
2085 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, value);
2086 //Set BBP R70=0x0A
2087 value = 0x0A;
2088 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, value);
2089 //Set BBP R73=0x16
2090 value = 0x16;
2091 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, value);
2092
2093 // If bandwidth = 40M, set RF Reg4 bit 21 = 1.
2094#ifdef RT30xx
2095 // Set BW
2096 if(IS_RT30xx(pAd))
2097 RT30xxWriteRFRegister(pAd, RF_R24, (UCHAR) pAd->Mlme.CaliBW40RfR24);
2098 else
2099#endif // RT30xx //
2100 {
2101 pAd->LatchRfRegs.R4 |= 0x00200000;
2102 RtmpRfIoWrite(pAd);
2103 }
2104 }
2105
2106 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_BW_Proc (BBPCurrentBW = %d)\n", pAd->ate.TxWI.BW));
2107 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_BW_Proc Success\n"));
2108
2109
2110 return TRUE;
2111}
2112
2113/*
2114 ==========================================================================
2115 Description:
2116 Set ATE Tx frame length
2117
2118 Return:
2119 TRUE if all parameters are OK, FALSE otherwise
2120 ==========================================================================
2121*/
2122INT Set_ATE_TX_LENGTH_Proc(
2123 IN PRTMP_ADAPTER pAd,
2124 IN PUCHAR arg)
2125{
2126 pAd->ate.TxLength = simple_strtol(arg, 0, 10);
2127
2128 if((pAd->ate.TxLength < 24) || (pAd->ate.TxLength > (MAX_FRAME_SIZE - 34/* == 2312 */)))
2129 {
2130 pAd->ate.TxLength = (MAX_FRAME_SIZE - 34/* == 2312 */);
2131 ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_LENGTH_Proc::Out of range, it should be in range of 24~%d.\n", (MAX_FRAME_SIZE - 34/* == 2312 */)));
2132 return FALSE;
2133 }
2134
2135 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_LENGTH_Proc (TxLength = %d)\n", pAd->ate.TxLength));
2136 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_LENGTH_Proc Success\n"));
2137
2138
2139 return TRUE;
2140}
2141
2142/*
2143 ==========================================================================
2144 Description:
2145 Set ATE Tx frame count
2146
2147 Return:
2148 TRUE if all parameters are OK, FALSE otherwise
2149 ==========================================================================
2150*/
2151INT Set_ATE_TX_COUNT_Proc(
2152 IN PRTMP_ADAPTER pAd,
2153 IN PUCHAR arg)
2154{
2155 pAd->ate.TxCount = simple_strtol(arg, 0, 10);
2156
2157 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_COUNT_Proc (TxCount = %d)\n", pAd->ate.TxCount));
2158 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_COUNT_Proc Success\n"));
2159
2160
2161 return TRUE;
2162}
2163
2164/*
2165 ==========================================================================
2166 Description:
2167 Set ATE Tx frame MCS
2168
2169 Return:
2170 TRUE if all parameters are OK, FALSE otherwise
2171 ==========================================================================
2172*/
2173INT Set_ATE_TX_MCS_Proc(
2174 IN PRTMP_ADAPTER pAd,
2175 IN PUCHAR arg)
2176{
2177 UCHAR MCS;
2178 int result;
2179
2180 MCS = simple_strtol(arg, 0, 10);
2181 result = CheckMCSValid(pAd->ate.TxWI.PHYMODE, MCS);
2182
2183 if (result != -1)
2184 {
2185 pAd->ate.TxWI.MCS = (UCHAR)MCS;
2186 }
2187 else
2188 {
2189 ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_MCS_Proc::Out of range, refer to rate table.\n"));
2190 return FALSE;
2191 }
2192
2193 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_MCS_Proc (MCS = %d)\n", pAd->ate.TxWI.MCS));
2194 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_MCS_Proc Success\n"));
2195
2196
2197 return TRUE;
2198}
2199
2200/*
2201 ==========================================================================
2202 Description:
2203 Set ATE Tx frame Mode
2204 0: MODE_CCK
2205 1: MODE_OFDM
2206 2: MODE_HTMIX
2207 3: MODE_HTGREENFIELD
2208
2209 Return:
2210 TRUE if all parameters are OK, FALSE otherwise
2211 ==========================================================================
2212*/
2213INT Set_ATE_TX_MODE_Proc(
2214 IN PRTMP_ADAPTER pAd,
2215 IN PUCHAR arg)
2216{
2217 pAd->ate.TxWI.PHYMODE = simple_strtol(arg, 0, 10);
2218
2219 if(pAd->ate.TxWI.PHYMODE > 3)
2220 {
2221 pAd->ate.TxWI.PHYMODE = 0;
2222 ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_MODE_Proc::Out of range. it should be in range of 0~3\n"));
2223 ATEDBGPRINT(RT_DEBUG_ERROR, ("0: CCK, 1: OFDM, 2: HT_MIX, 3: HT_GREEN_FIELD.\n"));
2224 return FALSE;
2225 }
2226
2227 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_MODE_Proc (TxMode = %d)\n", pAd->ate.TxWI.PHYMODE));
2228 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_MODE_Proc Success\n"));
2229
2230
2231 return TRUE;
2232}
2233
2234/*
2235 ==========================================================================
2236 Description:
2237 Set ATE Tx frame GI
2238
2239 Return:
2240 TRUE if all parameters are OK, FALSE otherwise
2241 ==========================================================================
2242*/
2243INT Set_ATE_TX_GI_Proc(
2244 IN PRTMP_ADAPTER pAd,
2245 IN PUCHAR arg)
2246{
2247 pAd->ate.TxWI.ShortGI = simple_strtol(arg, 0, 10);
2248
2249 if(pAd->ate.TxWI.ShortGI > 1)
2250 {
2251 pAd->ate.TxWI.ShortGI = 0;
2252 ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_GI_Proc::Out of range\n"));
2253 return FALSE;
2254 }
2255
2256 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_GI_Proc (GI = %d)\n", pAd->ate.TxWI.ShortGI));
2257 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_GI_Proc Success\n"));
2258
2259
2260 return TRUE;
2261}
2262
2263/*
2264 ==========================================================================
2265 Description:
2266 ==========================================================================
2267 */
2268INT Set_ATE_RX_FER_Proc(
2269 IN PRTMP_ADAPTER pAd,
2270 IN PUCHAR arg)
2271{
2272 pAd->ate.bRxFer = simple_strtol(arg, 0, 10);
2273
2274 if (pAd->ate.bRxFer == 1)
2275 {
2276 pAd->ate.RxCntPerSec = 0;
2277 pAd->ate.RxTotalCnt = 0;
2278 }
2279
2280 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_RX_FER_Proc (bRxFer = %d)\n", pAd->ate.bRxFer));
2281 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_RX_FER_Proc Success\n"));
2282
2283
2284 return TRUE;
2285}
2286
2287INT Set_ATE_Read_RF_Proc(
2288 IN PRTMP_ADAPTER pAd,
2289 IN PUCHAR arg)
2290{
2291#ifdef RT30xx
2292//2008/07/10:KH add to support RT30xx ATE<--
2293 if(IS_RT30xx(pAd))
2294 {
2295 /* modify by WY for Read RF Reg. error */
2296 UCHAR RFValue;
2297 INT index=0;
2298 for (index = 0; index < 32; index++)
2299 {
2300 RT30xxReadRFRegister(pAd, index, (PUCHAR)&RFValue);
2301 printk("R%d=%d\n",index,RFValue);
2302 }
2303 }
2304 else
2305//2008/07/10:KH add to support RT30xx ATE-->
2306#endif // RT30xx //
2307 {
2308 ate_print(KERN_EMERG "R1 = %lx\n", pAd->LatchRfRegs.R1);
2309 ate_print(KERN_EMERG "R2 = %lx\n", pAd->LatchRfRegs.R2);
2310 ate_print(KERN_EMERG "R3 = %lx\n", pAd->LatchRfRegs.R3);
2311 ate_print(KERN_EMERG "R4 = %lx\n", pAd->LatchRfRegs.R4);
2312 }
2313 return TRUE;
2314}
2315
2316INT Set_ATE_Write_RF1_Proc(
2317 IN PRTMP_ADAPTER pAd,
2318 IN PUCHAR arg)
2319{
2320#ifdef RT30xx
2321//2008/07/10:KH add to support 3070 ATE<--
2322 if(IS_RT30xx(pAd))
2323 {
2324 printk("Warning!! RT30xx Don't Support\n");
2325 return FALSE;
2326
2327 }
2328 else
2329//2008/07/10:KH add to support 3070 ATE-->
2330#endif // RT30xx //
2331 {
2332 UINT32 value = simple_strtol(arg, 0, 16);
2333
2334 pAd->LatchRfRegs.R1 = value;
2335 RtmpRfIoWrite(pAd);
2336 }
2337 return TRUE;
2338
2339}
2340
2341INT Set_ATE_Write_RF2_Proc(
2342 IN PRTMP_ADAPTER pAd,
2343 IN PUCHAR arg)
2344{
2345#ifdef RT30xx
2346//2008/07/10:KH add to support 3070 ATE<--
2347 if(IS_RT30xx(pAd))
2348 {
2349 printk("Warning!! RT30xx Don't Support\n");
2350 return FALSE;
2351
2352 }
2353 else
2354//2008/07/10:KH add to support 3070 ATE-->
2355#endif // RT30xx //
2356 {
2357 UINT32 value = simple_strtol(arg, 0, 16);
2358
2359 pAd->LatchRfRegs.R2 = value;
2360 RtmpRfIoWrite(pAd);
2361 }
2362 return TRUE;
2363}
2364
2365INT Set_ATE_Write_RF3_Proc(
2366 IN PRTMP_ADAPTER pAd,
2367 IN PUCHAR arg)
2368{
2369#ifdef RT30xx
2370//2008/07/10:KH add to support 3070 ATE<--
2371 if(IS_RT30xx(pAd))
2372 {
2373 printk("Warning!! RT30xx Don't Support\n");
2374 return FALSE;
2375
2376 }
2377 else
2378//2008/07/10:KH add to support 3070 ATE-->
2379#endif // RT30xx //
2380 {
2381 UINT32 value = simple_strtol(arg, 0, 16);
2382
2383 pAd->LatchRfRegs.R3 = value;
2384 RtmpRfIoWrite(pAd);
2385 }
2386 return TRUE;
2387}
2388
2389INT Set_ATE_Write_RF4_Proc(
2390 IN PRTMP_ADAPTER pAd,
2391 IN PUCHAR arg)
2392{
2393#ifdef RT30xx
2394//2008/07/10:KH add to support 3070 ATE<--
2395 if(IS_RT30xx(pAd))
2396 {
2397 printk("Warning!! RT30xx Don't Support\n");
2398 return FALSE;
2399
2400 }
2401 else
2402//2008/07/10:KH add to support 3070 ATE-->
2403#endif // RT30xx //
2404 {
2405 UINT32 value = simple_strtol(arg, 0, 16);
2406
2407 pAd->LatchRfRegs.R4 = value;
2408 RtmpRfIoWrite(pAd);
2409 }
2410 return TRUE;
2411}
2412#ifdef RT30xx
2413//2008/07/10:KH add to support 3070 ATE<--
2414INT SET_ATE_3070RF_Proc(
2415 IN PRTMP_ADAPTER pAd,
2416 IN PUCHAR arg)
2417{
2418 CHAR *this_char;
2419 CHAR *value;
2420 UINT32 Reg,RFValue;
2421 if(IS_RT30xx(pAd))
2422 {
2423 printk("SET_ATE_3070RF_Proc=%s\n",arg);
2424 this_char =arg;
2425 if ((value = strchr(this_char, ':')) != NULL)
2426 *value++ = 0;
2427 Reg= simple_strtol(this_char, 0, 16);
2428 RFValue= simple_strtol(value, 0, 16);
2429 printk("RF Reg[%d]=%d\n",Reg,RFValue);
2430 RT30xxWriteRFRegister(pAd, Reg,RFValue);
2431 }
2432 else
2433 printk("Warning!! Only 3070 Support\n");
2434 return TRUE;
2435}
2436//2008/07/10:KH add to support 3070 ATE-->
2437#endif // RT30xx //
2438/*
2439 ==========================================================================
2440 Description:
2441 Load and Write EEPROM from a binary file prepared in advance.
2442
2443 Return:
2444 TRUE if all parameters are OK, FALSE otherwise
2445 ==========================================================================
2446*/
2447#ifndef UCOS
2448INT Set_ATE_Load_E2P_Proc(
2449 IN PRTMP_ADAPTER pAd,
2450 IN PUCHAR arg)
2451{
2452 BOOLEAN ret = FALSE;
2453 PUCHAR src = EEPROM_BIN_FILE_NAME;
2454 struct file *srcf;
2455 INT32 retval, orgfsuid, orgfsgid;
2456 mm_segment_t orgfs;
2457 USHORT WriteEEPROM[(EEPROM_SIZE/2)];
2458 UINT32 FileLength = 0;
2459 UINT32 value = simple_strtol(arg, 0, 10);
2460
2461 ATEDBGPRINT(RT_DEBUG_ERROR, ("===> %s (value=%d)\n\n", __FUNCTION__, value));
2462
2463 if (value > 0)
2464 {
2465 /* zero the e2p buffer */
2466 NdisZeroMemory((PUCHAR)WriteEEPROM, EEPROM_SIZE);
2467
2468 /* save uid and gid used for filesystem access.
2469 ** set user and group to 0 (root)
2470 */
2471 orgfsuid = current->fsuid;
2472 orgfsgid = current->fsgid;
2473 /* as root */
2474 current->fsuid = current->fsgid = 0;
2475 orgfs = get_fs();
2476 set_fs(KERNEL_DS);
2477
2478 do
2479 {
2480 /* open the bin file */
2481 srcf = filp_open(src, O_RDONLY, 0);
2482
2483 if (IS_ERR(srcf))
2484 {
2485 ate_print("%s - Error %ld opening %s\n", __FUNCTION__, -PTR_ERR(srcf), src);
2486 break;
2487 }
2488
2489 /* the object must have a read method */
2490 if ((srcf->f_op == NULL) || (srcf->f_op->read == NULL))
2491 {
2492 ate_print("%s - %s does not have a read method\n", __FUNCTION__, src);
2493 break;
2494 }
2495
2496 /* read the firmware from the file *.bin */
2497 FileLength = srcf->f_op->read(srcf,
2498 (PUCHAR)WriteEEPROM,
2499 EEPROM_SIZE,
2500 &srcf->f_pos);
2501
2502 if (FileLength != EEPROM_SIZE)
2503 {
2504 ate_print("%s: error file length (=%d) in e2p.bin\n",
2505 __FUNCTION__, FileLength);
2506 break;
2507 }
2508 else
2509 {
2510 /* write the content of .bin file to EEPROM */
2511 rt_ee_write_all(pAd, WriteEEPROM);
2512 ret = TRUE;
2513 }
2514 break;
2515 } while(TRUE);
2516
2517 /* close firmware file */
2518 if (IS_ERR(srcf))
2519 {
2520 ;
2521 }
2522 else
2523 {
2524 retval = filp_close(srcf, NULL);
2525 if (retval)
2526 {
2527 ATEDBGPRINT(RT_DEBUG_ERROR, ("--> Error %d closing %s\n", -retval, src));
2528
2529 }
2530 }
2531
2532 /* restore */
2533 set_fs(orgfs);
2534 current->fsuid = orgfsuid;
2535 current->fsgid = orgfsgid;
2536 }
2537 ATEDBGPRINT(RT_DEBUG_ERROR, ("<=== %s (ret=%d)\n", __FUNCTION__, ret));
2538
2539 return ret;
2540
2541}
2542#else
2543INT Set_ATE_Load_E2P_Proc(
2544 IN PRTMP_ADAPTER pAd,
2545 IN PUCHAR arg)
2546{
2547 USHORT WriteEEPROM[(EEPROM_SIZE/2)];
2548 struct iwreq *wrq = (struct iwreq *)arg;
2549
2550 ATEDBGPRINT(RT_DEBUG_TRACE, ("===> %s (wrq->u.data.length = %d)\n\n", __FUNCTION__, wrq->u.data.length));
2551
2552 if (wrq->u.data.length != EEPROM_SIZE)
2553 {
2554 ate_print("%s: error length (=%d) from host\n",
2555 __FUNCTION__, wrq->u.data.length);
2556 return FALSE;
2557 }
2558 else/* (wrq->u.data.length == EEPROM_SIZE) */
2559 {
2560 /* zero the e2p buffer */
2561 NdisZeroMemory((PUCHAR)WriteEEPROM, EEPROM_SIZE);
2562
2563 /* fill the local buffer */
2564 NdisMoveMemory((PUCHAR)WriteEEPROM, wrq->u.data.pointer, wrq->u.data.length);
2565
2566 do
2567 {
2568 /* write the content of .bin file to EEPROM */
2569 rt_ee_write_all(pAd, WriteEEPROM);
2570
2571 } while(FALSE);
2572 }
2573
2574 ATEDBGPRINT(RT_DEBUG_TRACE, ("<=== %s\n", __FUNCTION__));
2575
2576 return TRUE;
2577
2578}
2579#endif // !UCOS //
2580
2581INT Set_ATE_Read_E2P_Proc(
2582 IN PRTMP_ADAPTER pAd,
2583 IN PUCHAR arg)
2584{
2585 USHORT buffer[EEPROM_SIZE/2];
2586 USHORT *p;
2587 int i;
2588
2589 rt_ee_read_all(pAd, (USHORT *)buffer);
2590 p = buffer;
2591 for (i = 0; i < (EEPROM_SIZE/2); i++)
2592 {
2593 ate_print("%4.4x ", *p);
2594 if (((i+1) % 16) == 0)
2595 ate_print("\n");
2596 p++;
2597 }
2598 return TRUE;
2599}
2600
2601INT Set_ATE_Show_Proc(
2602 IN PRTMP_ADAPTER pAd,
2603 IN PUCHAR arg)
2604{
2605 ate_print("Mode=%d\n", pAd->ate.Mode);
2606 ate_print("TxPower0=%d\n", pAd->ate.TxPower0);
2607 ate_print("TxPower1=%d\n", pAd->ate.TxPower1);
2608 ate_print("TxAntennaSel=%d\n", pAd->ate.TxAntennaSel);
2609 ate_print("RxAntennaSel=%d\n", pAd->ate.RxAntennaSel);
2610 ate_print("BBPCurrentBW=%d\n", pAd->ate.TxWI.BW);
2611 ate_print("GI=%d\n", pAd->ate.TxWI.ShortGI);
2612 ate_print("MCS=%d\n", pAd->ate.TxWI.MCS);
2613 ate_print("TxMode=%d\n", pAd->ate.TxWI.PHYMODE);
2614 ate_print("Addr1=%02x:%02x:%02x:%02x:%02x:%02x\n",
2615 pAd->ate.Addr1[0], pAd->ate.Addr1[1], pAd->ate.Addr1[2], pAd->ate.Addr1[3], pAd->ate.Addr1[4], pAd->ate.Addr1[5]);
2616 ate_print("Addr2=%02x:%02x:%02x:%02x:%02x:%02x\n",
2617 pAd->ate.Addr2[0], pAd->ate.Addr2[1], pAd->ate.Addr2[2], pAd->ate.Addr2[3], pAd->ate.Addr2[4], pAd->ate.Addr2[5]);
2618 ate_print("Addr3=%02x:%02x:%02x:%02x:%02x:%02x\n",
2619 pAd->ate.Addr3[0], pAd->ate.Addr3[1], pAd->ate.Addr3[2], pAd->ate.Addr3[3], pAd->ate.Addr3[4], pAd->ate.Addr3[5]);
2620 ate_print("Channel=%d\n", pAd->ate.Channel);
2621 ate_print("TxLength=%d\n", pAd->ate.TxLength);
2622 ate_print("TxCount=%u\n", pAd->ate.TxCount);
2623 ate_print("RFFreqOffset=%d\n", pAd->ate.RFFreqOffset);
2624 ate_print(KERN_EMERG "Set_ATE_Show_Proc Success\n");
2625 return TRUE;
2626}
2627
2628INT Set_ATE_Help_Proc(
2629 IN PRTMP_ADAPTER pAd,
2630 IN PUCHAR arg)
2631{
2632 ate_print("ATE=ATESTART, ATESTOP, TXCONT, TXCARR, TXFRAME, RXFRAME\n");
2633 ate_print("ATEDA\n");
2634 ate_print("ATESA\n");
2635 ate_print("ATEBSSID\n");
2636 ate_print("ATECHANNEL, range:0~14(unless A band !)\n");
2637 ate_print("ATETXPOW0, set power level of antenna 1.\n");
2638 ate_print("ATETXPOW1, set power level of antenna 2.\n");
2639 ate_print("ATETXANT, set TX antenna. 0:all, 1:antenna one, 2:antenna two.\n");
2640 ate_print("ATERXANT, set RX antenna.0:all, 1:antenna one, 2:antenna two, 3:antenna three.\n");
2641 ate_print("ATETXFREQOFFSET, set frequency offset, range 0~63\n");
2642 ate_print("ATETXBW, set BandWidth, 0:20MHz, 1:40MHz.\n");
2643 ate_print("ATETXLEN, set Frame length, range 24~%d\n", (MAX_FRAME_SIZE - 34/* == 2312 */));
2644 ate_print("ATETXCNT, set how many frame going to transmit.\n");
2645 ate_print("ATETXMCS, set MCS, reference to rate table.\n");
2646 ate_print("ATETXMODE, set Mode 0:CCK, 1:OFDM, 2:HT-Mix, 3:GreenField, reference to rate table.\n");
2647 ate_print("ATETXGI, set GI interval, 0:Long, 1:Short\n");
2648 ate_print("ATERXFER, 0:disable Rx Frame error rate. 1:enable Rx Frame error rate.\n");
2649 ate_print("ATERRF, show all RF registers.\n");
2650 ate_print("ATEWRF1, set RF1 register.\n");
2651 ate_print("ATEWRF2, set RF2 register.\n");
2652 ate_print("ATEWRF3, set RF3 register.\n");
2653 ate_print("ATEWRF4, set RF4 register.\n");
2654 ate_print("ATELDE2P, load EEPROM from .bin file.\n");
2655 ate_print("ATERE2P, display all EEPROM content.\n");
2656 ate_print("ATESHOW, display all parameters of ATE.\n");
2657 ate_print("ATEHELP, online help.\n");
2658
2659 return TRUE;
2660}
2661
2662/*
2663 ==========================================================================
2664 Description:
2665
2666 AsicSwitchChannel() dedicated for ATE.
2667
2668 ==========================================================================
2669*/
2670VOID ATEAsicSwitchChannel(
2671 IN PRTMP_ADAPTER pAd)
2672{
2673 UINT32 R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0, Value = 0;
2674 CHAR TxPwer = 0, TxPwer2 = 0;
2675 UCHAR index, BbpValue = 0, R66 = 0x30;
2676 RTMP_RF_REGS *RFRegTable;
2677 UCHAR Channel;
2678
2679#ifdef RALINK_28xx_QA
2680 if ((pAd->ate.bQATxStart == TRUE) || (pAd->ate.bQARxStart == TRUE))
2681 {
2682 if (pAd->ate.Channel != pAd->LatchRfRegs.Channel)
2683 {
2684 pAd->ate.Channel = pAd->LatchRfRegs.Channel;
2685 }
2686 return;
2687 }
2688 else
2689#endif // RALINK_28xx_QA //
2690 Channel = pAd->ate.Channel;
2691
2692 // Select antenna
2693 AsicAntennaSelect(pAd, Channel);
2694
2695 // fill Tx power value
2696 TxPwer = pAd->ate.TxPower0;
2697 TxPwer2 = pAd->ate.TxPower1;
2698#ifdef RT30xx
2699//2008/07/10:KH add to support 3070 ATE<--
2700
2701 // The RF programming sequence is difference between 3xxx and 2xxx
2702 // The 3070 is 1T1R. Therefore, we don't need to set the number of Tx/Rx path and the only job is to set the parameters of channels.
2703 if (IS_RT30xx(pAd) && ((pAd->RfIcType == RFIC_3020) ||
2704(pAd->RfIcType == RFIC_3021) || (pAd->RfIcType == RFIC_3022) ||
2705(pAd->RfIcType == RFIC_2020)))
2706 {
2707 /* modify by WY for Read RF Reg. error */
2708 UCHAR RFValue;
2709
2710 for (index = 0; index < NUM_OF_3020_CHNL; index++)
2711 {
2712 if (Channel == FreqItems3020[index].Channel)
2713 {
2714 // Programming channel parameters
2715 RT30xxWriteRFRegister(pAd, RF_R02, FreqItems3020[index].N);
2716 RT30xxWriteRFRegister(pAd, RF_R03, FreqItems3020[index].K);
2717
2718 RT30xxReadRFRegister(pAd, RF_R06, (PUCHAR)&RFValue);
2719 RFValue = (RFValue & 0xFC) | FreqItems3020[index].R;
2720 RT30xxWriteRFRegister(pAd, RF_R06, (UCHAR)RFValue);
2721
2722 // Set Tx Power
2723 RT30xxReadRFRegister(pAd, RF_R12, (PUCHAR)&RFValue);
2724 RFValue = (RFValue & 0xE0) | TxPwer;
2725 RT30xxWriteRFRegister(pAd, RF_R12, (UCHAR)RFValue);
2726
2727 // Set RF offset
2728 RT30xxReadRFRegister(pAd, RF_R23, (PUCHAR)&RFValue);
2729 //2008/08/06: KH modified "pAd->RFFreqOffset" to "pAd->ate.RFFreqOffset"
2730 RFValue = (RFValue & 0x80) | pAd->ate.RFFreqOffset;
2731 RT30xxWriteRFRegister(pAd, RF_R23, (UCHAR)RFValue);
2732
2733 // Set BW
2734 if (pAd->ate.TxWI.BW == BW_40)
2735 {
2736 RFValue = pAd->Mlme.CaliBW40RfR24;
2737 //DISABLE_11N_CHECK(pAd);
2738 }
2739 else
2740 {
2741 RFValue = pAd->Mlme.CaliBW20RfR24;
2742 }
2743 RT30xxWriteRFRegister(pAd, RF_R24, (UCHAR)RFValue);
2744
2745 // Enable RF tuning
2746 RT30xxReadRFRegister(pAd, RF_R07, (PUCHAR)&RFValue);
2747 RFValue = RFValue | 0x1;
2748 RT30xxWriteRFRegister(pAd, RF_R07, (UCHAR)RFValue);
2749
2750 // latch channel for future usage.
2751 pAd->LatchRfRegs.Channel = Channel;
2752
2753 break;
2754 }
2755 }
2756
2757 DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n",
2758 Channel,
2759 pAd->RfIcType,
2760 TxPwer,
2761 TxPwer2,
2762 pAd->Antenna.field.TxPath,
2763 FreqItems3020[index].N,
2764 FreqItems3020[index].K,
2765 FreqItems3020[index].R));
2766 }
2767 else
2768//2008/07/10:KH add to support 3070 ATE-->
2769#endif // RT30xx //
2770{
2771 RFRegTable = RF2850RegTable;
2772
2773 switch (pAd->RfIcType)
2774 {
2775 /* But only 2850 and 2750 support 5.5GHz band... */
2776 case RFIC_2820:
2777 case RFIC_2850:
2778 case RFIC_2720:
2779 case RFIC_2750:
2780
2781 for (index = 0; index < NUM_OF_2850_CHNL; index++)
2782 {
2783 if (Channel == RFRegTable[index].Channel)
2784 {
2785 R2 = RFRegTable[index].R2;
2786 if (pAd->Antenna.field.TxPath == 1)
2787 {
2788 R2 |= 0x4000; // If TXpath is 1, bit 14 = 1;
2789 }
2790
2791 if (pAd->Antenna.field.RxPath == 2)
2792 {
2793 switch (pAd->ate.RxAntennaSel)
2794 {
2795 case 1:
2796 R2 |= 0x20040;
2797 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
2798 BbpValue &= 0xE4;
2799 BbpValue |= 0x00;
2800 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
2801 break;
2802 case 2:
2803 R2 |= 0x10040;
2804 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
2805 BbpValue &= 0xE4;
2806 BbpValue |= 0x01;
2807 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
2808 break;
2809 default:
2810 R2 |= 0x40;
2811 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
2812 BbpValue &= 0xE4;
2813 /* Only enable two Antenna to receive. */
2814 BbpValue |= 0x08;
2815 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
2816 break;
2817 }
2818 }
2819 else if (pAd->Antenna.field.RxPath == 1)
2820 {
2821 R2 |= 0x20040; // write 1 to off RxPath
2822 }
2823
2824 if (pAd->Antenna.field.TxPath == 2)
2825 {
2826 if (pAd->ate.TxAntennaSel == 1)
2827 {
2828 R2 |= 0x4000; // If TX Antenna select is 1 , bit 14 = 1; Disable Ant 2
2829 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpValue);
2830 BbpValue &= 0xE7; //11100111B
2831 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpValue);
2832 }
2833 else if (pAd->ate.TxAntennaSel == 2)
2834 {
2835 R2 |= 0x8000; // If TX Antenna select is 2 , bit 15 = 1; Disable Ant 1
2836 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpValue);
2837 BbpValue &= 0xE7;
2838 BbpValue |= 0x08;
2839 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpValue);
2840 }
2841 else
2842 {
2843 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpValue);
2844 BbpValue &= 0xE7;
2845 BbpValue |= 0x10;
2846 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpValue);
2847 }
2848 }
2849 if (pAd->Antenna.field.RxPath == 3)
2850 {
2851 switch (pAd->ate.RxAntennaSel)
2852 {
2853 case 1:
2854 R2 |= 0x20040;
2855 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
2856 BbpValue &= 0xE4;
2857 BbpValue |= 0x00;
2858 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
2859 break;
2860 case 2:
2861 R2 |= 0x10040;
2862 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
2863 BbpValue &= 0xE4;
2864 BbpValue |= 0x01;
2865 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
2866 break;
2867 case 3:
2868 R2 |= 0x30000;
2869 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
2870 BbpValue &= 0xE4;
2871 BbpValue |= 0x02;
2872 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
2873 break;
2874 default:
2875 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
2876 BbpValue &= 0xE4;
2877 BbpValue |= 0x10;
2878 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
2879 break;
2880 }
2881 }
2882
2883 if (Channel > 14)
2884 {
2885 // initialize R3, R4
2886 R3 = (RFRegTable[index].R3 & 0xffffc1ff);
2887 R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->ate.RFFreqOffset << 15);
2888
2889 // According the Rory's suggestion to solve the middle range issue.
2890 // 5.5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB
2891 // R3
2892 if ((TxPwer >= -7) && (TxPwer < 0))
2893 {
2894 TxPwer = (7+TxPwer);
2895 TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
2896 R3 |= (TxPwer << 10);
2897 ATEDBGPRINT(RT_DEBUG_TRACE, ("ATEAsicSwitchChannel: TxPwer=%d \n", TxPwer));
2898 }
2899 else
2900 {
2901 TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
2902 R3 |= (TxPwer << 10) | (1 << 9);
2903 }
2904
2905 // R4
2906 if ((TxPwer2 >= -7) && (TxPwer2 < 0))
2907 {
2908 TxPwer2 = (7+TxPwer2);
2909 TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
2910 R4 |= (TxPwer2 << 7);
2911 ATEDBGPRINT(RT_DEBUG_TRACE, ("ATEAsicSwitchChannel: TxPwer2=%d \n", TxPwer2));
2912 }
2913 else
2914 {
2915 TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
2916 R4 |= (TxPwer2 << 7) | (1 << 6);
2917 }
2918 }
2919 else
2920 {
2921 R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9); // set TX power0
2922 R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->ate.RFFreqOffset << 15) | (TxPwer2 <<6);// Set freq offset & TxPwr1
2923 }
2924
2925 // Based on BBP current mode before changing RF channel.
2926 if (pAd->ate.TxWI.BW == BW_40)
2927 {
2928 R4 |=0x200000;
2929 }
2930
2931 // Update variables
2932 pAd->LatchRfRegs.Channel = Channel;
2933 pAd->LatchRfRegs.R1 = RFRegTable[index].R1;
2934 pAd->LatchRfRegs.R2 = R2;
2935 pAd->LatchRfRegs.R3 = R3;
2936 pAd->LatchRfRegs.R4 = R4;
2937
2938 RtmpRfIoWrite(pAd);
2939
2940 break;
2941 }
2942 }
2943 break;
2944
2945 default:
2946 break;
2947 }
2948}
2949 // Change BBP setting during switch from a->g, g->a
2950 if (Channel <= 14)
2951 {
2952 ULONG TxPinCfg = 0x00050F0A;// 2007.10.09 by Brian : 0x0005050A ==> 0x00050F0A
2953
2954 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
2955 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
2956 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
2957
2958 /* For 1T/2R chip only... */
2959 if (pAd->NicConfig2.field.ExternalLNAForG)
2960 {
2961 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
2962 }
2963 else
2964 {
2965 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84);
2966 }
2967
2968 // According the Rory's suggestion to solve the middle range issue.
2969 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R86, &BbpValue);
2970 ASSERT((BbpValue == 0x00));
2971 if ((BbpValue != 0x00))
2972 {
2973 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0x00);
2974 }
2975
2976 // 5.5GHz band selection PIN, bit1 and bit2 are complement
2977 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
2978 Value &= (~0x6);
2979 Value |= (0x04);
2980 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
2981
2982 // Turn off unused PA or LNA when only 1T or 1R.
2983 if (pAd->Antenna.field.TxPath == 1)
2984 {
2985 TxPinCfg &= 0xFFFFFFF3;
2986 }
2987 if (pAd->Antenna.field.RxPath == 1)
2988 {
2989 TxPinCfg &= 0xFFFFF3FF;
2990 }
2991
2992 RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
2993 }
2994 else
2995 {
2996 ULONG TxPinCfg = 0x00050F05;//2007.10.09 by Brian : 0x00050505 ==> 0x00050F05
2997
2998 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
2999 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
3000 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
3001 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0xF2);
3002
3003 // According the Rory's suggestion to solve the middle range issue.
3004 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R86, &BbpValue);
3005 ASSERT((BbpValue == 0x00));
3006 if ((BbpValue != 0x00))
3007 {
3008 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0x00);
3009 }
3010 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R91, &BbpValue);
3011 ASSERT((BbpValue == 0x04));
3012
3013 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R92, &BbpValue);
3014 ASSERT((BbpValue == 0x00));
3015
3016 // 5.5GHz band selection PIN, bit1 and bit2 are complement
3017 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
3018 Value &= (~0x6);
3019 Value |= (0x02);
3020 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
3021
3022 // Turn off unused PA or LNA when only 1T or 1R.
3023 if (pAd->Antenna.field.TxPath == 1)
3024 {
3025 TxPinCfg &= 0xFFFFFFF3;
3026 }
3027 if (pAd->Antenna.field.RxPath == 1)
3028 {
3029 TxPinCfg &= 0xFFFFF3FF;
3030 }
3031
3032 RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
3033 }
3034
3035 // R66 should be set according to Channel and use 20MHz when scanning
3036 if (Channel <= 14)
3037 {
3038 // BG band
3039 R66 = 0x2E + GET_LNA_GAIN(pAd);
3040 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
3041 }
3042 else
3043 {
3044 // 5.5 GHz band
3045 if (pAd->ate.TxWI.BW == BW_20)
3046 {
3047 R66 = (UCHAR)(0x32 + (GET_LNA_GAIN(pAd)*5)/3);
3048 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
3049 }
3050 else
3051 {
3052 R66 = (UCHAR)(0x3A + (GET_LNA_GAIN(pAd)*5)/3);
3053 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
3054 }
3055 }
3056
3057 //
3058 // On 11A, We should delay and wait RF/BBP to be stable
3059 // and the appropriate time should be 1000 micro seconds
3060 // 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL.
3061 //
3062 RTMPusecDelay(1000);
3063
3064 if (Channel > 14)
3065 {
3066 // When 5.5GHz band the LSB of TxPwr will be used to reduced 7dB or not.
3067 ATEDBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, %dT) to , R1=0x%08lx, R2=0x%08lx, R3=0x%08lx, R4=0x%08lx\n",
3068 Channel,
3069 pAd->RfIcType,
3070 pAd->Antenna.field.TxPath,
3071 pAd->LatchRfRegs.R1,
3072 pAd->LatchRfRegs.R2,
3073 pAd->LatchRfRegs.R3,
3074 pAd->LatchRfRegs.R4));
3075 }
3076 else
3077 {
3078 ATEDBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%u, Pwr1=%u, %dT) to , R1=0x%08lx, R2=0x%08lx, R3=0x%08lx, R4=0x%08lx\n",
3079 Channel,
3080 pAd->RfIcType,
3081 (R3 & 0x00003e00) >> 9,
3082 (R4 & 0x000007c0) >> 6,
3083 pAd->Antenna.field.TxPath,
3084 pAd->LatchRfRegs.R1,
3085 pAd->LatchRfRegs.R2,
3086 pAd->LatchRfRegs.R3,
3087 pAd->LatchRfRegs.R4));
3088 }
3089}
3090
3091//
3092// In fact, no one will call this routine so far !
3093//
3094/*
3095 ==========================================================================
3096 Description:
3097 Gives CCK TX rate 2 more dB TX power.
3098 This routine works only in ATE mode.
3099
3100 calculate desired Tx power in RF R3.Tx0~5, should consider -
3101 0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment)
3102 1. TxPowerPercentage
3103 2. auto calibration based on TSSI feedback
3104 3. extra 2 db for CCK
3105 4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP
3106
3107 NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment),
3108 it should be called AFTER MlmeDynamicTxRateSwitching()
3109 ==========================================================================
3110 */
3111VOID ATEAsicAdjustTxPower(
3112 IN PRTMP_ADAPTER pAd)
3113{
3114 INT i, j;
3115 CHAR DeltaPwr = 0;
3116 BOOLEAN bAutoTxAgc = FALSE;
3117 UCHAR TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep;
3118 UCHAR BbpR49 = 0, idx;
3119 PCHAR pTxAgcCompensate;
3120 ULONG TxPwr[5];
3121 CHAR Value;
3122
3123 /* no one calls this procedure so far */
3124 if (pAd->ate.TxWI.BW == BW_40)
3125 {
3126 if (pAd->ate.Channel > 14)
3127 {
3128 TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
3129 TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
3130 TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
3131 TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
3132 TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
3133 }
3134 else
3135 {
3136 TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
3137 TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
3138 TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
3139 TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
3140 TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
3141 }
3142 }
3143 else
3144 {
3145 if (pAd->ate.Channel > 14)
3146 {
3147 TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
3148 TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
3149 TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
3150 TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
3151 TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
3152 }
3153 else
3154 {
3155 TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
3156 TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
3157 TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
3158 TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
3159 TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
3160 }
3161 }
3162
3163 // TX power compensation for temperature variation based on TSSI.
3164 // Do it per 4 seconds.
3165 if (pAd->Mlme.OneSecPeriodicRound % 4 == 0)
3166 {
3167 if (pAd->ate.Channel <= 14)
3168 {
3169 /* bg channel */
3170 bAutoTxAgc = pAd->bAutoTxAgcG;
3171 TssiRef = pAd->TssiRefG;
3172 pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0];
3173 pTssiPlusBoundary = &pAd->TssiPlusBoundaryG[0];
3174 TxAgcStep = pAd->TxAgcStepG;
3175 pTxAgcCompensate = &pAd->TxAgcCompensateG;
3176 }
3177 else
3178 {
3179 /* a channel */
3180 bAutoTxAgc = pAd->bAutoTxAgcA;
3181 TssiRef = pAd->TssiRefA;
3182 pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0];
3183 pTssiPlusBoundary = &pAd->TssiPlusBoundaryA[0];
3184 TxAgcStep = pAd->TxAgcStepA;
3185 pTxAgcCompensate = &pAd->TxAgcCompensateA;
3186 }
3187
3188 if (bAutoTxAgc)
3189 {
3190 /* BbpR49 is unsigned char */
3191 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49);
3192
3193 /* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */
3194 /* compensate: +4 +3 +2 +1 0 -1 -2 -3 -4 * steps */
3195 /* step value is defined in pAd->TxAgcStepG for tx power value */
3196
3197 /* [4]+1+[4] p4 p3 p2 p1 o1 m1 m2 m3 m4 */
3198 /* ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
3199 above value are examined in mass factory production */
3200 /* [4] [3] [2] [1] [0] [1] [2] [3] [4] */
3201
3202 /* plus is 0x10 ~ 0x40, minus is 0x60 ~ 0x90 */
3203 /* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */
3204 /* if value is 0x65, tx power will be -= TxAgcStep*(2-1) */
3205
3206 if (BbpR49 > pTssiMinusBoundary[1])
3207 {
3208 // Reading is larger than the reference value.
3209 // Check for how large we need to decrease the Tx power.
3210 for (idx = 1; idx < 5; idx++)
3211 {
3212 if (BbpR49 <= pTssiMinusBoundary[idx]) // Found the range
3213 break;
3214 }
3215 // The index is the step we should decrease, idx = 0 means there is nothing to compensate
3216// if (R3 > (ULONG) (TxAgcStep * (idx-1)))
3217 *pTxAgcCompensate = -(TxAgcStep * (idx-1));
3218// else
3219// *pTxAgcCompensate = -((UCHAR)R3);
3220
3221 DeltaPwr += (*pTxAgcCompensate);
3222 ATEDBGPRINT(RT_DEBUG_TRACE, ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n",
3223 BbpR49, TssiRef, TxAgcStep, idx-1));
3224 }
3225 else if (BbpR49 < pTssiPlusBoundary[1])
3226 {
3227 // Reading is smaller than the reference value
3228 // check for how large we need to increase the Tx power
3229 for (idx = 1; idx < 5; idx++)
3230 {
3231 if (BbpR49 >= pTssiPlusBoundary[idx]) // Found the range
3232 break;
3233 }
3234 // The index is the step we should increase, idx = 0 means there is nothing to compensate
3235 *pTxAgcCompensate = TxAgcStep * (idx-1);
3236 DeltaPwr += (*pTxAgcCompensate);
3237 ATEDBGPRINT(RT_DEBUG_TRACE, ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
3238 BbpR49, TssiRef, TxAgcStep, idx-1));
3239 }
3240 else
3241 {
3242 *pTxAgcCompensate = 0;
3243 ATEDBGPRINT(RT_DEBUG_TRACE, (" Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
3244 BbpR49, TssiRef, TxAgcStep, 0));
3245 }
3246 }
3247 }
3248 else
3249 {
3250 if (pAd->ate.Channel <= 14)
3251 {
3252 bAutoTxAgc = pAd->bAutoTxAgcG;
3253 pTxAgcCompensate = &pAd->TxAgcCompensateG;
3254 }
3255 else
3256 {
3257 bAutoTxAgc = pAd->bAutoTxAgcA;
3258 pTxAgcCompensate = &pAd->TxAgcCompensateA;
3259 }
3260
3261 if (bAutoTxAgc)
3262 DeltaPwr += (*pTxAgcCompensate);
3263 }
3264
3265 /* calculate delta power based on the percentage specified from UI */
3266 // E2PROM setting is calibrated for maximum TX power (i.e. 100%)
3267 // We lower TX power here according to the percentage specified from UI
3268 if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff) // AUTO TX POWER control
3269 ;
3270 else if (pAd->CommonCfg.TxPowerPercentage > 90) // 91 ~ 100% & AUTO, treat as 100% in terms of mW
3271 ;
3272 else if (pAd->CommonCfg.TxPowerPercentage > 60) // 61 ~ 90%, treat as 75% in terms of mW
3273 {
3274 DeltaPwr -= 1;
3275 }
3276 else if (pAd->CommonCfg.TxPowerPercentage > 30) // 31 ~ 60%, treat as 50% in terms of mW
3277 {
3278 DeltaPwr -= 3;
3279 }
3280 else if (pAd->CommonCfg.TxPowerPercentage > 15) // 16 ~ 30%, treat as 25% in terms of mW
3281 {
3282 DeltaPwr -= 6;
3283 }
3284 else if (pAd->CommonCfg.TxPowerPercentage > 9) // 10 ~ 15%, treat as 12.5% in terms of mW
3285 {
3286 DeltaPwr -= 9;
3287 }
3288 else // 0 ~ 9 %, treat as MIN(~3%) in terms of mW
3289 {
3290 DeltaPwr -= 12;
3291 }
3292
3293 /* reset different new tx power for different TX rate */
3294 for(i=0; i<5; i++)
3295 {
3296 if (TxPwr[i] != 0xffffffff)
3297 {
3298 for (j=0; j<8; j++)
3299 {
3300 Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F); /* 0 ~ 15 */
3301
3302 if ((Value + DeltaPwr) < 0)
3303 {
3304 Value = 0; /* min */
3305 }
3306 else if ((Value + DeltaPwr) > 0xF)
3307 {
3308 Value = 0xF; /* max */
3309 }
3310 else
3311 {
3312 Value += DeltaPwr; /* temperature compensation */
3313 }
3314
3315 /* fill new value to CSR offset */
3316 TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4);
3317 }
3318
3319 /* write tx power value to CSR */
3320 /* TX_PWR_CFG_0 (8 tx rate) for TX power for OFDM 12M/18M
3321 TX power for OFDM 6M/9M
3322 TX power for CCK5.5M/11M
3323 TX power for CCK1M/2M */
3324 /* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */
3325 RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, TxPwr[i]);
3326
3327
3328 }
3329 }
3330
3331}
3332
3333/*
3334 ========================================================================
3335 Routine Description:
3336 Write TxWI for ATE mode.
3337
3338 Return Value:
3339 None
3340 ========================================================================
3341*/
3342
3343#ifdef RT2870
3344static VOID ATEWriteTxWI(
3345 IN PRTMP_ADAPTER pAd,
3346 IN PTXWI_STRUC pTxWI,
3347 IN BOOLEAN FRAG,
3348 IN BOOLEAN InsTimestamp,
3349 IN BOOLEAN AMPDU,
3350 IN BOOLEAN Ack,
3351 IN BOOLEAN NSeq, // HW new a sequence.
3352 IN UCHAR BASize,
3353 IN UCHAR WCID,
3354 IN ULONG Length,
3355 IN UCHAR PID,
3356 IN UCHAR MIMOps,
3357 IN UCHAR Txopmode,
3358 IN BOOLEAN CfAck,
3359 IN HTTRANSMIT_SETTING Transmit)
3360{
3361 //
3362 // Always use Long preamble before verifiation short preamble functionality works well.
3363 // Todo: remove the following line if short preamble functionality works
3364 //
3365 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
3366 pTxWI->FRAG= FRAG;
3367 pTxWI->TS= InsTimestamp;
3368 pTxWI->AMPDU = AMPDU;
3369
3370 pTxWI->MIMOps = PWR_ACTIVE;
3371 pTxWI->MpduDensity = 4;
3372 pTxWI->ACK = Ack;
3373 pTxWI->txop = Txopmode;
3374 pTxWI->NSEQ = NSeq;
3375 pTxWI->BAWinSize = BASize;
3376
3377 pTxWI->WirelessCliID = WCID;
3378 pTxWI->MPDUtotalByteCount = Length;
3379 pTxWI->PacketId = PID;
3380
3381 pTxWI->BW = Transmit.field.BW;
3382 pTxWI->ShortGI = Transmit.field.ShortGI;
3383 pTxWI->STBC= Transmit.field.STBC;
3384
3385 pTxWI->MCS = Transmit.field.MCS;
3386 pTxWI->PHYMODE= Transmit.field.MODE;
3387
3388#ifdef DOT11_N_SUPPORT
3389 //
3390 // MMPS is 802.11n features. Because TxWI->MCS > 7 must be HT mode,
3391 // so need not check if it's HT rate.
3392 //
3393 if ((MIMOps == MMPS_STATIC) && (pTxWI->MCS > 7))
3394 pTxWI->MCS = 7;
3395
3396 if ((MIMOps == MMPS_DYNAMIC) && (pTxWI->MCS > 7)) // SMPS protect 2 spatial.
3397 pTxWI->MIMOps = 1;
3398#endif // DOT11_N_SUPPORT //
3399
3400 pTxWI->CFACK = CfAck;
3401
3402 return;
3403}
3404#endif // RT2870 //
3405/*
3406 ========================================================================
3407
3408 Routine Description:
3409 Disable protection for ATE.
3410 ========================================================================
3411*/
3412VOID ATEDisableAsicProtect(
3413 IN PRTMP_ADAPTER pAd)
3414{
3415 PROT_CFG_STRUC ProtCfg, ProtCfg4;
3416 UINT32 Protect[6];
3417 USHORT offset;
3418 UCHAR i;
3419 UINT32 MacReg = 0;
3420
3421 // Config ASIC RTS threshold register
3422 RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg);
3423 MacReg &= 0xFF0000FF;
3424 MacReg |= (pAd->CommonCfg.RtsThreshold << 8);
3425 RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg);
3426
3427 // Initial common protection settings
3428 RTMPZeroMemory(Protect, sizeof(Protect));
3429 ProtCfg4.word = 0;
3430 ProtCfg.word = 0;
3431 ProtCfg.field.TxopAllowGF40 = 1;
3432 ProtCfg.field.TxopAllowGF20 = 1;
3433 ProtCfg.field.TxopAllowMM40 = 1;
3434 ProtCfg.field.TxopAllowMM20 = 1;
3435 ProtCfg.field.TxopAllowOfdm = 1;
3436 ProtCfg.field.TxopAllowCck = 1;
3437 ProtCfg.field.RTSThEn = 1;
3438 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
3439
3440 // Handle legacy(B/G) protection
3441 ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
3442 ProtCfg.field.ProtectCtrl = 0;
3443 Protect[0] = ProtCfg.word;
3444 Protect[1] = ProtCfg.word;
3445
3446 // NO PROTECT
3447 // 1.All STAs in the BSS are 20/40 MHz HT
3448 // 2. in ai 20/40MHz BSS
3449 // 3. all STAs are 20MHz in a 20MHz BSS
3450 // Pure HT. no protection.
3451
3452 // MM20_PROT_CFG
3453 // Reserved (31:27)
3454 // PROT_TXOP(25:20) -- 010111
3455 // PROT_NAV(19:18) -- 01 (Short NAV protection)
3456 // PROT_CTRL(17:16) -- 00 (None)
3457 // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
3458 Protect[2] = 0x01744004;
3459
3460 // MM40_PROT_CFG
3461 // Reserved (31:27)
3462 // PROT_TXOP(25:20) -- 111111
3463 // PROT_NAV(19:18) -- 01 (Short NAV protection)
3464 // PROT_CTRL(17:16) -- 00 (None)
3465 // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
3466 Protect[3] = 0x03f44084;
3467
3468 // CF20_PROT_CFG
3469 // Reserved (31:27)
3470 // PROT_TXOP(25:20) -- 010111
3471 // PROT_NAV(19:18) -- 01 (Short NAV protection)
3472 // PROT_CTRL(17:16) -- 00 (None)
3473 // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
3474 Protect[4] = 0x01744004;
3475
3476 // CF40_PROT_CFG
3477 // Reserved (31:27)
3478 // PROT_TXOP(25:20) -- 111111
3479 // PROT_NAV(19:18) -- 01 (Short NAV protection)
3480 // PROT_CTRL(17:16) -- 00 (None)
3481 // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
3482 Protect[5] = 0x03f44084;
3483
3484 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
3485
3486 offset = CCK_PROT_CFG;
3487 for (i = 0;i < 6;i++)
3488 RTMP_IO_WRITE32(pAd, offset + i*4, Protect[i]);
3489
3490}
3491
3492#ifdef RT2870
3493/*
3494 ========================================================================
3495 Routine Description:
3496 Write TxInfo for ATE mode.
3497
3498 Return Value:
3499 None
3500 ========================================================================
3501*/
3502static VOID ATEWriteTxInfo(
3503 IN PRTMP_ADAPTER pAd,
3504 IN PTXINFO_STRUC pTxInfo,
3505 IN USHORT USBDMApktLen,
3506 IN BOOLEAN bWiv,
3507 IN UCHAR QueueSel,
3508 IN UCHAR NextValid,
3509 IN UCHAR TxBurst)
3510{
3511 pTxInfo->USBDMATxPktLen = USBDMApktLen;
3512 pTxInfo->QSEL = QueueSel;
3513
3514 if (QueueSel != FIFO_EDCA)
3515 ATEDBGPRINT(RT_DEBUG_TRACE, ("=======> QueueSel != FIFO_EDCA<=======\n"));
3516
3517 pTxInfo->USBDMANextVLD = NextValid;
3518 pTxInfo->USBDMATxburst = TxBurst;
3519 pTxInfo->WIV = bWiv;
3520 pTxInfo->SwUseLastRound = 0;
3521 pTxInfo->rsv = 0;
3522 pTxInfo->rsv2 = 0;
3523
3524 return;
3525}
3526#endif // RT2870 //
3527
3528/* There are two ways to convert Rssi */
3529#if 1
3530//
3531// The way used with GET_LNA_GAIN().
3532//
3533CHAR ATEConvertToRssi(
3534 IN PRTMP_ADAPTER pAd,
3535 IN CHAR Rssi,
3536 IN UCHAR RssiNumber)
3537{
3538 UCHAR RssiOffset, LNAGain;
3539
3540 // Rssi equals to zero should be an invalid value
3541 if (Rssi == 0)
3542 return -99;
3543
3544 LNAGain = GET_LNA_GAIN(pAd);
3545 if (pAd->LatchRfRegs.Channel > 14)
3546 {
3547 if (RssiNumber == 0)
3548 RssiOffset = pAd->ARssiOffset0;
3549 else if (RssiNumber == 1)
3550 RssiOffset = pAd->ARssiOffset1;
3551 else
3552 RssiOffset = pAd->ARssiOffset2;
3553 }
3554 else
3555 {
3556 if (RssiNumber == 0)
3557 RssiOffset = pAd->BGRssiOffset0;
3558 else if (RssiNumber == 1)
3559 RssiOffset = pAd->BGRssiOffset1;
3560 else
3561 RssiOffset = pAd->BGRssiOffset2;
3562 }
3563
3564 return (-12 - RssiOffset - LNAGain - Rssi);
3565}
3566#else
3567//
3568// The way originally used in ATE of rt2860ap.
3569//
3570CHAR ATEConvertToRssi(
3571 IN PRTMP_ADAPTER pAd,
3572 IN CHAR Rssi,
3573 IN UCHAR RssiNumber)
3574{
3575 UCHAR RssiOffset, LNAGain;
3576
3577 // Rssi equals to zero should be an invalid value
3578 if (Rssi == 0)
3579 return -99;
3580
3581 if (pAd->LatchRfRegs.Channel > 14)
3582 {
3583 LNAGain = pAd->ALNAGain;
3584 if (RssiNumber == 0)
3585 RssiOffset = pAd->ARssiOffset0;
3586 else if (RssiNumber == 1)
3587 RssiOffset = pAd->ARssiOffset1;
3588 else
3589 RssiOffset = pAd->ARssiOffset2;
3590 }
3591 else
3592 {
3593 LNAGain = pAd->BLNAGain;
3594 if (RssiNumber == 0)
3595 RssiOffset = pAd->BGRssiOffset0;
3596 else if (RssiNumber == 1)
3597 RssiOffset = pAd->BGRssiOffset1;
3598 else
3599 RssiOffset = pAd->BGRssiOffset2;
3600 }
3601
3602 return (-32 - RssiOffset + LNAGain - Rssi);
3603}
3604#endif /* end of #if 1 */
3605
3606/*
3607 ========================================================================
3608
3609 Routine Description:
3610 Set Japan filter coefficients if needed.
3611 Note:
3612 This routine should only be called when
3613 entering TXFRAME mode or TXCONT mode.
3614
3615 ========================================================================
3616*/
3617static VOID SetJapanFilter(
3618 IN PRTMP_ADAPTER pAd)
3619{
3620 UCHAR BbpData = 0;
3621
3622 //
3623 // If Channel=14 and Bandwidth=20M and Mode=CCK, set BBP R4 bit5=1
3624 // (Japan Tx filter coefficients)when (TXFRAME or TXCONT).
3625 //
3626 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BbpData);
3627
3628 if ((pAd->ate.TxWI.PHYMODE == MODE_CCK) && (pAd->ate.Channel == 14) && (pAd->ate.TxWI.BW == BW_20))
3629 {
3630 BbpData |= 0x20; // turn on
3631 ATEDBGPRINT(RT_DEBUG_TRACE, ("SetJapanFilter!!!\n"));
3632 }
3633 else
3634 {
3635 BbpData &= 0xdf; // turn off
3636 ATEDBGPRINT(RT_DEBUG_TRACE, ("ClearJapanFilter!!!\n"));
3637 }
3638
3639 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BbpData);
3640}
3641
3642VOID ATESampleRssi(
3643 IN PRTMP_ADAPTER pAd,
3644 IN PRXWI_STRUC pRxWI)
3645{
3646 /* There are two ways to collect RSSI. */
3647#if 1
3648 //pAd->LastRxRate = (USHORT)((pRxWI->MCS) + (pRxWI->BW <<7) + (pRxWI->ShortGI <<8)+ (pRxWI->PHYMODE <<14)) ;
3649 if (pRxWI->RSSI0 != 0)
3650 {
3651 pAd->ate.LastRssi0 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI0, RSSI_0);
3652 pAd->ate.AvgRssi0X8 = (pAd->ate.AvgRssi0X8 - pAd->ate.AvgRssi0) + pAd->ate.LastRssi0;
3653 pAd->ate.AvgRssi0 = pAd->ate.AvgRssi0X8 >> 3;
3654 }
3655 if (pRxWI->RSSI1 != 0)
3656 {
3657 pAd->ate.LastRssi1 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI1, RSSI_1);
3658 pAd->ate.AvgRssi1X8 = (pAd->ate.AvgRssi1X8 - pAd->ate.AvgRssi1) + pAd->ate.LastRssi1;
3659 pAd->ate.AvgRssi1 = pAd->ate.AvgRssi1X8 >> 3;
3660 }
3661 if (pRxWI->RSSI2 != 0)
3662 {
3663 pAd->ate.LastRssi2 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI2, RSSI_2);
3664 pAd->ate.AvgRssi2X8 = (pAd->ate.AvgRssi2X8 - pAd->ate.AvgRssi2) + pAd->ate.LastRssi2;
3665 pAd->ate.AvgRssi2 = pAd->ate.AvgRssi2X8 >> 3;
3666 }
3667
3668 pAd->ate.LastSNR0 = (CHAR)(pRxWI->SNR0);// CHAR ==> UCHAR ?
3669 pAd->ate.LastSNR1 = (CHAR)(pRxWI->SNR1);// CHAR ==> UCHAR ?
3670
3671 pAd->ate.NumOfAvgRssiSample ++;
3672#else
3673 pAd->ate.LastSNR0 = (CHAR)(pRxWI->SNR0);
3674 pAd->ate.LastSNR1 = (CHAR)(pRxWI->SNR1);
3675 pAd->ate.RxCntPerSec++;
3676 pAd->ate.LastRssi0 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI0, RSSI_0);
3677 pAd->ate.LastRssi1 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI1, RSSI_1);
3678 pAd->ate.LastRssi2 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI2, RSSI_2);
3679 pAd->ate.AvgRssi0X8 = (pAd->ate.AvgRssi0X8 - pAd->ate.AvgRssi0) + pAd->ate.LastRssi0;
3680 pAd->ate.AvgRssi0 = pAd->ate.AvgRssi0X8 >> 3;
3681 pAd->ate.AvgRssi1X8 = (pAd->ate.AvgRssi1X8 - pAd->ate.AvgRssi1) + pAd->ate.LastRssi1;
3682 pAd->ate.AvgRssi1 = pAd->ate.AvgRssi1X8 >> 3;
3683 pAd->ate.AvgRssi2X8 = (pAd->ate.AvgRssi2X8 - pAd->ate.AvgRssi2) + pAd->ate.LastRssi2;
3684 pAd->ate.AvgRssi2 = pAd->ate.AvgRssi2X8 >> 3;
3685 pAd->ate.NumOfAvgRssiSample ++;
3686#endif
3687}
3688
3689#ifdef CONFIG_STA_SUPPORT
3690VOID RTMPStationStop(
3691 IN PRTMP_ADAPTER pAd)
3692{
3693// BOOLEAN Cancelled;
3694
3695 ATEDBGPRINT(RT_DEBUG_TRACE, ("==> RTMPStationStop\n"));
3696
3697 // For rx statistics, we need to keep this timer running.
3698// RTMPCancelTimer(&pAd->Mlme.PeriodicTimer, &Cancelled);
3699
3700 ATEDBGPRINT(RT_DEBUG_TRACE, ("<== RTMPStationStop\n"));
3701}
3702
3703VOID RTMPStationStart(
3704 IN PRTMP_ADAPTER pAd)
3705{
3706 ATEDBGPRINT(RT_DEBUG_TRACE, ("==> RTMPStationStart\n"));
3707 ATEDBGPRINT(RT_DEBUG_TRACE, ("<== RTMPStationStart\n"));
3708}
3709#endif // CONFIG_STA_SUPPORT //
3710
3711/*
3712 ==========================================================================
3713 Description:
3714 Setup Frame format.
3715 NOTE:
3716 This routine should only be used in ATE mode.
3717 ==========================================================================
3718 */
3719
3720#ifdef RT2870
3721/*======================Start of RT2870======================*/
3722/* */
3723/* */
3724static INT ATESetUpFrame(
3725 IN PRTMP_ADAPTER pAd,
3726 IN UINT32 TxIdx)
3727{
3728 UINT j;
3729 PTX_CONTEXT pNullContext;
3730 PUCHAR pDest;
3731 HTTRANSMIT_SETTING TxHTPhyMode;
3732 PTXWI_STRUC pTxWI;
3733 PTXINFO_STRUC pTxInfo;
3734 UINT32 TransferBufferLength, OrgBufferLength = 0;
3735 UCHAR padLen = 0;
3736#ifdef RALINK_28xx_QA
3737 PHEADER_802_11 pHeader80211 = NULL;
3738#endif // RALINK_28xx_QA //
3739
3740 if ((RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) ||
3741 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) ||
3742 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) ||
3743 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
3744 {
3745 return -1;
3746 }
3747
3748 /* We always use QID_AC_BE and FIFO_EDCA in ATE mode. */
3749
3750 pNullContext = &(pAd->NullContext);
3751 ASSERT(pNullContext != NULL);
3752
3753 if (pNullContext->InUse == FALSE)
3754 {
3755 // Set the in use bit
3756 pNullContext->InUse = TRUE;
3757 NdisZeroMemory(&(pAd->NullFrame), sizeof(HEADER_802_11));
3758
3759 // Fill 802.11 header.
3760#ifdef RALINK_28xx_QA
3761 if (pAd->ate.bQATxStart == TRUE)
3762 {
3763 pHeader80211 = NdisMoveMemory(&(pAd->NullFrame), pAd->ate.Header, pAd->ate.HLen);
3764// pDest = NdisMoveMemory(&(pAd->NullFrame), pAd->ate.Header, pAd->ate.HLen);
3765// pHeader80211 = (PHEADER_802_11)pDest;
3766 }
3767 else
3768#endif // RALINK_28xx_QA //
3769 {
3770 // Fill 802.11 header.
3771 NdisMoveMemory(&(pAd->NullFrame), TemplateFrame, sizeof(HEADER_802_11));
3772 }
3773#ifdef RT_BIG_ENDIAN
3774 RTMPFrameEndianChange(pAd, (PUCHAR)&(pAd->NullFrame), DIR_READ, FALSE);
3775#endif // RT_BIG_ENDIAN //
3776
3777#ifdef RALINK_28xx_QA
3778 if (pAd->ate.bQATxStart == TRUE)
3779 {
3780 /* modify sequence number.... */
3781 if (pAd->ate.TxDoneCount == 0)
3782 {
3783 pAd->ate.seq = pHeader80211->Sequence;
3784 }
3785 else
3786 {
3787 pHeader80211->Sequence = ++pAd->ate.seq;
3788 }
3789 /* We already got all the addr. fields from QA GUI. */
3790 }
3791 else
3792#endif // RALINK_28xx_QA //
3793 {
3794 COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->ate.Addr1);
3795 COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->ate.Addr2);
3796 COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->ate.Addr3);
3797 }
3798
3799 RTMPZeroMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[0], TX_BUFFER_NORMSIZE);//???
3800 pTxInfo = (PTXINFO_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[0];
3801
3802#ifdef RALINK_28xx_QA
3803 if (pAd->ate.bQATxStart == TRUE)
3804 {
3805 // Avoid to exceed the range of WirelessPacket[].
3806 ASSERT(pAd->ate.TxInfo.USBDMATxPktLen <= (MAX_FRAME_SIZE - 34/* == 2312 */));
3807 NdisMoveMemory(pTxInfo, &(pAd->ate.TxInfo), sizeof(pAd->ate.TxInfo));
3808 }
3809 else
3810#endif // RALINK_28xx_QA //
3811 {
3812 // Avoid to exceed the range of WirelessPacket[].
3813 ASSERT(pAd->ate.TxLength <= (MAX_FRAME_SIZE - 34/* == 2312 */));
3814
3815 // pTxInfo->USBDMATxPktLen will be updated to include padding later.
3816 ATEWriteTxInfo(pAd, pTxInfo, (USHORT)(TXWI_SIZE + pAd->ate.TxLength), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
3817 pTxInfo->QSEL = FIFO_EDCA;
3818 }
3819
3820 pTxWI = (PTXWI_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
3821
3822 // Fill TxWI.
3823 if (pAd->ate.bQATxStart == TRUE)
3824 {
3825 TxHTPhyMode.field.BW = pAd->ate.TxWI.BW;
3826 TxHTPhyMode.field.ShortGI = pAd->ate.TxWI.ShortGI;
3827 TxHTPhyMode.field.STBC = pAd->ate.TxWI.STBC;
3828 TxHTPhyMode.field.MCS = pAd->ate.TxWI.MCS;
3829 TxHTPhyMode.field.MODE = pAd->ate.TxWI.PHYMODE;
3830 ATEWriteTxWI(pAd, pTxWI, pAd->ate.TxWI.FRAG, pAd->ate.TxWI.TS, pAd->ate.TxWI.AMPDU, pAd->ate.TxWI.ACK, pAd->ate.TxWI.NSEQ,
3831 pAd->ate.TxWI.BAWinSize, BSSID_WCID, pAd->ate.TxWI.MPDUtotalByteCount/* include 802.11 header */, pAd->ate.TxWI.PacketId, 0, pAd->ate.TxWI.txop/*IFS_HTTXOP*/, pAd->ate.TxWI.CFACK/*FALSE*/, TxHTPhyMode);
3832 }
3833 else
3834 {
3835 TxHTPhyMode.field.BW = pAd->ate.TxWI.BW;
3836 TxHTPhyMode.field.ShortGI = pAd->ate.TxWI.ShortGI;
3837 TxHTPhyMode.field.STBC = 0;
3838 TxHTPhyMode.field.MCS = pAd->ate.TxWI.MCS;
3839 TxHTPhyMode.field.MODE = pAd->ate.TxWI.PHYMODE;
3840
3841 ATEWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE/* No ack required. */, FALSE, 0, BSSID_WCID, pAd->ate.TxLength,
3842 0, 0, IFS_HTTXOP, FALSE, TxHTPhyMode);// "MMPS_STATIC" instead of "MMPS_DYNAMIC" ???
3843 }
3844
3845 RTMPMoveMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE+TXWI_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11));
3846
3847 pDest = &(pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE+TXWI_SIZE+sizeof(HEADER_802_11)]);
3848
3849 // Prepare frame payload
3850#ifdef RALINK_28xx_QA
3851 if (pAd->ate.bQATxStart == TRUE)
3852 {
3853 // copy pattern
3854 if ((pAd->ate.PLen != 0))
3855 {
3856 for (j = 0; j < pAd->ate.DLen; j+=pAd->ate.PLen)
3857 {
3858 RTMPMoveMemory(pDest, pAd->ate.Pattern, pAd->ate.PLen);
3859 pDest += pAd->ate.PLen;
3860 }
3861 }
3862 TransferBufferLength = TXINFO_SIZE + TXWI_SIZE + pAd->ate.TxWI.MPDUtotalByteCount;
3863 }
3864 else
3865#endif // RALINK_28xx_QA //
3866 {
3867 for (j = 0; j < (pAd->ate.TxLength - sizeof(HEADER_802_11)); j++)
3868 {
3869 *pDest = 0xA5;
3870 pDest += 1;
3871 }
3872 TransferBufferLength = TXINFO_SIZE + TXWI_SIZE + pAd->ate.TxLength;
3873 }
3874
3875#if 1
3876 OrgBufferLength = TransferBufferLength;
3877 TransferBufferLength = (TransferBufferLength + 3) & (~3);
3878
3879 // Always add 4 extra bytes at every packet.
3880 padLen = TransferBufferLength - OrgBufferLength + 4;/* 4 == last packet padding */
3881 ASSERT((padLen <= (RTMP_PKT_TAIL_PADDING - 4/* 4 == MaxBulkOutsize alignment padding */)));
3882
3883 /* Now memzero all extra padding bytes. */
3884 NdisZeroMemory(pDest, padLen);
3885 pDest += padLen;
3886#else
3887 if ((TransferBufferLength % 4) == 1)
3888 {
3889 NdisZeroMemory(pDest, 7);
3890 pDest += 7;
3891 TransferBufferLength += 3;
3892 }
3893 else if ((TransferBufferLength % 4) == 2)
3894 {
3895 NdisZeroMemory(pDest, 6);
3896 pDest += 6;
3897 TransferBufferLength += 2;
3898 }
3899 else if ((TransferBufferLength % 4) == 3)
3900 {
3901 NdisZeroMemory(pDest, 5);
3902 pDest += 5;
3903 TransferBufferLength += 1;
3904 }
3905#endif // 1 //
3906
3907 // Update pTxInfo->USBDMATxPktLen to include padding.
3908 pTxInfo->USBDMATxPktLen = TransferBufferLength - TXINFO_SIZE;
3909
3910 TransferBufferLength += 4;
3911
3912 // If TransferBufferLength is multiple of 64, add extra 4 bytes again.
3913 if ((TransferBufferLength % pAd->BulkOutMaxPacketSize) == 0)
3914 {
3915 NdisZeroMemory(pDest, 4);
3916 TransferBufferLength += 4;
3917 }
3918
3919 // Fill out frame length information for global Bulk out arbitor
3920 pAd->NullContext.BulkOutSize = TransferBufferLength;
3921 }
3922#ifdef RT_BIG_ENDIAN
3923 RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
3924 RTMPFrameEndianChange(pAd, (((PUCHAR)pTxInfo)+TXWI_SIZE+TXINFO_SIZE), DIR_WRITE, FALSE);
3925 RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO);
3926#endif // RT_BIG_ENDIAN //
3927 return 0;
3928}
3929
3930VOID ATE_RTUSBBulkOutDataPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
3931{
3932 PRTMP_ADAPTER pAd;
3933 PTX_CONTEXT pNullContext;
3934 UCHAR BulkOutPipeId;
3935 NTSTATUS Status;
3936 unsigned long IrqFlags;
3937 ULONG OldValue;
3938
3939 pNullContext = (PTX_CONTEXT)pUrb->context;
3940 pAd = pNullContext->pAd;
3941
3942
3943 // Reset Null frame context flags
3944 pNullContext->IRPPending = FALSE;
3945 pNullContext->InUse = FALSE;
3946 Status = pUrb->status;
3947
3948 // Store BulkOut PipeId
3949 BulkOutPipeId = pNullContext->BulkOutPipeId;
3950 pAd->BulkOutDataOneSecCount++;
3951
3952 if (Status == USB_ST_NOERROR)
3953 {
3954#ifdef RALINK_28xx_QA
3955 if ((ATE_ON(pAd)) && (pAd->ate.bQATxStart == TRUE))
3956 {
3957 if (pAd->ate.QID == BulkOutPipeId)
3958 {
3959 // Let Rx can have a chance to break in during Tx process,
3960 // especially for loopback mode in QA ATE.
3961 // To trade off between tx performance and loopback mode integrity.
3962 /* Q : Now Rx is handled by tasklet, do we still need this delay ? */
3963 /* Ans : Even tasklet is used, Rx/Tx < 1 if we do not delay for a while right here. */
3964 RTMPusecDelay(500);
3965 pAd->ate.TxDoneCount++;
3966 pAd->RalinkCounters.KickTxCount++;
3967 ASSERT(pAd->ate.QID == 0);
3968 pAd->ate.TxAc0++;
3969 }
3970 }
3971#endif // RALINK_28xx_QA //
3972 pAd->BulkOutComplete++;
3973
3974 pAd->Counters8023.GoodTransmits++;
3975
3976 /* Don't worry about the queue is empty or not. This function will check itself. */
3977 RTMPDeQueuePacket(pAd, TRUE, BulkOutPipeId, MAX_TX_PROCESS);
3978
3979 /* In 28xx, SendTxWaitQueue ==> TxSwQueue */
3980/*
3981 if (pAd->SendTxWaitQueue[BulkOutPipeId].Number > 0)
3982 {
3983 RTMPDeQueuePacket(pAd, BulkOutPipeId);
3984 }
3985*/
3986 }
3987 else // STATUS_OTHER
3988 {
3989 pAd->BulkOutCompleteOther++;
3990
3991 ATEDBGPRINT(RT_DEBUG_ERROR, ("BulkOutDataPacket Failed STATUS_OTHER = 0x%x . \n", Status));
3992 ATEDBGPRINT(RT_DEBUG_ERROR, (">>BulkOutReq=0x%lx, BulkOutComplete=0x%lx\n", pAd->BulkOutReq, pAd->BulkOutComplete));
3993
3994 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
3995 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
3996 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
3997 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
3998 {
3999 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
4000 /* In 28xx, RT_OID_USB_RESET_BULK_OUT ==> CMDTHREAD_RESET_BULK_OUT */
4001 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
4002 // Check
4003 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
4004 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
4005 pAd->bulkResetPipeid = BulkOutPipeId;
4006 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
4007 return;
4008 }
4009 }
4010
4011
4012
4013 if (atomic_read(&pAd->BulkOutRemained) > 0)
4014 {
4015 atomic_dec(&pAd->BulkOutRemained);
4016 }
4017
4018 // 1st - Transmit Success
4019 OldValue = pAd->WlanCounters.TransmittedFragmentCount.u.LowPart;
4020 pAd->WlanCounters.TransmittedFragmentCount.u.LowPart++;
4021
4022 if (pAd->WlanCounters.TransmittedFragmentCount.u.LowPart < OldValue)
4023 {
4024 pAd->WlanCounters.TransmittedFragmentCount.u.HighPart++;
4025 }
4026
4027 if(((pAd->ContinBulkOut == TRUE ) ||(atomic_read(&pAd->BulkOutRemained) > 0)) && (pAd->ate.Mode & ATE_TXFRAME))
4028 {
4029 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
4030 }
4031 else
4032 {
4033 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
4034#ifdef RALINK_28xx_QA
4035 pAd->ate.TxStatus = 0;
4036#endif // RALINK_28xx_QA //
4037 }
4038
4039 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
4040 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
4041 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
4042
4043 // Always call Bulk routine, even reset bulk.
4044 // The protection of rest bulk should be in BulkOut routine.
4045 RTUSBKickBulkOut(pAd);
4046}
4047
4048/*
4049 ========================================================================
4050
4051 Routine Description:
4052
4053 Arguments:
4054
4055 Return Value:
4056
4057 Note:
4058
4059 ========================================================================
4060*/
4061VOID ATE_RTUSBBulkOutDataPacket(
4062 IN PRTMP_ADAPTER pAd,
4063 IN UCHAR BulkOutPipeId)
4064{
4065 PTX_CONTEXT pNullContext = &(pAd->NullContext);
4066 PURB pUrb;
4067 int ret = 0;
4068 unsigned long IrqFlags;
4069
4070
4071 ASSERT(BulkOutPipeId == 0);
4072
4073 /* Build up the frame first. */
4074// ATESetUpFrame(pAd, 0);
4075
4076 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
4077
4078 if (pAd->BulkOutPending[BulkOutPipeId] == TRUE)
4079 {
4080 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
4081 return;
4082 }
4083
4084 pAd->BulkOutPending[BulkOutPipeId] = TRUE;
4085 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
4086
4087 // Increase Total transmit byte counter
4088 pAd->RalinkCounters.OneSecTransmittedByteCount += pNullContext->BulkOutSize;
4089 pAd->RalinkCounters.TransmittedByteCount += pNullContext->BulkOutSize;
4090
4091 // Clear ATE frame bulk out flag
4092 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
4093
4094 // Init Tx context descriptor
4095 pNullContext->IRPPending = TRUE;
4096 RTUSBInitTxDesc(pAd, pNullContext, BulkOutPipeId, (usb_complete_t)ATE_RTUSBBulkOutDataPacketComplete);
4097 pUrb = pNullContext->pUrb;
4098
4099 if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
4100 {
4101 ATEDBGPRINT(RT_DEBUG_ERROR, ("ATE_RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret));
4102 return;
4103 }
4104
4105 pAd->BulkOutReq++;
4106 return;
4107
4108}
4109
4110/*
4111 ========================================================================
4112
4113 Routine Description:
4114
4115 Arguments:
4116
4117 Return Value:
4118
4119 Note:
4120
4121 ========================================================================
4122*/
4123VOID ATE_RTUSBCancelPendingBulkInIRP(
4124 IN PRTMP_ADAPTER pAd)
4125{
4126 PRX_CONTEXT pRxContext;
4127 UINT i;
4128
4129 ATEDBGPRINT(RT_DEBUG_TRACE, ("--->ATE_RTUSBCancelPendingBulkInIRP\n"));
4130#if 1
4131 for ( i = 0; i < (RX_RING_SIZE); i++)
4132 {
4133 pRxContext = &(pAd->RxContext[i]);
4134 if(pRxContext->IRPPending == TRUE)
4135 {
4136 RTUSB_UNLINK_URB(pRxContext->pUrb);
4137 pRxContext->IRPPending = FALSE;
4138 pRxContext->InUse = FALSE;
4139 //NdisInterlockedDecrement(&pAd->PendingRx);
4140 //pAd->PendingRx--;
4141 }
4142 }
4143#else
4144 for ( i = 0; i < (RX_RING_SIZE); i++)
4145 {
4146 pRxContext = &(pAd->RxContext[i]);
4147 if(atomic_read(&pRxContext->IrpLock) == IRPLOCK_CANCELABLE)
4148 {
4149 RTUSB_UNLINK_URB(pRxContext->pUrb);
4150 }
4151 InterlockedExchange(&pRxContext->IrpLock, IRPLOCK_CANCE_START);
4152 }
4153#endif // 1 //
4154 ATEDBGPRINT(RT_DEBUG_TRACE, ("<---ATE_RTUSBCancelPendingBulkInIRP\n"));
4155 return;
4156}
4157#endif // RT2870 //
4158
4159VOID rt_ee_read_all(PRTMP_ADAPTER pAd, USHORT *Data)
4160{
4161 USHORT i;
4162 USHORT value;
4163
4164 for (i = 0 ; i < EEPROM_SIZE/2 ; )
4165 {
4166 /* "value" is expecially for some compilers... */
4167 RT28xx_EEPROM_READ16(pAd, i*2, value);
4168 Data[i] = value;
4169 i++;
4170 }
4171}
4172
4173VOID rt_ee_write_all(PRTMP_ADAPTER pAd, USHORT *Data)
4174{
4175 USHORT i;
4176 USHORT value;
4177
4178 for (i = 0 ; i < EEPROM_SIZE/2 ; )
4179 {
4180 /* "value" is expecially for some compilers... */
4181 value = Data[i];
4182 RT28xx_EEPROM_WRITE16(pAd, i*2, value);
4183 i ++;
4184 }
4185}
4186#ifdef RALINK_28xx_QA
4187VOID ATE_QA_Statistics(
4188 IN PRTMP_ADAPTER pAd,
4189 IN PRXWI_STRUC pRxWI,
4190 IN PRT28XX_RXD_STRUC pRxD,
4191 IN PHEADER_802_11 pHeader)
4192{
4193 // update counter first
4194 if (pHeader != NULL)
4195 {
4196 if (pHeader->FC.Type == BTYPE_DATA)
4197 {
4198 if (pRxD->U2M)
4199 pAd->ate.U2M++;
4200 else
4201 pAd->ate.OtherData++;
4202 }
4203 else if (pHeader->FC.Type == BTYPE_MGMT)
4204 {
4205 if (pHeader->FC.SubType == SUBTYPE_BEACON)
4206 pAd->ate.Beacon++;
4207 else
4208 pAd->ate.OtherCount++;
4209 }
4210 else if (pHeader->FC.Type == BTYPE_CNTL)
4211 {
4212 pAd->ate.OtherCount++;
4213 }
4214 }
4215 pAd->ate.RSSI0 = pRxWI->RSSI0;
4216 pAd->ate.RSSI1 = pRxWI->RSSI1;
4217 pAd->ate.RSSI2 = pRxWI->RSSI2;
4218 pAd->ate.SNR0 = pRxWI->SNR0;
4219 pAd->ate.SNR1 = pRxWI->SNR1;
4220}
4221
4222/* command id with Cmd Type == 0x0008(for 28xx)/0x0005(for iNIC) */
4223#define RACFG_CMD_RF_WRITE_ALL 0x0000
4224#define RACFG_CMD_E2PROM_READ16 0x0001
4225#define RACFG_CMD_E2PROM_WRITE16 0x0002
4226#define RACFG_CMD_E2PROM_READ_ALL 0x0003
4227#define RACFG_CMD_E2PROM_WRITE_ALL 0x0004
4228#define RACFG_CMD_IO_READ 0x0005
4229#define RACFG_CMD_IO_WRITE 0x0006
4230#define RACFG_CMD_IO_READ_BULK 0x0007
4231#define RACFG_CMD_BBP_READ8 0x0008
4232#define RACFG_CMD_BBP_WRITE8 0x0009
4233#define RACFG_CMD_BBP_READ_ALL 0x000a
4234#define RACFG_CMD_GET_COUNTER 0x000b
4235#define RACFG_CMD_CLEAR_COUNTER 0x000c
4236
4237#define RACFG_CMD_RSV1 0x000d
4238#define RACFG_CMD_RSV2 0x000e
4239#define RACFG_CMD_RSV3 0x000f
4240
4241#define RACFG_CMD_TX_START 0x0010
4242#define RACFG_CMD_GET_TX_STATUS 0x0011
4243#define RACFG_CMD_TX_STOP 0x0012
4244#define RACFG_CMD_RX_START 0x0013
4245#define RACFG_CMD_RX_STOP 0x0014
4246#define RACFG_CMD_GET_NOISE_LEVEL 0x0015
4247
4248#define RACFG_CMD_ATE_START 0x0080
4249#define RACFG_CMD_ATE_STOP 0x0081
4250
4251#define RACFG_CMD_ATE_START_TX_CARRIER 0x0100
4252#define RACFG_CMD_ATE_START_TX_CONT 0x0101
4253#define RACFG_CMD_ATE_START_TX_FRAME 0x0102
4254#define RACFG_CMD_ATE_SET_BW 0x0103
4255#define RACFG_CMD_ATE_SET_TX_POWER0 0x0104
4256#define RACFG_CMD_ATE_SET_TX_POWER1 0x0105
4257#define RACFG_CMD_ATE_SET_FREQ_OFFSET 0x0106
4258#define RACFG_CMD_ATE_GET_STATISTICS 0x0107
4259#define RACFG_CMD_ATE_RESET_COUNTER 0x0108
4260#define RACFG_CMD_ATE_SEL_TX_ANTENNA 0x0109
4261#define RACFG_CMD_ATE_SEL_RX_ANTENNA 0x010a
4262#define RACFG_CMD_ATE_SET_PREAMBLE 0x010b
4263#define RACFG_CMD_ATE_SET_CHANNEL 0x010c
4264#define RACFG_CMD_ATE_SET_ADDR1 0x010d
4265#define RACFG_CMD_ATE_SET_ADDR2 0x010e
4266#define RACFG_CMD_ATE_SET_ADDR3 0x010f
4267#define RACFG_CMD_ATE_SET_RATE 0x0110
4268#define RACFG_CMD_ATE_SET_TX_FRAME_LEN 0x0111
4269#define RACFG_CMD_ATE_SET_TX_FRAME_COUNT 0x0112
4270#define RACFG_CMD_ATE_START_RX_FRAME 0x0113
4271#define RACFG_CMD_ATE_E2PROM_READ_BULK 0x0114
4272#define RACFG_CMD_ATE_E2PROM_WRITE_BULK 0x0115
4273#define RACFG_CMD_ATE_IO_WRITE_BULK 0x0116
4274#define RACFG_CMD_ATE_BBP_READ_BULK 0x0117
4275#define RACFG_CMD_ATE_BBP_WRITE_BULK 0x0118
4276#define RACFG_CMD_ATE_RF_READ_BULK 0x0119
4277#define RACFG_CMD_ATE_RF_WRITE_BULK 0x011a
4278
4279
4280
4281#define A2Hex(_X, _p) \
4282{ \
4283 UCHAR *p; \
4284 _X = 0; \
4285 p = _p; \
4286 while (((*p >= 'a') && (*p <= 'f')) || ((*p >= 'A') && (*p <= 'F')) || ((*p >= '0') && (*p <= '9'))) \
4287 { \
4288 if ((*p >= 'a') && (*p <= 'f')) \
4289 _X = _X * 16 + *p - 87; \
4290 else if ((*p >= 'A') && (*p <= 'F')) \
4291 _X = _X * 16 + *p - 55; \
4292 else if ((*p >= '0') && (*p <= '9')) \
4293 _X = _X * 16 + *p - 48; \
4294 p++; \
4295 } \
4296}
4297
4298
4299static VOID memcpy_exl(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len);
4300static VOID memcpy_exs(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len);
4301static VOID RTMP_IO_READ_BULK(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, UINT32 len);
4302
4303#ifdef UCOS
4304int ate_copy_to_user(
4305 IN PUCHAR payload,
4306 IN PUCHAR msg,
4307 IN INT len)
4308{
4309 memmove(payload, msg, len);
4310 return 0;
4311}
4312
4313#undef copy_to_user
4314#define copy_to_user(x,y,z) ate_copy_to_user((PUCHAR)x, (PUCHAR)y, z)
4315#endif // UCOS //
4316
4317#define LEN_OF_ARG 16
4318
4319VOID RtmpDoAte(
4320 IN PRTMP_ADAPTER pAdapter,
4321 IN struct iwreq *wrq)
4322{
4323 unsigned short Command_Id;
4324 struct ate_racfghdr *pRaCfg;
4325 INT Status = NDIS_STATUS_SUCCESS;
4326
4327
4328
4329 if((pRaCfg = kmalloc(sizeof(struct ate_racfghdr), GFP_KERNEL)) == NULL)
4330 {
4331 Status = -EINVAL;
4332 return;
4333 }
4334
4335 NdisZeroMemory(pRaCfg, sizeof(struct ate_racfghdr));
4336
4337 if (copy_from_user((PUCHAR)pRaCfg, wrq->u.data.pointer, wrq->u.data.length))
4338 {
4339 Status = -EFAULT;
4340 kfree(pRaCfg);
4341 return;
4342 }
4343
4344
4345 Command_Id = ntohs(pRaCfg->command_id);
4346
4347 ATEDBGPRINT(RT_DEBUG_TRACE,("\n%s: Command_Id = 0x%04x !\n", __FUNCTION__, Command_Id));
4348
4349 switch (Command_Id)
4350 {
4351 // We will get this command when QA starts.
4352 case RACFG_CMD_ATE_START:
4353 {
4354 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START\n"));
4355
4356 // prepare feedback as soon as we can to avoid QA timeout.
4357 pRaCfg->length = htons(2);
4358 pRaCfg->status = htons(0);
4359
4360 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4361 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4362 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4363
4364 ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
4365
4366 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4367 {
4368 ATEDBGPRINT(RT_DEBUG_TRACE, ("copy_to_user() fail in case RACFG_CMD_ATE_START\n"));
4369 Status = -EFAULT;
4370 }
4371 else
4372 {
4373 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_START is done !\n"));
4374 }
4375 Set_ATE_Proc(pAdapter, "ATESTART");
4376 }
4377 break;
4378
4379 // We will get this command either QA is closed or ated is killed by user.
4380 case RACFG_CMD_ATE_STOP:
4381 {
4382#ifndef UCOS
4383 INT32 ret;
4384#endif // !UCOS //
4385
4386 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_STOP\n"));
4387
4388 // Distinguish this command came from QA(via ated)
4389 // or ate daemon according to the existence of pid in payload.
4390 // No need to prepare feedback if this cmd came directly from ate daemon.
4391 pRaCfg->length = ntohs(pRaCfg->length);
4392
4393 if (pRaCfg->length == sizeof(pAdapter->ate.AtePid))
4394 {
4395 // This command came from QA.
4396 // Get the pid of ATE daemon.
4397 memcpy((UCHAR *)&pAdapter->ate.AtePid,
4398 (&pRaCfg->data[0]) - 2/* == &(pRaCfg->status) */,
4399 sizeof(pAdapter->ate.AtePid));
4400
4401 // prepare feedback as soon as we can to avoid QA timeout.
4402 pRaCfg->length = htons(2);
4403 pRaCfg->status = htons(0);
4404
4405 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4406 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4407 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4408
4409 ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
4410
4411 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4412 {
4413 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_STOP\n"));
4414 Status = -EFAULT;
4415 }
4416
4417 //
4418 // kill ATE daemon when leaving ATE mode.
4419 // We must kill ATE daemon first before setting ATESTOP,
4420 // or Microsoft will report sth. wrong.
4421#ifndef UCOS
4422 ret = kill_proc(pAdapter->ate.AtePid, SIGTERM, 1);
4423 if (ret)
4424 {
4425 ATEDBGPRINT(RT_DEBUG_ERROR, ("%s: unable to signal thread\n", pAdapter->net_dev->name));
4426 }
4427#endif // !UCOS //
4428 }
4429
4430#ifdef UCOS
4431 // Roger add to avoid error message after close QA
4432 if (pAdapter->CSRBaseAddress == RT2860_CSR_ADDR)
4433 {
4434
4435 // prepare feedback as soon as we can to avoid QA timeout.
4436 pRaCfg->length = htons(2);
4437 pRaCfg->status = htons(0);
4438
4439 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4440 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4441 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4442
4443 ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
4444 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4445 {
4446 ATEDBGPRINT(RT_DEBUG_TRACE, ("copy_to_user() fail in case RACFG_CMD_AP_START\n"));
4447 Status = -EFAULT;
4448 }
4449 }
4450#endif // UCOS //
4451
4452 // AP might have in ATE_STOP mode due to cmd from QA.
4453 if (ATE_ON(pAdapter))
4454 {
4455 // Someone has killed ate daemon while QA GUI is still open.
4456 Set_ATE_Proc(pAdapter, "ATESTOP");
4457 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_AP_START is done !\n"));
4458 }
4459 }
4460 break;
4461
4462 case RACFG_CMD_RF_WRITE_ALL:
4463 {
4464 UINT32 R1, R2, R3, R4;
4465 USHORT channel;
4466
4467 memcpy(&R1, pRaCfg->data-2, 4);
4468 memcpy(&R2, pRaCfg->data+2, 4);
4469 memcpy(&R3, pRaCfg->data+6, 4);
4470 memcpy(&R4, pRaCfg->data+10, 4);
4471 memcpy(&channel, pRaCfg->data+14, 2);
4472
4473 pAdapter->LatchRfRegs.R1 = ntohl(R1);
4474 pAdapter->LatchRfRegs.R2 = ntohl(R2);
4475 pAdapter->LatchRfRegs.R3 = ntohl(R3);
4476 pAdapter->LatchRfRegs.R4 = ntohl(R4);
4477 pAdapter->LatchRfRegs.Channel = ntohs(channel);
4478
4479 RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R1);
4480 RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R2);
4481 RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R3);
4482 RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R4);
4483
4484 // prepare feedback
4485 pRaCfg->length = htons(2);
4486 pRaCfg->status = htons(0);
4487
4488 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4489 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4490 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4491
4492 ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
4493 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4494 {
4495 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_RF_WRITE_ALL\n"));
4496 Status = -EFAULT;
4497 }
4498 else
4499 {
4500 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_RF_WRITE_ALL is done !\n"));
4501 }
4502 }
4503 break;
4504
4505 case RACFG_CMD_E2PROM_READ16:
4506 {
4507 USHORT offset, value, tmp;
4508
4509 offset = ntohs(pRaCfg->status);
4510 /* "tmp" is expecially for some compilers... */
4511 RT28xx_EEPROM_READ16(pAdapter, offset, tmp);
4512 value = tmp;
4513 value = htons(value);
4514
4515 ATEDBGPRINT(RT_DEBUG_TRACE,("EEPROM Read offset = 0x%04x, value = 0x%04x\n", offset, value));
4516
4517 // prepare feedback
4518 pRaCfg->length = htons(4);
4519 pRaCfg->status = htons(0);
4520 memcpy(pRaCfg->data, &value, 2);
4521
4522 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4523 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4524 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4525
4526 ATEDBGPRINT(RT_DEBUG_TRACE, ("sizeof(struct ate_racfghdr) = %d\n", sizeof(struct ate_racfghdr)));
4527 ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
4528
4529 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4530 {
4531 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_E2PROM_READ16\n"));
4532 Status = -EFAULT;
4533 }
4534 else
4535 {
4536 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_E2PROM_READ16 is done !\n"));
4537 }
4538 }
4539 break;
4540
4541 case RACFG_CMD_E2PROM_WRITE16:
4542 {
4543 USHORT offset, value;
4544
4545 offset = ntohs(pRaCfg->status);
4546 memcpy(&value, pRaCfg->data, 2);
4547 value = ntohs(value);
4548 RT28xx_EEPROM_WRITE16(pAdapter, offset, value);
4549
4550 // prepare feedback
4551 pRaCfg->length = htons(2);
4552 pRaCfg->status = htons(0);
4553 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4554 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4555 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4556
4557 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4558 {
4559 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_E2PROM_WRITE16\n"));
4560 Status = -EFAULT;
4561 }
4562 else
4563 {
4564 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_E2PROM_WRITE16 is done !\n"));
4565 }
4566 }
4567 break;
4568
4569 case RACFG_CMD_E2PROM_READ_ALL:
4570 {
4571 USHORT buffer[EEPROM_SIZE/2];
4572
4573 rt_ee_read_all(pAdapter,(USHORT *)buffer);
4574 memcpy_exs(pAdapter, pRaCfg->data, (UCHAR *)buffer, EEPROM_SIZE);
4575
4576 // prepare feedback
4577 pRaCfg->length = htons(2+EEPROM_SIZE);
4578 pRaCfg->status = htons(0);
4579 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4580 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4581 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4582
4583 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4584 {
4585 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_E2PROM_READ_ALL\n"));
4586 Status = -EFAULT;
4587 }
4588 else
4589 {
4590 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_E2PROM_READ_ALL is done !\n"));
4591 }
4592 }
4593 break;
4594
4595 case RACFG_CMD_E2PROM_WRITE_ALL:
4596 {
4597 USHORT buffer[EEPROM_SIZE/2];
4598
4599 NdisZeroMemory((UCHAR *)buffer, EEPROM_SIZE);
4600 memcpy_exs(pAdapter, (UCHAR *)buffer, (UCHAR *)&pRaCfg->status, EEPROM_SIZE);
4601 rt_ee_write_all(pAdapter,(USHORT *)buffer);
4602
4603 // prepare feedback
4604 pRaCfg->length = htons(2);
4605 pRaCfg->status = htons(0);
4606 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4607 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4608 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4609
4610 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4611 {
4612 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_E2PROM_WRITE_ALL\n"));
4613 Status = -EFAULT;
4614 }
4615 else
4616 {
4617 ATEDBGPRINT(RT_DEBUG_ERROR, ("RACFG_CMD_E2PROM_WRITE_ALL is done !\n"));
4618 }
4619
4620 }
4621 break;
4622
4623 case RACFG_CMD_IO_READ:
4624 {
4625 UINT32 offset;
4626 UINT32 value;
4627
4628 memcpy(&offset, &pRaCfg->status, 4);
4629 offset = ntohl(offset);
4630
4631 // We do not need the base address.
4632 // So just extract the offset out.
4633 offset &= 0x0000FFFF;
4634 RTMP_IO_READ32(pAdapter, offset, &value);
4635 value = htonl(value);
4636
4637 // prepare feedback
4638 pRaCfg->length = htons(6);
4639 pRaCfg->status = htons(0);
4640 memcpy(pRaCfg->data, &value, 4);
4641
4642 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4643 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4644 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4645
4646 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4647 {
4648 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_IO_READ\n"));
4649 Status = -EFAULT;
4650 }
4651 else
4652 {
4653 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_IO_READ is done !\n"));
4654 }
4655 }
4656 break;
4657
4658 case RACFG_CMD_IO_WRITE:
4659 {
4660 UINT32 offset, value;
4661
4662 memcpy(&offset, pRaCfg->data-2, 4);
4663 memcpy(&value, pRaCfg->data+2, 4);
4664
4665 offset = ntohl(offset);
4666
4667 // We do not need the base address.
4668 // So just extract out the offset.
4669 offset &= 0x0000FFFF;
4670 value = ntohl(value);
4671 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_IO_WRITE: offset = %x, value = %x\n", offset, value));
4672 RTMP_IO_WRITE32(pAdapter, offset, value);
4673
4674 // prepare feedback
4675 pRaCfg->length = htons(2);
4676 pRaCfg->status = htons(0);
4677 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4678 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4679 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4680
4681 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4682 {
4683 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_IO_WRITE\n"));
4684 Status = -EFAULT;
4685 }
4686 else
4687 {
4688 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_IO_WRITE is done !\n"));
4689 }
4690 }
4691 break;
4692
4693 case RACFG_CMD_IO_READ_BULK:
4694 {
4695 UINT32 offset;
4696 USHORT len;
4697
4698 memcpy(&offset, &pRaCfg->status, 4);
4699 offset = ntohl(offset);
4700
4701 // We do not need the base address.
4702 // So just extract the offset.
4703 offset &= 0x0000FFFF;
4704 memcpy(&len, pRaCfg->data+2, 2);
4705 len = ntohs(len);
4706
4707 if (len > 371)
4708 {
4709 ATEDBGPRINT(RT_DEBUG_TRACE,("len is too large, make it smaller\n"));
4710 pRaCfg->length = htons(2);
4711 pRaCfg->status = htons(1);
4712 break;
4713 }
4714
4715 RTMP_IO_READ_BULK(pAdapter, pRaCfg->data, (UCHAR *)offset, len*4);// unit in four bytes
4716
4717 // prepare feedback
4718 pRaCfg->length = htons(2+len*4);// unit in four bytes
4719 pRaCfg->status = htons(0);
4720 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4721 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4722 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4723
4724 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4725 {
4726 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_IO_READ_BULK\n"));
4727 Status = -EFAULT;
4728 }
4729 else
4730 {
4731 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_IO_READ_BULK is done !\n"));
4732 }
4733 }
4734 break;
4735
4736 case RACFG_CMD_BBP_READ8:
4737 {
4738 USHORT offset;
4739 UCHAR value;
4740
4741 value = 0;
4742 offset = ntohs(pRaCfg->status);
4743
4744 if (ATE_ON(pAdapter))
4745 {
4746 ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, offset, &value);
4747 }
4748 else
4749 {
4750 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, offset, &value);
4751 }
4752 // prepare feedback
4753 pRaCfg->length = htons(3);
4754 pRaCfg->status = htons(0);
4755 pRaCfg->data[0] = value;
4756
4757 ATEDBGPRINT(RT_DEBUG_TRACE,("BBP value = %x\n", value));
4758
4759 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4760 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4761 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4762
4763 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4764 {
4765 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_BBP_READ8\n"));
4766 Status = -EFAULT;
4767 }
4768 else
4769 {
4770 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_BBP_READ8 is done !\n"));
4771 }
4772 }
4773 break;
4774 case RACFG_CMD_BBP_WRITE8:
4775 {
4776 USHORT offset;
4777 UCHAR value;
4778
4779 offset = ntohs(pRaCfg->status);
4780 memcpy(&value, pRaCfg->data, 1);
4781
4782 if (ATE_ON(pAdapter))
4783 {
4784 ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, offset, value);
4785 }
4786 else
4787 {
4788 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, offset, value);
4789 }
4790
4791 if ((offset == BBP_R1) || (offset == BBP_R3))
4792 {
4793 SyncTxRxConfig(pAdapter, offset, value);
4794 }
4795
4796 // prepare feedback
4797 pRaCfg->length = htons(2);
4798 pRaCfg->status = htons(0);
4799 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4800 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4801 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4802
4803 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4804 {
4805 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_BBP_WRITE8\n"));
4806 Status = -EFAULT;
4807 }
4808 else
4809 {
4810 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_BBP_WRITE8 is done !\n"));
4811 }
4812 }
4813 break;
4814
4815 case RACFG_CMD_BBP_READ_ALL:
4816 {
4817 USHORT j;
4818
4819 for (j = 0; j < 137; j++)
4820 {
4821 pRaCfg->data[j] = 0;
4822
4823 if (ATE_ON(pAdapter))
4824 {
4825 ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, j, &pRaCfg->data[j]);
4826 }
4827 else
4828 {
4829 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, j, &pRaCfg->data[j]);
4830 }
4831 }
4832
4833 // prepare feedback
4834 pRaCfg->length = htons(2+137);
4835 pRaCfg->status = htons(0);
4836
4837 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4838 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4839 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4840
4841 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4842 {
4843 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_BBP_READ_ALL\n"));
4844 Status = -EFAULT;
4845 }
4846 else
4847 {
4848 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_BBP_READ_ALL is done !\n"));
4849 }
4850 }
4851
4852 break;
4853
4854 case RACFG_CMD_ATE_E2PROM_READ_BULK:
4855 {
4856 USHORT offset;
4857 USHORT len;
4858 USHORT buffer[EEPROM_SIZE/2];
4859
4860 offset = ntohs(pRaCfg->status);
4861 memcpy(&len, pRaCfg->data, 2);
4862 len = ntohs(len);
4863
4864 rt_ee_read_all(pAdapter,(USHORT *)buffer);
4865 if (offset + len <= EEPROM_SIZE)
4866 memcpy_exs(pAdapter, pRaCfg->data, (UCHAR *)buffer+offset, len);
4867 else
4868 ATEDBGPRINT(RT_DEBUG_ERROR, ("exceed EEPROM size\n"));
4869
4870 // prepare feedback
4871 pRaCfg->length = htons(2+len);
4872 pRaCfg->status = htons(0);
4873 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4874 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4875 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4876
4877 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4878 {
4879 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_E2PROM_READ_BULK\n"));
4880 Status = -EFAULT;
4881 }
4882 else
4883 {
4884 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_E2PROM_READ_BULK is done !\n"));
4885 }
4886
4887 }
4888 break;
4889
4890 case RACFG_CMD_ATE_E2PROM_WRITE_BULK:
4891 {
4892 USHORT offset;
4893 USHORT len;
4894 USHORT buffer[EEPROM_SIZE/2];
4895
4896 offset = ntohs(pRaCfg->status);
4897 memcpy(&len, pRaCfg->data, 2);
4898 len = ntohs(len);
4899
4900 rt_ee_read_all(pAdapter,(USHORT *)buffer);
4901 memcpy_exs(pAdapter, (UCHAR *)buffer + offset, (UCHAR *)pRaCfg->data + 2, len);
4902 rt_ee_write_all(pAdapter,(USHORT *)buffer);
4903
4904 // prepare feedback
4905 pRaCfg->length = htons(2);
4906 pRaCfg->status = htons(0);
4907 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4908 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4909 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4910 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4911 {
4912 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_E2PROM_WRITE_BULK\n"));
4913 Status = -EFAULT;
4914 }
4915 else
4916 {
4917 ATEDBGPRINT(RT_DEBUG_ERROR, ("RACFG_CMD_ATE_E2PROM_WRITE_BULK is done !\n"));
4918 }
4919
4920 }
4921 break;
4922
4923 case RACFG_CMD_ATE_IO_WRITE_BULK:
4924 {
4925 UINT32 offset, i, value;
4926 USHORT len;
4927
4928 memcpy(&offset, &pRaCfg->status, 4);
4929 offset = ntohl(offset);
4930 memcpy(&len, pRaCfg->data+2, 2);
4931 len = ntohs(len);
4932
4933 for (i = 0; i < len; i += 4)
4934 {
4935 memcpy_exl(pAdapter, (UCHAR *)&value, pRaCfg->data+4+i, 4);
4936 printk("Write %x %x\n", offset + i, value);
4937 RTMP_IO_WRITE32(pAdapter, (offset +i) & 0xffff, value);
4938 }
4939
4940 // prepare feedback
4941 pRaCfg->length = htons(2);
4942 pRaCfg->status = htons(0);
4943 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4944 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4945 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4946 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4947 {
4948 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_IO_WRITE_BULK\n"));
4949 Status = -EFAULT;
4950 }
4951 else
4952 {
4953 ATEDBGPRINT(RT_DEBUG_ERROR, ("RACFG_CMD_ATE_IO_WRITE_BULK is done !\n"));
4954 }
4955
4956 }
4957 break;
4958
4959 case RACFG_CMD_ATE_BBP_READ_BULK:
4960 {
4961 USHORT offset;
4962 USHORT len;
4963 USHORT j;
4964
4965 offset = ntohs(pRaCfg->status);
4966 memcpy(&len, pRaCfg->data, 2);
4967 len = ntohs(len);
4968
4969
4970 for (j = offset; j < (offset+len); j++)
4971 {
4972 pRaCfg->data[j - offset] = 0;
4973
4974 if (pAdapter->ate.Mode == ATE_STOP)
4975 {
4976 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, j, &pRaCfg->data[j - offset]);
4977 }
4978 else
4979 {
4980 ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, j, &pRaCfg->data[j - offset]);
4981 }
4982 }
4983
4984 // prepare feedback
4985 pRaCfg->length = htons(2+len);
4986 pRaCfg->status = htons(0);
4987 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4988 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4989 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4990
4991 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4992 {
4993 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_BBP_READ_BULK\n"));
4994 Status = -EFAULT;
4995 }
4996 else
4997 {
4998 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_BBP_READ_BULK is done !\n"));
4999 }
5000
5001 }
5002 break;
5003
5004 case RACFG_CMD_ATE_BBP_WRITE_BULK:
5005 {
5006 USHORT offset;
5007 USHORT len;
5008 USHORT j;
5009 UCHAR *value;
5010
5011 offset = ntohs(pRaCfg->status);
5012 memcpy(&len, pRaCfg->data, 2);
5013 len = ntohs(len);
5014
5015 for (j = offset; j < (offset+len); j++)
5016 {
5017 value = pRaCfg->data + 2 + (j - offset);
5018 if (pAdapter->ate.Mode == ATE_STOP)
5019 {
5020 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, j, *value);
5021 }
5022 else
5023 {
5024 ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, j, *value);
5025 }
5026 }
5027
5028 // prepare feedback
5029 pRaCfg->length = htons(2);
5030 pRaCfg->status = htons(0);
5031 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5032 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5033 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5034
5035 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5036 {
5037 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_BBP_WRITE_BULK\n"));
5038 Status = -EFAULT;
5039 }
5040 else
5041 {
5042 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_BBP_WRITE_BULK is done !\n"));
5043 }
5044 }
5045 break;
5046
5047#ifdef CONFIG_RALINK_RT3052
5048 case RACFG_CMD_ATE_RF_READ_BULK:
5049 {
5050 USHORT offset;
5051 USHORT len;
5052 USHORT j;
5053
5054 offset = ntohs(pRaCfg->status);
5055 memcpy(&len, pRaCfg->data, 2);
5056 len = ntohs(len);
5057
5058 for (j = offset; j < (offset+len); j++)
5059 {
5060 pRaCfg->data[j - offset] = 0;
5061 RT30xxReadRFRegister(pAdapter, j, &pRaCfg->data[j - offset]);
5062 }
5063
5064 // prepare feedback
5065 pRaCfg->length = htons(2+len);
5066 pRaCfg->status = htons(0);
5067 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5068 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5069 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5070
5071 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5072 {
5073 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_RF_READ_BULK\n"));
5074 Status = -EFAULT;
5075 }
5076 else
5077 {
5078 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_RF_READ_BULK is done !\n"));
5079 }
5080
5081 }
5082 break;
5083
5084 case RACFG_CMD_ATE_RF_WRITE_BULK:
5085 {
5086 USHORT offset;
5087 USHORT len;
5088 USHORT j;
5089 UCHAR *value;
5090
5091 offset = ntohs(pRaCfg->status);
5092 memcpy(&len, pRaCfg->data, 2);
5093 len = ntohs(len);
5094
5095 for (j = offset; j < (offset+len); j++)
5096 {
5097 value = pRaCfg->data + 2 + (j - offset);
5098 RT30xxWriteRFRegister(pAdapter, j, *value);
5099 }
5100
5101 // prepare feedback
5102 pRaCfg->length = htons(2);
5103 pRaCfg->status = htons(0);
5104 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5105 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5106 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5107
5108 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5109 {
5110 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_RF_WRITE_BULK\n"));
5111 Status = -EFAULT;
5112 }
5113 else
5114 {
5115 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_RF_WRITE_BULK is done !\n"));
5116 }
5117
5118 }
5119 break;
5120#endif
5121
5122
5123 case RACFG_CMD_GET_NOISE_LEVEL:
5124 {
5125 UCHAR channel;
5126 INT32 buffer[3][10];/* 3 : RxPath ; 10 : no. of per rssi samples */
5127
5128 channel = (ntohs(pRaCfg->status) & 0x00FF);
5129 CalNoiseLevel(pAdapter, channel, buffer);
5130 memcpy_exl(pAdapter, (UCHAR *)pRaCfg->data, (UCHAR *)&(buffer[0][0]), (sizeof(INT32)*3*10));
5131
5132 // prepare feedback
5133 pRaCfg->length = htons(2 + (sizeof(INT32)*3*10));
5134 pRaCfg->status = htons(0);
5135 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5136 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5137 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5138
5139 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5140 {
5141 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_GET_NOISE_LEVEL\n"));
5142 Status = -EFAULT;
5143 }
5144 else
5145 {
5146 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_GET_NOISE_LEVEL is done !\n"));
5147 }
5148 }
5149 break;
5150
5151 case RACFG_CMD_GET_COUNTER:
5152 {
5153 memcpy_exl(pAdapter, &pRaCfg->data[0], (UCHAR *)&pAdapter->ate.U2M, 4);
5154 memcpy_exl(pAdapter, &pRaCfg->data[4], (UCHAR *)&pAdapter->ate.OtherData, 4);
5155 memcpy_exl(pAdapter, &pRaCfg->data[8], (UCHAR *)&pAdapter->ate.Beacon, 4);
5156 memcpy_exl(pAdapter, &pRaCfg->data[12], (UCHAR *)&pAdapter->ate.OtherCount, 4);
5157 memcpy_exl(pAdapter, &pRaCfg->data[16], (UCHAR *)&pAdapter->ate.TxAc0, 4);
5158 memcpy_exl(pAdapter, &pRaCfg->data[20], (UCHAR *)&pAdapter->ate.TxAc1, 4);
5159 memcpy_exl(pAdapter, &pRaCfg->data[24], (UCHAR *)&pAdapter->ate.TxAc2, 4);
5160 memcpy_exl(pAdapter, &pRaCfg->data[28], (UCHAR *)&pAdapter->ate.TxAc3, 4);
5161 memcpy_exl(pAdapter, &pRaCfg->data[32], (UCHAR *)&pAdapter->ate.TxHCCA, 4);
5162 memcpy_exl(pAdapter, &pRaCfg->data[36], (UCHAR *)&pAdapter->ate.TxMgmt, 4);
5163 memcpy_exl(pAdapter, &pRaCfg->data[40], (UCHAR *)&pAdapter->ate.RSSI0, 4);
5164 memcpy_exl(pAdapter, &pRaCfg->data[44], (UCHAR *)&pAdapter->ate.RSSI1, 4);
5165 memcpy_exl(pAdapter, &pRaCfg->data[48], (UCHAR *)&pAdapter->ate.RSSI2, 4);
5166 memcpy_exl(pAdapter, &pRaCfg->data[52], (UCHAR *)&pAdapter->ate.SNR0, 4);
5167 memcpy_exl(pAdapter, &pRaCfg->data[56], (UCHAR *)&pAdapter->ate.SNR1, 4);
5168
5169 pRaCfg->length = htons(2+60);
5170 pRaCfg->status = htons(0);
5171 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5172 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5173 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5174
5175 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5176 {
5177 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_GET_COUNTER\n"));
5178 Status = -EFAULT;
5179 }
5180 else
5181 {
5182 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_GET_COUNTER is done !\n"));
5183 }
5184 }
5185 break;
5186
5187 case RACFG_CMD_CLEAR_COUNTER:
5188 {
5189 pAdapter->ate.U2M = 0;
5190 pAdapter->ate.OtherData = 0;
5191 pAdapter->ate.Beacon = 0;
5192 pAdapter->ate.OtherCount = 0;
5193 pAdapter->ate.TxAc0 = 0;
5194 pAdapter->ate.TxAc1 = 0;
5195 pAdapter->ate.TxAc2 = 0;
5196 pAdapter->ate.TxAc3 = 0;
5197 pAdapter->ate.TxHCCA = 0;
5198 pAdapter->ate.TxMgmt = 0;
5199 pAdapter->ate.TxDoneCount = 0;
5200
5201 pRaCfg->length = htons(2);
5202 pRaCfg->status = htons(0);
5203
5204 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5205 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5206 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5207
5208 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5209 {
5210 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_CLEAR_COUNTER\n"));
5211 Status = -EFAULT;
5212 }
5213 else
5214 {
5215 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_CLEAR_COUNTER is done !\n"));
5216 }
5217 }
5218
5219 break;
5220
5221 case RACFG_CMD_TX_START:
5222 {
5223 USHORT *p;
5224 USHORT err = 1;
5225 UCHAR Bbp22Value = 0, Bbp24Value = 0;
5226
5227 if ((pAdapter->ate.TxStatus != 0) && (pAdapter->ate.Mode & ATE_TXFRAME))
5228 {
5229 ATEDBGPRINT(RT_DEBUG_TRACE,("Ate Tx is already running, to run next Tx, you must stop it first\n"));
5230 err = 2;
5231 goto TX_START_ERROR;
5232 }
5233 else if ((pAdapter->ate.TxStatus != 0) && !(pAdapter->ate.Mode & ATE_TXFRAME))
5234 {
5235 int i = 0;
5236
5237 while ((i++ < 10) && (pAdapter->ate.TxStatus != 0))
5238 {
5239 RTMPusecDelay(5000);
5240 }
5241
5242 // force it to stop
5243 pAdapter->ate.TxStatus = 0;
5244 pAdapter->ate.TxDoneCount = 0;
5245 //pAdapter->ate.Repeat = 0;
5246 pAdapter->ate.bQATxStart = FALSE;
5247 }
5248
5249 // If pRaCfg->length == 0, this "RACFG_CMD_TX_START" is for Carrier test or Carrier Suppression.
5250 if (ntohs(pRaCfg->length) != 0)
5251 {
5252 // Get frame info
5253#ifdef RT2870
5254 NdisMoveMemory(&pAdapter->ate.TxInfo, pRaCfg->data - 2, 4);
5255#ifdef RT_BIG_ENDIAN
5256 RTMPDescriptorEndianChange((PUCHAR) &pAdapter->ate.TxInfo, TYPE_TXINFO);
5257#endif // RT_BIG_ENDIAN //
5258#endif // RT2870 //
5259
5260 NdisMoveMemory(&pAdapter->ate.TxWI, pRaCfg->data + 2, 16);
5261#ifdef RT_BIG_ENDIAN
5262 RTMPWIEndianChange((PUCHAR)&pAdapter->ate.TxWI, TYPE_TXWI);
5263#endif // RT_BIG_ENDIAN //
5264
5265 NdisMoveMemory(&pAdapter->ate.TxCount, pRaCfg->data + 18, 4);
5266 pAdapter->ate.TxCount = ntohl(pAdapter->ate.TxCount);
5267
5268 p = (USHORT *)(&pRaCfg->data[22]);
5269 //p = pRaCfg->data + 22;
5270 // always use QID_AC_BE
5271 pAdapter->ate.QID = 0;
5272 p = (USHORT *)(&pRaCfg->data[24]);
5273 //p = pRaCfg->data + 24;
5274 pAdapter->ate.HLen = ntohs(*p);
5275
5276 if (pAdapter->ate.HLen > 32)
5277 {
5278 ATEDBGPRINT(RT_DEBUG_ERROR,("pAdapter->ate.HLen > 32\n"));
5279 err = 3;
5280 goto TX_START_ERROR;
5281 }
5282
5283 NdisMoveMemory(&pAdapter->ate.Header, pRaCfg->data + 26, pAdapter->ate.HLen);
5284
5285
5286 pAdapter->ate.PLen = ntohs(pRaCfg->length) - (pAdapter->ate.HLen + 28);
5287
5288 if (pAdapter->ate.PLen > 32)
5289 {
5290 ATEDBGPRINT(RT_DEBUG_ERROR,("pAdapter->ate.PLen > 32\n"));
5291 err = 4;
5292 goto TX_START_ERROR;
5293 }
5294
5295 NdisMoveMemory(&pAdapter->ate.Pattern, pRaCfg->data + 26 + pAdapter->ate.HLen, pAdapter->ate.PLen);
5296 pAdapter->ate.DLen = pAdapter->ate.TxWI.MPDUtotalByteCount - pAdapter->ate.HLen;
5297 }
5298
5299 ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R22, &Bbp22Value);
5300
5301 switch (Bbp22Value)
5302 {
5303 case BBP22_TXFRAME:
5304 {
5305 if (pAdapter->ate.TxCount == 0)
5306 {
5307 }
5308 ATEDBGPRINT(RT_DEBUG_TRACE,("START TXFRAME\n"));
5309 pAdapter->ate.bQATxStart = TRUE;
5310 Set_ATE_Proc(pAdapter, "TXFRAME");
5311 }
5312 break;
5313
5314 case BBP22_TXCONT_OR_CARRSUPP:
5315 {
5316 ATEDBGPRINT(RT_DEBUG_TRACE,("BBP22_TXCONT_OR_CARRSUPP\n"));
5317 ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, 24, &Bbp24Value);
5318
5319 switch (Bbp24Value)
5320 {
5321 case BBP24_TXCONT:
5322 {
5323 ATEDBGPRINT(RT_DEBUG_TRACE,("START TXCONT\n"));
5324 pAdapter->ate.bQATxStart = TRUE;
5325 Set_ATE_Proc(pAdapter, "TXCONT");
5326 }
5327 break;
5328
5329 case BBP24_CARRSUPP:
5330 {
5331 ATEDBGPRINT(RT_DEBUG_TRACE,("START TXCARRSUPP\n"));
5332 pAdapter->ate.bQATxStart = TRUE;
5333 pAdapter->ate.Mode |= ATE_TXCARRSUPP;
5334 }
5335 break;
5336
5337 default:
5338 {
5339 ATEDBGPRINT(RT_DEBUG_ERROR,("Unknown Start TX subtype !"));
5340 }
5341 break;
5342 }
5343 }
5344 break;
5345
5346 case BBP22_TXCARR:
5347 {
5348 ATEDBGPRINT(RT_DEBUG_TRACE,("START TXCARR\n"));
5349 pAdapter->ate.bQATxStart = TRUE;
5350 Set_ATE_Proc(pAdapter, "TXCARR");
5351 }
5352 break;
5353
5354 default:
5355 {
5356 ATEDBGPRINT(RT_DEBUG_ERROR,("Unknown Start TX subtype !"));
5357 }
5358 break;
5359 }
5360
5361 if (pAdapter->ate.bQATxStart == TRUE)
5362 {
5363 // prepare feedback
5364 pRaCfg->length = htons(2);
5365 pRaCfg->status = htons(0);
5366
5367 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5368 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5369 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5370
5371 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5372 {
5373 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() was failed in case RACFG_CMD_TX_START\n"));
5374 Status = -EFAULT;
5375 }
5376 else
5377 {
5378 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_TX_START is done !\n"));
5379 }
5380 break;
5381 }
5382
5383TX_START_ERROR:
5384 // prepare feedback
5385 pRaCfg->length = htons(2);
5386 pRaCfg->status = htons(err);
5387
5388 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5389 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5390 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5391 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5392 {
5393 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_TX_START\n"));
5394 Status = -EFAULT;
5395 }
5396 else
5397 {
5398 ATEDBGPRINT(RT_DEBUG_TRACE, ("feedback of TX_START_ERROR is done !\n"));
5399 }
5400 }
5401 break;
5402
5403 case RACFG_CMD_GET_TX_STATUS:
5404 {
5405 UINT32 count;
5406
5407 // prepare feedback
5408 pRaCfg->length = htons(6);
5409 pRaCfg->status = htons(0);
5410 count = htonl(pAdapter->ate.TxDoneCount);
5411 NdisMoveMemory(pRaCfg->data, &count, 4);
5412 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5413 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5414 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5415
5416 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5417 {
5418 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_GET_TX_STATUS\n"));
5419 Status = -EFAULT;
5420 }
5421 else
5422 {
5423 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_GET_TX_STATUS is done !\n"));
5424 }
5425 }
5426 break;
5427
5428 case RACFG_CMD_TX_STOP:
5429 {
5430 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_TX_STOP\n"));
5431
5432 Set_ATE_Proc(pAdapter, "TXSTOP");
5433
5434 // prepare feedback
5435 pRaCfg->length = htons(2);
5436 pRaCfg->status = htons(0);
5437 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5438 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5439 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5440
5441 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5442 {
5443 ATEDBGPRINT(RT_DEBUG_TRACE, ("copy_to_user() fail in case RACFG_CMD_TX_STOP\n"));
5444 Status = -EFAULT;
5445 }
5446 else
5447 {
5448 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_TX_STOP is done !\n"));
5449 }
5450 }
5451 break;
5452
5453 case RACFG_CMD_RX_START:
5454 {
5455 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_RX_START\n"));
5456
5457 pAdapter->ate.bQARxStart = TRUE;
5458 Set_ATE_Proc(pAdapter, "RXFRAME");
5459
5460 // prepare feedback
5461 pRaCfg->length = htons(2);
5462 pRaCfg->status = htons(0);
5463 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5464 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5465 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5466
5467 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5468 {
5469 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_RX_START\n"));
5470 Status = -EFAULT;
5471 }
5472 else
5473 {
5474 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_RX_START is done !\n"));
5475 }
5476 }
5477 break;
5478
5479 case RACFG_CMD_RX_STOP:
5480 {
5481 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_RX_STOP\n"));
5482
5483 Set_ATE_Proc(pAdapter, "RXSTOP");
5484
5485 // prepare feedback
5486 pRaCfg->length = htons(2);
5487 pRaCfg->status = htons(0);
5488 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5489 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5490 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5491
5492 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5493 {
5494 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_RX_STOP\n"));
5495 Status = -EFAULT;
5496 }
5497 else
5498 {
5499 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_RX_STOP is done !\n"));
5500 }
5501 }
5502 break;
5503
5504 /* The following cases are for new ATE GUI(not QA). */
5505 /*==================================================*/
5506 case RACFG_CMD_ATE_START_TX_CARRIER:
5507 {
5508 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START_TX_CARRIER\n"));
5509
5510 Set_ATE_Proc(pAdapter, "TXCARR");
5511
5512 pRaCfg->length = htons(2);
5513 pRaCfg->status = htons(0);
5514
5515 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5516 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5517 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5518
5519 ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
5520
5521 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5522 {
5523 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_START_TX_CARRIER\n"));
5524 Status = -EFAULT;
5525 }
5526 else
5527 {
5528 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_START_TX_CARRIER is done !\n"));
5529 }
5530 }
5531 break;
5532
5533 case RACFG_CMD_ATE_START_TX_CONT:
5534 {
5535 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START_TX_CONT\n"));
5536
5537 Set_ATE_Proc(pAdapter, "TXCONT");
5538
5539 pRaCfg->length = htons(2);
5540 pRaCfg->status = htons(0);
5541
5542 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5543 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5544 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5545
5546 ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
5547
5548 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5549 {
5550 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_START_TX_CONT\n"));
5551 Status = -EFAULT;
5552 }
5553 else
5554 {
5555 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_START_TX_CONT is done !\n"));
5556 }
5557 }
5558 break;
5559
5560 case RACFG_CMD_ATE_START_TX_FRAME:
5561 {
5562 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START_TX_FRAME\n"));
5563
5564 Set_ATE_Proc(pAdapter, "TXFRAME");
5565
5566 pRaCfg->length = htons(2);
5567 pRaCfg->status = htons(0);
5568
5569 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5570 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5571 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5572
5573 ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
5574
5575 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5576 {
5577 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_START_TX_FRAME\n"));
5578 Status = -EFAULT;
5579 }
5580 else
5581 {
5582 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_START_TX_FRAME is done !\n"));
5583 }
5584 }
5585 break;
5586
5587 case RACFG_CMD_ATE_SET_BW:
5588 {
5589 SHORT value = 0;
5590 UCHAR str[LEN_OF_ARG];
5591
5592 NdisZeroMemory(str, LEN_OF_ARG);
5593
5594 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_BW\n"));
5595
5596 memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
5597 value = ntohs(value);
5598 sprintf((PCHAR)str, "%d", value);
5599
5600 Set_ATE_TX_BW_Proc(pAdapter, str);
5601
5602 // prepare feedback
5603 pRaCfg->length = htons(2);
5604 pRaCfg->status = htons(0);
5605 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5606 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5607 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5608
5609 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5610 {
5611 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_BW\n"));
5612 Status = -EFAULT;
5613 }
5614 else
5615 {
5616 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_BW is done !\n"));
5617 }
5618 }
5619 break;
5620
5621 case RACFG_CMD_ATE_SET_TX_POWER0:
5622 {
5623 SHORT value = 0;
5624 UCHAR str[LEN_OF_ARG];
5625
5626 NdisZeroMemory(str, LEN_OF_ARG);
5627
5628 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_POWER0\n"));
5629
5630 memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
5631 value = ntohs(value);
5632 sprintf((PCHAR)str, "%d", value);
5633 Set_ATE_TX_POWER0_Proc(pAdapter, str);
5634
5635 // prepare feedback
5636 pRaCfg->length = htons(2);
5637 pRaCfg->status = htons(0);
5638 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5639 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5640 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5641
5642 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5643 {
5644 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_TX_POWER0\n"));
5645 Status = -EFAULT;
5646 }
5647 else
5648 {
5649 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_TX_POWER0 is done !\n"));
5650 }
5651 }
5652 break;
5653
5654 case RACFG_CMD_ATE_SET_TX_POWER1:
5655 {
5656 SHORT value = 0;
5657 UCHAR str[LEN_OF_ARG];
5658
5659 NdisZeroMemory(str, LEN_OF_ARG);
5660
5661 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_POWER1\n"));
5662
5663 memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
5664 value = ntohs(value);
5665 sprintf((PCHAR)str, "%d", value);
5666 Set_ATE_TX_POWER1_Proc(pAdapter, str);
5667
5668 // prepare feedback
5669 pRaCfg->length = htons(2);
5670 pRaCfg->status = htons(0);
5671 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5672 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5673 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5674
5675 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5676 {
5677 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_TX_POWER1\n"));
5678 Status = -EFAULT;
5679 }
5680 else
5681 {
5682 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_TX_POWER1 is done !\n"));
5683 }
5684 }
5685 break;
5686
5687 case RACFG_CMD_ATE_SET_FREQ_OFFSET:
5688 {
5689 SHORT value = 0;
5690 UCHAR str[LEN_OF_ARG];
5691
5692 NdisZeroMemory(str, LEN_OF_ARG);
5693
5694 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_FREQ_OFFSET\n"));
5695
5696 memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
5697 value = ntohs(value);
5698 sprintf((PCHAR)str, "%d", value);
5699 Set_ATE_TX_FREQOFFSET_Proc(pAdapter, str);
5700
5701 // prepare feedback
5702 pRaCfg->length = htons(2);
5703 pRaCfg->status = htons(0);
5704 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5705 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5706 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5707
5708 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5709 {
5710 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_FREQ_OFFSET\n"));
5711 Status = -EFAULT;
5712 }
5713 else
5714 {
5715 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_FREQ_OFFSET is done !\n"));
5716 }
5717 }
5718 break;
5719
5720 case RACFG_CMD_ATE_GET_STATISTICS:
5721 {
5722 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_GET_STATISTICS\n"));
5723
5724 memcpy_exl(pAdapter, &pRaCfg->data[0], (UCHAR *)&pAdapter->ate.TxDoneCount, 4);
5725 memcpy_exl(pAdapter, &pRaCfg->data[4], (UCHAR *)&pAdapter->WlanCounters.RetryCount.u.LowPart, 4);
5726 memcpy_exl(pAdapter, &pRaCfg->data[8], (UCHAR *)&pAdapter->WlanCounters.FailedCount.u.LowPart, 4);
5727 memcpy_exl(pAdapter, &pRaCfg->data[12], (UCHAR *)&pAdapter->WlanCounters.RTSSuccessCount.u.LowPart, 4);
5728 memcpy_exl(pAdapter, &pRaCfg->data[16], (UCHAR *)&pAdapter->WlanCounters.RTSFailureCount.u.LowPart, 4);
5729 memcpy_exl(pAdapter, &pRaCfg->data[20], (UCHAR *)&pAdapter->WlanCounters.ReceivedFragmentCount.QuadPart, 4);
5730 memcpy_exl(pAdapter, &pRaCfg->data[24], (UCHAR *)&pAdapter->WlanCounters.FCSErrorCount.u.LowPart, 4);
5731 memcpy_exl(pAdapter, &pRaCfg->data[28], (UCHAR *)&pAdapter->Counters8023.RxNoBuffer, 4);
5732 memcpy_exl(pAdapter, &pRaCfg->data[32], (UCHAR *)&pAdapter->WlanCounters.FrameDuplicateCount.u.LowPart, 4);
5733 memcpy_exl(pAdapter, &pRaCfg->data[36], (UCHAR *)&pAdapter->RalinkCounters.OneSecFalseCCACnt, 4);
5734
5735 if (pAdapter->ate.RxAntennaSel == 0)
5736 {
5737 INT32 RSSI0 = 0;
5738 INT32 RSSI1 = 0;
5739 INT32 RSSI2 = 0;
5740
5741 RSSI0 = (INT32)(pAdapter->ate.LastRssi0 - pAdapter->BbpRssiToDbmDelta);
5742 RSSI1 = (INT32)(pAdapter->ate.LastRssi1 - pAdapter->BbpRssiToDbmDelta);
5743 RSSI2 = (INT32)(pAdapter->ate.LastRssi2 - pAdapter->BbpRssiToDbmDelta);
5744 memcpy_exl(pAdapter, &pRaCfg->data[40], (UCHAR *)&RSSI0, 4);
5745 memcpy_exl(pAdapter, &pRaCfg->data[44], (UCHAR *)&RSSI1, 4);
5746 memcpy_exl(pAdapter, &pRaCfg->data[48], (UCHAR *)&RSSI2, 4);
5747 pRaCfg->length = htons(2+52);
5748 }
5749 else
5750 {
5751 INT32 RSSI0 = 0;
5752
5753 RSSI0 = (INT32)(pAdapter->ate.LastRssi0 - pAdapter->BbpRssiToDbmDelta);
5754 memcpy_exl(pAdapter, &pRaCfg->data[40], (UCHAR *)&RSSI0, 4);
5755 pRaCfg->length = htons(2+44);
5756 }
5757 pRaCfg->status = htons(0);
5758 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5759 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5760 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5761
5762 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5763 {
5764 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_GET_STATISTICS\n"));
5765 Status = -EFAULT;
5766 }
5767 else
5768 {
5769 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_GET_STATISTICS is done !\n"));
5770 }
5771 }
5772 break;
5773
5774 case RACFG_CMD_ATE_RESET_COUNTER:
5775 {
5776 SHORT value = 1;
5777 UCHAR str[LEN_OF_ARG];
5778
5779 NdisZeroMemory(str, LEN_OF_ARG);
5780
5781 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_RESET_COUNTER\n"));
5782
5783 sprintf((PCHAR)str, "%d", value);
5784 Set_ResetStatCounter_Proc(pAdapter, str);
5785
5786 pAdapter->ate.TxDoneCount = 0;
5787
5788 pRaCfg->length = htons(2);
5789 pRaCfg->status = htons(0);
5790
5791 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5792 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5793 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5794
5795 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5796 {
5797 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_RESET_COUNTER\n"));
5798 Status = -EFAULT;
5799 }
5800 else
5801 {
5802 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_RESET_COUNTER is done !\n"));
5803 }
5804 }
5805
5806 break;
5807
5808 case RACFG_CMD_ATE_SEL_TX_ANTENNA:
5809 {
5810 SHORT value = 0;
5811 UCHAR str[LEN_OF_ARG];
5812
5813 NdisZeroMemory(str, LEN_OF_ARG);
5814
5815 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SEL_TX_ANTENNA\n"));
5816
5817 memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
5818 value = ntohs(value);
5819 sprintf((PCHAR)str, "%d", value);
5820 Set_ATE_TX_Antenna_Proc(pAdapter, str);
5821
5822 // prepare feedback
5823 pRaCfg->length = htons(2);
5824 pRaCfg->status = htons(0);
5825 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5826 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5827 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5828
5829 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5830 {
5831 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SEL_TX_ANTENNA\n"));
5832 Status = -EFAULT;
5833 }
5834 else
5835 {
5836 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SEL_TX_ANTENNA is done !\n"));
5837 }
5838 }
5839 break;
5840
5841 case RACFG_CMD_ATE_SEL_RX_ANTENNA:
5842 {
5843 SHORT value = 0;
5844 UCHAR str[LEN_OF_ARG];
5845
5846 NdisZeroMemory(str, LEN_OF_ARG);
5847
5848 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SEL_RX_ANTENNA\n"));
5849
5850 memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
5851 value = ntohs(value);
5852 sprintf((PCHAR)str, "%d", value);
5853 Set_ATE_RX_Antenna_Proc(pAdapter, str);
5854
5855 // prepare feedback
5856 pRaCfg->length = htons(2);
5857 pRaCfg->status = htons(0);
5858 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5859 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5860 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5861
5862 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5863 {
5864 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SEL_RX_ANTENNA\n"));
5865 Status = -EFAULT;
5866 }
5867 else
5868 {
5869 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SEL_RX_ANTENNA is done !\n"));
5870 }
5871 }
5872 break;
5873
5874 case RACFG_CMD_ATE_SET_PREAMBLE:
5875 {
5876 SHORT value = 0;
5877 UCHAR str[LEN_OF_ARG];
5878
5879 NdisZeroMemory(str, LEN_OF_ARG);
5880
5881 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_PREAMBLE\n"));
5882
5883 memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
5884 value = ntohs(value);
5885 sprintf((PCHAR)str, "%d", value);
5886 Set_ATE_TX_MODE_Proc(pAdapter, str);
5887
5888 // prepare feedback
5889 pRaCfg->length = htons(2);
5890 pRaCfg->status = htons(0);
5891 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5892 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5893 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5894
5895 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5896 {
5897 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_PREAMBLE\n"));
5898 Status = -EFAULT;
5899 }
5900 else
5901 {
5902 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_PREAMBLE is done !\n"));
5903 }
5904 }
5905 break;
5906
5907 case RACFG_CMD_ATE_SET_CHANNEL:
5908 {
5909 SHORT value = 0;
5910 UCHAR str[LEN_OF_ARG];
5911
5912 NdisZeroMemory(str, LEN_OF_ARG);
5913
5914 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_CHANNEL\n"));
5915
5916 memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
5917 value = ntohs(value);
5918 sprintf((PCHAR)str, "%d", value);
5919 Set_ATE_CHANNEL_Proc(pAdapter, str);
5920
5921 // prepare feedback
5922 pRaCfg->length = htons(2);
5923 pRaCfg->status = htons(0);
5924 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5925 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5926 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5927
5928 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5929 {
5930 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_CHANNEL\n"));
5931 Status = -EFAULT;
5932 }
5933 else
5934 {
5935 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_CHANNEL is done !\n"));
5936 }
5937 }
5938 break;
5939
5940 case RACFG_CMD_ATE_SET_ADDR1:
5941 {
5942 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_ADDR1\n"));
5943
5944 // Addr is an array of UCHAR,
5945 // so no need to perform endian swap.
5946 memcpy(pAdapter->ate.Addr1, (PUCHAR)(pRaCfg->data - 2), MAC_ADDR_LEN);
5947
5948 // prepare feedback
5949 pRaCfg->length = htons(2);
5950 pRaCfg->status = htons(0);
5951 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5952 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5953 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5954
5955 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5956 {
5957 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_ADDR1\n"));
5958 Status = -EFAULT;
5959 }
5960 else
5961 {
5962 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_ADDR1 is done !\n (ADDR1 = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAdapter->ate.Addr1[0],
5963 pAdapter->ate.Addr1[1], pAdapter->ate.Addr1[2], pAdapter->ate.Addr1[3], pAdapter->ate.Addr1[4], pAdapter->ate.Addr1[5]));
5964 }
5965 }
5966 break;
5967
5968 case RACFG_CMD_ATE_SET_ADDR2:
5969 {
5970 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_ADDR2\n"));
5971
5972 // Addr is an array of UCHAR,
5973 // so no need to perform endian swap.
5974 memcpy(pAdapter->ate.Addr2, (PUCHAR)(pRaCfg->data - 2), MAC_ADDR_LEN);
5975
5976 // prepare feedback
5977 pRaCfg->length = htons(2);
5978 pRaCfg->status = htons(0);
5979 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5980 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5981 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5982
5983 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5984 {
5985 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_ADDR2\n"));
5986 Status = -EFAULT;
5987 }
5988 else
5989 {
5990 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_ADDR2 is done !\n (ADDR2 = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAdapter->ate.Addr2[0],
5991 pAdapter->ate.Addr2[1], pAdapter->ate.Addr2[2], pAdapter->ate.Addr2[3], pAdapter->ate.Addr2[4], pAdapter->ate.Addr2[5]));
5992 }
5993 }
5994 break;
5995
5996 case RACFG_CMD_ATE_SET_ADDR3:
5997 {
5998 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_ADDR3\n"));
5999
6000 // Addr is an array of UCHAR,
6001 // so no need to perform endian swap.
6002 memcpy(pAdapter->ate.Addr3, (PUCHAR)(pRaCfg->data - 2), MAC_ADDR_LEN);
6003
6004 // prepare feedback
6005 pRaCfg->length = htons(2);
6006 pRaCfg->status = htons(0);
6007 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
6008 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
6009 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
6010
6011 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
6012 {
6013 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_ADDR3\n"));
6014 Status = -EFAULT;
6015 }
6016 else
6017 {
6018 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_ADDR3 is done !\n (ADDR3 = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAdapter->ate.Addr3[0],
6019 pAdapter->ate.Addr3[1], pAdapter->ate.Addr3[2], pAdapter->ate.Addr3[3], pAdapter->ate.Addr3[4], pAdapter->ate.Addr3[5]));
6020 }
6021 }
6022 break;
6023
6024 case RACFG_CMD_ATE_SET_RATE:
6025 {
6026 SHORT value = 0;
6027 UCHAR str[LEN_OF_ARG];
6028
6029 NdisZeroMemory(str, LEN_OF_ARG);
6030
6031 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_RATE\n"));
6032
6033 memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
6034 value = ntohs(value);
6035 sprintf((PCHAR)str, "%d", value);
6036 Set_ATE_TX_MCS_Proc(pAdapter, str);
6037
6038 // prepare feedback
6039 pRaCfg->length = htons(2);
6040 pRaCfg->status = htons(0);
6041 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
6042 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
6043 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
6044
6045 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
6046 {
6047 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_RATE\n"));
6048 Status = -EFAULT;
6049 }
6050 else
6051 {
6052 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_RATE is done !\n"));
6053 }
6054 }
6055 break;
6056
6057 case RACFG_CMD_ATE_SET_TX_FRAME_LEN:
6058 {
6059 SHORT value = 0;
6060 UCHAR str[LEN_OF_ARG];
6061
6062 NdisZeroMemory(str, LEN_OF_ARG);
6063
6064 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_FRAME_LEN\n"));
6065
6066 memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
6067 value = ntohs(value);
6068 sprintf((PCHAR)str, "%d", value);
6069 Set_ATE_TX_LENGTH_Proc(pAdapter, str);
6070
6071 // prepare feedback
6072 pRaCfg->length = htons(2);
6073 pRaCfg->status = htons(0);
6074 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
6075 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
6076 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
6077
6078 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
6079 {
6080 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_TX_FRAME_LEN\n"));
6081 Status = -EFAULT;
6082 }
6083 else
6084 {
6085 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_TX_FRAME_LEN is done !\n"));
6086 }
6087 }
6088 break;
6089
6090 case RACFG_CMD_ATE_SET_TX_FRAME_COUNT:
6091 {
6092 USHORT value = 0;
6093 UCHAR str[LEN_OF_ARG];
6094
6095 NdisZeroMemory(str, LEN_OF_ARG);
6096
6097 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_FRAME_COUNT\n"));
6098
6099 memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
6100 value = ntohs(value);
6101 {
6102 sprintf((PCHAR)str, "%d", value);
6103 Set_ATE_TX_COUNT_Proc(pAdapter, str);
6104 }
6105
6106 // prepare feedback
6107 pRaCfg->length = htons(2);
6108 pRaCfg->status = htons(0);
6109 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
6110 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
6111 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
6112
6113 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
6114 {
6115 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_TX_FRAME_COUNT\n"));
6116 Status = -EFAULT;
6117 }
6118 else
6119 {
6120 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_TX_FRAME_COUNT is done !\n"));
6121 }
6122 }
6123 break;
6124
6125 case RACFG_CMD_ATE_START_RX_FRAME:
6126 {
6127 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_RX_START\n"));
6128
6129 Set_ATE_Proc(pAdapter, "RXFRAME");
6130
6131 // prepare feedback
6132 pRaCfg->length = htons(2);
6133 pRaCfg->status = htons(0);
6134 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
6135 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
6136 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
6137
6138 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
6139 {
6140 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_RX_START\n"));
6141 Status = -EFAULT;
6142 }
6143 else
6144 {
6145 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_RX_START is done !\n"));
6146 }
6147 }
6148 break;
6149 default:
6150 break;
6151 }
6152 ASSERT(pRaCfg != NULL);
6153 if (pRaCfg != NULL)
6154 {
6155 kfree(pRaCfg);
6156 }
6157 return;
6158}
6159
6160VOID BubbleSort(INT32 n, INT32 a[])
6161{
6162 INT32 k, j, temp;
6163
6164 for (k = n-1; k>0; k--)
6165 {
6166 for (j = 0; j<k; j++)
6167 {
6168 if(a[j] > a[j+1])
6169 {
6170 temp = a[j];
6171 a[j]=a[j+1];
6172 a[j+1]=temp;
6173 }
6174 }
6175 }
6176}
6177
6178VOID CalNoiseLevel(PRTMP_ADAPTER pAd, UCHAR channel, INT32 RSSI[3][10])
6179{
6180 INT32 RSSI0, RSSI1, RSSI2;
6181 CHAR Rssi0Offset, Rssi1Offset, Rssi2Offset;
6182 UCHAR BbpR50Rssi0 = 0, BbpR51Rssi1 = 0, BbpR52Rssi2 = 0;
6183 UCHAR Org_BBP66value = 0, Org_BBP69value = 0, Org_BBP70value = 0, data = 0;
6184 USHORT LNA_Gain = 0;
6185 INT32 j = 0;
6186 UCHAR Org_Channel = pAd->ate.Channel;
6187 USHORT GainValue = 0, OffsetValue = 0;
6188
6189 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &Org_BBP66value);
6190 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R69, &Org_BBP69value);
6191 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R70, &Org_BBP70value);
6192
6193 //**********************************************************************
6194 // Read the value of LNA gain and Rssi offset
6195 //**********************************************************************
6196 RT28xx_EEPROM_READ16(pAd, EEPROM_LNA_OFFSET, GainValue);
6197
6198 // for Noise Level
6199 if (channel <= 14)
6200 {
6201 LNA_Gain = GainValue & 0x00FF;
6202
6203 RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET, OffsetValue);
6204 Rssi0Offset = OffsetValue & 0x00FF;
6205 Rssi1Offset = (OffsetValue & 0xFF00) >> 8;
6206 RT28xx_EEPROM_READ16(pAd, (EEPROM_RSSI_BG_OFFSET + 2)/* 0x48 */, OffsetValue);
6207 Rssi2Offset = OffsetValue & 0x00FF;
6208 }
6209 else
6210 {
6211 LNA_Gain = (GainValue & 0xFF00) >> 8;
6212
6213 RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_A_OFFSET, OffsetValue);
6214 Rssi0Offset = OffsetValue & 0x00FF;
6215 Rssi1Offset = (OffsetValue & 0xFF00) >> 8;
6216 RT28xx_EEPROM_READ16(pAd, (EEPROM_RSSI_A_OFFSET + 2)/* 0x4C */, OffsetValue);
6217 Rssi2Offset = OffsetValue & 0x00FF;
6218 }
6219 //**********************************************************************
6220 {
6221 pAd->ate.Channel = channel;
6222 ATEAsicSwitchChannel(pAd);
6223 mdelay(5);
6224
6225 data = 0x10;
6226 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, data);
6227 data = 0x40;
6228 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, data);
6229 data = 0x40;
6230 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, data);
6231 mdelay(5);
6232
6233 // Start Rx
6234 pAd->ate.bQARxStart = TRUE;
6235 Set_ATE_Proc(pAd, "RXFRAME");
6236
6237 mdelay(5);
6238
6239 for (j = 0; j < 10; j++)
6240 {
6241 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R50, &BbpR50Rssi0);
6242 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R51, &BbpR51Rssi1);
6243 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R52, &BbpR52Rssi2);
6244
6245 mdelay(10);
6246
6247 // Calculate RSSI 0
6248 if (BbpR50Rssi0 == 0)
6249 {
6250 RSSI0 = -100;
6251 }
6252 else
6253 {
6254 RSSI0 = (INT32)(-12 - BbpR50Rssi0 - LNA_Gain - Rssi0Offset);
6255 }
6256 RSSI[0][j] = RSSI0;
6257
6258 if ( pAd->Antenna.field.RxPath >= 2 ) // 2R
6259 {
6260 // Calculate RSSI 1
6261 if (BbpR51Rssi1 == 0)
6262 {
6263 RSSI1 = -100;
6264 }
6265 else
6266 {
6267 RSSI1 = (INT32)(-12 - BbpR51Rssi1 - LNA_Gain - Rssi1Offset);
6268 }
6269 RSSI[1][j] = RSSI1;
6270 }
6271
6272 if ( pAd->Antenna.field.RxPath >= 3 ) // 3R
6273 {
6274 // Calculate RSSI 2
6275 if (BbpR52Rssi2 == 0)
6276 RSSI2 = -100;
6277 else
6278 RSSI2 = (INT32)(-12 - BbpR52Rssi2 - LNA_Gain - Rssi2Offset);
6279
6280 RSSI[2][j] = RSSI2;
6281 }
6282 }
6283
6284 // Stop Rx
6285 Set_ATE_Proc(pAd, "RXSTOP");
6286
6287 mdelay(5);
6288
6289 BubbleSort(10, RSSI[0]); // 1R
6290
6291 if ( pAd->Antenna.field.RxPath >= 2 ) // 2R
6292 {
6293 BubbleSort(10, RSSI[1]);
6294 }
6295
6296 if ( pAd->Antenna.field.RxPath >= 3 ) // 3R
6297 {
6298 BubbleSort(10, RSSI[2]);
6299 }
6300
6301 }
6302
6303 pAd->ate.Channel = Org_Channel;
6304 ATEAsicSwitchChannel(pAd);
6305
6306 // Restore original value
6307 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, Org_BBP66value);
6308 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, Org_BBP69value);
6309 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, Org_BBP70value);
6310
6311 return;
6312}
6313
6314BOOLEAN SyncTxRxConfig(PRTMP_ADAPTER pAd, USHORT offset, UCHAR value)
6315{
6316 UCHAR tmp = 0, bbp_data = 0;
6317
6318 if (ATE_ON(pAd))
6319 {
6320 ATE_BBP_IO_READ8_BY_REG_ID(pAd, offset, &bbp_data);
6321 }
6322 else
6323 {
6324 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, offset, &bbp_data);
6325 }
6326
6327 /* confirm again */
6328 ASSERT(bbp_data == value);
6329
6330 switch(offset)
6331 {
6332 case BBP_R1:
6333 /* Need to sync. tx configuration with legacy ATE. */
6334 tmp = (bbp_data & ((1 << 4) | (1 << 3))/* 0x18 */) >> 3;
6335 switch(tmp)
6336 {
6337 /* The BBP R1 bit[4:3] = 2 :: Both DACs will be used by QA. */
6338 case 2:
6339 /* All */
6340 pAd->ate.TxAntennaSel = 0;
6341 break;
6342 /* The BBP R1 bit[4:3] = 0 :: DAC 0 will be used by QA. */
6343 case 0:
6344 /* Antenna one */
6345 pAd->ate.TxAntennaSel = 1;
6346 break;
6347 /* The BBP R1 bit[4:3] = 1 :: DAC 1 will be used by QA. */
6348 case 1:
6349 /* Antenna two */
6350 pAd->ate.TxAntennaSel = 2;
6351 break;
6352 default:
6353 DBGPRINT(RT_DEBUG_TRACE, ("%s -- Sth. wrong! : return FALSE; \n", __FUNCTION__));
6354 return FALSE;
6355 }
6356 break;/* case BBP_R1 */
6357
6358 case BBP_R3:
6359 /* Need to sync. rx configuration with legacy ATE. */
6360 tmp = (bbp_data & ((1 << 1) | (1 << 0))/* 0x03 */);
6361 switch(tmp)
6362 {
6363 /* The BBP R3 bit[1:0] = 3 :: All ADCs will be used by QA. */
6364 case 3:
6365 /* All */
6366 pAd->ate.RxAntennaSel = 0;
6367 break;
6368 /* The BBP R3 bit[1:0] = 0 :: ADC 0 will be used by QA, */
6369 /* unless the BBP R3 bit[4:3] = 2 */
6370 case 0:
6371 /* Antenna one */
6372 pAd->ate.RxAntennaSel = 1;
6373 tmp = ((bbp_data & ((1 << 4) | (1 << 3))/* 0x03 */) >> 3);
6374 if (tmp == 2)// 3R
6375 {
6376 /* Default : All ADCs will be used by QA */
6377 pAd->ate.RxAntennaSel = 0;
6378 }
6379 break;
6380 /* The BBP R3 bit[1:0] = 1 :: ADC 1 will be used by QA. */
6381 case 1:
6382 /* Antenna two */
6383 pAd->ate.RxAntennaSel = 2;
6384 break;
6385 /* The BBP R3 bit[1:0] = 2 :: ADC 2 will be used by QA. */
6386 case 2:
6387 /* Antenna three */
6388 pAd->ate.RxAntennaSel = 3;
6389 break;
6390 default:
6391 DBGPRINT(RT_DEBUG_ERROR, ("%s -- Impossible! : return FALSE; \n", __FUNCTION__));
6392 return FALSE;
6393 }
6394 break;/* case BBP_R3 */
6395
6396 default:
6397 DBGPRINT(RT_DEBUG_ERROR, ("%s -- Sth. wrong! : return FALSE; \n", __FUNCTION__));
6398 return FALSE;
6399
6400 }
6401 return TRUE;
6402}
6403
6404static VOID memcpy_exl(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len)
6405{
6406 ULONG i, Value = 0;
6407 ULONG *pDst, *pSrc;
6408 UCHAR *p8;
6409
6410 p8 = src;
6411 pDst = (ULONG *) dst;
6412 pSrc = (ULONG *) src;
6413
6414 for (i = 0 ; i < (len/4); i++)
6415 {
6416 /* For alignment issue, we need a variable "Value". */
6417 memmove(&Value, pSrc, 4);
6418 Value = htonl(Value);
6419 memmove(pDst, &Value, 4);
6420 pDst++;
6421 pSrc++;
6422 }
6423 if ((len % 4) != 0)
6424 {
6425 /* wish that it will never reach here */
6426 memmove(&Value, pSrc, (len % 4));
6427 Value = htonl(Value);
6428 memmove(pDst, &Value, (len % 4));
6429 }
6430}
6431
6432static VOID memcpy_exs(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len)
6433{
6434 ULONG i;
6435 UCHAR *pDst, *pSrc;
6436
6437 pDst = dst;
6438 pSrc = src;
6439
6440 for (i = 0; i < (len/2); i++)
6441 {
6442 memmove(pDst, pSrc, 2);
6443 *((USHORT *)pDst) = htons(*((USHORT *)pDst));
6444 pDst+=2;
6445 pSrc+=2;
6446 }
6447
6448 if ((len % 2) != 0)
6449 {
6450 memmove(pDst, pSrc, 1);
6451 }
6452}
6453
6454static VOID RTMP_IO_READ_BULK(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, UINT32 len)
6455{
6456 UINT32 i, Value;
6457 UINT32 *pDst, *pSrc;
6458
6459 pDst = (UINT32 *) dst;
6460 pSrc = (UINT32 *) src;
6461
6462 for (i = 0 ; i < (len/4); i++)
6463 {
6464 RTMP_IO_READ32(pAd, (ULONG)pSrc, &Value);
6465 Value = htonl(Value);
6466 memmove(pDst, &Value, 4);
6467 pDst++;
6468 pSrc++;
6469 }
6470 return;
6471}
6472
6473INT Set_TxStop_Proc(
6474 IN PRTMP_ADAPTER pAd,
6475 IN PUCHAR arg)
6476{
6477 ATEDBGPRINT(RT_DEBUG_TRACE,("Set_TxStop_Proc\n"));
6478
6479 if (Set_ATE_Proc(pAd, "TXSTOP"))
6480 {
6481 return TRUE;
6482}
6483 else
6484 {
6485 return FALSE;
6486 }
6487}
6488
6489INT Set_RxStop_Proc(
6490 IN PRTMP_ADAPTER pAd,
6491 IN PUCHAR arg)
6492{
6493 ATEDBGPRINT(RT_DEBUG_TRACE,("Set_RxStop_Proc\n"));
6494
6495 if (Set_ATE_Proc(pAd, "RXSTOP"))
6496 {
6497 return TRUE;
6498}
6499 else
6500 {
6501 return FALSE;
6502 }
6503}
6504#endif // RALINK_28xx_QA //
6505#endif // RALINK_ATE //
6506
diff --git a/drivers/staging/rt3070/rt_ate.h b/drivers/staging/rt3070/rt_ate.h
new file mode 100644
index 000000000000..829ebb5f7236
--- /dev/null
+++ b/drivers/staging/rt3070/rt_ate.h
@@ -0,0 +1,294 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26 */
27
28#ifndef __ATE_H__
29#define __ATE_H__
30
31#ifndef UCOS
32#define ate_print printk
33#define ATEDBGPRINT DBGPRINT
34
35#ifdef RT2870
36#define EEPROM_SIZE 0x400
37#ifdef CONFIG_STA_SUPPORT
38#define EEPROM_BIN_FILE_NAME "/etc/Wireless/RT2870STA/e2p.bin"
39#endif // CONFIG_STA_SUPPORT //
40#endif // RT2870 //
41#else // !UCOS //
42#define fATE_LOAD_EEPROM 0x0C43
43#ifdef CONFIG_PRINTK
44extern INT ConsoleResponse(IN PUCHAR buff);
45extern int (*remote_display)(char *);
46extern void puts (const char *s);
47
48/* specificly defined to redirect and show ate-related messages to host. */
49/* Try to define ate_print as a macro. */
50#define ate_print(fmt, args...) \
51do{ int (*org_remote_display)(char *) = NULL; \
52 org_remote_display = remote_display;\
53 /* Save original "remote_display" */\
54 remote_display = (int (*)(char *))ConsoleResponse; \
55 printk(fmt, ## args); \
56 /* Restore the remote_display function pointer */ \
57 remote_display = org_remote_display; }while(0)
58
59#define ATEDBGPRINT(Level, Fmt) \
60{ \
61 if ((Level) <= RTDebugLevel) \
62 { \
63 ate_print Fmt; \
64 } \
65}
66#endif // CONFIG_PRINTK //
67#endif // !UCOS //
68
69#define ATE_ON(_p) (((_p)->ate.Mode) != ATE_STOP)
70
71/* RT2880_iNIC will define "RT2860". */
72
73/* RT2880_iNIC will define RT2860. */
74
75#ifdef RT2870
76#define EEPROM_SIZE 0x400
77#ifdef CONFIG_STA_SUPPORT
78#define EEPROM_BIN_FILE_NAME "/etc/Wireless/RT2870STA/e2p.bin"
79#endif // CONFIG_STA_SUPPORT //
80#endif // RT2870 //
81
82#ifdef RT2870
83#define ATE_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)
84#define ATE_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V)
85
86#define BULK_OUT_LOCK(pLock, IrqFlags) \
87 if(1 /*!(in_interrupt() & 0xffff0000)*/) \
88 RTMP_IRQ_LOCK((pLock), IrqFlags);
89
90#define BULK_OUT_UNLOCK(pLock, IrqFlags) \
91 if(1 /*!(in_interrupt() & 0xffff0000)*/) \
92 RTMP_IRQ_UNLOCK((pLock), IrqFlags);
93
94// Prototypes of completion funuc.
95#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
96#define ATE_RTUSBBulkOutDataPacketComplete(purb, pt_regs) ATE_RTUSBBulkOutDataPacketComplete(purb)
97#endif
98
99VOID ATE_RTUSBBulkOutDataPacketComplete(
100 IN purbb_t purb,
101 OUT struct pt_regs *pt_regs);
102
103VOID ATE_RTUSBBulkOutDataPacket(
104 IN PRTMP_ADAPTER pAd,
105 IN UCHAR BulkOutPipeId);
106
107VOID ATE_RTUSBCancelPendingBulkInIRP(
108 IN PRTMP_ADAPTER pAd);
109#endif // RT2870 //
110
111#ifdef RT30xx
112#define ATE_RF_IO_READ8_BY_REG_ID(_A, _I, _pV) RTMP_RF_IO_READ8_BY_REG_ID(_A, _I, _pV)
113#define ATE_RF_IO_WRITE8_BY_REG_ID(_A, _I, _V) RTMP_RF_IO_WRITE8_BY_REG_ID(_A, _I, _V)
114#endif // RT30xx //
115
116
117VOID rt_ee_read_all(
118 IN PRTMP_ADAPTER pAd,
119 OUT USHORT *Data);
120
121
122VOID rt_ee_write_all(
123 IN PRTMP_ADAPTER pAd,
124 IN USHORT *Data);
125
126INT Set_ATE_Proc(
127 IN PRTMP_ADAPTER pAd,
128 IN PUCHAR arg);
129
130INT Set_ATE_DA_Proc(
131 IN PRTMP_ADAPTER pAd,
132 IN PUCHAR arg);
133
134INT Set_ATE_SA_Proc(
135 IN PRTMP_ADAPTER pAd,
136 IN PUCHAR arg);
137
138INT Set_ATE_BSSID_Proc(
139 IN PRTMP_ADAPTER pAd,
140 IN PUCHAR arg);
141
142INT Set_ATE_CHANNEL_Proc(
143 IN PRTMP_ADAPTER pAd,
144 IN PUCHAR arg);
145
146INT Set_ATE_TX_POWER0_Proc(
147 IN PRTMP_ADAPTER pAd,
148 IN PUCHAR arg);
149
150INT Set_ATE_TX_POWER1_Proc(
151 IN PRTMP_ADAPTER pAd,
152 IN PUCHAR arg);
153
154INT Set_ATE_TX_Antenna_Proc(
155 IN PRTMP_ADAPTER pAd,
156 IN PUCHAR arg);
157
158INT Set_ATE_RX_Antenna_Proc(
159 IN PRTMP_ADAPTER pAd,
160 IN PUCHAR arg);
161
162INT Set_ATE_TX_FREQOFFSET_Proc(
163 IN PRTMP_ADAPTER pAd,
164 IN PUCHAR arg);
165
166INT Set_ATE_TX_BW_Proc(
167 IN PRTMP_ADAPTER pAd,
168 IN PUCHAR arg);
169
170INT Set_ATE_TX_LENGTH_Proc(
171 IN PRTMP_ADAPTER pAd,
172 IN PUCHAR arg);
173
174INT Set_ATE_TX_COUNT_Proc(
175 IN PRTMP_ADAPTER pAd,
176 IN PUCHAR arg);
177
178INT Set_ATE_TX_MCS_Proc(
179 IN PRTMP_ADAPTER pAd,
180 IN PUCHAR arg);
181
182INT Set_ATE_TX_MODE_Proc(
183 IN PRTMP_ADAPTER pAd,
184 IN PUCHAR arg);
185
186INT Set_ATE_TX_GI_Proc(
187 IN PRTMP_ADAPTER pAd,
188 IN PUCHAR arg);
189
190
191INT Set_ATE_RX_FER_Proc(
192 IN PRTMP_ADAPTER pAd,
193 IN PUCHAR arg);
194
195INT Set_ATE_Read_RF_Proc(
196 IN PRTMP_ADAPTER pAd,
197 IN PUCHAR arg);
198
199INT Set_ATE_Write_RF1_Proc(
200 IN PRTMP_ADAPTER pAd,
201 IN PUCHAR arg);
202
203INT Set_ATE_Write_RF2_Proc(
204 IN PRTMP_ADAPTER pAd,
205 IN PUCHAR arg);
206
207INT Set_ATE_Write_RF3_Proc(
208 IN PRTMP_ADAPTER pAd,
209 IN PUCHAR arg);
210
211INT Set_ATE_Write_RF4_Proc(
212 IN PRTMP_ADAPTER pAd,
213 IN PUCHAR arg);
214
215INT Set_ATE_Load_E2P_Proc(
216 IN PRTMP_ADAPTER pAd,
217 IN PUCHAR arg);
218
219INT Set_ATE_Read_E2P_Proc(
220 IN PRTMP_ADAPTER pAd,
221 IN PUCHAR arg);
222
223INT Set_ATE_Show_Proc(
224 IN PRTMP_ADAPTER pAd,
225 IN PUCHAR arg);
226
227INT Set_ATE_Help_Proc(
228 IN PRTMP_ADAPTER pAd,
229 IN PUCHAR arg);
230
231#ifdef RALINK_ATE
232#ifdef RALINK_28xx_QA
233VOID ATE_QA_Statistics(
234 IN PRTMP_ADAPTER pAd,
235 IN PRXWI_STRUC pRxWI,
236 IN PRT28XX_RXD_STRUC p28xxRxD,
237 IN PHEADER_802_11 pHeader);
238
239VOID RtmpDoAte(
240 IN PRTMP_ADAPTER pAdapter,
241 IN struct iwreq *wrq);
242
243VOID BubbleSort(
244 IN INT32 n,
245 IN INT32 a[]);
246
247VOID CalNoiseLevel(
248 IN PRTMP_ADAPTER pAdapter,
249 IN UCHAR channel,
250 OUT INT32 buffer[3][10]);
251
252BOOLEAN SyncTxRxConfig(
253 IN PRTMP_ADAPTER pAdapter,
254 IN USHORT offset,
255 IN UCHAR value);
256
257INT Set_TxStop_Proc(
258 IN PRTMP_ADAPTER pAd,
259 IN PUCHAR arg);
260
261INT Set_RxStop_Proc(
262 IN PRTMP_ADAPTER pAd,
263 IN PUCHAR arg);
264
265#endif // RALINK_28xx_QA //
266#endif // RALINK_ATE //
267
268VOID ATEAsicSwitchChannel(
269 IN PRTMP_ADAPTER pAd);
270
271VOID ATEAsicAdjustTxPower(
272 IN PRTMP_ADAPTER pAd);
273
274VOID ATEDisableAsicProtect(
275 IN PRTMP_ADAPTER pAd);
276
277CHAR ATEConvertToRssi(
278 IN PRTMP_ADAPTER pAd,
279 IN CHAR Rssi,
280 IN UCHAR RssiNumber);
281
282VOID ATESampleRssi(
283 IN PRTMP_ADAPTER pAd,
284 IN PRXWI_STRUC pRxWI);
285
286
287#ifdef CONFIG_STA_SUPPORT
288VOID RTMPStationStop(
289 IN PRTMP_ADAPTER pAd);
290
291VOID RTMPStationStart(
292 IN PRTMP_ADAPTER pAd);
293#endif // CONFIG_STA_SUPPORT //
294#endif // __ATE_H__ //
diff --git a/drivers/staging/rt3070/rt_config.h b/drivers/staging/rt3070/rt_config.h
new file mode 100644
index 000000000000..9e06417f63d3
--- /dev/null
+++ b/drivers/staging/rt3070/rt_config.h
@@ -0,0 +1,121 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 rt_config.h
29
30 Abstract:
31 Central header file to maintain all include files for all NDIS
32 miniport driver routines.
33
34 Revision History:
35 Who When What
36 -------- ---------- ----------------------------------------------
37 Paul Lin 08-01-2002 created
38
39*/
40#ifndef __RT_CONFIG_H__
41#define __RT_CONFIG_H__
42
43#include "rtmp_type.h"
44#ifdef UCOS
45#include "includes.h"
46#include <stdio.h>
47#include "rt_ucos.h"
48#endif
49
50#ifdef LINUX
51#include "rt_linux.h"
52#endif
53#include "rtmp_def.h"
54#include "rt28xx.h"
55
56
57#ifdef RT2870
58#include "rt2870.h"
59#endif // RT2870 //
60
61#include "oid.h"
62#include "mlme.h"
63#include "wpa.h"
64#include "md5.h"
65#include "rtmp.h"
66#include "ap.h"
67#include "dfs.h"
68#include "chlist.h"
69#include "spectrum.h"
70#ifdef MLME_EX
71#include "mlme_ex_def.h"
72#include "mlme_ex.h"
73#endif // MLME_EX //
74
75#undef AP_WSC_INCLUDED
76#undef STA_WSC_INCLUDED
77#undef WSC_INCLUDED
78
79
80#ifdef LEAP_SUPPORT
81#include "leap.h"
82#endif // LEAP_SUPPORT //
83
84#ifdef CONFIG_STA_SUPPORT
85#endif // CONFIG_STA_SUPPORT //
86
87#ifdef BLOCK_NET_IF
88#include "netif_block.h"
89#endif // BLOCK_NET_IF //
90
91#ifdef IGMP_SNOOP_SUPPORT
92#include "igmp_snoop.h"
93#endif // IGMP_SNOOP_SUPPORT //
94
95#ifdef RALINK_ATE
96#include "rt_ate.h"
97#endif // RALINK_ATE //
98
99
100
101#if defined(AP_WSC_INCLUDED) || defined(STA_WSC_INCLUDED)
102#define WSC_INCLUDED
103#endif
104
105
106#ifdef CONFIG_STA_SUPPORT
107#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
108#ifndef WPA_SUPPLICANT_SUPPORT
109#error "Build for being controlled by NetworkManager or wext, please set HAS_WPA_SUPPLICANT=y and HAS_NATIVE_WPA_SUPPLICANT_SUPPORT=y"
110#endif // WPA_SUPPLICANT_SUPPORT //
111#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
112
113#endif // CONFIG_STA_SUPPORT //
114
115
116#ifdef IKANOS_VX_1X0
117#include "vr_ikans.h"
118#endif // IKANOS_VX_1X0 //
119
120#endif // __RT_CONFIG_H__
121
diff --git a/drivers/staging/rt3070/rt_linux.c b/drivers/staging/rt3070/rt_linux.c
new file mode 100644
index 000000000000..bf3385365da1
--- /dev/null
+++ b/drivers/staging/rt3070/rt_linux.c
@@ -0,0 +1,1063 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26 */
27
28#include "rt_config.h"
29
30ULONG RTDebugLevel = RT_DEBUG_ERROR;
31
32BUILD_TIMER_FUNCTION(MlmePeriodicExec);
33//BUILD_TIMER_FUNCTION(MlmeRssiReportExec);
34BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout);
35BUILD_TIMER_FUNCTION(APSDPeriodicExec);
36BUILD_TIMER_FUNCTION(AsicRfTuningExec);
37#ifdef RT2870
38BUILD_TIMER_FUNCTION(BeaconUpdateExec);
39#endif // RT2870 //
40
41
42#ifdef CONFIG_STA_SUPPORT
43BUILD_TIMER_FUNCTION(BeaconTimeout);
44BUILD_TIMER_FUNCTION(ScanTimeout);
45BUILD_TIMER_FUNCTION(AuthTimeout);
46BUILD_TIMER_FUNCTION(AssocTimeout);
47BUILD_TIMER_FUNCTION(ReassocTimeout);
48BUILD_TIMER_FUNCTION(DisassocTimeout);
49BUILD_TIMER_FUNCTION(LinkDownExec);
50#ifdef LEAP_SUPPORT
51BUILD_TIMER_FUNCTION(LeapAuthTimeout);
52#endif
53BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
54BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
55#ifdef QOS_DLS_SUPPORT
56BUILD_TIMER_FUNCTION(DlsTimeoutAction);
57#endif // QOS_DLS_SUPPORT //
58#endif // CONFIG_STA_SUPPORT //
59
60
61
62
63// for wireless system event message
64char const *pWirelessSysEventText[IW_SYS_EVENT_TYPE_NUM] = {
65 // system status event
66 "had associated successfully", /* IW_ASSOC_EVENT_FLAG */
67 "had disassociated", /* IW_DISASSOC_EVENT_FLAG */
68 "had deauthenticated", /* IW_DEAUTH_EVENT_FLAG */
69 "had been aged-out and disassociated", /* IW_AGEOUT_EVENT_FLAG */
70 "occurred CounterMeasures attack", /* IW_COUNTER_MEASURES_EVENT_FLAG */
71 "occurred replay counter different in Key Handshaking", /* IW_REPLAY_COUNTER_DIFF_EVENT_FLAG */
72 "occurred RSNIE different in Key Handshaking", /* IW_RSNIE_DIFF_EVENT_FLAG */
73 "occurred MIC different in Key Handshaking", /* IW_MIC_DIFF_EVENT_FLAG */
74 "occurred ICV error in RX", /* IW_ICV_ERROR_EVENT_FLAG */
75 "occurred MIC error in RX", /* IW_MIC_ERROR_EVENT_FLAG */
76 "Group Key Handshaking timeout", /* IW_GROUP_HS_TIMEOUT_EVENT_FLAG */
77 "Pairwise Key Handshaking timeout", /* IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG */
78 "RSN IE sanity check failure", /* IW_RSNIE_SANITY_FAIL_EVENT_FLAG */
79 "set key done in WPA/WPAPSK", /* IW_SET_KEY_DONE_WPA1_EVENT_FLAG */
80 "set key done in WPA2/WPA2PSK", /* IW_SET_KEY_DONE_WPA2_EVENT_FLAG */
81 "connects with our wireless client", /* IW_STA_LINKUP_EVENT_FLAG */
82 "disconnects with our wireless client", /* IW_STA_LINKDOWN_EVENT_FLAG */
83 "scan completed" /* IW_SCAN_COMPLETED_EVENT_FLAG */
84 "scan terminate!! Busy!! Enqueue fail!!" /* IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG */
85 };
86
87// for wireless IDS_spoof_attack event message
88char const *pWirelessSpoofEventText[IW_SPOOF_EVENT_TYPE_NUM] = {
89 "detected conflict SSID", /* IW_CONFLICT_SSID_EVENT_FLAG */
90 "detected spoofed association response", /* IW_SPOOF_ASSOC_RESP_EVENT_FLAG */
91 "detected spoofed reassociation responses", /* IW_SPOOF_REASSOC_RESP_EVENT_FLAG */
92 "detected spoofed probe response", /* IW_SPOOF_PROBE_RESP_EVENT_FLAG */
93 "detected spoofed beacon", /* IW_SPOOF_BEACON_EVENT_FLAG */
94 "detected spoofed disassociation", /* IW_SPOOF_DISASSOC_EVENT_FLAG */
95 "detected spoofed authentication", /* IW_SPOOF_AUTH_EVENT_FLAG */
96 "detected spoofed deauthentication", /* IW_SPOOF_DEAUTH_EVENT_FLAG */
97 "detected spoofed unknown management frame", /* IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG */
98 "detected replay attack" /* IW_REPLAY_ATTACK_EVENT_FLAG */
99 };
100
101// for wireless IDS_flooding_attack event message
102char const *pWirelessFloodEventText[IW_FLOOD_EVENT_TYPE_NUM] = {
103 "detected authentication flooding", /* IW_FLOOD_AUTH_EVENT_FLAG */
104 "detected association request flooding", /* IW_FLOOD_ASSOC_REQ_EVENT_FLAG */
105 "detected reassociation request flooding", /* IW_FLOOD_REASSOC_REQ_EVENT_FLAG */
106 "detected probe request flooding", /* IW_FLOOD_PROBE_REQ_EVENT_FLAG */
107 "detected disassociation flooding", /* IW_FLOOD_DISASSOC_EVENT_FLAG */
108 "detected deauthentication flooding", /* IW_FLOOD_DEAUTH_EVENT_FLAG */
109 "detected 802.1x eap-request flooding" /* IW_FLOOD_EAP_REQ_EVENT_FLAG */
110 };
111
112
113/* timeout -- ms */
114VOID RTMP_SetPeriodicTimer(
115 IN NDIS_MINIPORT_TIMER *pTimer,
116 IN unsigned long timeout)
117{
118 timeout = ((timeout*HZ) / 1000);
119 pTimer->expires = jiffies + timeout;
120 add_timer(pTimer);
121}
122
123/* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */
124VOID RTMP_OS_Init_Timer(
125 IN PRTMP_ADAPTER pAd,
126 IN NDIS_MINIPORT_TIMER *pTimer,
127 IN TIMER_FUNCTION function,
128 IN PVOID data)
129{
130 init_timer(pTimer);
131 pTimer->data = (unsigned long)data;
132 pTimer->function = function;
133}
134
135
136VOID RTMP_OS_Add_Timer(
137 IN NDIS_MINIPORT_TIMER *pTimer,
138 IN unsigned long timeout)
139{
140 if (timer_pending(pTimer))
141 return;
142
143 timeout = ((timeout*HZ) / 1000);
144 pTimer->expires = jiffies + timeout;
145 add_timer(pTimer);
146}
147
148VOID RTMP_OS_Mod_Timer(
149 IN NDIS_MINIPORT_TIMER *pTimer,
150 IN unsigned long timeout)
151{
152 timeout = ((timeout*HZ) / 1000);
153 mod_timer(pTimer, jiffies + timeout);
154}
155
156VOID RTMP_OS_Del_Timer(
157 IN NDIS_MINIPORT_TIMER *pTimer,
158 OUT BOOLEAN *pCancelled)
159{
160 if (timer_pending(pTimer))
161 {
162 *pCancelled = del_timer_sync(pTimer);
163 }
164 else
165 {
166 *pCancelled = TRUE;
167 }
168
169}
170
171VOID RTMP_OS_Release_Packet(
172 IN PRTMP_ADAPTER pAd,
173 IN PQUEUE_ENTRY pEntry)
174{
175 //RTMPFreeNdisPacket(pAd, (struct sk_buff *)pEntry);
176}
177
178// Unify all delay routine by using udelay
179VOID RTMPusecDelay(
180 IN ULONG usec)
181{
182 ULONG i;
183
184 for (i = 0; i < (usec / 50); i++)
185 udelay(50);
186
187 if (usec % 50)
188 udelay(usec % 50);
189}
190
191void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time)
192{
193 time->u.LowPart = jiffies;
194}
195
196// pAd MUST allow to be NULL
197NDIS_STATUS os_alloc_mem(
198 IN PRTMP_ADAPTER pAd,
199 OUT PUCHAR *mem,
200 IN ULONG size)
201{
202 *mem = (PUCHAR) kmalloc(size, GFP_ATOMIC);
203 if (*mem)
204 return (NDIS_STATUS_SUCCESS);
205 else
206 return (NDIS_STATUS_FAILURE);
207}
208
209// pAd MUST allow to be NULL
210NDIS_STATUS os_free_mem(
211 IN PRTMP_ADAPTER pAd,
212 IN PUCHAR mem)
213{
214
215 ASSERT(mem);
216 kfree(mem);
217 return (NDIS_STATUS_SUCCESS);
218}
219
220
221PNDIS_PACKET RTMP_AllocateFragPacketBuffer(
222 IN PRTMP_ADAPTER pAd,
223 IN ULONG Length)
224{
225 struct sk_buff *pkt;
226
227 pkt = dev_alloc_skb(Length);
228
229 if (pkt == NULL)
230 {
231 DBGPRINT(RT_DEBUG_ERROR, ("can't allocate frag rx %ld size packet\n",Length));
232 }
233
234 if (pkt)
235 {
236 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
237 }
238
239 return (PNDIS_PACKET) pkt;
240}
241
242
243PNDIS_PACKET RTMP_AllocateTxPacketBuffer(
244 IN PRTMP_ADAPTER pAd,
245 IN ULONG Length,
246 IN BOOLEAN Cached,
247 OUT PVOID *VirtualAddress)
248{
249 struct sk_buff *pkt;
250
251 pkt = dev_alloc_skb(Length);
252
253 if (pkt == NULL)
254 {
255 DBGPRINT(RT_DEBUG_ERROR, ("can't allocate tx %ld size packet\n",Length));
256 }
257
258 if (pkt)
259 {
260 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
261 *VirtualAddress = (PVOID) pkt->data;
262 }
263 else
264 {
265 *VirtualAddress = (PVOID) NULL;
266 }
267
268 return (PNDIS_PACKET) pkt;
269}
270
271
272VOID build_tx_packet(
273 IN PRTMP_ADAPTER pAd,
274 IN PNDIS_PACKET pPacket,
275 IN PUCHAR pFrame,
276 IN ULONG FrameLen)
277{
278
279 struct sk_buff *pTxPkt;
280
281 ASSERT(pPacket);
282 pTxPkt = RTPKT_TO_OSPKT(pPacket);
283
284 NdisMoveMemory(skb_put(pTxPkt, FrameLen), pFrame, FrameLen);
285}
286
287VOID RTMPFreeAdapter(
288 IN PRTMP_ADAPTER pAd)
289{
290 POS_COOKIE os_cookie;
291 int index;
292
293 os_cookie=(POS_COOKIE)pAd->OS_Cookie;
294
295 kfree(pAd->BeaconBuf);
296
297
298 NdisFreeSpinLock(&pAd->MgmtRingLock);
299
300
301 for (index =0 ; index < NUM_OF_TX_RING; index++)
302 {
303 NdisFreeSpinLock(&pAd->TxSwQueueLock[index]);
304 NdisFreeSpinLock(&pAd->DeQueueLock[index]);
305 pAd->DeQueueRunning[index] = FALSE;
306 }
307
308 NdisFreeSpinLock(&pAd->irq_lock);
309
310
311 vfree(pAd); // pci_free_consistent(os_cookie->pci_dev,sizeof(RTMP_ADAPTER),pAd,os_cookie->pAd_pa);
312 kfree(os_cookie);
313}
314
315BOOLEAN OS_Need_Clone_Packet(void)
316{
317 return (FALSE);
318}
319
320
321
322/*
323 ========================================================================
324
325 Routine Description:
326 clone an input NDIS PACKET to another one. The new internally created NDIS PACKET
327 must have only one NDIS BUFFER
328 return - byte copied. 0 means can't create NDIS PACKET
329 NOTE: internally created NDIS_PACKET should be destroyed by RTMPFreeNdisPacket
330
331 Arguments:
332 pAd Pointer to our adapter
333 pInsAMSDUHdr EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU.
334 *pSrcTotalLen return total packet length. This lenght is calculated with 802.3 format packet.
335
336 Return Value:
337 NDIS_STATUS_SUCCESS
338 NDIS_STATUS_FAILURE
339
340 Note:
341
342 ========================================================================
343*/
344NDIS_STATUS RTMPCloneNdisPacket(
345 IN PRTMP_ADAPTER pAd,
346 IN BOOLEAN pInsAMSDUHdr,
347 IN PNDIS_PACKET pInPacket,
348 OUT PNDIS_PACKET *ppOutPacket)
349{
350
351 struct sk_buff *pkt;
352
353 ASSERT(pInPacket);
354 ASSERT(ppOutPacket);
355
356 // 1. Allocate a packet
357 pkt = dev_alloc_skb(2048);
358
359 if (pkt == NULL)
360 {
361 return NDIS_STATUS_FAILURE;
362 }
363
364 skb_put(pkt, GET_OS_PKT_LEN(pInPacket));
365 NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket), GET_OS_PKT_LEN(pInPacket));
366 *ppOutPacket = OSPKT_TO_RTPKT(pkt);
367
368
369 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
370
371 printk("###Clone###\n");
372
373 return NDIS_STATUS_SUCCESS;
374}
375
376
377// the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket()
378NDIS_STATUS RTMPAllocateNdisPacket(
379 IN PRTMP_ADAPTER pAd,
380 OUT PNDIS_PACKET *ppPacket,
381 IN PUCHAR pHeader,
382 IN UINT HeaderLen,
383 IN PUCHAR pData,
384 IN UINT DataLen)
385{
386 PNDIS_PACKET pPacket;
387 ASSERT(pData);
388 ASSERT(DataLen);
389
390 // 1. Allocate a packet
391 pPacket = (PNDIS_PACKET *) dev_alloc_skb(HeaderLen + DataLen + TXPADDING_SIZE);
392 if (pPacket == NULL)
393 {
394 *ppPacket = NULL;
395#ifdef DEBUG
396 printk("RTMPAllocateNdisPacket Fail\n\n");
397#endif
398 return NDIS_STATUS_FAILURE;
399 }
400
401 // 2. clone the frame content
402 if (HeaderLen > 0)
403 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket), pHeader, HeaderLen);
404 if (DataLen > 0)
405 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData, DataLen);
406
407 // 3. update length of packet
408 skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen+DataLen);
409
410 RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
411// printk("%s : pPacket = %p, len = %d\n", __FUNCTION__, pPacket, GET_OS_PKT_LEN(pPacket));
412 *ppPacket = pPacket;
413 return NDIS_STATUS_SUCCESS;
414}
415
416/*
417 ========================================================================
418 Description:
419 This routine frees a miniport internally allocated NDIS_PACKET and its
420 corresponding NDIS_BUFFER and allocated memory.
421 ========================================================================
422*/
423VOID RTMPFreeNdisPacket(
424 IN PRTMP_ADAPTER pAd,
425 IN PNDIS_PACKET pPacket)
426{
427 dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket));
428}
429
430
431// IRQL = DISPATCH_LEVEL
432// NOTE: we do have an assumption here, that Byte0 and Byte1 always reasid at the same
433// scatter gather buffer
434NDIS_STATUS Sniff2BytesFromNdisBuffer(
435 IN PNDIS_BUFFER pFirstBuffer,
436 IN UCHAR DesiredOffset,
437 OUT PUCHAR pByte0,
438 OUT PUCHAR pByte1)
439{
440 *pByte0 = *(PUCHAR)(pFirstBuffer + DesiredOffset);
441 *pByte1 = *(PUCHAR)(pFirstBuffer + DesiredOffset + 1);
442
443 return NDIS_STATUS_SUCCESS;
444}
445
446
447void RTMP_QueryPacketInfo(
448 IN PNDIS_PACKET pPacket,
449 OUT PACKET_INFO *pPacketInfo,
450 OUT PUCHAR *pSrcBufVA,
451 OUT UINT *pSrcBufLen)
452{
453 pPacketInfo->BufferCount = 1;
454 pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
455 pPacketInfo->PhysicalBufferCount = 1;
456 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
457
458 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
459 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
460}
461
462void RTMP_QueryNextPacketInfo(
463 IN PNDIS_PACKET *ppPacket,
464 OUT PACKET_INFO *pPacketInfo,
465 OUT PUCHAR *pSrcBufVA,
466 OUT UINT *pSrcBufLen)
467{
468 PNDIS_PACKET pPacket = NULL;
469
470 if (*ppPacket)
471 pPacket = GET_OS_PKT_NEXT(*ppPacket);
472
473 if (pPacket)
474 {
475 pPacketInfo->BufferCount = 1;
476 pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
477 pPacketInfo->PhysicalBufferCount = 1;
478 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
479
480 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
481 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
482 *ppPacket = GET_OS_PKT_NEXT(pPacket);
483 }
484 else
485 {
486 pPacketInfo->BufferCount = 0;
487 pPacketInfo->pFirstBuffer = NULL;
488 pPacketInfo->PhysicalBufferCount = 0;
489 pPacketInfo->TotalPacketLength = 0;
490
491 *pSrcBufVA = NULL;
492 *pSrcBufLen = 0;
493 *ppPacket = NULL;
494 }
495}
496
497// not yet support MBSS
498PNET_DEV get_netdev_from_bssid(
499 IN PRTMP_ADAPTER pAd,
500 IN UCHAR FromWhichBSSID)
501{
502 PNET_DEV dev_p = NULL;
503
504
505#ifdef CONFIG_STA_SUPPORT
506 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
507 {
508 dev_p = pAd->net_dev;
509 }
510#endif // CONFIG_STA_SUPPORT //
511
512 ASSERT(dev_p);
513 return dev_p; /* return one of MBSS */
514}
515
516PNDIS_PACKET DuplicatePacket(
517 IN PRTMP_ADAPTER pAd,
518 IN PNDIS_PACKET pPacket,
519 IN UCHAR FromWhichBSSID)
520{
521 struct sk_buff *skb;
522 PNDIS_PACKET pRetPacket = NULL;
523 USHORT DataSize;
524 UCHAR *pData;
525
526 DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
527 pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
528
529
530 skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG);
531 if (skb)
532 {
533 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
534 pRetPacket = OSPKT_TO_RTPKT(skb);
535 }
536
537 return pRetPacket;
538
539}
540
541PNDIS_PACKET duplicate_pkt(
542 IN PRTMP_ADAPTER pAd,
543 IN PUCHAR pHeader802_3,
544 IN UINT HdrLen,
545 IN PUCHAR pData,
546 IN ULONG DataSize,
547 IN UCHAR FromWhichBSSID)
548{
549 struct sk_buff *skb;
550 PNDIS_PACKET pPacket = NULL;
551
552
553 if ((skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL)
554 {
555 skb_reserve(skb, 2);
556 NdisMoveMemory(skb->tail, pHeader802_3, HdrLen);
557 skb_put(skb, HdrLen);
558 NdisMoveMemory(skb->tail, pData, DataSize);
559 skb_put(skb, DataSize);
560 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
561 pPacket = OSPKT_TO_RTPKT(skb);
562 }
563
564 return pPacket;
565}
566
567
568#define TKIP_TX_MIC_SIZE 8
569PNDIS_PACKET duplicate_pkt_with_TKIP_MIC(
570 IN PRTMP_ADAPTER pAd,
571 IN PNDIS_PACKET pPacket)
572{
573 struct sk_buff *skb, *newskb;
574
575
576 skb = RTPKT_TO_OSPKT(pPacket);
577 if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE)
578 {
579 // alloc a new skb and copy the packet
580 newskb = skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE, GFP_ATOMIC);
581 dev_kfree_skb_any(skb);
582 if (newskb == NULL)
583 {
584 DBGPRINT(RT_DEBUG_ERROR, ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
585 return NULL;
586 }
587 skb = newskb;
588 }
589
590 return OSPKT_TO_RTPKT(skb);
591}
592
593
594
595
596PNDIS_PACKET ClonePacket(
597 IN PRTMP_ADAPTER pAd,
598 IN PNDIS_PACKET pPacket,
599 IN PUCHAR pData,
600 IN ULONG DataSize)
601{
602 struct sk_buff *pRxPkt;
603 struct sk_buff *pClonedPkt;
604
605 ASSERT(pPacket);
606 pRxPkt = RTPKT_TO_OSPKT(pPacket);
607
608 // clone the packet
609 pClonedPkt = skb_clone(pRxPkt, MEM_ALLOC_FLAG);
610
611 if (pClonedPkt)
612 {
613 // set the correct dataptr and data len
614 pClonedPkt->dev = pRxPkt->dev;
615 pClonedPkt->data = pData;
616 pClonedPkt->len = DataSize;
617 pClonedPkt->tail = pClonedPkt->data + pClonedPkt->len;
618 ASSERT(DataSize < 1530);
619 }
620 return pClonedPkt;
621}
622
623//
624// change OS packet DataPtr and DataLen
625//
626void update_os_packet_info(
627 IN PRTMP_ADAPTER pAd,
628 IN RX_BLK *pRxBlk,
629 IN UCHAR FromWhichBSSID)
630{
631 struct sk_buff *pOSPkt;
632
633 ASSERT(pRxBlk->pRxPacket);
634 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
635
636 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
637 pOSPkt->data = pRxBlk->pData;
638 pOSPkt->len = pRxBlk->DataSize;
639 pOSPkt->tail = pOSPkt->data + pOSPkt->len;
640}
641
642
643void wlan_802_11_to_802_3_packet(
644 IN PRTMP_ADAPTER pAd,
645 IN RX_BLK *pRxBlk,
646 IN PUCHAR pHeader802_3,
647 IN UCHAR FromWhichBSSID)
648{
649 struct sk_buff *pOSPkt;
650
651 ASSERT(pRxBlk->pRxPacket);
652 ASSERT(pHeader802_3);
653
654 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
655
656 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
657 pOSPkt->data = pRxBlk->pData;
658 pOSPkt->len = pRxBlk->DataSize;
659 pOSPkt->tail = pOSPkt->data + pOSPkt->len;
660
661 //
662 // copy 802.3 header
663 //
664 //
665
666#ifdef CONFIG_STA_SUPPORT
667 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
668 NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3, LENGTH_802_3);
669#endif // CONFIG_STA_SUPPORT //
670 }
671
672
673
674void announce_802_3_packet(
675 IN PRTMP_ADAPTER pAd,
676 IN PNDIS_PACKET pPacket)
677{
678
679 struct sk_buff *pRxPkt;
680
681 ASSERT(pPacket);
682
683 pRxPkt = RTPKT_TO_OSPKT(pPacket);
684
685#ifdef CONFIG_STA_SUPPORT
686#endif // CONFIG_STA_SUPPORT //
687
688 /* Push up the protocol stack */
689#ifdef IKANOS_VX_1X0
690 IKANOS_DataFrameRx(pAd, pRxPkt->dev, pRxPkt, pRxPkt->len);
691#else
692 pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev);
693
694//#ifdef CONFIG_5VT_ENHANCE
695// *(int*)(pRxPkt->cb) = BRIDGE_TAG;
696//#endif
697 netif_rx(pRxPkt);
698#endif // IKANOS_VX_1X0 //
699}
700
701
702PRTMP_SCATTER_GATHER_LIST
703rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg)
704{
705 sg->NumberOfElements = 1;
706 sg->Elements[0].Address = GET_OS_PKT_DATAPTR(pPacket);
707 sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket);
708 return (sg);
709}
710
711void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen)
712{
713 unsigned char *pt;
714 int x;
715
716 if (RTDebugLevel < RT_DEBUG_TRACE)
717 return;
718
719 pt = pSrcBufVA;
720 printk("%s: %p, len = %d\n",str, pSrcBufVA, SrcBufLen);
721 for (x=0; x<SrcBufLen; x++)
722 {
723 if (x % 16 == 0)
724 printk("0x%04x : ", x);
725 printk("%02x ", ((unsigned char)pt[x]));
726 if (x%16 == 15) printk("\n");
727 }
728 printk("\n");
729}
730
731/*
732 ========================================================================
733
734 Routine Description:
735 Send log message through wireless event
736
737 Support standard iw_event with IWEVCUSTOM. It is used below.
738
739 iwreq_data.data.flags is used to store event_flag that is defined by user.
740 iwreq_data.data.length is the length of the event log.
741
742 The format of the event log is composed of the entry's MAC address and
743 the desired log message (refer to pWirelessEventText).
744
745 ex: 11:22:33:44:55:66 has associated successfully
746
747 p.s. The requirement of Wireless Extension is v15 or newer.
748
749 ========================================================================
750*/
751VOID RTMPSendWirelessEvent(
752 IN PRTMP_ADAPTER pAd,
753 IN USHORT Event_flag,
754 IN PUCHAR pAddr,
755 IN UCHAR BssIdx,
756 IN CHAR Rssi)
757{
758#if WIRELESS_EXT >= 15
759
760 union iwreq_data wrqu;
761 PUCHAR pBuf = NULL, pBufPtr = NULL;
762 USHORT event, type, BufLen;
763 UCHAR event_table_len = 0;
764
765 type = Event_flag & 0xFF00;
766 event = Event_flag & 0x00FF;
767
768 switch (type)
769 {
770 case IW_SYS_EVENT_FLAG_START:
771 event_table_len = IW_SYS_EVENT_TYPE_NUM;
772 break;
773
774 case IW_SPOOF_EVENT_FLAG_START:
775 event_table_len = IW_SPOOF_EVENT_TYPE_NUM;
776 break;
777
778 case IW_FLOOD_EVENT_FLAG_START:
779 event_table_len = IW_FLOOD_EVENT_TYPE_NUM;
780 break;
781 }
782
783 if (event_table_len == 0)
784 {
785 DBGPRINT(RT_DEBUG_ERROR, ("%s : The type(%0x02x) is not valid.\n", __FUNCTION__, type));
786 return;
787 }
788
789 if (event >= event_table_len)
790 {
791 DBGPRINT(RT_DEBUG_ERROR, ("%s : The event(%0x02x) is not valid.\n", __FUNCTION__, event));
792 return;
793 }
794
795 //Allocate memory and copy the msg.
796 if((pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC)) != NULL)
797 {
798 //Prepare the payload
799 memset(pBuf, 0, IW_CUSTOM_MAX_LEN);
800
801 pBufPtr = pBuf;
802
803 if (pAddr)
804 pBufPtr += sprintf(pBufPtr, "(RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) ", PRINT_MAC(pAddr));
805 else if (BssIdx < MAX_MBSSID_NUM)
806 pBufPtr += sprintf(pBufPtr, "(RT2860) BSS(ra%d) ", BssIdx);
807 else
808 pBufPtr += sprintf(pBufPtr, "(RT2860) ");
809
810 if (type == IW_SYS_EVENT_FLAG_START)
811 pBufPtr += sprintf(pBufPtr, "%s", pWirelessSysEventText[event]);
812 else if (type == IW_SPOOF_EVENT_FLAG_START)
813 pBufPtr += sprintf(pBufPtr, "%s (RSSI=%d)", pWirelessSpoofEventText[event], Rssi);
814 else if (type == IW_FLOOD_EVENT_FLAG_START)
815 pBufPtr += sprintf(pBufPtr, "%s", pWirelessFloodEventText[event]);
816 else
817 pBufPtr += sprintf(pBufPtr, "%s", "unknown event");
818
819 pBufPtr[pBufPtr - pBuf] = '\0';
820 BufLen = pBufPtr - pBuf;
821
822 memset(&wrqu, 0, sizeof(wrqu));
823 wrqu.data.flags = Event_flag;
824 wrqu.data.length = BufLen;
825
826 //send wireless event
827 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, pBuf);
828
829 //DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __FUNCTION__, pBuf));
830
831 kfree(pBuf);
832 }
833 else
834 DBGPRINT(RT_DEBUG_ERROR, ("%s : Can't allocate memory for wireless event.\n", __FUNCTION__));
835#else
836 DBGPRINT(RT_DEBUG_ERROR, ("%s : The Wireless Extension MUST be v15 or newer.\n", __FUNCTION__));
837#endif /* WIRELESS_EXT >= 15 */
838}
839
840
841#ifdef CONFIG_STA_SUPPORT
842void send_monitor_packets(
843 IN PRTMP_ADAPTER pAd,
844 IN RX_BLK *pRxBlk)
845{
846 struct sk_buff *pOSPkt;
847 wlan_ng_prism2_header *ph;
848 int rate_index = 0;
849 USHORT header_len = 0;
850 UCHAR temp_header[40] = {0};
851
852 u_int32_t ralinkrate[256] = {2,4,11,22, 12,18,24,36,48,72,96, 108, 109, 110, 111, 112, 13, 26, 39, 52,78,104, 117, 130, 26, 52, 78,104, 156, 208, 234, 260, 27, 54,81,108,162, 216, 243, 270, // Last 38
853 54, 108, 162, 216, 324, 432, 486, 540, 14, 29, 43, 57, 87, 115, 130, 144, 29, 59,87,115, 173, 230,260, 288, 30, 60,90,120,180,240,270,300,60,120,180,240,360,480,540,600, 0,1,2,3,4,5,6,7,8,9,10,
854 11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80};
855
856
857 ASSERT(pRxBlk->pRxPacket);
858 if (pRxBlk->DataSize < 10)
859 {
860 DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too small! (%d)\n", __FUNCTION__, pRxBlk->DataSize));
861 goto err_free_sk_buff;
862 }
863
864 if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE)
865 {
866 DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%d)\n", __FUNCTION__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
867 goto err_free_sk_buff;
868 }
869
870 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
871 pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0);
872 if (pRxBlk->pHeader->FC.Type == BTYPE_DATA)
873 {
874 pRxBlk->DataSize -= LENGTH_802_11;
875 if ((pRxBlk->pHeader->FC.ToDs == 1) &&
876 (pRxBlk->pHeader->FC.FrDs == 1))
877 header_len = LENGTH_802_11_WITH_ADDR4;
878 else
879 header_len = LENGTH_802_11;
880
881 // QOS
882 if (pRxBlk->pHeader->FC.SubType & 0x08)
883 {
884 header_len += 2;
885 // Data skip QOS contorl field
886 pRxBlk->DataSize -=2;
887 }
888
889 // Order bit: A-Ralink or HTC+
890 if (pRxBlk->pHeader->FC.Order)
891 {
892 header_len += 4;
893 // Data skip HTC contorl field
894 pRxBlk->DataSize -= 4;
895 }
896
897 // Copy Header
898 if (header_len <= 40)
899 NdisMoveMemory(temp_header, pRxBlk->pData, header_len);
900
901 // skip HW padding
902 if (pRxBlk->RxD.L2PAD)
903 pRxBlk->pData += (header_len + 2);
904 else
905 pRxBlk->pData += header_len;
906 } //end if
907
908
909 if (pRxBlk->DataSize < pOSPkt->len) {
910 skb_trim(pOSPkt,pRxBlk->DataSize);
911 } else {
912 skb_put(pOSPkt,(pRxBlk->DataSize - pOSPkt->len));
913 } //end if
914
915 if ((pRxBlk->pData - pOSPkt->data) > 0) {
916 skb_put(pOSPkt,(pRxBlk->pData - pOSPkt->data));
917 skb_pull(pOSPkt,(pRxBlk->pData - pOSPkt->data));
918 } //end if
919
920 if (skb_headroom(pOSPkt) < (sizeof(wlan_ng_prism2_header)+ header_len)) {
921 if (pskb_expand_head(pOSPkt, (sizeof(wlan_ng_prism2_header) + header_len), 0, GFP_ATOMIC)) {
922 DBGPRINT(RT_DEBUG_ERROR, ("%s : Reallocate header size of sk_buff fail!\n", __FUNCTION__));
923 goto err_free_sk_buff;
924 } //end if
925 } //end if
926
927 if (header_len > 0)
928 NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header, header_len);
929
930 ph = (wlan_ng_prism2_header *) skb_push(pOSPkt, sizeof(wlan_ng_prism2_header));
931 NdisZeroMemory(ph, sizeof(wlan_ng_prism2_header));
932
933 ph->msgcode = DIDmsg_lnxind_wlansniffrm;
934 ph->msglen = sizeof(wlan_ng_prism2_header);
935 strcpy(ph->devname, pAd->net_dev->name);
936
937 ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
938 ph->hosttime.status = 0;
939 ph->hosttime.len = 4;
940 ph->hosttime.data = jiffies;
941
942 ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
943 ph->mactime.status = 0;
944 ph->mactime.len = 0;
945 ph->mactime.data = 0;
946
947 ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
948 ph->istx.status = 0;
949 ph->istx.len = 0;
950 ph->istx.data = 0;
951
952 ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
953 ph->channel.status = 0;
954 ph->channel.len = 4;
955
956 ph->channel.data = (u_int32_t)pAd->CommonCfg.Channel;
957
958 ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
959 ph->rssi.status = 0;
960 ph->rssi.len = 4;
961 ph->rssi.data = (u_int32_t)RTMPMaxRssi(pAd, ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI0, RSSI_0), ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI1, RSSI_1), ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI2, RSSI_2));;
962
963 ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
964 ph->signal.status = 0;
965 ph->signal.len = 4;
966 ph->signal.data = 0; //rssi + noise;
967
968 ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
969 ph->noise.status = 0;
970 ph->noise.len = 4;
971 ph->noise.data = 0;
972
973#ifdef DOT11_N_SUPPORT
974 if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX)
975 {
976 rate_index = 16 + ((UCHAR)pRxBlk->pRxWI->BW *16) + ((UCHAR)pRxBlk->pRxWI->ShortGI *32) + ((UCHAR)pRxBlk->pRxWI->MCS);
977 }
978 else
979#endif // DOT11_N_SUPPORT //
980 if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM)
981 rate_index = (UCHAR)(pRxBlk->pRxWI->MCS) + 4;
982 else
983 rate_index = (UCHAR)(pRxBlk->pRxWI->MCS);
984 if (rate_index < 0)
985 rate_index = 0;
986 if (rate_index > 255)
987 rate_index = 255;
988
989 ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
990 ph->rate.status = 0;
991 ph->rate.len = 4;
992 ph->rate.data = ralinkrate[rate_index];
993
994 ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
995 ph->frmlen.status = 0;
996 ph->frmlen.len = 4;
997 ph->frmlen.data = (u_int32_t)pRxBlk->DataSize;
998
999
1000 pOSPkt->pkt_type = PACKET_OTHERHOST;
1001 pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev);
1002 pOSPkt->ip_summed = CHECKSUM_NONE;
1003 netif_rx(pOSPkt);
1004
1005 return;
1006
1007err_free_sk_buff:
1008 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
1009 return;
1010
1011}
1012#endif // CONFIG_STA_SUPPORT //
1013
1014
1015void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify)
1016{
1017
1018#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1019 daemonize(pThreadName /*"%s",pAd->net_dev->name*/);
1020
1021 allow_signal(SIGTERM);
1022 allow_signal(SIGKILL);
1023 current->flags |= PF_NOFREEZE;
1024#else
1025 unsigned long flags;
1026
1027 daemonize();
1028 reparent_to_init();
1029 strcpy(current->comm, pThreadName);
1030
1031 siginitsetinv(&current->blocked, sigmask(SIGTERM) | sigmask(SIGKILL));
1032
1033 /* Allow interception of SIGKILL only
1034 * Don't allow other signals to interrupt the transmission */
1035#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22)
1036 spin_lock_irqsave(&current->sigmask_lock, flags);
1037 flush_signals(current);
1038 recalc_sigpending(current);
1039 spin_unlock_irqrestore(&current->sigmask_lock, flags);
1040#endif
1041#endif
1042
1043 /* signal that we've started the thread */
1044 complete(pNotify);
1045
1046}
1047
1048void RTMP_IndicateMediaState(
1049 IN PRTMP_ADAPTER pAd)
1050{
1051 if (pAd->CommonCfg.bWirelessEvent)
1052 {
1053 if (pAd->IndicateMediaState == NdisMediaStateConnected)
1054 {
1055 RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1056 }
1057 else
1058 {
1059 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1060 }
1061 }
1062}
1063
diff --git a/drivers/staging/rt3070/rt_linux.h b/drivers/staging/rt3070/rt_linux.h
new file mode 100644
index 000000000000..0540d02da79b
--- /dev/null
+++ b/drivers/staging/rt3070/rt_linux.h
@@ -0,0 +1,887 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26 */
27
28/***********************************************************************/
29/* */
30/* Program: rt_linux.c */
31/* Created: 4/21/2006 1:17:38 PM */
32/* Author: Wu Xi-Kun */
33/* Comments: `description` */
34/* */
35/*---------------------------------------------------------------------*/
36/* */
37/* History: */
38/* Revision 1.1 4/21/2006 1:17:38 PM xsikun */
39/* Initial revision */
40/* */
41/***********************************************************************/
42
43#include "rtmp_type.h"
44#include <linux/module.h>
45#include <linux/version.h>
46#include <linux/kernel.h>
47
48#include <linux/spinlock.h>
49#include <linux/init.h>
50#include <linux/string.h>
51#include <linux/timer.h>
52#include <linux/errno.h>
53#include <linux/slab.h>
54#include <linux/interrupt.h>
55#include <linux/pci.h>
56#include <linux/netdevice.h>
57#include <linux/etherdevice.h>
58#include <linux/skbuff.h>
59#include <linux/ethtool.h>
60#include <linux/wireless.h>
61#include <linux/proc_fs.h>
62#include <linux/delay.h>
63#include <linux/if_arp.h>
64#include <linux/ctype.h>
65#include <linux/vmalloc.h>
66
67
68#include <linux/wireless.h>
69#include <net/iw_handler.h>
70
71// load firmware
72#define __KERNEL_SYSCALLS__
73#include <linux/unistd.h>
74#include <asm/uaccess.h>
75
76
77#define MEM_ALLOC_FLAG (GFP_ATOMIC) //(GFP_DMA | GFP_ATOMIC)
78
79#ifndef IFNAMSIZ
80#define IFNAMSIZ 16
81#endif
82
83//#define CONFIG_CKIP_SUPPORT
84
85#undef __inline
86#define __inline static inline
87
88typedef int (*HARD_START_XMIT_FUNC)(struct sk_buff *skb, struct net_device *net_dev);
89
90// add by kathy
91
92#ifdef CONFIG_STA_SUPPORT
93
94#ifdef RT2870
95#define STA_PROFILE_PATH "/etc/Wireless/RT2870STA/RT2870STA.dat"
96#define STA_RT2870_IMAGE_FILE_NAME "/etc/Wireless/RT2870STA/rt2870.bin"
97#define STA_NIC_DEVICE_NAME "RT2870STA"
98#define STA_DRIVER_VERSION "2.0.1.0"
99#ifdef MULTIPLE_CARD_SUPPORT
100#define CARD_INFO_PATH "/etc/Wireless/RT2870STA/RT2870STACard.dat"
101#endif // MULTIPLE_CARD_SUPPORT //
102#endif // RT2870 //
103
104#endif // CONFIG_STA_SUPPORT //
105
106
107#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
108
109#define RTMP_TIME_AFTER(a,b) \
110 (typecheck(unsigned long, (unsigned long)a) && \
111 typecheck(unsigned long, (unsigned long)b) && \
112 ((long)(b) - (long)(a) < 0))
113
114#define RTMP_TIME_AFTER_EQ(a,b) \
115 (typecheck(unsigned long, (unsigned long)a) && \
116 typecheck(unsigned long, (unsigned long)b) && \
117 ((long)(a) - (long)(b) >= 0))
118#define RTMP_TIME_BEFORE(a,b) RTMP_TIME_AFTER_EQ(b,a)
119#else
120#define RTMP_TIME_AFTER(a,b) time_after(a, b)
121#endif
122
123#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
124#define RT_MOD_INC_USE_COUNT() \
125 if (!try_module_get(THIS_MODULE)) \
126 { \
127 DBGPRINT(RT_DEBUG_ERROR, ("%s: cannot reserve module\n", __FUNCTION__)); \
128 return -1; \
129 }
130
131#define RT_MOD_DEC_USE_COUNT() module_put(THIS_MODULE);
132#else
133#define RT_MOD_INC_USE_COUNT() MOD_INC_USE_COUNT;
134#define RT_MOD_DEC_USE_COUNT() MOD_DEC_USE_COUNT;
135#endif
136
137#define OS_HZ HZ
138
139#define ETH_LENGTH_OF_ADDRESS 6
140
141#define IN
142#define OUT
143
144#define NDIS_STATUS INT
145#define NDIS_STATUS_SUCCESS 0x00
146#define NDIS_STATUS_FAILURE 0x01
147#define NDIS_STATUS_INVALID_DATA 0x02
148#define NDIS_STATUS_RESOURCES 0x03
149
150#define MIN_NET_DEVICE_FOR_AID 0x00 //0x00~0x3f
151#define MIN_NET_DEVICE_FOR_MBSSID 0x00 //0x00,0x10,0x20,0x30
152#define MIN_NET_DEVICE_FOR_WDS 0x10 //0x40,0x50,0x60,0x70
153#define MIN_NET_DEVICE_FOR_APCLI 0x20
154#define MIN_NET_DEVICE_FOR_MESH 0x30
155#ifdef CONFIG_STA_SUPPORT
156#define MIN_NET_DEVICE_FOR_DLS 0x40
157#endif // CONFIG_STA_SUPPORT //
158
159
160#ifdef CONFIG_STA_SUPPORT
161#define NDIS_PACKET_TYPE_DIRECTED 0
162#define NDIS_PACKET_TYPE_MULTICAST 1
163#define NDIS_PACKET_TYPE_BROADCAST 2
164#define NDIS_PACKET_TYPE_ALL_MULTICAST 3
165#endif // CONFIG_STA_SUPPORT //
166
167struct os_lock {
168 spinlock_t lock;
169 unsigned long flags;
170};
171
172
173struct os_cookie {
174
175#ifdef RT2870
176 struct usb_device *pUsb_Dev;
177
178 struct pid * MLMEThr_pid;
179 struct pid * RTUSBCmdThr_pid;
180 struct pid * TimerQThr_pid;
181#endif // RT2870 //
182
183 struct tasklet_struct rx_done_task;
184 struct tasklet_struct mgmt_dma_done_task;
185 struct tasklet_struct ac0_dma_done_task;
186 struct tasklet_struct ac1_dma_done_task;
187 struct tasklet_struct ac2_dma_done_task;
188 struct tasklet_struct ac3_dma_done_task;
189 struct tasklet_struct hcca_dma_done_task;
190 struct tasklet_struct tbtt_task;
191#ifdef RT2870
192 struct tasklet_struct null_frame_complete_task;
193 struct tasklet_struct rts_frame_complete_task;
194 struct tasklet_struct pspoll_frame_complete_task;
195#endif // RT2870 //
196
197
198 unsigned long apd_pid; //802.1x daemon pid
199 INT ioctl_if_type;
200 INT ioctl_if;
201};
202
203typedef struct _VIRTUAL_ADAPTER
204{
205 struct net_device *RtmpDev;
206 struct net_device *VirtualDev;
207} VIRTUAL_ADAPTER, PVIRTUAL_ADAPTER;
208
209#undef ASSERT
210#define ASSERT(x) \
211{ \
212 if (!(x)) \
213 { \
214 printk(KERN_WARNING __FILE__ ":%d assert " #x "failed\n", __LINE__); \
215 } \
216}
217
218typedef struct os_cookie * POS_COOKIE;
219typedef struct pci_dev * PPCI_DEV;
220typedef struct net_device * PNET_DEV;
221typedef void * PNDIS_PACKET;
222typedef char NDIS_PACKET;
223typedef PNDIS_PACKET * PPNDIS_PACKET;
224typedef dma_addr_t NDIS_PHYSICAL_ADDRESS;
225typedef dma_addr_t * PNDIS_PHYSICAL_ADDRESS;
226//typedef struct timer_list RALINK_TIMER_STRUCT;
227//typedef struct timer_list * PRALINK_TIMER_STRUCT;
228//typedef struct os_lock NDIS_SPIN_LOCK;
229typedef spinlock_t NDIS_SPIN_LOCK;
230typedef struct timer_list NDIS_MINIPORT_TIMER;
231typedef void * NDIS_HANDLE;
232typedef char * PNDIS_BUFFER;
233
234
235
236void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen);
237
238dma_addr_t linux_pci_map_single(void *handle, void *ptr, size_t size, int sd_idx, int direction);
239void linux_pci_unmap_single(void *handle, dma_addr_t dma_addr, size_t size, int direction);
240
241
242////////////////////////////////////////
243// MOVE TO rtmp.h ?
244/////////////////////////////////////////
245#define PKTSRC_NDIS 0x7f
246#define PKTSRC_DRIVER 0x0f
247#define PRINT_MAC(addr) \
248 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]
249
250
251#define RT2860_PCI_DEVICE_ID 0x0601
252
253#ifdef RT2870
254#define PCI_MAP_SINGLE(_handle, _ptr, _size, _dir) (ULONG)0
255
256#define PCI_UNMAP_SINGLE(_handle, _ptr, _size, _dir)
257#endif // RT2870 //
258
259
260#define BEACON_FRAME_DMA_CACHE_WBACK(_ptr, _size) \
261 dma_cache_wback(_ptr, _size)
262
263
264//////////////////////////////////////////
265//
266//////////////////////////////////////////
267
268
269#define NdisMIndicateStatus(_w, _x, _y, _z)
270
271
272typedef struct timer_list RTMP_OS_TIMER;
273
274#ifdef RT2870
275/* ----------------- Timer Related MARCO ---------------*/
276// In RT2870, we have a lot of timer functions and will read/write register, it's
277// not allowed in Linux USB sub-system to do it ( because of sleep issue when submit
278// to ctrl pipe). So we need a wrapper function to take care it.
279
280typedef VOID (*RT2870_TIMER_HANDLE)(
281 IN PVOID SystemSpecific1,
282 IN PVOID FunctionContext,
283 IN PVOID SystemSpecific2,
284 IN PVOID SystemSpecific3);
285#endif // RT2870 //
286
287
288typedef struct _RALINK_TIMER_STRUCT {
289 RTMP_OS_TIMER TimerObj; // Ndis Timer object
290 BOOLEAN Valid; // Set to True when call RTMPInitTimer
291 BOOLEAN State; // True if timer cancelled
292 BOOLEAN PeriodicType; // True if timer is periodic timer
293 BOOLEAN Repeat; // True if periodic timer
294 ULONG TimerValue; // Timer value in milliseconds
295 ULONG cookie; // os specific object
296#ifdef RT2870
297 RT2870_TIMER_HANDLE handle;
298 void *pAd;
299#endif // RT2870 //
300} RALINK_TIMER_STRUCT, *PRALINK_TIMER_STRUCT;
301
302
303#ifdef RT2870
304
305typedef enum _RT2870_KERNEL_THREAD_STATUS_
306{
307 RT2870_THREAD_UNKNOWN = 0,
308 RT2870_THREAD_INITED = 1,
309 RT2870_THREAD_RUNNING = 2,
310 RT2870_THREAD_STOPED = 4,
311}RT2870_KERNEL_THREAD_STATUS;
312
313#define RT2870_THREAD_CAN_DO_INSERT (RT2870_THREAD_INITED |RT2870_THREAD_RUNNING)
314
315typedef struct _RT2870_TIMER_ENTRY_
316{
317 RALINK_TIMER_STRUCT *pRaTimer;
318 struct _RT2870_TIMER_ENTRY_ *pNext;
319}RT2870_TIMER_ENTRY;
320
321
322#define TIMER_QUEUE_SIZE_MAX 128
323typedef struct _RT2870_TIMER_QUEUE_
324{
325 unsigned int status;
326 //wait_queue_head_t timerWaitQ;
327 //atomic_t count;
328 UCHAR *pTimerQPoll;
329 RT2870_TIMER_ENTRY *pQPollFreeList;
330 RT2870_TIMER_ENTRY *pQHead;
331 RT2870_TIMER_ENTRY *pQTail;
332}RT2870_TIMER_QUEUE;
333#endif // RT2870 //
334
335
336//#define DBG 1
337
338//
339// MACRO for debugging information
340//
341
342#ifdef DBG
343extern ULONG RTDebugLevel;
344
345#define DBGPRINT_RAW(Level, Fmt) \
346{ \
347 if (Level <= RTDebugLevel) \
348 { \
349 printk Fmt; \
350 } \
351}
352
353#define DBGPRINT(Level, Fmt) DBGPRINT_RAW(Level, Fmt)
354
355
356#define DBGPRINT_ERR(Fmt) \
357{ \
358 printk("ERROR!!! "); \
359 printk Fmt; \
360}
361
362#define DBGPRINT_S(Status, Fmt) \
363{ \
364 printk Fmt; \
365}
366
367
368#else
369#define DBGPRINT(Level, Fmt)
370#define DBGPRINT_RAW(Level, Fmt)
371#define DBGPRINT_S(Status, Fmt)
372#define DBGPRINT_ERR(Fmt)
373#endif
374
375
376//
377// spin_lock enhanced for Nested spin lock
378//
379#define NdisAllocateSpinLock(__lock) \
380{ \
381 spin_lock_init((spinlock_t *)(__lock)); \
382}
383
384#define NdisFreeSpinLock(lock) \
385{ \
386}
387
388
389#define RTMP_SEM_LOCK(__lock) \
390{ \
391 spin_lock_bh((spinlock_t *)(__lock)); \
392}
393
394#define RTMP_SEM_UNLOCK(__lock) \
395{ \
396 spin_unlock_bh((spinlock_t *)(__lock)); \
397}
398
399// sample, use semaphore lock to replace IRQ lock, 2007/11/15
400#define RTMP_IRQ_LOCK(__lock, __irqflags) \
401{ \
402 __irqflags = 0; \
403 spin_lock_bh((spinlock_t *)(__lock)); \
404 pAd->irq_disabled |= 1; \
405}
406
407#define RTMP_IRQ_UNLOCK(__lock, __irqflag) \
408{ \
409 pAd->irq_disabled &= 0; \
410 spin_unlock_bh((spinlock_t *)(__lock)); \
411}
412
413#define RTMP_INT_LOCK(__lock, __irqflags) \
414{ \
415 spin_lock_irqsave((spinlock_t *)__lock, __irqflags); \
416}
417
418#define RTMP_INT_UNLOCK(__lock, __irqflag) \
419{ \
420 spin_unlock_irqrestore((spinlock_t *)(__lock), ((unsigned long)__irqflag)); \
421}
422
423#ifdef RT2870
424#define RTMP_IO_READ32(_A, _R, _pV) \
425 RTUSBReadMACRegister(_A, _R, _pV)
426
427#define RTMP_IO_READ8(_A, _R, _pV) \
428{ \
429}
430
431#define RTMP_IO_WRITE32(_A, _R, _V) \
432 RTUSBWriteMACRegister(_A, _R, _V)
433
434
435#define RTMP_IO_WRITE8(_A, _R, _V) \
436{ \
437 USHORT _Val = _V; \
438 RTUSBSingleWrite(_A, _R, _Val); \
439}
440
441
442#define RTMP_IO_WRITE16(_A, _R, _V) \
443{ \
444 RTUSBSingleWrite(_A, _R, _V); \
445}
446#endif // RT2870 //
447
448#ifndef wait_event_interruptible_timeout
449#define __wait_event_interruptible_timeout(wq, condition, ret) \
450do { \
451 wait_queue_t __wait; \
452 init_waitqueue_entry(&__wait, current); \
453 add_wait_queue(&wq, &__wait); \
454 for (;;) { \
455 set_current_state(TASK_INTERRUPTIBLE); \
456 if (condition) \
457 break; \
458 if (!signal_pending(current)) { \
459 ret = schedule_timeout(ret); \
460 if (!ret) \
461 break; \
462 continue; \
463 } \
464 ret = -ERESTARTSYS; \
465 break; \
466 } \
467 current->state = TASK_RUNNING; \
468 remove_wait_queue(&wq, &__wait); \
469} while (0)
470
471#define wait_event_interruptible_timeout(wq, condition, timeout) \
472({ \
473 long __ret = timeout; \
474 if (!(condition)) \
475 __wait_event_interruptible_timeout(wq, condition, __ret); \
476 __ret; \
477})
478#endif
479#define ONE_TICK 1
480#define OS_WAIT(_time) \
481{ int _i; \
482 long _loop = ((_time)/(1000/OS_HZ)) > 0 ? ((_time)/(1000/OS_HZ)) : 1;\
483 wait_queue_head_t _wait; \
484 init_waitqueue_head(&_wait); \
485 for (_i=0; _i<(_loop); _i++) \
486 wait_event_interruptible_timeout(_wait, 0, ONE_TICK); }
487
488
489/* Modified by Wu Xi-Kun 4/21/2006 */
490typedef void (*TIMER_FUNCTION)(unsigned long);
491
492#define COPY_MAC_ADDR(Addr1, Addr2) memcpy((Addr1), (Addr2), MAC_ADDR_LEN)
493
494#define MlmeAllocateMemory(_pAd, _ppVA) os_alloc_mem(_pAd, _ppVA, MGMT_DMA_BUFFER_SIZE)
495#define MlmeFreeMemory(_pAd, _pVA) os_free_mem(_pAd, _pVA)
496
497
498#ifdef RT2870
499#define BUILD_TIMER_FUNCTION(_func) \
500void linux_##_func(unsigned long data) \
501{ \
502 PRALINK_TIMER_STRUCT _pTimer = (PRALINK_TIMER_STRUCT)data; \
503 RT2870_TIMER_ENTRY *_pQNode; \
504 RTMP_ADAPTER *_pAd; \
505 \
506 _pTimer->handle = _func; \
507 _pAd = (RTMP_ADAPTER *)_pTimer->pAd; \
508 _pQNode = RT2870_TimerQ_Insert(_pAd, _pTimer); \
509 if ((_pQNode == NULL) && (_pAd->TimerQ.status & RT2870_THREAD_CAN_DO_INSERT)) \
510 RTMP_OS_Add_Timer(&_pTimer->TimerObj, HZ); \
511}
512#endif // RT2870 //
513
514
515#define DECLARE_TIMER_FUNCTION(_func) \
516void linux_##_func(unsigned long data)
517
518#define GET_TIMER_FUNCTION(_func) \
519 linux_##_func
520
521DECLARE_TIMER_FUNCTION(MlmePeriodicExec);
522DECLARE_TIMER_FUNCTION(MlmeRssiReportExec);
523DECLARE_TIMER_FUNCTION(AsicRxAntEvalTimeout);
524DECLARE_TIMER_FUNCTION(APSDPeriodicExec);
525DECLARE_TIMER_FUNCTION(AsicRfTuningExec);
526#ifdef RT2870
527DECLARE_TIMER_FUNCTION(BeaconUpdateExec);
528#endif // RT2870 //
529
530
531#ifdef CONFIG_STA_SUPPORT
532DECLARE_TIMER_FUNCTION(BeaconTimeout);
533DECLARE_TIMER_FUNCTION(ScanTimeout);
534DECLARE_TIMER_FUNCTION(AuthTimeout);
535DECLARE_TIMER_FUNCTION(AssocTimeout);
536DECLARE_TIMER_FUNCTION(ReassocTimeout);
537DECLARE_TIMER_FUNCTION(DisassocTimeout);
538DECLARE_TIMER_FUNCTION(LinkDownExec);
539#ifdef LEAP_SUPPORT
540DECLARE_TIMER_FUNCTION(LeapAuthTimeout);
541#endif
542DECLARE_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
543DECLARE_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
544DECLARE_TIMER_FUNCTION(PsPollWakeExec);
545DECLARE_TIMER_FUNCTION(RadioOnExec);
546
547#ifdef QOS_DLS_SUPPORT
548DECLARE_TIMER_FUNCTION(DlsTimeoutAction);
549#endif // QOS_DLS_SUPPORT //
550#endif // CONFIG_STA_SUPPORT //
551
552#undef AP_WSC_INCLUDED
553#undef STA_WSC_INCLUDED
554#undef WSC_INCLUDED
555
556
557#ifdef CONFIG_STA_SUPPORT
558#endif // CONFIG_STA_SUPPORT //
559
560#if defined(AP_WSC_INCLUDED) || defined(STA_WSC_INCLUDED)
561#define WSC_INCLUDED
562#endif
563
564
565
566void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time);
567
568
569/*
570 * packet helper
571 * - convert internal rt packet to os packet or
572 * os packet to rt packet
573 */
574#define RTPKT_TO_OSPKT(_p) ((struct sk_buff *)(_p))
575#define OSPKT_TO_RTPKT(_p) ((PNDIS_PACKET)(_p))
576
577#define GET_OS_PKT_DATAPTR(_pkt) \
578 (RTPKT_TO_OSPKT(_pkt)->data)
579
580#define GET_OS_PKT_LEN(_pkt) \
581 (RTPKT_TO_OSPKT(_pkt)->len)
582
583#define GET_OS_PKT_DATATAIL(_pkt) \
584 (RTPKT_TO_OSPKT(_pkt)->tail)
585
586#define GET_OS_PKT_HEAD(_pkt) \
587 (RTPKT_TO_OSPKT(_pkt)->head)
588
589#define GET_OS_PKT_END(_pkt) \
590 (RTPKT_TO_OSPKT(_pkt)->end)
591
592#define GET_OS_PKT_NETDEV(_pkt) \
593 (RTPKT_TO_OSPKT(_pkt)->dev)
594
595#define GET_OS_PKT_TYPE(_pkt) \
596 (RTPKT_TO_OSPKT(_pkt))
597
598#define GET_OS_PKT_NEXT(_pkt) \
599 (RTPKT_TO_OSPKT(_pkt)->next)
600
601
602#define OS_NTOHS(_Val) \
603 (ntohs(_Val))
604#define OS_HTONS(_Val) \
605 (htons(_Val))
606#define OS_NTOHL(_Val) \
607 (ntohl(_Val))
608#define OS_HTONL(_Val) \
609 (htonl(_Val))
610
611/* statistics counter */
612#define STATS_INC_RX_PACKETS(_pAd, _dev)
613#define STATS_INC_TX_PACKETS(_pAd, _dev)
614
615#define STATS_INC_RX_BYTESS(_pAd, _dev, len)
616#define STATS_INC_TX_BYTESS(_pAd, _dev, len)
617
618#define STATS_INC_RX_ERRORS(_pAd, _dev)
619#define STATS_INC_TX_ERRORS(_pAd, _dev)
620
621#define STATS_INC_RX_DROPPED(_pAd, _dev)
622#define STATS_INC_TX_DROPPED(_pAd, _dev)
623
624
625#define CB_OFF 10
626
627
628// check DDK NDIS_PACKET data structure and find out only MiniportReservedEx[0..7] can be used by our driver without
629// ambiguity. Fields after pPacket->MiniportReservedEx[8] may be used by other wrapper layer thus crashes the driver
630//
631//#define RTMP_GET_PACKET_MR(_p) (RTPKT_TO_OSPKT(_p))
632
633// User Priority
634#define RTMP_SET_PACKET_UP(_p, _prio) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+0] = _prio)
635#define RTMP_GET_PACKET_UP(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+0])
636
637// Fragment #
638#define RTMP_SET_PACKET_FRAGMENTS(_p, _num) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+1] = _num)
639#define RTMP_GET_PACKET_FRAGMENTS(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+1])
640
641// 0x0 ~0x7f: TX to AP's own BSS which has the specified AID. if AID>127, set bit 7 in RTMP_SET_PACKET_EMACTAB too.
642//(this value also as MAC(on-chip WCID) table index)
643// 0x80~0xff: TX to a WDS link. b0~6: WDS index
644#define RTMP_SET_PACKET_WCID(_p, _wdsidx) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+2] = _wdsidx)
645#define RTMP_GET_PACKET_WCID(_p) ((UCHAR)(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+2]))
646
647// 0xff: PKTSRC_NDIS, others: local TX buffer index. This value affects how to a packet
648#define RTMP_SET_PACKET_SOURCE(_p, _pktsrc) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+3] = _pktsrc)
649#define RTMP_GET_PACKET_SOURCE(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+3])
650
651// RTS/CTS-to-self protection method
652#define RTMP_SET_PACKET_RTS(_p, _num) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+4] = _num)
653#define RTMP_GET_PACKET_RTS(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+4])
654// see RTMP_S(G)ET_PACKET_EMACTAB
655
656// TX rate index
657#define RTMP_SET_PACKET_TXRATE(_p, _rate) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+5] = _rate)
658#define RTMP_GET_PACKET_TXRATE(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+5])
659
660// From which Interface
661#define RTMP_SET_PACKET_IF(_p, _ifdx) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+6] = _ifdx)
662#define RTMP_GET_PACKET_IF(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+6])
663#define RTMP_SET_PACKET_NET_DEVICE_MBSSID(_p, _bss) RTMP_SET_PACKET_IF((_p), (_bss))
664#define RTMP_SET_PACKET_NET_DEVICE_WDS(_p, _bss) RTMP_SET_PACKET_IF((_p), ((_bss) + MIN_NET_DEVICE_FOR_WDS))
665#define RTMP_SET_PACKET_NET_DEVICE_APCLI(_p, _idx) RTMP_SET_PACKET_IF((_p), ((_idx) + MIN_NET_DEVICE_FOR_APCLI))
666#define RTMP_SET_PACKET_NET_DEVICE_MESH(_p, _idx) RTMP_SET_PACKET_IF((_p), ((_idx) + MIN_NET_DEVICE_FOR_MESH))
667#define RTMP_GET_PACKET_NET_DEVICE_MBSSID(_p) RTMP_GET_PACKET_IF((_p))
668#define RTMP_GET_PACKET_NET_DEVICE(_p) RTMP_GET_PACKET_IF((_p))
669
670#define RTMP_SET_PACKET_MOREDATA(_p, _morebit) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+7] = _morebit)
671#define RTMP_GET_PACKET_MOREDATA(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+7])
672
673//#define RTMP_SET_PACKET_NET_DEVICE_MBSSID(_p, _bss) (RTPKT_TO_OSPKT(_p)->cb[8] = _bss)
674//#define RTMP_GET_PACKET_NET_DEVICE_MBSSID(_p) (RTPKT_TO_OSPKT(_p)->cb[8])
675
676//
677// Sepcific Pakcet Type definition
678//
679#define RTMP_PACKET_SPECIFIC_CB_OFFSET 11
680
681#define RTMP_PACKET_SPECIFIC_DHCP 0x01
682#define RTMP_PACKET_SPECIFIC_EAPOL 0x02
683#define RTMP_PACKET_SPECIFIC_IPV4 0x04
684#define RTMP_PACKET_SPECIFIC_WAI 0x08
685#define RTMP_PACKET_SPECIFIC_VLAN 0x10
686#define RTMP_PACKET_SPECIFIC_LLCSNAP 0x20
687
688//Specific
689#define RTMP_SET_PACKET_SPECIFIC(_p, _flg) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] = _flg)
690
691//DHCP
692#define RTMP_SET_PACKET_DHCP(_p, _flg) \
693 do{ \
694 if (_flg) \
695 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_DHCP); \
696 else \
697 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_DHCP); \
698 }while(0)
699#define RTMP_GET_PACKET_DHCP(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_DHCP)
700
701//EAPOL
702#define RTMP_SET_PACKET_EAPOL(_p, _flg) \
703 do{ \
704 if (_flg) \
705 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_EAPOL); \
706 else \
707 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_EAPOL); \
708 }while(0)
709#define RTMP_GET_PACKET_EAPOL(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_EAPOL)
710
711//WAI
712#define RTMP_SET_PACKET_WAI(_p, _flg) \
713 do{ \
714 if (_flg) \
715 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_WAI); \
716 else \
717 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_WAI); \
718 }while(0)
719#define RTMP_GET_PACKET_WAI(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_WAI)
720
721#define RTMP_GET_PACKET_LOWRATE(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & (RTMP_PACKET_SPECIFIC_EAPOL | RTMP_PACKET_SPECIFIC_DHCP | RTMP_PACKET_SPECIFIC_WAI))
722
723//VLAN
724#define RTMP_SET_PACKET_VLAN(_p, _flg) \
725 do{ \
726 if (_flg) \
727 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_VLAN); \
728 else \
729 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_VLAN); \
730 }while(0)
731#define RTMP_GET_PACKET_VLAN(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_VLAN)
732
733//LLC/SNAP
734#define RTMP_SET_PACKET_LLCSNAP(_p, _flg) \
735 do{ \
736 if (_flg) \
737 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_LLCSNAP); \
738 else \
739 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_LLCSNAP); \
740 }while(0)
741
742#define RTMP_GET_PACKET_LLCSNAP(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_LLCSNAP)
743
744// IP
745#define RTMP_SET_PACKET_IPV4(_p, _flg) \
746 do{ \
747 if (_flg) \
748 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_IPV4); \
749 else \
750 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_IPV4); \
751 }while(0)
752
753#define RTMP_GET_PACKET_IPV4(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_IPV4)
754
755// If this flag is set, it indicates that this EAPoL frame MUST be clear.
756#define RTMP_SET_PACKET_CLEAR_EAP_FRAME(_p, _flg) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+12] = _flg)
757#define RTMP_GET_PACKET_CLEAR_EAP_FRAME(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+12])
758
759#define RTMP_SET_PACKET_5VT(_p, _flg) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+22] = _flg)
760#define RTMP_GET_PACKET_5VT(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+22])
761
762
763#ifdef INF_AMAZON_SE
764/*Iverson patch for WMM A5-T07 ,WirelessStaToWirelessSta do not bulk out aggregate */
765#define RTMP_SET_PACKET_NOBULKOUT(_p, _morebit) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+23] = _morebit)
766#define RTMP_GET_PACKET_NOBULKOUT(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+23])
767#endif // INF_AMAZON_SE //
768
769
770
771#ifdef CONFIG_5VT_ENHANCE
772#define BRIDGE_TAG 0x35564252 // depends on 5VT define in br_input.c
773#endif
774
775
776#define NDIS_SET_PACKET_STATUS(_p, _status)
777
778
779#define GET_SG_LIST_FROM_PACKET(_p, _sc) \
780 rt_get_sg_list_from_packet(_p, _sc)
781
782#define NdisMoveMemory(Destination, Source, Length) memmove(Destination, Source, Length)
783#define NdisZeroMemory(Destination, Length) memset(Destination, 0, Length)
784#define NdisFillMemory(Destination, Length, Fill) memset(Destination, Fill, Length)
785#define NdisEqualMemory(Source1, Source2, Length) (!memcmp(Source1, Source2, Length))
786#define RTMPEqualMemory(Source1, Source2, Length) (!memcmp(Source1, Source2, Length))
787
788
789#define RTMP_INC_REF(_A) 0
790#define RTMP_DEC_REF(_A) 0
791#define RTMP_GET_REF(_A) 0
792
793
794
795/*
796 * ULONG
797 * RTMP_GetPhysicalAddressLow(
798 * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress);
799 */
800#define RTMP_GetPhysicalAddressLow(PhysicalAddress) (PhysicalAddress)
801
802/*
803 * ULONG
804 * RTMP_GetPhysicalAddressHigh(
805 * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress);
806 */
807#define RTMP_GetPhysicalAddressHigh(PhysicalAddress) (0)
808
809/*
810 * VOID
811 * RTMP_SetPhysicalAddressLow(
812 * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress,
813 * IN ULONG Value);
814 */
815#define RTMP_SetPhysicalAddressLow(PhysicalAddress, Value) \
816 PhysicalAddress = Value;
817
818/*
819 * VOID
820 * RTMP_SetPhysicalAddressHigh(
821 * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress,
822 * IN ULONG Value);
823 */
824#define RTMP_SetPhysicalAddressHigh(PhysicalAddress, Value)
825
826
827//CONTAINING_RECORD(pEntry, NDIS_PACKET, MiniportReservedEx);
828#define QUEUE_ENTRY_TO_PACKET(pEntry) \
829 (PNDIS_PACKET)(pEntry)
830
831#define PACKET_TO_QUEUE_ENTRY(pPacket) \
832 (PQUEUE_ENTRY)(pPacket)
833
834
835#ifndef CONTAINING_RECORD
836#define CONTAINING_RECORD(address, type, field) \
837((type *)((PCHAR)(address) - offsetof(type, field)))
838#endif
839
840
841#define RELEASE_NDIS_PACKET(_pAd, _pPacket, _Status) \
842{ \
843 RTMPFreeNdisPacket(_pAd, _pPacket); \
844}
845
846
847#define SWITCH_PhyAB(_pAA, _pBB) \
848{ \
849 ULONG AABasePaHigh; \
850 ULONG AABasePaLow; \
851 ULONG BBBasePaHigh; \
852 ULONG BBBasePaLow; \
853 BBBasePaHigh = RTMP_GetPhysicalAddressHigh(_pBB); \
854 BBBasePaLow = RTMP_GetPhysicalAddressLow(_pBB); \
855 AABasePaHigh = RTMP_GetPhysicalAddressHigh(_pAA); \
856 AABasePaLow = RTMP_GetPhysicalAddressLow(_pAA); \
857 RTMP_SetPhysicalAddressHigh(_pAA, BBBasePaHigh); \
858 RTMP_SetPhysicalAddressLow(_pAA, BBBasePaLow); \
859 RTMP_SetPhysicalAddressHigh(_pBB, AABasePaHigh); \
860 RTMP_SetPhysicalAddressLow(_pBB, AABasePaLow); \
861}
862
863
864#define NdisWriteErrorLogEntry(_a, _b, _c, _d)
865#define NdisMAllocateMapRegisters(_a, _b, _c, _d, _e) NDIS_STATUS_SUCCESS
866
867
868#define NdisAcquireSpinLock RTMP_SEM_LOCK
869#define NdisReleaseSpinLock RTMP_SEM_UNLOCK
870
871static inline void NdisGetSystemUpTime(ULONG *time)
872{
873 *time = jiffies;
874}
875
876//pPacket = CONTAINING_RECORD(pEntry, NDIS_PACKET, MiniportReservedEx);
877#define QUEUE_ENTRY_TO_PKT(pEntry) \
878 ((PNDIS_PACKET) (pEntry))
879
880int rt28xx_packet_xmit(struct sk_buff *skb);
881
882
883
884void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify);
885
886
887
diff --git a/drivers/staging/rt3070/rt_main_dev.c b/drivers/staging/rt3070/rt_main_dev.c
new file mode 100644
index 000000000000..c000646286e6
--- /dev/null
+++ b/drivers/staging/rt3070/rt_main_dev.c
@@ -0,0 +1,1800 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 rt_main_dev.c
29
30 Abstract:
31 Create and register network interface.
32
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36 Sample Mar/21/07 Merge RT2870 and RT2860 drivers.
37*/
38
39#include "rt_config.h"
40
41#define FORTY_MHZ_INTOLERANT_INTERVAL (60*1000) // 1 min
42
43#ifdef MULTIPLE_CARD_SUPPORT
44// record whether the card in the card list is used in the card file
45UINT8 MC_CardUsed[MAX_NUM_OF_MULTIPLE_CARD];
46// record used card mac address in the card list
47static UINT8 MC_CardMac[MAX_NUM_OF_MULTIPLE_CARD][6];
48#endif // MULTIPLE_CARD_SUPPORT //
49
50#ifdef CONFIG_APSTA_MIXED_SUPPORT
51UINT32 CW_MAX_IN_BITS;
52#endif // CONFIG_APSTA_MIXED_SUPPORT //
53
54/*---------------------------------------------------------------------*/
55/* Private Variables Used */
56/*---------------------------------------------------------------------*/
57//static RALINK_TIMER_STRUCT PeriodicTimer;
58
59char *mac = ""; // default 00:00:00:00:00:00
60char *hostname = ""; // default CMPC
61#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12)
62MODULE_PARM (mac, "s");
63#else
64module_param (mac, charp, 0);
65#endif
66MODULE_PARM_DESC (mac, "rt28xx: wireless mac addr");
67
68
69/*---------------------------------------------------------------------*/
70/* Prototypes of Functions Used */
71/*---------------------------------------------------------------------*/
72#ifdef DOT11_N_SUPPORT
73extern BOOLEAN ba_reordering_resource_init(PRTMP_ADAPTER pAd, int num);
74extern void ba_reordering_resource_release(PRTMP_ADAPTER pAd);
75#endif // DOT11_N_SUPPORT //
76extern NDIS_STATUS NICLoadRateSwitchingParams(IN PRTMP_ADAPTER pAd);
77
78
79// public function prototype
80INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p,
81 IN UINT argc, OUT PRTMP_ADAPTER *ppAd);
82
83// private function prototype
84static int rt28xx_init(IN struct net_device *net_dev);
85INT rt28xx_send_packets(IN struct sk_buff *skb_p, IN struct net_device *net_dev);
86
87#if LINUX_VERSION_CODE <= 0x20402 // Red Hat 7.1
88struct net_device *alloc_netdev(
89 int sizeof_priv,
90 const char *mask,
91 void (*setup)(struct net_device *));
92#endif // LINUX_VERSION_CODE //
93
94static void CfgInitHook(PRTMP_ADAPTER pAd);
95//static BOOLEAN RT28XXAvailRANameAssign(IN CHAR *name_p);
96
97#ifdef CONFIG_STA_SUPPORT
98extern const struct iw_handler_def rt28xx_iw_handler_def;
99#endif // CONFIG_STA_SUPPORT //
100
101#ifdef CONFIG_APSTA_MIXED_SUPPORT
102extern const struct iw_handler_def rt28xx_ap_iw_handler_def;
103#endif // CONFIG_APSTA_MIXED_SUPPORT //
104
105#if WIRELESS_EXT >= 12
106// This function will be called when query /proc
107struct iw_statistics *rt28xx_get_wireless_stats(
108 IN struct net_device *net_dev);
109#endif
110
111struct net_device_stats *RT28xx_get_ether_stats(
112 IN struct net_device *net_dev);
113
114/*
115========================================================================
116Routine Description:
117 Close raxx interface.
118
119Arguments:
120 *net_dev the raxx interface pointer
121
122Return Value:
123 0 Open OK
124 otherwise Open Fail
125
126Note:
127 1. if open fail, kernel will not call the close function.
128 2. Free memory for
129 (1) Mlme Memory Handler: MlmeHalt()
130 (2) TX & RX: RTMPFreeTxRxRingMemory()
131 (3) BA Reordering: ba_reordering_resource_release()
132========================================================================
133*/
134int MainVirtualIF_close(IN struct net_device *net_dev)
135{
136 RTMP_ADAPTER *pAd = net_dev->ml_priv;
137
138 // Sanity check for pAd
139 if (pAd == NULL)
140 return 0; // close ok
141
142 netif_carrier_off(pAd->net_dev);
143 netif_stop_queue(pAd->net_dev);
144
145
146
147 VIRTUAL_IF_DOWN(pAd);
148
149 RT_MOD_DEC_USE_COUNT();
150
151 return 0; // close ok
152}
153
154/*
155========================================================================
156Routine Description:
157 Open raxx interface.
158
159Arguments:
160 *net_dev the raxx interface pointer
161
162Return Value:
163 0 Open OK
164 otherwise Open Fail
165
166Note:
167 1. if open fail, kernel will not call the close function.
168 2. Free memory for
169 (1) Mlme Memory Handler: MlmeHalt()
170 (2) TX & RX: RTMPFreeTxRxRingMemory()
171 (3) BA Reordering: ba_reordering_resource_release()
172========================================================================
173*/
174int MainVirtualIF_open(IN struct net_device *net_dev)
175{
176 RTMP_ADAPTER *pAd = net_dev->ml_priv;
177
178 // Sanity check for pAd
179 if (pAd == NULL)
180 return 0; // close ok
181
182 if (VIRTUAL_IF_UP(pAd) != 0)
183 return -1;
184
185 // increase MODULE use count
186 RT_MOD_INC_USE_COUNT();
187
188 netif_start_queue(net_dev);
189 netif_carrier_on(net_dev);
190 netif_wake_queue(net_dev);
191
192 return 0;
193}
194
195/*
196========================================================================
197Routine Description:
198 Close raxx interface.
199
200Arguments:
201 *net_dev the raxx interface pointer
202
203Return Value:
204 0 Open OK
205 otherwise Open Fail
206
207Note:
208 1. if open fail, kernel will not call the close function.
209 2. Free memory for
210 (1) Mlme Memory Handler: MlmeHalt()
211 (2) TX & RX: RTMPFreeTxRxRingMemory()
212 (3) BA Reordering: ba_reordering_resource_release()
213========================================================================
214*/
215int rt28xx_close(IN PNET_DEV dev)
216{
217 struct net_device * net_dev = (struct net_device *)dev;
218 RTMP_ADAPTER *pAd = net_dev->ml_priv;
219 BOOLEAN Cancelled = FALSE;
220 UINT32 i = 0;
221#ifdef RT2870
222 DECLARE_WAIT_QUEUE_HEAD(unlink_wakeup);
223 DECLARE_WAITQUEUE(wait, current);
224
225 //RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
226#endif // RT2870 //
227
228
229 DBGPRINT(RT_DEBUG_TRACE, ("===> rt28xx_close\n"));
230
231 // Sanity check for pAd
232 if (pAd == NULL)
233 return 0; // close ok
234
235
236#ifdef WDS_SUPPORT
237 WdsDown(pAd);
238#endif // WDS_SUPPORT //
239
240#ifdef CONFIG_STA_SUPPORT
241 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
242 {
243
244 // If dirver doesn't wake up firmware here,
245 // NICLoadFirmware will hang forever when interface is up again.
246 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
247 {
248 AsicForceWakeup(pAd, TRUE);
249 }
250
251#ifdef QOS_DLS_SUPPORT
252 // send DLS-TEAR_DOWN message,
253 if (pAd->CommonCfg.bDLSCapable)
254 {
255 UCHAR i;
256
257 // tear down local dls table entry
258 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
259 {
260 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
261 {
262 RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
263 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
264 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
265 }
266 }
267
268 // tear down peer dls table entry
269 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
270 {
271 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
272 {
273 RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
274 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
275 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
276 }
277 }
278 RT28XX_MLME_HANDLER(pAd);
279 }
280#endif // QOS_DLS_SUPPORT //
281
282 if (INFRA_ON(pAd) &&
283 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
284 {
285 MLME_DISASSOC_REQ_STRUCT DisReq;
286 MLME_QUEUE_ELEM *MsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
287
288 COPY_MAC_ADDR(DisReq.Addr, pAd->CommonCfg.Bssid);
289 DisReq.Reason = REASON_DEAUTH_STA_LEAVING;
290
291 MsgElem->Machine = ASSOC_STATE_MACHINE;
292 MsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
293 MsgElem->MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
294 NdisMoveMemory(MsgElem->Msg, &DisReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
295
296 // Prevent to connect AP again in STAMlmePeriodicExec
297 pAd->MlmeAux.AutoReconnectSsidLen= 32;
298 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
299
300 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
301 MlmeDisassocReqAction(pAd, MsgElem);
302 kfree(MsgElem);
303
304 RTMPusecDelay(1000);
305 }
306
307#ifdef RT2870
308 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
309#endif // RT2870 //
310
311#ifdef CCX_SUPPORT
312 RTMPCancelTimer(&pAd->StaCfg.LeapAuthTimer, &Cancelled);
313#endif
314
315 RTMPCancelTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, &Cancelled);
316 RTMPCancelTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, &Cancelled);
317
318#ifdef WPA_SUPPLICANT_SUPPORT
319#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
320 {
321 union iwreq_data wrqu;
322 // send wireless event to wpa_supplicant for infroming interface down.
323 memset(&wrqu, 0, sizeof(wrqu));
324 wrqu.data.flags = RT_INTERFACE_DOWN;
325 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
326 }
327#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
328#endif // WPA_SUPPLICANT_SUPPORT //
329
330 MlmeRadioOff(pAd);
331 }
332#endif // CONFIG_STA_SUPPORT //
333
334 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
335
336 for (i = 0 ; i < NUM_OF_TX_RING; i++)
337 {
338 while (pAd->DeQueueRunning[i] == TRUE)
339 {
340 printk("Waiting for TxQueue[%d] done..........\n", i);
341 RTMPusecDelay(1000);
342 }
343 }
344
345#ifdef RT2870
346 // ensure there are no more active urbs.
347 add_wait_queue (&unlink_wakeup, &wait);
348 pAd->wait = &unlink_wakeup;
349
350 // maybe wait for deletions to finish.
351 i = 0;
352 //while((i < 25) && atomic_read(&pAd->PendingRx) > 0)
353 while(i < 25)
354 {
355 unsigned long IrqFlags;
356
357 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
358 if (pAd->PendingRx == 0)
359 {
360 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
361 break;
362 }
363 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
364
365#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9)
366 msleep(UNLINK_TIMEOUT_MS); //Time in millisecond
367#else
368 RTMPusecDelay(UNLINK_TIMEOUT_MS*1000); //Time in microsecond
369#endif
370 i++;
371 }
372 pAd->wait = NULL;
373 remove_wait_queue (&unlink_wakeup, &wait);
374#endif // RT2870 //
375
376 //RTUSBCleanUpMLMEWaitQueue(pAd); /*not used in RT28xx*/
377
378
379#ifdef RT2870
380 // We need clear timerQ related structure before exits of the timer thread.
381 RT2870_TimerQ_Exit(pAd);
382 // Close kernel threads or tasklets
383 RT28xxThreadTerminate(pAd);
384#endif // RT2870 //
385
386 // Stop Mlme state machine
387 MlmeHalt(pAd);
388
389 // Close kernel threads or tasklets
390 kill_thread_task(pAd);
391
392
393#ifdef CONFIG_STA_SUPPORT
394 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
395 {
396 MacTableReset(pAd);
397 }
398#endif // CONFIG_STA_SUPPORT //
399
400
401 MeasureReqTabExit(pAd);
402 TpcReqTabExit(pAd);
403
404
405
406
407 // Free Ring or USB buffers
408 RTMPFreeTxRxRingMemory(pAd);
409
410 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
411
412#ifdef DOT11_N_SUPPORT
413 // Free BA reorder resource
414 ba_reordering_resource_release(pAd);
415#endif // DOT11_N_SUPPORT //
416
417#ifdef RT2870
418#ifdef INF_AMAZON_SE
419 if (pAd->UsbVendorReqBuf)
420 os_free_mem(pAd, pAd->UsbVendorReqBuf);
421#endif // INF_AMAZON_SE //
422#endif // RT2870 //
423
424 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_START_UP);
425
426 return 0; // close ok
427} /* End of rt28xx_close */
428
429static int rt28xx_init(IN struct net_device *net_dev)
430{
431 PRTMP_ADAPTER pAd = net_dev->ml_priv;
432 UINT index;
433 UCHAR TmpPhy;
434// ULONG Value=0;
435 NDIS_STATUS Status;
436// OID_SET_HT_PHYMODE SetHT;
437// WPDMA_GLO_CFG_STRUC GloCfg;
438 UINT32 MacCsr0 = 0;
439 UINT32 MacValue = 0;
440
441#ifdef RT2870
442#ifdef INF_AMAZON_SE
443 init_MUTEX(&(pAd->UsbVendorReq_semaphore));
444 os_alloc_mem(pAd, (PUCHAR)&pAd->UsbVendorReqBuf, MAX_PARAM_BUFFER_SIZE - 1);
445 if (pAd->UsbVendorReqBuf == NULL)
446 {
447 DBGPRINT(RT_DEBUG_ERROR, ("Allocate vendor request temp buffer failed!\n"));
448 goto err0;
449 }
450#endif // INF_AMAZON_SE //
451#endif // RT2870 //
452
453#ifdef DOT11_N_SUPPORT
454 // Allocate BA Reordering memory
455 ba_reordering_resource_init(pAd, MAX_REORDERING_MPDU_NUM);
456#endif // DOT11_N_SUPPORT //
457
458 // Make sure MAC gets ready.
459 index = 0;
460 do
461 {
462 RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
463 pAd->MACVersion = MacCsr0;
464
465 if ((pAd->MACVersion != 0x00) && (pAd->MACVersion != 0xFFFFFFFF))
466 break;
467
468 RTMPusecDelay(10);
469 } while (index++ < 100);
470
471 DBGPRINT(RT_DEBUG_TRACE, ("MAC_CSR0 [ Ver:Rev=0x%08x]\n", pAd->MACVersion));
472/*Iverson patch PCIE L1 issue */
473
474 // Disable DMA
475 RT28XXDMADisable(pAd);
476
477
478 // Load 8051 firmware
479 Status = NICLoadFirmware(pAd);
480 if (Status != NDIS_STATUS_SUCCESS)
481 {
482 DBGPRINT_ERR(("NICLoadFirmware failed, Status[=0x%08x]\n", Status));
483 goto err1;
484 }
485
486 NICLoadRateSwitchingParams(pAd);
487
488 // Disable interrupts here which is as soon as possible
489 // This statement should never be true. We might consider to remove it later
490
491 Status = RTMPAllocTxRxRingMemory(pAd);
492 if (Status != NDIS_STATUS_SUCCESS)
493 {
494 DBGPRINT_ERR(("RTMPAllocDMAMemory failed, Status[=0x%08x]\n", Status));
495 goto err1;
496 }
497
498 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
499
500 // initialize MLME
501 //
502
503 Status = MlmeInit(pAd);
504 if (Status != NDIS_STATUS_SUCCESS)
505 {
506 DBGPRINT_ERR(("MlmeInit failed, Status[=0x%08x]\n", Status));
507 goto err2;
508 }
509
510 // Initialize pAd->StaCfg, pAd->ApCfg, pAd->CommonCfg to manufacture default
511 //
512 UserCfgInit(pAd);
513
514#ifdef RT2870
515 // We need init timerQ related structure before create the timer thread.
516 RT2870_TimerQ_Init(pAd);
517#endif // RT2870 //
518
519 RT28XX_TASK_THREAD_INIT(pAd, Status);
520 if (Status != NDIS_STATUS_SUCCESS)
521 goto err1;
522
523// COPY_MAC_ADDR(pAd->ApCfg.MBSSID[apidx].Bssid, netif->hwaddr);
524// pAd->bForcePrintTX = TRUE;
525
526 CfgInitHook(pAd);
527
528
529#ifdef BLOCK_NET_IF
530 initblockQueueTab(pAd);
531#endif // BLOCK_NET_IF //
532
533#ifdef CONFIG_STA_SUPPORT
534 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
535 NdisAllocateSpinLock(&pAd->MacTabLock);
536#endif // CONFIG_STA_SUPPORT //
537
538 MeasureReqTabInit(pAd);
539 TpcReqTabInit(pAd);
540
541 //
542 // Init the hardware, we need to init asic before read registry, otherwise mac register will be reset
543 //
544 Status = NICInitializeAdapter(pAd, TRUE);
545 if (Status != NDIS_STATUS_SUCCESS)
546 {
547 DBGPRINT_ERR(("NICInitializeAdapter failed, Status[=0x%08x]\n", Status));
548 if (Status != NDIS_STATUS_SUCCESS)
549 goto err3;
550 }
551
552 // Read parameters from Config File
553 Status = RTMPReadParametersHook(pAd);
554
555 printk("1. Phy Mode = %d\n", pAd->CommonCfg.PhyMode);
556 if (Status != NDIS_STATUS_SUCCESS)
557 {
558 DBGPRINT_ERR(("NICReadRegParameters failed, Status[=0x%08x]\n",Status));
559 goto err4;
560 }
561
562#ifdef RT2870
563 pAd->CommonCfg.bMultipleIRP = FALSE;
564
565 if (pAd->CommonCfg.bMultipleIRP)
566 pAd->CommonCfg.NumOfBulkInIRP = RX_RING_SIZE;
567 else
568 pAd->CommonCfg.NumOfBulkInIRP = 1;
569#endif // RT2870 //
570
571
572 //Init Ba Capability parameters.
573// RT28XX_BA_INIT(pAd);
574#ifdef DOT11_N_SUPPORT
575 pAd->CommonCfg.DesiredHtPhy.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
576 pAd->CommonCfg.DesiredHtPhy.AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable;
577 pAd->CommonCfg.DesiredHtPhy.AmsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize;
578 pAd->CommonCfg.DesiredHtPhy.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode;
579 // UPdata to HT IE
580 pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode;
581 pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize;
582 pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
583#endif // DOT11_N_SUPPORT //
584
585 // after reading Registry, we now know if in AP mode or STA mode
586
587 // Load 8051 firmware; crash when FW image not existent
588 // Status = NICLoadFirmware(pAd);
589 // if (Status != NDIS_STATUS_SUCCESS)
590 // break;
591
592 printk("2. Phy Mode = %d\n", pAd->CommonCfg.PhyMode);
593
594 // We should read EEPROM for all cases. rt2860b
595 NICReadEEPROMParameters(pAd, mac);
596#ifdef CONFIG_STA_SUPPORT
597#endif // CONFIG_STA_SUPPORT //
598
599 printk("3. Phy Mode = %d\n", pAd->CommonCfg.PhyMode);
600
601 NICInitAsicFromEEPROM(pAd); //rt2860b
602
603 // Set PHY to appropriate mode
604 TmpPhy = pAd->CommonCfg.PhyMode;
605 pAd->CommonCfg.PhyMode = 0xff;
606 RTMPSetPhyMode(pAd, TmpPhy);
607#ifdef DOT11_N_SUPPORT
608 SetCommonHT(pAd);
609#endif // DOT11_N_SUPPORT //
610
611 // No valid channels.
612 if (pAd->ChannelListNum == 0)
613 {
614 printk("Wrong configuration. No valid channel found. Check \"ContryCode\" and \"ChannelGeography\" setting.\n");
615 goto err4;
616 }
617
618#ifdef DOT11_N_SUPPORT
619 printk("MCS Set = %02x %02x %02x %02x %02x\n", pAd->CommonCfg.HtCapability.MCSSet[0],
620 pAd->CommonCfg.HtCapability.MCSSet[1], pAd->CommonCfg.HtCapability.MCSSet[2],
621 pAd->CommonCfg.HtCapability.MCSSet[3], pAd->CommonCfg.HtCapability.MCSSet[4]);
622#endif // DOT11_N_SUPPORT //
623
624#ifdef RT30xx
625 //Init RT30xx RFRegisters after read RFIC type from EEPROM
626 NICInitRT30xxRFRegisters(pAd);
627#endif // RT30xx //
628
629// APInitialize(pAd);
630
631#ifdef IKANOS_VX_1X0
632 VR_IKANOS_FP_Init(pAd->ApCfg.BssidNum, pAd->PermanentAddress);
633#endif // IKANOS_VX_1X0 //
634
635 //
636 // Initialize RF register to default value
637 //
638 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
639 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
640
641 if (pAd && (Status != NDIS_STATUS_SUCCESS))
642 {
643 //
644 // Undo everything if it failed
645 //
646 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
647 {
648// NdisMDeregisterInterrupt(&pAd->Interrupt);
649 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
650 }
651// RTMPFreeAdapter(pAd); // we will free it in disconnect()
652 }
653 else if (pAd)
654 {
655 // Microsoft HCT require driver send a disconnect event after driver initialization.
656 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
657// pAd->IndicateMediaState = NdisMediaStateDisconnected;
658 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE);
659
660 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event B!\n"));
661
662
663#ifdef RT2870
664 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS);
665 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
666
667 //
668 // Support multiple BulkIn IRP,
669 // the value on pAd->CommonCfg.NumOfBulkInIRP may be large than 1.
670 //
671 for(index=0; index<pAd->CommonCfg.NumOfBulkInIRP; index++)
672 {
673 RTUSBBulkReceive(pAd);
674 DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkReceive!\n" ));
675 }
676#endif // RT2870 //
677 }// end of else
678
679
680 DBGPRINT_S(Status, ("<==== RTMPInitialize, Status=%x\n", Status));
681
682 return TRUE;
683
684
685err4:
686err3:
687 MlmeHalt(pAd);
688err2:
689 RTMPFreeTxRxRingMemory(pAd);
690// RTMPFreeAdapter(pAd);
691err1:
692
693#ifdef DOT11_N_SUPPORT
694 os_free_mem(pAd, pAd->mpdu_blk_pool.mem); // free BA pool
695#endif // DOT11_N_SUPPORT //
696 RT28XX_IRQ_RELEASE(net_dev);
697
698 // shall not set priv to NULL here because the priv didn't been free yet.
699 //net_dev->ml_priv = 0;
700#ifdef INF_AMAZON_SE
701err0:
702#endif // INF_AMAZON_SE //
703 printk("!!! %s Initialized fail !!!\n", RT28xx_CHIP_NAME);
704 return FALSE;
705} /* End of rt28xx_init */
706
707
708/*
709========================================================================
710Routine Description:
711 Open raxx interface.
712
713Arguments:
714 *net_dev the raxx interface pointer
715
716Return Value:
717 0 Open OK
718 otherwise Open Fail
719
720Note:
721========================================================================
722*/
723int rt28xx_open(IN PNET_DEV dev)
724{
725 struct net_device * net_dev = (struct net_device *)dev;
726 PRTMP_ADAPTER pAd = net_dev->ml_priv;
727 int retval = 0;
728 POS_COOKIE pObj;
729
730
731 // Sanity check for pAd
732 if (pAd == NULL)
733 {
734 /* if 1st open fail, pAd will be free;
735 So the net_dev->ml_priv will be NULL in 2rd open */
736 return -1;
737 }
738
739#ifdef CONFIG_APSTA_MIXED_SUPPORT
740 if (pAd->OpMode == OPMODE_AP)
741 {
742 CW_MAX_IN_BITS = 6;
743 }
744 else if (pAd->OpMode == OPMODE_STA)
745 {
746 CW_MAX_IN_BITS = 10;
747 }
748
749#if WIRELESS_EXT >= 12
750 if (net_dev->ml_priv_flags == INT_MAIN)
751 {
752 if (pAd->OpMode == OPMODE_AP)
753 net_dev->wireless_handlers = (struct iw_handler_def *) &rt28xx_ap_iw_handler_def;
754 else if (pAd->OpMode == OPMODE_STA)
755 net_dev->wireless_handlers = (struct iw_handler_def *) &rt28xx_iw_handler_def;
756 }
757#endif // WIRELESS_EXT >= 12 //
758#endif // CONFIG_APSTA_MIXED_SUPPORT //
759
760#ifdef CONFIG_STA_SUPPORT
761#endif // CONFIG_STA_SUPPORT //
762
763 // Init
764 pObj = (POS_COOKIE)pAd->OS_Cookie;
765
766 // reset Adapter flags
767 RTMP_CLEAR_FLAGS(pAd);
768
769 // Request interrupt service routine for PCI device
770 // register the interrupt routine with the os
771 RT28XX_IRQ_REQUEST(net_dev);
772
773
774 // Init BssTab & ChannelInfo tabbles for auto channel select.
775
776
777 // Chip & other init
778 if (rt28xx_init(net_dev) == FALSE)
779 goto err;
780
781#ifdef CONFIG_STA_SUPPORT
782 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
783 {
784 NdisZeroMemory(pAd->StaCfg.dev_name, 16);
785 NdisMoveMemory(pAd->StaCfg.dev_name, net_dev->name, strlen(net_dev->name));
786 }
787#endif // CONFIG_STA_SUPPORT //
788
789 // Set up the Mac address
790 NdisMoveMemory(net_dev->dev_addr, (void *) pAd->CurrentAddress, 6);
791
792 // Init IRQ parameters
793 RT28XX_IRQ_INIT(pAd);
794
795 // Various AP function init
796
797
798
799#ifdef CONFIG_STA_SUPPORT
800 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
801 {
802#ifdef WPA_SUPPLICANT_SUPPORT
803#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
804 {
805 union iwreq_data wrqu;
806 // send wireless event to wpa_supplicant for infroming interface down.
807 memset(&wrqu, 0, sizeof(wrqu));
808 wrqu.data.flags = RT_INTERFACE_UP;
809 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
810 }
811#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
812#endif // WPA_SUPPLICANT_SUPPORT //
813
814 }
815#endif // CONFIG_STA_SUPPORT //
816
817 // Enable Interrupt
818 RT28XX_IRQ_ENABLE(pAd);
819
820 // Now Enable RxTx
821 RTMPEnableRxTx(pAd);
822 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP);
823
824 {
825 UINT32 reg = 0;
826 RTMP_IO_READ32(pAd, 0x1300, &reg); // clear garbage interrupts
827 printk("0x1300 = %08x\n", reg);
828 }
829
830 {
831// u32 reg;
832// u8 byte;
833// u16 tmp;
834
835// RTMP_IO_READ32(pAd, XIFS_TIME_CFG, &reg);
836
837// tmp = 0x0805;
838// reg = (reg & 0xffff0000) | tmp;
839// RTMP_IO_WRITE32(pAd, XIFS_TIME_CFG, reg);
840
841 }
842
843#ifdef CONFIG_STA_SUPPORT
844#endif // CONFIG_STA_SUPPORT //
845
846 return (retval);
847
848err:
849 return (-1);
850} /* End of rt28xx_open */
851
852
853/* Must not be called for mdev and apdev */
854static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER pAd)
855{
856 NDIS_STATUS Status;
857 INT i=0;
858 CHAR slot_name[IFNAMSIZ];
859 struct net_device *device;
860
861
862 //ether_setup(dev);
863 dev->hard_start_xmit = rt28xx_send_packets;
864
865#ifdef IKANOS_VX_1X0
866 dev->hard_start_xmit = IKANOS_DataFramesTx;
867#endif // IKANOS_VX_1X0 //
868
869// dev->set_multicast_list = ieee80211_set_multicast_list;
870// dev->change_mtu = ieee80211_change_mtu;
871#ifdef CONFIG_STA_SUPPORT
872#if WIRELESS_EXT >= 12
873 if (pAd->OpMode == OPMODE_STA)
874 {
875 dev->wireless_handlers = &rt28xx_iw_handler_def;
876 }
877#endif //WIRELESS_EXT >= 12
878#endif // CONFIG_STA_SUPPORT //
879
880#ifdef CONFIG_APSTA_MIXED_SUPPORT
881#if WIRELESS_EXT >= 12
882 if (pAd->OpMode == OPMODE_AP)
883 {
884 dev->wireless_handlers = &rt28xx_ap_iw_handler_def;
885 }
886#endif //WIRELESS_EXT >= 12
887#endif // CONFIG_APSTA_MIXED_SUPPORT //
888
889#if WIRELESS_EXT < 21
890 dev->get_wireless_stats = rt28xx_get_wireless_stats;
891#endif
892 dev->get_stats = RT28xx_get_ether_stats;
893 dev->open = MainVirtualIF_open; //rt28xx_open;
894 dev->stop = MainVirtualIF_close; //rt28xx_close;
895// dev->uninit = ieee80211_if_reinit;
896// dev->destructor = ieee80211_if_free;
897 dev->priv_flags = INT_MAIN;
898 dev->do_ioctl = rt28xx_ioctl;
899#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
900 dev->validate_addr = NULL;
901#endif
902 // find available device name
903 for (i = 0; i < 8; i++)
904 {
905#ifdef MULTIPLE_CARD_SUPPORT
906 if (pAd->MC_RowID >= 0)
907 sprintf(slot_name, "ra%02d_%d", pAd->MC_RowID, i);
908 else
909#endif // MULTIPLE_CARD_SUPPORT //
910 sprintf(slot_name, "ra%d", i);
911
912#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
913#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
914#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
915 device = dev_get_by_name(dev_net(dev), slot_name);
916#else
917 device = dev_get_by_name(dev->nd_net, slot_name);
918#endif
919#else
920 device = dev_get_by_name(slot_name);
921#endif
922 if (device != NULL) dev_put(device);
923#else
924 for (device = dev_base; device != NULL; device = device->next)
925 {
926 if (strncmp(device->name, slot_name, 4) == 0)
927 break;
928 }
929#endif
930 if(device == NULL)
931 break;
932 }
933
934 if(i == 8)
935 {
936 DBGPRINT(RT_DEBUG_ERROR, ("No available slot name\n"));
937 Status = NDIS_STATUS_FAILURE;
938 }
939 else
940 {
941#ifdef MULTIPLE_CARD_SUPPORT
942 if (pAd->MC_RowID >= 0)
943 sprintf(dev->name, "ra%02d_%d", pAd->MC_RowID, i);
944 else
945#endif // MULTIPLE_CARD_SUPPORT //
946 sprintf(dev->name, "ra%d", i);
947 Status = NDIS_STATUS_SUCCESS;
948 }
949
950 return Status;
951
952}
953
954
955#ifdef MULTIPLE_CARD_SUPPORT
956/*
957========================================================================
958Routine Description:
959 Get card profile path.
960
961Arguments:
962 pAd
963
964Return Value:
965 TRUE - Find a card profile
966 FALSE - use default profile
967
968Note:
969========================================================================
970*/
971extern INT RTMPGetKeyParameter(
972 IN PCHAR key,
973 OUT PCHAR dest,
974 IN INT destsize,
975 IN PCHAR buffer);
976
977BOOLEAN RTMP_CardInfoRead(
978 IN PRTMP_ADAPTER pAd)
979{
980#define MC_SELECT_CARDID 0 /* use CARD ID (0 ~ 31) to identify different cards */
981#define MC_SELECT_MAC 1 /* use CARD MAC to identify different cards */
982#define MC_SELECT_CARDTYPE 2 /* use CARD type (abgn or bgn) to identify different cards */
983
984#define LETTER_CASE_TRANSLATE(txt_p, card_id) \
985 { UINT32 _len; char _char; \
986 for(_len=0; _len<strlen(card_id); _len++) { \
987 _char = *(txt_p + _len); \
988 if (('A' <= _char) && (_char <= 'Z')) \
989 *(txt_p+_len) = 'a'+(_char-'A'); \
990 } }
991
992 struct file *srcf;
993 INT retval, orgfsuid, orgfsgid;
994 mm_segment_t orgfs;
995 CHAR *buffer, *tmpbuf, card_id_buf[30], RFIC_word[30];
996 BOOLEAN flg_match_ok = FALSE;
997 INT32 card_select_method;
998 INT32 card_free_id, card_nouse_id, card_same_mac_id, card_match_id;
999 EEPROM_ANTENNA_STRUC antenna;
1000 USHORT addr01, addr23, addr45;
1001 UINT8 mac[6];
1002 UINT32 data, card_index;
1003 UCHAR *start_ptr;
1004
1005
1006 // init
1007 buffer = kmalloc(MAX_INI_BUFFER_SIZE, MEM_ALLOC_FLAG);
1008 if (buffer == NULL)
1009 return FALSE;
1010
1011 tmpbuf = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
1012 if(tmpbuf == NULL)
1013 {
1014 kfree(buffer);
1015 return NDIS_STATUS_FAILURE;
1016 }
1017
1018 orgfsuid = current->fsuid;
1019 orgfsgid = current->fsgid;
1020 current->fsuid = current->fsgid = 0;
1021 orgfs = get_fs();
1022 set_fs(KERNEL_DS);
1023
1024 // get RF IC type
1025 RTMP_IO_READ32(pAd, E2PROM_CSR, &data);
1026
1027 if ((data & 0x30) == 0)
1028 pAd->EEPROMAddressNum = 6; // 93C46
1029 else if ((data & 0x30) == 0x10)
1030 pAd->EEPROMAddressNum = 8; // 93C66
1031 else
1032 pAd->EEPROMAddressNum = 8; // 93C86
1033
1034 //antenna.word = RTMP_EEPROM_READ16(pAd, EEPROM_NIC1_OFFSET);
1035 RT28xx_EEPROM_READ16(pAd, EEPROM_NIC1_OFFSET, antenna.word);
1036
1037 if ((antenna.field.RfIcType == RFIC_2850) ||
1038 (antenna.field.RfIcType == RFIC_2750))
1039 {
1040 /* ABGN card */
1041 strcpy(RFIC_word, "abgn");
1042 }
1043 else
1044 {
1045 /* BGN card */
1046 strcpy(RFIC_word, "bgn");
1047 }
1048
1049 // get MAC address
1050 //addr01 = RTMP_EEPROM_READ16(pAd, 0x04);
1051 //addr23 = RTMP_EEPROM_READ16(pAd, 0x06);
1052 //addr45 = RTMP_EEPROM_READ16(pAd, 0x08);
1053 RT28xx_EEPROM_READ16(pAd, 0x04, addr01);
1054 RT28xx_EEPROM_READ16(pAd, 0x06, addr23);
1055 RT28xx_EEPROM_READ16(pAd, 0x08, addr45);
1056
1057 mac[0] = (UCHAR)(addr01 & 0xff);
1058 mac[1] = (UCHAR)(addr01 >> 8);
1059 mac[2] = (UCHAR)(addr23 & 0xff);
1060 mac[3] = (UCHAR)(addr23 >> 8);
1061 mac[4] = (UCHAR)(addr45 & 0xff);
1062 mac[5] = (UCHAR)(addr45 >> 8);
1063
1064 // open card information file
1065 srcf = filp_open(CARD_INFO_PATH, O_RDONLY, 0);
1066 if (IS_ERR(srcf))
1067 {
1068 /* card information file does not exist */
1069 DBGPRINT(RT_DEBUG_TRACE,
1070 ("--> Error %ld opening %s\n", -PTR_ERR(srcf), CARD_INFO_PATH));
1071 return FALSE;
1072 }
1073
1074 if (srcf->f_op && srcf->f_op->read)
1075 {
1076 /* card information file exists so reading the card information */
1077 memset(buffer, 0x00, MAX_INI_BUFFER_SIZE);
1078 retval = srcf->f_op->read(srcf, buffer, MAX_INI_BUFFER_SIZE, &srcf->f_pos);
1079 if (retval < 0)
1080 {
1081 /* read fail */
1082 DBGPRINT(RT_DEBUG_TRACE,
1083 ("--> Read %s error %d\n", CARD_INFO_PATH, -retval));
1084 }
1085 else
1086 {
1087 /* get card selection method */
1088 memset(tmpbuf, 0x00, MAX_PARAM_BUFFER_SIZE);
1089 card_select_method = MC_SELECT_CARDTYPE; // default
1090
1091 if (RTMPGetKeyParameter("SELECT", tmpbuf, 256, buffer))
1092 {
1093 if (strcmp(tmpbuf, "CARDID") == 0)
1094 card_select_method = MC_SELECT_CARDID;
1095 else if (strcmp(tmpbuf, "MAC") == 0)
1096 card_select_method = MC_SELECT_MAC;
1097 else if (strcmp(tmpbuf, "CARDTYPE") == 0)
1098 card_select_method = MC_SELECT_CARDTYPE;
1099 }
1100
1101 DBGPRINT(RT_DEBUG_TRACE,
1102 ("MC> Card Selection = %d\n", card_select_method));
1103
1104 // init
1105 card_free_id = -1;
1106 card_nouse_id = -1;
1107 card_same_mac_id = -1;
1108 card_match_id = -1;
1109
1110 // search current card information records
1111 for(card_index=0;
1112 card_index<MAX_NUM_OF_MULTIPLE_CARD;
1113 card_index++)
1114 {
1115 if ((*(UINT32 *)&MC_CardMac[card_index][0] == 0) &&
1116 (*(UINT16 *)&MC_CardMac[card_index][4] == 0))
1117 {
1118 // MAC is all-0 so the entry is available
1119 MC_CardUsed[card_index] = 0;
1120
1121 if (card_free_id < 0)
1122 card_free_id = card_index; // 1st free entry
1123 }
1124 else
1125 {
1126 if (memcmp(MC_CardMac[card_index], mac, 6) == 0)
1127 {
1128 // we find the entry with same MAC
1129 if (card_same_mac_id < 0)
1130 card_same_mac_id = card_index; // 1st same entry
1131 }
1132 else
1133 {
1134 // MAC is not all-0 but used flag == 0
1135 if ((MC_CardUsed[card_index] == 0) &&
1136 (card_nouse_id < 0))
1137 {
1138 card_nouse_id = card_index; // 1st available entry
1139 }
1140 }
1141 }
1142 }
1143
1144 DBGPRINT(RT_DEBUG_TRACE,
1145 ("MC> Free = %d, Same = %d, NOUSE = %d\n",
1146 card_free_id, card_same_mac_id, card_nouse_id));
1147
1148 if ((card_same_mac_id >= 0) &&
1149 ((card_select_method == MC_SELECT_CARDID) ||
1150 (card_select_method == MC_SELECT_CARDTYPE)))
1151 {
1152 // same MAC entry is found
1153 card_match_id = card_same_mac_id;
1154
1155 if (card_select_method == MC_SELECT_CARDTYPE)
1156 {
1157 // for CARDTYPE
1158 sprintf(card_id_buf, "%02dCARDTYPE%s",
1159 card_match_id, RFIC_word);
1160
1161 if ((start_ptr=rtstrstruncasecmp(buffer, card_id_buf)) != NULL)
1162 {
1163 // we found the card ID
1164 LETTER_CASE_TRANSLATE(start_ptr, card_id_buf);
1165 }
1166 }
1167 }
1168 else
1169 {
1170 // the card is 1st plug-in, try to find the match card profile
1171 switch(card_select_method)
1172 {
1173 case MC_SELECT_CARDID: // CARDID
1174 default:
1175 if (card_free_id >= 0)
1176 card_match_id = card_free_id;
1177 else
1178 card_match_id = card_nouse_id;
1179 break;
1180
1181 case MC_SELECT_MAC: // MAC
1182 sprintf(card_id_buf, "MAC%02x:%02x:%02x:%02x:%02x:%02x",
1183 mac[0], mac[1], mac[2],
1184 mac[3], mac[4], mac[5]);
1185
1186 /* try to find the key word in the card file */
1187 if ((start_ptr=rtstrstruncasecmp(buffer, card_id_buf)) != NULL)
1188 {
1189 LETTER_CASE_TRANSLATE(start_ptr, card_id_buf);
1190
1191 /* get the row ID (2 ASCII characters) */
1192 start_ptr -= 2;
1193 card_id_buf[0] = *(start_ptr);
1194 card_id_buf[1] = *(start_ptr+1);
1195 card_id_buf[2] = 0x00;
1196
1197 card_match_id = simple_strtol(card_id_buf, 0, 10);
1198 }
1199 break;
1200
1201 case MC_SELECT_CARDTYPE: // CARDTYPE
1202 card_nouse_id = -1;
1203
1204 for(card_index=0;
1205 card_index<MAX_NUM_OF_MULTIPLE_CARD;
1206 card_index++)
1207 {
1208 sprintf(card_id_buf, "%02dCARDTYPE%s",
1209 card_index, RFIC_word);
1210
1211 if ((start_ptr=rtstrstruncasecmp(buffer,
1212 card_id_buf)) != NULL)
1213 {
1214 LETTER_CASE_TRANSLATE(start_ptr, card_id_buf);
1215
1216 if (MC_CardUsed[card_index] == 0)
1217 {
1218 /* current the card profile is not used */
1219 if ((*(UINT32 *)&MC_CardMac[card_index][0] == 0) &&
1220 (*(UINT16 *)&MC_CardMac[card_index][4] == 0))
1221 {
1222 // find it and no previous card use it
1223 card_match_id = card_index;
1224 break;
1225 }
1226 else
1227 {
1228 // ever a card use it
1229 if (card_nouse_id < 0)
1230 card_nouse_id = card_index;
1231 }
1232 }
1233 }
1234 }
1235
1236 // if not find a free one, use the available one
1237 if (card_match_id < 0)
1238 card_match_id = card_nouse_id;
1239 break;
1240 }
1241 }
1242
1243 if (card_match_id >= 0)
1244 {
1245 // make up search keyword
1246 switch(card_select_method)
1247 {
1248 case MC_SELECT_CARDID: // CARDID
1249 sprintf(card_id_buf, "%02dCARDID", card_match_id);
1250 break;
1251
1252 case MC_SELECT_MAC: // MAC
1253 sprintf(card_id_buf,
1254 "%02dmac%02x:%02x:%02x:%02x:%02x:%02x",
1255 card_match_id,
1256 mac[0], mac[1], mac[2],
1257 mac[3], mac[4], mac[5]);
1258 break;
1259
1260 case MC_SELECT_CARDTYPE: // CARDTYPE
1261 default:
1262 sprintf(card_id_buf, "%02dcardtype%s",
1263 card_match_id, RFIC_word);
1264 break;
1265 }
1266
1267 DBGPRINT(RT_DEBUG_TRACE, ("Search Keyword = %s\n", card_id_buf));
1268
1269 // read card file path
1270 if (RTMPGetKeyParameter(card_id_buf, tmpbuf, 256, buffer))
1271 {
1272 if (strlen(tmpbuf) < sizeof(pAd->MC_FileName))
1273 {
1274 // backup card information
1275 pAd->MC_RowID = card_match_id; /* base 0 */
1276 MC_CardUsed[card_match_id] = 1;
1277 memcpy(MC_CardMac[card_match_id], mac, sizeof(mac));
1278
1279 // backup card file path
1280 NdisMoveMemory(pAd->MC_FileName, tmpbuf , strlen(tmpbuf));
1281 pAd->MC_FileName[strlen(tmpbuf)] = '\0';
1282 flg_match_ok = TRUE;
1283
1284 DBGPRINT(RT_DEBUG_TRACE,
1285 ("Card Profile Name = %s\n", pAd->MC_FileName));
1286 }
1287 else
1288 {
1289 DBGPRINT(RT_DEBUG_ERROR,
1290 ("Card Profile Name length too large!\n"));
1291 }
1292 }
1293 else
1294 {
1295 DBGPRINT(RT_DEBUG_ERROR,
1296 ("Can not find search key word in card.dat!\n"));
1297 }
1298
1299 if ((flg_match_ok != TRUE) &&
1300 (card_match_id < MAX_NUM_OF_MULTIPLE_CARD))
1301 {
1302 MC_CardUsed[card_match_id] = 0;
1303 memset(MC_CardMac[card_match_id], 0, sizeof(mac));
1304 }
1305 } // if (card_match_id >= 0)
1306 }
1307 }
1308
1309 // close file
1310 retval = filp_close(srcf, NULL);
1311 set_fs(orgfs);
1312 current->fsuid = orgfsuid;
1313 current->fsgid = orgfsgid;
1314 kfree(buffer);
1315 kfree(tmpbuf);
1316 return flg_match_ok;
1317}
1318#endif // MULTIPLE_CARD_SUPPORT //
1319
1320
1321/*
1322========================================================================
1323Routine Description:
1324 Probe RT28XX chipset.
1325
1326Arguments:
1327 _dev_p Point to the PCI or USB device
1328 _dev_id_p Point to the PCI or USB device ID
1329
1330Return Value:
1331 0 Probe OK
1332 -ENODEV Probe Fail
1333
1334Note:
1335========================================================================
1336*/
1337INT __devinit rt28xx_probe(
1338 IN void *_dev_p,
1339 IN void *_dev_id_p,
1340 IN UINT argc,
1341 OUT PRTMP_ADAPTER *ppAd)
1342{
1343 struct net_device *net_dev;
1344 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) NULL;
1345 INT status;
1346 PVOID handle;
1347#ifdef RT2870
1348#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
1349 struct usb_device *dev_p = (struct usb_device *)_dev_p;
1350#else
1351 struct usb_interface *intf = (struct usb_interface *)_dev_p;
1352 struct usb_device *dev_p = interface_to_usbdev(intf);
1353
1354 dev_p = usb_get_dev(dev_p);
1355#endif // LINUX_VERSION_CODE //
1356#endif // RT2870 //
1357
1358
1359#ifdef CONFIG_STA_SUPPORT
1360 DBGPRINT(RT_DEBUG_TRACE, ("STA Driver version-%s\n", STA_DRIVER_VERSION));
1361#endif // CONFIG_STA_SUPPORT //
1362
1363 // Check chipset vendor/product ID
1364// if (RT28XXChipsetCheck(_dev_p) == FALSE)
1365// goto err_out;
1366
1367#if LINUX_VERSION_CODE <= 0x20402 // Red Hat 7.1
1368 net_dev = alloc_netdev(sizeof(PRTMP_ADAPTER), "eth%d", ether_setup);
1369#else
1370 net_dev = alloc_etherdev(sizeof(PRTMP_ADAPTER));
1371#endif
1372 if (net_dev == NULL)
1373 {
1374 printk("alloc_netdev failed\n");
1375
1376#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1377#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
1378 module_put(THIS_MODULE);
1379#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
1380#else
1381 MOD_DEC_USE_COUNT;
1382#endif
1383 goto err_out;
1384 }
1385
1386// sample
1387// if (rt_ieee80211_if_setup(net_dev) != NDIS_STATUS_SUCCESS)
1388// goto err_out;
1389
1390#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
1391 SET_MODULE_OWNER(net_dev);
1392#endif
1393
1394 netif_stop_queue(net_dev);
1395#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
1396/* for supporting Network Manager */
1397/* Set the sysfs physical device reference for the network logical device
1398 * if set prior to registration will cause a symlink during initialization.
1399 */
1400#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
1401 SET_NETDEV_DEV(net_dev, &(dev_p->dev));
1402#endif
1403#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1404
1405 // Allocate RTMP_ADAPTER miniport adapter structure
1406 handle = kmalloc(sizeof(struct os_cookie), GFP_KERNEL);
1407 RT28XX_HANDLE_DEV_ASSIGN(handle, dev_p);
1408
1409 status = RTMPAllocAdapterBlock(handle, &pAd);
1410 if (status != NDIS_STATUS_SUCCESS)
1411 goto err_out_free_netdev;
1412
1413 net_dev->ml_priv = (PVOID)pAd;
1414 pAd->net_dev = net_dev; // must be before RT28XXNetDevInit()
1415
1416 RT28XXNetDevInit(_dev_p, net_dev, pAd);
1417
1418#ifdef CONFIG_STA_SUPPORT
1419 pAd->StaCfg.OriDevType = net_dev->type;
1420#endif // CONFIG_STA_SUPPORT //
1421
1422 // Find and assign a free interface name, raxx
1423// RT28XXAvailRANameAssign(net_dev->name);
1424
1425 // Post config
1426#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
1427 if (RT28XXProbePostConfig(_dev_p, pAd, argc) == FALSE)
1428 goto err_out_unmap;
1429#else
1430 if (RT28XXProbePostConfig(_dev_p, pAd, 0) == FALSE)
1431 goto err_out_unmap;
1432#endif // LINUX_VERSION_CODE //
1433
1434#ifdef CONFIG_STA_SUPPORT
1435 pAd->OpMode = OPMODE_STA;
1436#endif // CONFIG_STA_SUPPORT //
1437
1438
1439#ifdef MULTIPLE_CARD_SUPPORT
1440 // find its profile path
1441 pAd->MC_RowID = -1; // use default profile path
1442 RTMP_CardInfoRead(pAd);
1443
1444 if (pAd->MC_RowID == -1)
1445#ifdef CONFIG_STA_SUPPORT
1446 strcpy(pAd->MC_FileName, STA_PROFILE_PATH);
1447#endif // CONFIG_STA_SUPPORT //
1448
1449 DBGPRINT(RT_DEBUG_TRACE,
1450 ("MC> ROW = %d, PATH = %s\n", pAd->MC_RowID, pAd->MC_FileName));
1451#endif // MULTIPLE_CARD_SUPPORT //
1452
1453 // sample move
1454 if (rt_ieee80211_if_setup(net_dev, pAd) != NDIS_STATUS_SUCCESS)
1455 goto err_out_unmap;
1456
1457 // Register this device
1458 status = register_netdev(net_dev);
1459 if (status)
1460 goto err_out_unmap;
1461
1462 // Set driver data
1463 RT28XX_DRVDATA_SET(_dev_p);
1464
1465
1466
1467 *ppAd = pAd;
1468 return 0; // probe ok
1469
1470
1471 /* --------------------------- ERROR HANDLE --------------------------- */
1472err_out_unmap:
1473 RTMPFreeAdapter(pAd);
1474 RT28XX_UNMAP();
1475
1476err_out_free_netdev:
1477#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1478 free_netdev(net_dev);
1479#else
1480 kfree(net_dev);
1481#endif
1482
1483err_out:
1484 RT28XX_PUT_DEVICE(dev_p);
1485
1486#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
1487 return (LONG)NULL;
1488#else
1489 return -ENODEV; /* probe fail */
1490#endif // LINUX_VERSION_CODE //
1491} /* End of rt28xx_probe */
1492
1493
1494/*
1495========================================================================
1496Routine Description:
1497 The entry point for Linux kernel sent packet to our driver.
1498
1499Arguments:
1500 sk_buff *skb the pointer refer to a sk_buffer.
1501
1502Return Value:
1503 0
1504
1505Note:
1506 This function is the entry point of Tx Path for Os delivery packet to
1507 our driver. You only can put OS-depened & STA/AP common handle procedures
1508 in here.
1509========================================================================
1510*/
1511int rt28xx_packet_xmit(struct sk_buff *skb)
1512{
1513 struct net_device *net_dev = skb->dev;
1514 PRTMP_ADAPTER pAd = net_dev->ml_priv;
1515 int status = 0;
1516 PNDIS_PACKET pPacket = (PNDIS_PACKET) skb;
1517
1518 /* RT2870STA does this in RTMPSendPackets() */
1519#ifdef RALINK_ATE
1520 if (ATE_ON(pAd))
1521 {
1522 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_RESOURCES);
1523 return 0;
1524 }
1525#endif // RALINK_ATE //
1526
1527#ifdef CONFIG_STA_SUPPORT
1528 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1529 {
1530 // Drop send request since we are in monitor mode
1531 if (MONITOR_ON(pAd))
1532 {
1533 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
1534 goto done;
1535 }
1536 }
1537#endif // CONFIG_STA_SUPPORT //
1538
1539 // EapolStart size is 18
1540 if (skb->len < 14)
1541 {
1542 //printk("bad packet size: %d\n", pkt->len);
1543 hex_dump("bad packet", skb->data, skb->len);
1544 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
1545 goto done;
1546 }
1547
1548 RTMP_SET_PACKET_5VT(pPacket, 0);
1549// MiniportMMRequest(pAd, pkt->data, pkt->len);
1550#ifdef CONFIG_5VT_ENHANCE
1551 if (*(int*)(skb->cb) == BRIDGE_TAG) {
1552 RTMP_SET_PACKET_5VT(pPacket, 1);
1553 }
1554#endif
1555
1556
1557
1558#ifdef CONFIG_STA_SUPPORT
1559 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1560 {
1561
1562 STASendPackets((NDIS_HANDLE)pAd, (PPNDIS_PACKET) &pPacket, 1);
1563 }
1564
1565#endif // CONFIG_STA_SUPPORT //
1566
1567 status = 0;
1568done:
1569
1570 return status;
1571}
1572
1573
1574/*
1575========================================================================
1576Routine Description:
1577 Send a packet to WLAN.
1578
1579Arguments:
1580 skb_p points to our adapter
1581 dev_p which WLAN network interface
1582
1583Return Value:
1584 0: transmit successfully
1585 otherwise: transmit fail
1586
1587Note:
1588========================================================================
1589*/
1590INT rt28xx_send_packets(
1591 IN struct sk_buff *skb_p,
1592 IN struct net_device *net_dev)
1593{
1594 RTMP_ADAPTER *pAd = net_dev->ml_priv;
1595
1596 if (!(net_dev->flags & IFF_UP))
1597 {
1598 RELEASE_NDIS_PACKET(pAd, (PNDIS_PACKET)skb_p, NDIS_STATUS_FAILURE);
1599 return 0;
1600 }
1601
1602 NdisZeroMemory((PUCHAR)&skb_p->cb[CB_OFF], 15);
1603 RTMP_SET_PACKET_NET_DEVICE_MBSSID(skb_p, MAIN_MBSSID);
1604
1605 return rt28xx_packet_xmit(skb_p);
1606} /* End of MBSS_VirtualIF_PacketSend */
1607
1608
1609
1610
1611#if LINUX_VERSION_CODE <= 0x20402 // Red Hat 7.1
1612//static struct net_device *alloc_netdev(int sizeof_priv, const char *mask, void (*setup)(struct net_device *)) //sample
1613struct net_device *alloc_netdev(
1614 int sizeof_priv,
1615 const char *mask,
1616 void (*setup)(struct net_device *))
1617{
1618 struct net_device *dev;
1619 INT alloc_size;
1620
1621
1622 /* ensure 32-byte alignment of the private area */
1623 alloc_size = sizeof (*dev) + sizeof_priv + 31;
1624
1625 dev = (struct net_device *) kmalloc(alloc_size, GFP_KERNEL);
1626 if (dev == NULL)
1627 {
1628 DBGPRINT(RT_DEBUG_ERROR,
1629 ("alloc_netdev: Unable to allocate device memory.\n"));
1630 return NULL;
1631 }
1632
1633 memset(dev, 0, alloc_size);
1634
1635 if (sizeof_priv)
1636 dev->ml_priv = (void *) (((long)(dev + 1) + 31) & ~31);
1637
1638 setup(dev);
1639 strcpy(dev->name, mask);
1640
1641 return dev;
1642}
1643#endif // LINUX_VERSION_CODE //
1644
1645
1646void CfgInitHook(PRTMP_ADAPTER pAd)
1647{
1648 pAd->bBroadComHT = TRUE;
1649} /* End of CfgInitHook */
1650
1651
1652#if WIRELESS_EXT >= 12
1653// This function will be called when query /proc
1654struct iw_statistics *rt28xx_get_wireless_stats(
1655 IN struct net_device *net_dev)
1656{
1657 PRTMP_ADAPTER pAd = net_dev->ml_priv;
1658
1659
1660 DBGPRINT(RT_DEBUG_TRACE, ("rt28xx_get_wireless_stats --->\n"));
1661
1662 pAd->iw_stats.status = 0; // Status - device dependent for now
1663
1664 // link quality
1665 pAd->iw_stats.qual.qual = ((pAd->Mlme.ChannelQuality * 12)/10 + 10);
1666 if(pAd->iw_stats.qual.qual > 100)
1667 pAd->iw_stats.qual.qual = 100;
1668
1669#ifdef CONFIG_STA_SUPPORT
1670 if (pAd->OpMode == OPMODE_STA)
1671 pAd->iw_stats.qual.level = RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2);
1672#endif // CONFIG_STA_SUPPORT //
1673
1674 pAd->iw_stats.qual.noise = pAd->BbpWriteLatch[66]; // noise level (dBm)
1675
1676 pAd->iw_stats.qual.noise += 256 - 143;
1677 pAd->iw_stats.qual.updated = 1; // Flags to know if updated
1678#ifdef IW_QUAL_DBM
1679 pAd->iw_stats.qual.updated |= IW_QUAL_DBM; // Level + Noise are dBm
1680#endif // IW_QUAL_DBM //
1681
1682 pAd->iw_stats.discard.nwid = 0; // Rx : Wrong nwid/essid
1683 pAd->iw_stats.miss.beacon = 0; // Missed beacons/superframe
1684
1685 DBGPRINT(RT_DEBUG_TRACE, ("<--- rt28xx_get_wireless_stats\n"));
1686 return &pAd->iw_stats;
1687} /* End of rt28xx_get_wireless_stats */
1688#endif // WIRELESS_EXT //
1689
1690
1691
1692void tbtt_tasklet(unsigned long data)
1693{
1694#define MAX_TX_IN_TBTT (16)
1695
1696}
1697
1698INT rt28xx_ioctl(
1699 IN struct net_device *net_dev,
1700 IN OUT struct ifreq *rq,
1701 IN INT cmd)
1702{
1703 VIRTUAL_ADAPTER *pVirtualAd = NULL;
1704 RTMP_ADAPTER *pAd = NULL;
1705 INT ret = 0;
1706
1707 if (net_dev->priv_flags == INT_MAIN)
1708 {
1709 pAd = net_dev->ml_priv;
1710 }
1711 else
1712 {
1713 pVirtualAd = net_dev->ml_priv;
1714 pAd = pVirtualAd->RtmpDev->ml_priv;
1715 }
1716
1717 if (pAd == NULL)
1718 {
1719 /* if 1st open fail, pAd will be free;
1720 So the net_dev->ml_priv will be NULL in 2rd open */
1721 return -ENETDOWN;
1722 }
1723
1724
1725#ifdef CONFIG_STA_SUPPORT
1726 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1727 {
1728 ret = rt28xx_sta_ioctl(net_dev, rq, cmd);
1729 }
1730#endif // CONFIG_STA_SUPPORT //
1731
1732 return ret;
1733}
1734
1735/*
1736 ========================================================================
1737
1738 Routine Description:
1739 return ethernet statistics counter
1740
1741 Arguments:
1742 net_dev Pointer to net_device
1743
1744 Return Value:
1745 net_device_stats*
1746
1747 Note:
1748
1749 ========================================================================
1750*/
1751struct net_device_stats *RT28xx_get_ether_stats(
1752 IN struct net_device *net_dev)
1753{
1754 RTMP_ADAPTER *pAd = NULL;
1755
1756 if (net_dev)
1757 pAd = net_dev->ml_priv;
1758
1759 if (pAd)
1760 {
1761
1762 pAd->stats.rx_packets = pAd->WlanCounters.ReceivedFragmentCount.QuadPart;
1763 pAd->stats.tx_packets = pAd->WlanCounters.TransmittedFragmentCount.QuadPart;
1764
1765 pAd->stats.rx_bytes = pAd->RalinkCounters.ReceivedByteCount;
1766 pAd->stats.tx_bytes = pAd->RalinkCounters.TransmittedByteCount;
1767
1768 pAd->stats.rx_errors = pAd->Counters8023.RxErrors;
1769 pAd->stats.tx_errors = pAd->Counters8023.TxErrors;
1770
1771 pAd->stats.rx_dropped = 0;
1772 pAd->stats.tx_dropped = 0;
1773
1774 pAd->stats.multicast = pAd->WlanCounters.MulticastReceivedFrameCount.QuadPart; // multicast packets received
1775 pAd->stats.collisions = pAd->Counters8023.OneCollision + pAd->Counters8023.MoreCollisions; // Collision packets
1776
1777 pAd->stats.rx_length_errors = 0;
1778 pAd->stats.rx_over_errors = pAd->Counters8023.RxNoBuffer; // receiver ring buff overflow
1779 pAd->stats.rx_crc_errors = 0;//pAd->WlanCounters.FCSErrorCount; // recved pkt with crc error
1780 pAd->stats.rx_frame_errors = pAd->Counters8023.RcvAlignmentErrors; // recv'd frame alignment error
1781 pAd->stats.rx_fifo_errors = pAd->Counters8023.RxNoBuffer; // recv'r fifo overrun
1782 pAd->stats.rx_missed_errors = 0; // receiver missed packet
1783
1784 // detailed tx_errors
1785 pAd->stats.tx_aborted_errors = 0;
1786 pAd->stats.tx_carrier_errors = 0;
1787 pAd->stats.tx_fifo_errors = 0;
1788 pAd->stats.tx_heartbeat_errors = 0;
1789 pAd->stats.tx_window_errors = 0;
1790
1791 // for cslip etc
1792 pAd->stats.rx_compressed = 0;
1793 pAd->stats.tx_compressed = 0;
1794
1795 return &pAd->stats;
1796 }
1797 else
1798 return NULL;
1799}
1800
diff --git a/drivers/staging/rt3070/rt_profile.c b/drivers/staging/rt3070/rt_profile.c
new file mode 100644
index 000000000000..6eda27e6b8dc
--- /dev/null
+++ b/drivers/staging/rt3070/rt_profile.c
@@ -0,0 +1,2041 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26 */
27
28#include "rt_config.h"
29
30#ifdef DOT11_N_SUPPORT
31static void HTParametersHook(
32 IN PRTMP_ADAPTER pAd,
33 IN CHAR *pValueStr,
34 IN CHAR *pInput);
35#endif // DOT11_N_SUPPORT //
36
37#define ETH_MAC_ADDR_STR_LEN 17 // in format of xx:xx:xx:xx:xx:xx
38
39// We assume the s1 is a sting, s2 is a memory space with 6 bytes. and content of s1 will be changed.
40BOOLEAN rtstrmactohex(char *s1, char *s2)
41{
42 int i = 0;
43 char *ptokS = s1, *ptokE = s1;
44
45 if (strlen(s1) != ETH_MAC_ADDR_STR_LEN)
46 return FALSE;
47
48 while((*ptokS) != '\0')
49 {
50 if((ptokE = strchr(ptokS, ':')) != NULL)
51 *ptokE++ = '\0';
52 if ((strlen(ptokS) != 2) || (!isxdigit(*ptokS)) || (!isxdigit(*(ptokS+1))))
53 break; // fail
54 AtoH(ptokS, &s2[i++], 1);
55 ptokS = ptokE;
56 if (i == 6)
57 break; // parsing finished
58 }
59
60 return ( i == 6 ? TRUE : FALSE);
61
62}
63
64
65// we assume the s1 and s2 both are strings.
66BOOLEAN rtstrcasecmp(char *s1, char *s2)
67{
68 char *p1 = s1, *p2 = s2;
69
70 if (strlen(s1) != strlen(s2))
71 return FALSE;
72
73 while(*p1 != '\0')
74 {
75 if((*p1 != *p2) && ((*p1 ^ *p2) != 0x20))
76 return FALSE;
77 p1++;
78 p2++;
79 }
80
81 return TRUE;
82}
83
84// we assume the s1 (buffer) and s2 (key) both are strings.
85char * rtstrstruncasecmp(char * s1, char * s2)
86{
87 INT l1, l2, i;
88 char temp1, temp2;
89
90 l2 = strlen(s2);
91 if (!l2)
92 return (char *) s1;
93
94 l1 = strlen(s1);
95
96 while (l1 >= l2)
97 {
98 l1--;
99
100 for(i=0; i<l2; i++)
101 {
102 temp1 = *(s1+i);
103 temp2 = *(s2+i);
104
105 if (('a' <= temp1) && (temp1 <= 'z'))
106 temp1 = 'A'+(temp1-'a');
107 if (('a' <= temp2) && (temp2 <= 'z'))
108 temp2 = 'A'+(temp2-'a');
109
110 if (temp1 != temp2)
111 break;
112 }
113
114 if (i == l2)
115 return (char *) s1;
116
117 s1++;
118 }
119
120 return NULL; // not found
121}
122
123//add by kathy
124
125 /**
126 * strstr - Find the first substring in a %NUL terminated string
127 * @s1: The string to be searched
128 * @s2: The string to search for
129 */
130char * rtstrstr(const char * s1,const char * s2)
131{
132 INT l1, l2;
133
134 l2 = strlen(s2);
135 if (!l2)
136 return (char *) s1;
137
138 l1 = strlen(s1);
139
140 while (l1 >= l2)
141 {
142 l1--;
143 if (!memcmp(s1,s2,l2))
144 return (char *) s1;
145 s1++;
146 }
147
148 return NULL;
149}
150
151/**
152 * rstrtok - Split a string into tokens
153 * @s: The string to be searched
154 * @ct: The characters to search for
155 * * WARNING: strtok is deprecated, use strsep instead. However strsep is not compatible with old architecture.
156 */
157char * __rstrtok;
158char * rstrtok(char * s,const char * ct)
159{
160 char *sbegin, *send;
161
162 sbegin = s ? s : __rstrtok;
163 if (!sbegin)
164 {
165 return NULL;
166 }
167
168 sbegin += strspn(sbegin,ct);
169 if (*sbegin == '\0')
170 {
171 __rstrtok = NULL;
172 return( NULL );
173 }
174
175 send = strpbrk( sbegin, ct);
176 if (send && *send != '\0')
177 *send++ = '\0';
178
179 __rstrtok = send;
180
181 return (sbegin);
182}
183
184/**
185 * delimitcnt - return the count of a given delimiter in a given string.
186 * @s: The string to be searched.
187 * @ct: The delimiter to search for.
188 * Notice : We suppose the delimiter is a single-char string(for example : ";").
189 */
190INT delimitcnt(char * s,const char * ct)
191{
192 INT count = 0;
193 /* point to the beginning of the line */
194 const char *token = s;
195
196 for ( ;; )
197 {
198 token = strpbrk(token, ct); /* search for delimiters */
199
200 if ( token == NULL )
201 {
202 /* advanced to the terminating null character */
203 break;
204 }
205 /* skip the delimiter */
206 ++token;
207
208 /*
209 * Print the found text: use len with %.*s to specify field width.
210 */
211
212 /* accumulate delimiter count */
213 ++count;
214 }
215 return count;
216}
217
218/*
219 * converts the Internet host address from the standard numbers-and-dots notation
220 * into binary data.
221 * returns nonzero if the address is valid, zero if not.
222 */
223int rtinet_aton(const char *cp, unsigned int *addr)
224{
225 unsigned int val;
226 int base, n;
227 char c;
228 unsigned int parts[4];
229 unsigned int *pp = parts;
230
231 for (;;)
232 {
233 /*
234 * Collect number up to ``.''.
235 * Values are specified as for C:
236 * 0x=hex, 0=octal, other=decimal.
237 */
238 val = 0;
239 base = 10;
240 if (*cp == '0')
241 {
242 if (*++cp == 'x' || *cp == 'X')
243 base = 16, cp++;
244 else
245 base = 8;
246 }
247 while ((c = *cp) != '\0')
248 {
249 if (isdigit((unsigned char) c))
250 {
251 val = (val * base) + (c - '0');
252 cp++;
253 continue;
254 }
255 if (base == 16 && isxdigit((unsigned char) c))
256 {
257 val = (val << 4) +
258 (c + 10 - (islower((unsigned char) c) ? 'a' : 'A'));
259 cp++;
260 continue;
261 }
262 break;
263 }
264 if (*cp == '.')
265 {
266 /*
267 * Internet format: a.b.c.d a.b.c (with c treated as 16-bits)
268 * a.b (with b treated as 24 bits)
269 */
270 if (pp >= parts + 3 || val > 0xff)
271 return 0;
272 *pp++ = val, cp++;
273 }
274 else
275 break;
276 }
277
278 /*
279 * Check for trailing junk.
280 */
281 while (*cp)
282 if (!isspace((unsigned char) *cp++))
283 return 0;
284
285 /*
286 * Concoct the address according to the number of parts specified.
287 */
288 n = pp - parts + 1;
289 switch (n)
290 {
291
292 case 1: /* a -- 32 bits */
293 break;
294
295 case 2: /* a.b -- 8.24 bits */
296 if (val > 0xffffff)
297 return 0;
298 val |= parts[0] << 24;
299 break;
300
301 case 3: /* a.b.c -- 8.8.16 bits */
302 if (val > 0xffff)
303 return 0;
304 val |= (parts[0] << 24) | (parts[1] << 16);
305 break;
306
307 case 4: /* a.b.c.d -- 8.8.8.8 bits */
308 if (val > 0xff)
309 return 0;
310 val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
311 break;
312 }
313
314 *addr = htonl(val);
315 return 1;
316
317}
318
319/*
320 ========================================================================
321
322 Routine Description:
323 Find key section for Get key parameter.
324
325 Arguments:
326 buffer Pointer to the buffer to start find the key section
327 section the key of the secion to be find
328
329 Return Value:
330 NULL Fail
331 Others Success
332 ========================================================================
333*/
334PUCHAR RTMPFindSection(
335 IN PCHAR buffer)
336{
337 CHAR temp_buf[32];
338 PUCHAR ptr;
339
340 strcpy(temp_buf, "Default");
341
342 if((ptr = rtstrstr(buffer, temp_buf)) != NULL)
343 return (ptr+strlen("\n"));
344 else
345 return NULL;
346}
347
348/*
349 ========================================================================
350
351 Routine Description:
352 Get key parameter.
353
354 Arguments:
355 key Pointer to key string
356 dest Pointer to destination
357 destsize The datasize of the destination
358 buffer Pointer to the buffer to start find the key
359
360 Return Value:
361 TRUE Success
362 FALSE Fail
363
364 Note:
365 This routine get the value with the matched key (case case-sensitive)
366 ========================================================================
367*/
368INT RTMPGetKeyParameter(
369 IN PCHAR key,
370 OUT PCHAR dest,
371 IN INT destsize,
372 IN PCHAR buffer)
373{
374 UCHAR *temp_buf1 = NULL;
375 UCHAR *temp_buf2 = NULL;
376 CHAR *start_ptr;
377 CHAR *end_ptr;
378 CHAR *ptr;
379 CHAR *offset = 0;
380 INT len;
381
382 //temp_buf1 = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
383 os_alloc_mem(NULL, &temp_buf1, MAX_PARAM_BUFFER_SIZE);
384
385 if(temp_buf1 == NULL)
386 return (FALSE);
387
388 //temp_buf2 = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
389 os_alloc_mem(NULL, &temp_buf2, MAX_PARAM_BUFFER_SIZE);
390 if(temp_buf2 == NULL)
391 {
392 os_free_mem(NULL, temp_buf1);
393 return (FALSE);
394 }
395
396 //find section
397 if((offset = RTMPFindSection(buffer)) == NULL)
398 {
399 os_free_mem(NULL, temp_buf1);
400 os_free_mem(NULL, temp_buf2);
401 return (FALSE);
402 }
403
404 strcpy(temp_buf1, "\n");
405 strcat(temp_buf1, key);
406 strcat(temp_buf1, "=");
407
408 //search key
409 if((start_ptr=rtstrstr(offset, temp_buf1))==NULL)
410 {
411 os_free_mem(NULL, temp_buf1);
412 os_free_mem(NULL, temp_buf2);
413 return (FALSE);
414 }
415
416 start_ptr+=strlen("\n");
417 if((end_ptr=rtstrstr(start_ptr, "\n"))==NULL)
418 end_ptr=start_ptr+strlen(start_ptr);
419
420 if (end_ptr<start_ptr)
421 {
422 os_free_mem(NULL, temp_buf1);
423 os_free_mem(NULL, temp_buf2);
424 return (FALSE);
425 }
426
427 NdisMoveMemory(temp_buf2, start_ptr, end_ptr-start_ptr);
428 temp_buf2[end_ptr-start_ptr]='\0';
429 len = strlen(temp_buf2);
430 strcpy(temp_buf1, temp_buf2);
431 if((start_ptr=rtstrstr(temp_buf1, "=")) == NULL)
432 {
433 os_free_mem(NULL, temp_buf1);
434 os_free_mem(NULL, temp_buf2);
435 return (FALSE);
436 }
437
438 strcpy(temp_buf2, start_ptr+1);
439 ptr = temp_buf2;
440 //trim space or tab
441 while(*ptr != 0x00)
442 {
443 if( (*ptr == ' ') || (*ptr == '\t') )
444 ptr++;
445 else
446 break;
447 }
448
449 len = strlen(ptr);
450 memset(dest, 0x00, destsize);
451 strncpy(dest, ptr, len >= destsize ? destsize: len);
452
453 os_free_mem(NULL, temp_buf1);
454 os_free_mem(NULL, temp_buf2);
455 return TRUE;
456}
457
458/*
459 ========================================================================
460
461 Routine Description:
462 Get key parameter.
463
464 Arguments:
465 key Pointer to key string
466 dest Pointer to destination
467 destsize The datasize of the destination
468 buffer Pointer to the buffer to start find the key
469
470 Return Value:
471 TRUE Success
472 FALSE Fail
473
474 Note:
475 This routine get the value with the matched key (case case-sensitive).
476 It is called for parsing SSID and any key string.
477 ========================================================================
478*/
479INT RTMPGetCriticalParameter(
480 IN PCHAR key,
481 OUT PCHAR dest,
482 IN INT destsize,
483 IN PCHAR buffer)
484{
485 UCHAR *temp_buf1 = NULL;
486 UCHAR *temp_buf2 = NULL;
487 CHAR *start_ptr;
488 CHAR *end_ptr;
489 CHAR *ptr;
490 CHAR *offset = 0;
491 INT len;
492
493 //temp_buf1 = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
494 os_alloc_mem(NULL, &temp_buf1, MAX_PARAM_BUFFER_SIZE);
495
496 if(temp_buf1 == NULL)
497 return (FALSE);
498
499 //temp_buf2 = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
500 os_alloc_mem(NULL, &temp_buf2, MAX_PARAM_BUFFER_SIZE);
501 if(temp_buf2 == NULL)
502 {
503 os_free_mem(NULL, temp_buf1);
504 return (FALSE);
505 }
506
507 //find section
508 if((offset = RTMPFindSection(buffer)) == NULL)
509 {
510 os_free_mem(NULL, temp_buf1);
511 os_free_mem(NULL, temp_buf2);
512 return (FALSE);
513 }
514
515 strcpy(temp_buf1, "\n");
516 strcat(temp_buf1, key);
517 strcat(temp_buf1, "=");
518
519 //search key
520 if((start_ptr=rtstrstr(offset, temp_buf1))==NULL)
521 {
522 os_free_mem(NULL, temp_buf1);
523 os_free_mem(NULL, temp_buf2);
524 return (FALSE);
525 }
526
527 start_ptr+=strlen("\n");
528 if((end_ptr=rtstrstr(start_ptr, "\n"))==NULL)
529 end_ptr=start_ptr+strlen(start_ptr);
530
531 if (end_ptr<start_ptr)
532 {
533 os_free_mem(NULL, temp_buf1);
534 os_free_mem(NULL, temp_buf2);
535 return (FALSE);
536 }
537
538 NdisMoveMemory(temp_buf2, start_ptr, end_ptr-start_ptr);
539 temp_buf2[end_ptr-start_ptr]='\0';
540 len = strlen(temp_buf2);
541 strcpy(temp_buf1, temp_buf2);
542 if((start_ptr=rtstrstr(temp_buf1, "=")) == NULL)
543 {
544 os_free_mem(NULL, temp_buf1);
545 os_free_mem(NULL, temp_buf2);
546 return (FALSE);
547 }
548
549 strcpy(temp_buf2, start_ptr+1);
550 ptr = temp_buf2;
551
552 //trim tab
553 /* We cannot trim space(' ') for SSID and key string. */
554 while(*ptr != 0x00)
555 {
556 //if( (*ptr == ' ') || (*ptr == '\t') )
557 if( (*ptr == '\t') )
558 ptr++;
559 else
560 break;
561 }
562
563 len = strlen(ptr);
564 memset(dest, 0x00, destsize);
565 strncpy(dest, ptr, len >= destsize ? destsize: len);
566
567 os_free_mem(NULL, temp_buf1);
568 os_free_mem(NULL, temp_buf2);
569 return TRUE;
570}
571
572/*
573 ========================================================================
574
575 Routine Description:
576 Get multiple key parameter.
577
578 Arguments:
579 key Pointer to key string
580 dest Pointer to destination
581 destsize The datasize of the destination
582 buffer Pointer to the buffer to start find the key
583
584 Return Value:
585 TRUE Success
586 FALSE Fail
587
588 Note:
589 This routine get the value with the matched key (case case-sensitive)
590 ========================================================================
591*/
592INT RTMPGetKeyParameterWithOffset(
593 IN PCHAR key,
594 OUT PCHAR dest,
595 OUT USHORT *end_offset,
596 IN INT destsize,
597 IN PCHAR buffer,
598 IN BOOLEAN bTrimSpace)
599{
600 UCHAR *temp_buf1 = NULL;
601 UCHAR *temp_buf2 = NULL;
602 CHAR *start_ptr;
603 CHAR *end_ptr;
604 CHAR *ptr;
605 CHAR *offset = 0;
606 INT len;
607
608 if (*end_offset >= MAX_INI_BUFFER_SIZE)
609 return (FALSE);
610
611 os_alloc_mem(NULL, &temp_buf1, MAX_PARAM_BUFFER_SIZE);
612
613 if(temp_buf1 == NULL)
614 return (FALSE);
615
616 os_alloc_mem(NULL, &temp_buf2, MAX_PARAM_BUFFER_SIZE);
617 if(temp_buf2 == NULL)
618 {
619 os_free_mem(NULL, temp_buf1);
620 return (FALSE);
621 }
622
623 //find section
624 if(*end_offset == 0)
625 {
626 if ((offset = RTMPFindSection(buffer)) == NULL)
627 {
628 os_free_mem(NULL, temp_buf1);
629 os_free_mem(NULL, temp_buf2);
630 return (FALSE);
631 }
632 }
633 else
634 offset = buffer + (*end_offset);
635
636 strcpy(temp_buf1, "\n");
637 strcat(temp_buf1, key);
638 strcat(temp_buf1, "=");
639
640 //search key
641 if((start_ptr=rtstrstr(offset, temp_buf1))==NULL)
642 {
643 os_free_mem(NULL, temp_buf1);
644 os_free_mem(NULL, temp_buf2);
645 return (FALSE);
646 }
647
648 start_ptr+=strlen("\n");
649 if((end_ptr=rtstrstr(start_ptr, "\n"))==NULL)
650 end_ptr=start_ptr+strlen(start_ptr);
651
652 if (end_ptr<start_ptr)
653 {
654 os_free_mem(NULL, temp_buf1);
655 os_free_mem(NULL, temp_buf2);
656 return (FALSE);
657 }
658
659 *end_offset = end_ptr - buffer;
660
661 NdisMoveMemory(temp_buf2, start_ptr, end_ptr-start_ptr);
662 temp_buf2[end_ptr-start_ptr]='\0';
663 len = strlen(temp_buf2);
664 strcpy(temp_buf1, temp_buf2);
665 if((start_ptr=rtstrstr(temp_buf1, "=")) == NULL)
666 {
667 os_free_mem(NULL, temp_buf1);
668 os_free_mem(NULL, temp_buf2);
669 return (FALSE);
670 }
671
672 strcpy(temp_buf2, start_ptr+1);
673 ptr = temp_buf2;
674 //trim space or tab
675 while(*ptr != 0x00)
676 {
677 if((bTrimSpace && (*ptr == ' ')) || (*ptr == '\t') )
678 ptr++;
679 else
680 break;
681 }
682
683 len = strlen(ptr);
684 memset(dest, 0x00, destsize);
685 strncpy(dest, ptr, len >= destsize ? destsize: len);
686
687 os_free_mem(NULL, temp_buf1);
688 os_free_mem(NULL, temp_buf2);
689 return TRUE;
690}
691
692
693static int rtmp_parse_key_buffer_from_file(IN PRTMP_ADAPTER pAd,IN char *buffer,IN ULONG KeyType,IN INT BSSIdx,IN INT KeyIdx)
694{
695 PUCHAR keybuff;
696 INT i = BSSIdx, idx = KeyIdx;
697 ULONG KeyLen;
698 UCHAR CipherAlg = CIPHER_WEP64;
699
700 keybuff = buffer;
701 KeyLen = strlen(keybuff);
702
703 if (KeyType == 1)
704 {//Ascii
705 if( (KeyLen == 5) || (KeyLen == 13))
706 {
707 pAd->SharedKey[i][idx].KeyLen = KeyLen;
708 NdisMoveMemory(pAd->SharedKey[i][idx].Key, keybuff, KeyLen);
709 if (KeyLen == 5)
710 CipherAlg = CIPHER_WEP64;
711 else
712 CipherAlg = CIPHER_WEP128;
713 pAd->SharedKey[i][idx].CipherAlg = CipherAlg;
714
715 DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) Key%dStr=%s and type=%s\n", i, idx+1, keybuff, (KeyType == 0) ? "Hex":"Ascii"));
716 return 1;
717 }
718 else
719 {//Invalid key length
720 DBGPRINT(RT_DEBUG_ERROR, ("Key%dStr is Invalid key length! KeyLen = %ld!\n", idx+1, KeyLen));
721 return 0;
722 }
723 }
724 else
725 {//Hex type
726 if( (KeyLen == 10) || (KeyLen == 26))
727 {
728 pAd->SharedKey[i][idx].KeyLen = KeyLen / 2;
729 AtoH(keybuff, pAd->SharedKey[i][idx].Key, KeyLen / 2);
730 if (KeyLen == 10)
731 CipherAlg = CIPHER_WEP64;
732 else
733 CipherAlg = CIPHER_WEP128;
734 pAd->SharedKey[i][idx].CipherAlg = CipherAlg;
735
736 DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) Key%dStr=%s and type=%s\n", i, idx+1, keybuff, (KeyType == 0) ? "Hex":"Ascii"));
737 return 1;
738 }
739 else
740 {//Invalid key length
741 DBGPRINT(RT_DEBUG_ERROR, ("I/F(ra%d) Key%dStr is Invalid key length! KeyLen = %ld!\n", i, idx+1, KeyLen));
742 return 0;
743 }
744 }
745}
746static void rtmp_read_key_parms_from_file(IN PRTMP_ADAPTER pAd, char *tmpbuf, char *buffer)
747{
748 char tok_str[16];
749 PUCHAR macptr;
750 INT i = 0, idx;
751 ULONG KeyType[MAX_MBSSID_NUM];
752 ULONG KeyIdx;
753
754 NdisZeroMemory(KeyType, MAX_MBSSID_NUM);
755
756 //DefaultKeyID
757 if(RTMPGetKeyParameter("DefaultKeyID", tmpbuf, 25, buffer))
758 {
759
760#ifdef CONFIG_STA_SUPPORT
761 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
762 {
763 KeyIdx = simple_strtol(tmpbuf, 0, 10);
764 if((KeyIdx >= 1 ) && (KeyIdx <= 4))
765 pAd->StaCfg.DefaultKeyId = (UCHAR) (KeyIdx - 1);
766 else
767 pAd->StaCfg.DefaultKeyId = 0;
768
769 DBGPRINT(RT_DEBUG_TRACE, ("DefaultKeyID(0~3)=%d\n", pAd->StaCfg.DefaultKeyId));
770 }
771#endif // CONFIG_STA_SUPPORT //
772 }
773
774
775 for (idx = 0; idx < 4; idx++)
776 {
777 sprintf(tok_str, "Key%dType", idx + 1);
778 //Key1Type
779 if (RTMPGetKeyParameter(tok_str, tmpbuf, 128, buffer))
780 {
781 for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
782 {
783 KeyType[i] = simple_strtol(macptr, 0, 10);
784 }
785
786#ifdef CONFIG_STA_SUPPORT
787 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
788 {
789 sprintf(tok_str, "Key%dStr", idx + 1);
790 if (RTMPGetCriticalParameter(tok_str, tmpbuf, 128, buffer))
791 {
792 rtmp_parse_key_buffer_from_file(pAd, tmpbuf, KeyType[BSS0], BSS0, idx);
793 }
794 }
795#endif // CONFIG_STA_SUPPORT //
796 }
797 }
798}
799
800
801#ifdef CONFIG_STA_SUPPORT
802static void rtmp_read_sta_wmm_parms_from_file(IN PRTMP_ADAPTER pAd, char *tmpbuf, char *buffer)
803{
804 PUCHAR macptr;
805 INT i=0;
806 BOOLEAN bWmmEnable = FALSE;
807
808 //WmmCapable
809 if(RTMPGetKeyParameter("WmmCapable", tmpbuf, 32, buffer))
810 {
811 if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
812 {
813 pAd->CommonCfg.bWmmCapable = TRUE;
814 bWmmEnable = TRUE;
815 }
816 else //Disable
817 {
818 pAd->CommonCfg.bWmmCapable = FALSE;
819 }
820
821 DBGPRINT(RT_DEBUG_TRACE, ("WmmCapable=%d\n", pAd->CommonCfg.bWmmCapable));
822 }
823
824#ifdef QOS_DLS_SUPPORT
825 //DLSCapable
826 if(RTMPGetKeyParameter("DLSCapable", tmpbuf, 32, buffer))
827 {
828 if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
829 {
830 pAd->CommonCfg.bDLSCapable = TRUE;
831 }
832 else //Disable
833 {
834 pAd->CommonCfg.bDLSCapable = FALSE;
835 }
836
837 DBGPRINT(RT_DEBUG_TRACE, ("bDLSCapable=%d\n", pAd->CommonCfg.bDLSCapable));
838 }
839#endif // QOS_DLS_SUPPORT //
840
841 //AckPolicy for AC_BK, AC_BE, AC_VI, AC_VO
842 if(RTMPGetKeyParameter("AckPolicy", tmpbuf, 32, buffer))
843 {
844 for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
845 {
846 pAd->CommonCfg.AckPolicy[i] = (UCHAR)simple_strtol(macptr, 0, 10);
847
848 DBGPRINT(RT_DEBUG_TRACE, ("AckPolicy[%d]=%d\n", i, pAd->CommonCfg.AckPolicy[i]));
849 }
850 }
851
852 if (bWmmEnable)
853 {
854 //APSDCapable
855 if(RTMPGetKeyParameter("APSDCapable", tmpbuf, 10, buffer))
856 {
857 if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
858 pAd->CommonCfg.bAPSDCapable = TRUE;
859 else
860 pAd->CommonCfg.bAPSDCapable = FALSE;
861
862 DBGPRINT(RT_DEBUG_TRACE, ("APSDCapable=%d\n", pAd->CommonCfg.bAPSDCapable));
863 }
864
865 //APSDAC for AC_BE, AC_BK, AC_VI, AC_VO
866 if(RTMPGetKeyParameter("APSDAC", tmpbuf, 32, buffer))
867 {
868 BOOLEAN apsd_ac[4];
869
870 for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
871 {
872 apsd_ac[i] = (BOOLEAN)simple_strtol(macptr, 0, 10);
873
874 DBGPRINT(RT_DEBUG_TRACE, ("APSDAC%d %d\n", i, apsd_ac[i]));
875 }
876
877 pAd->CommonCfg.bAPSDAC_BE = apsd_ac[0];
878 pAd->CommonCfg.bAPSDAC_BK = apsd_ac[1];
879 pAd->CommonCfg.bAPSDAC_VI = apsd_ac[2];
880 pAd->CommonCfg.bAPSDAC_VO = apsd_ac[3];
881 }
882 }
883
884}
885#endif // CONFIG_STA_SUPPORT //
886
887
888NDIS_STATUS RTMPReadParametersHook(
889 IN PRTMP_ADAPTER pAd)
890{
891 PUCHAR src = NULL;
892 struct file *srcf;
893 INT retval, orgfsuid, orgfsgid;
894 mm_segment_t orgfs;
895 CHAR *buffer;
896 CHAR *tmpbuf;
897 ULONG RtsThresh;
898 ULONG FragThresh;
899#ifdef CONFIG_STA_SUPPORT
900 UCHAR keyMaterial[40];
901#endif // CONFIG_STA_SUPPORT //
902
903
904 PUCHAR macptr;
905 INT i = 0;
906
907 buffer = kmalloc(MAX_INI_BUFFER_SIZE, MEM_ALLOC_FLAG);
908 if(buffer == NULL)
909 return NDIS_STATUS_FAILURE;
910
911 tmpbuf = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
912 if(tmpbuf == NULL)
913 {
914 kfree(buffer);
915 return NDIS_STATUS_FAILURE;
916 }
917
918#ifdef CONFIG_STA_SUPPORT
919 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
920 src = STA_PROFILE_PATH;
921#endif // CONFIG_STA_SUPPORT //
922#ifdef MULTIPLE_CARD_SUPPORT
923 src = pAd->MC_FileName;
924#endif // MULTIPLE_CARD_SUPPORT //
925
926 // Save uid and gid used for filesystem access.
927 // Set user and group to 0 (root)
928#if 0
929 orgfsuid = current->fsuid;
930 orgfsgid = current->fsgid;
931 current->fsuid=current->fsgid = 0;
932#endif
933 orgfs = get_fs();
934 set_fs(KERNEL_DS);
935
936 if (src && *src)
937 {
938 srcf = filp_open(src, O_RDONLY, 0);
939 if (IS_ERR(srcf))
940 {
941 DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld opening %s\n", -PTR_ERR(srcf),src));
942 }
943 else
944 {
945 // The object must have a read method
946 if (srcf->f_op && srcf->f_op->read)
947 {
948 memset(buffer, 0x00, MAX_INI_BUFFER_SIZE);
949 retval=srcf->f_op->read(srcf, buffer, MAX_INI_BUFFER_SIZE, &srcf->f_pos);
950 if (retval < 0)
951 {
952 DBGPRINT(RT_DEBUG_TRACE, ("--> Read %s error %d\n", src, -retval));
953 }
954 else
955 {
956 // set file parameter to portcfg
957 //CountryRegion
958 if(RTMPGetKeyParameter("CountryRegion", tmpbuf, 25, buffer))
959 {
960 pAd->CommonCfg.CountryRegion = (UCHAR) simple_strtol(tmpbuf, 0, 10);
961 DBGPRINT(RT_DEBUG_TRACE, ("CountryRegion=%d\n", pAd->CommonCfg.CountryRegion));
962 }
963 //CountryRegionABand
964 if(RTMPGetKeyParameter("CountryRegionABand", tmpbuf, 25, buffer))
965 {
966 pAd->CommonCfg.CountryRegionForABand= (UCHAR) simple_strtol(tmpbuf, 0, 10);
967 DBGPRINT(RT_DEBUG_TRACE, ("CountryRegionABand=%d\n", pAd->CommonCfg.CountryRegionForABand));
968 }
969 //CountryCode
970 if(RTMPGetKeyParameter("CountryCode", tmpbuf, 25, buffer))
971 {
972 NdisMoveMemory(pAd->CommonCfg.CountryCode, tmpbuf , 2);
973#ifdef CONFIG_STA_SUPPORT
974#ifdef EXT_BUILD_CHANNEL_LIST
975 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
976 NdisMoveMemory(pAd->StaCfg.StaOriCountryCode, tmpbuf , 2);
977#endif // EXT_BUILD_CHANNEL_LIST //
978#endif // CONFIG_STA_SUPPORT //
979 if (strlen(pAd->CommonCfg.CountryCode) != 0)
980 {
981 pAd->CommonCfg.bCountryFlag = TRUE;
982 }
983 DBGPRINT(RT_DEBUG_TRACE, ("CountryCode=%s\n", pAd->CommonCfg.CountryCode));
984 }
985 //ChannelGeography
986 if(RTMPGetKeyParameter("ChannelGeography", tmpbuf, 25, buffer))
987 {
988 UCHAR Geography = (UCHAR) simple_strtol(tmpbuf, 0, 10);
989 if (Geography <= BOTH)
990 {
991 pAd->CommonCfg.Geography = Geography;
992 pAd->CommonCfg.CountryCode[2] =
993 (pAd->CommonCfg.Geography == BOTH) ? ' ' : ((pAd->CommonCfg.Geography == IDOR) ? 'I' : 'O');
994#ifdef CONFIG_STA_SUPPORT
995#ifdef EXT_BUILD_CHANNEL_LIST
996 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
997 pAd->StaCfg.StaOriGeography = pAd->CommonCfg.Geography;
998#endif // EXT_BUILD_CHANNEL_LIST //
999#endif // CONFIG_STA_SUPPORT //
1000 DBGPRINT(RT_DEBUG_TRACE, ("ChannelGeography=%d\n", pAd->CommonCfg.Geography));
1001 }
1002 }
1003 else
1004 {
1005 pAd->CommonCfg.Geography = BOTH;
1006 pAd->CommonCfg.CountryCode[2] = ' ';
1007 }
1008
1009
1010#ifdef CONFIG_STA_SUPPORT
1011 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1012 {
1013 //SSID
1014 if (RTMPGetCriticalParameter("SSID", tmpbuf, 256, buffer))
1015 {
1016 if (strlen(tmpbuf) <= 32)
1017 {
1018 pAd->CommonCfg.SsidLen = (UCHAR) strlen(tmpbuf);
1019 NdisZeroMemory(pAd->CommonCfg.Ssid, NDIS_802_11_LENGTH_SSID);
1020 NdisMoveMemory(pAd->CommonCfg.Ssid, tmpbuf, pAd->CommonCfg.SsidLen);
1021 pAd->MlmeAux.AutoReconnectSsidLen = pAd->CommonCfg.SsidLen;
1022 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, NDIS_802_11_LENGTH_SSID);
1023 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, tmpbuf, pAd->MlmeAux.AutoReconnectSsidLen);
1024 pAd->MlmeAux.SsidLen = pAd->CommonCfg.SsidLen;
1025 NdisZeroMemory(pAd->MlmeAux.Ssid, NDIS_802_11_LENGTH_SSID);
1026 NdisMoveMemory(pAd->MlmeAux.Ssid, tmpbuf, pAd->MlmeAux.SsidLen);
1027 DBGPRINT(RT_DEBUG_TRACE, ("%s::(SSID=%s)\n", __FUNCTION__, tmpbuf));
1028 }
1029 }
1030 }
1031#endif // CONFIG_STA_SUPPORT //
1032
1033#ifdef CONFIG_STA_SUPPORT
1034 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1035 {
1036 //NetworkType
1037 if (RTMPGetKeyParameter("NetworkType", tmpbuf, 25, buffer))
1038 {
1039 pAd->bConfigChanged = TRUE;
1040 if (strcmp(tmpbuf, "Adhoc") == 0)
1041 pAd->StaCfg.BssType = BSS_ADHOC;
1042 else //Default Infrastructure mode
1043 pAd->StaCfg.BssType = BSS_INFRA;
1044 // Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
1045 pAd->StaCfg.WpaState = SS_NOTUSE;
1046 DBGPRINT(RT_DEBUG_TRACE, ("%s::(NetworkType=%d)\n", __FUNCTION__, pAd->StaCfg.BssType));
1047 }
1048 }
1049#endif // CONFIG_STA_SUPPORT //
1050 //Channel
1051 if(RTMPGetKeyParameter("Channel", tmpbuf, 10, buffer))
1052 {
1053 pAd->CommonCfg.Channel = (UCHAR) simple_strtol(tmpbuf, 0, 10);
1054 DBGPRINT(RT_DEBUG_TRACE, ("Channel=%d\n", pAd->CommonCfg.Channel));
1055 }
1056 //WirelessMode
1057 if(RTMPGetKeyParameter("WirelessMode", tmpbuf, 10, buffer))
1058 {
1059 int value = 0, maxPhyMode = PHY_11G;
1060
1061#ifdef DOT11_N_SUPPORT
1062 maxPhyMode = PHY_11N_5G;
1063#endif // DOT11_N_SUPPORT //
1064
1065 value = simple_strtol(tmpbuf, 0, 10);
1066
1067 if (value <= maxPhyMode)
1068 {
1069 pAd->CommonCfg.PhyMode = value;
1070 }
1071 DBGPRINT(RT_DEBUG_TRACE, ("PhyMode=%d\n", pAd->CommonCfg.PhyMode));
1072 }
1073 //BasicRate
1074 if(RTMPGetKeyParameter("BasicRate", tmpbuf, 10, buffer))
1075 {
1076 pAd->CommonCfg.BasicRateBitmap = (ULONG) simple_strtol(tmpbuf, 0, 10);
1077 DBGPRINT(RT_DEBUG_TRACE, ("BasicRate=%ld\n", pAd->CommonCfg.BasicRateBitmap));
1078 }
1079 //BeaconPeriod
1080 if(RTMPGetKeyParameter("BeaconPeriod", tmpbuf, 10, buffer))
1081 {
1082 pAd->CommonCfg.BeaconPeriod = (USHORT) simple_strtol(tmpbuf, 0, 10);
1083 DBGPRINT(RT_DEBUG_TRACE, ("BeaconPeriod=%d\n", pAd->CommonCfg.BeaconPeriod));
1084 }
1085 //TxPower
1086 if(RTMPGetKeyParameter("TxPower", tmpbuf, 10, buffer))
1087 {
1088 pAd->CommonCfg.TxPowerPercentage = (ULONG) simple_strtol(tmpbuf, 0, 10);
1089#ifdef CONFIG_STA_SUPPORT
1090 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1091 pAd->CommonCfg.TxPowerDefault = pAd->CommonCfg.TxPowerPercentage;
1092#endif // CONFIG_STA_SUPPORT //
1093 DBGPRINT(RT_DEBUG_TRACE, ("TxPower=%ld\n", pAd->CommonCfg.TxPowerPercentage));
1094 }
1095 //BGProtection
1096 if(RTMPGetKeyParameter("BGProtection", tmpbuf, 10, buffer))
1097 {
1098 switch (simple_strtol(tmpbuf, 0, 10))
1099 {
1100 case 1: //Always On
1101 pAd->CommonCfg.UseBGProtection = 1;
1102 break;
1103 case 2: //Always OFF
1104 pAd->CommonCfg.UseBGProtection = 2;
1105 break;
1106 case 0: //AUTO
1107 default:
1108 pAd->CommonCfg.UseBGProtection = 0;
1109 break;
1110 }
1111 DBGPRINT(RT_DEBUG_TRACE, ("BGProtection=%ld\n", pAd->CommonCfg.UseBGProtection));
1112 }
1113 //OLBCDetection
1114 if(RTMPGetKeyParameter("DisableOLBC", tmpbuf, 10, buffer))
1115 {
1116 switch (simple_strtol(tmpbuf, 0, 10))
1117 {
1118 case 1: //disable OLBC Detection
1119 pAd->CommonCfg.DisableOLBCDetect = 1;
1120 break;
1121 case 0: //enable OLBC Detection
1122 pAd->CommonCfg.DisableOLBCDetect = 0;
1123 break;
1124 default:
1125 pAd->CommonCfg.DisableOLBCDetect= 0;
1126 break;
1127 }
1128 DBGPRINT(RT_DEBUG_TRACE, ("OLBCDetection=%ld\n", pAd->CommonCfg.DisableOLBCDetect));
1129 }
1130 //TxPreamble
1131 if(RTMPGetKeyParameter("TxPreamble", tmpbuf, 10, buffer))
1132 {
1133 switch (simple_strtol(tmpbuf, 0, 10))
1134 {
1135 case Rt802_11PreambleShort:
1136 pAd->CommonCfg.TxPreamble = Rt802_11PreambleShort;
1137 break;
1138 case Rt802_11PreambleLong:
1139 default:
1140 pAd->CommonCfg.TxPreamble = Rt802_11PreambleLong;
1141 break;
1142 }
1143 DBGPRINT(RT_DEBUG_TRACE, ("TxPreamble=%ld\n", pAd->CommonCfg.TxPreamble));
1144 }
1145 //RTSThreshold
1146 if(RTMPGetKeyParameter("RTSThreshold", tmpbuf, 10, buffer))
1147 {
1148 RtsThresh = simple_strtol(tmpbuf, 0, 10);
1149 if( (RtsThresh >= 1) && (RtsThresh <= MAX_RTS_THRESHOLD) )
1150 pAd->CommonCfg.RtsThreshold = (USHORT)RtsThresh;
1151 else
1152 pAd->CommonCfg.RtsThreshold = MAX_RTS_THRESHOLD;
1153
1154 DBGPRINT(RT_DEBUG_TRACE, ("RTSThreshold=%d\n", pAd->CommonCfg.RtsThreshold));
1155 }
1156 //FragThreshold
1157 if(RTMPGetKeyParameter("FragThreshold", tmpbuf, 10, buffer))
1158 {
1159 FragThresh = simple_strtol(tmpbuf, 0, 10);
1160 pAd->CommonCfg.bUseZeroToDisableFragment = FALSE;
1161
1162 if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD)
1163 { //illegal FragThresh so we set it to default
1164 pAd->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD;
1165 pAd->CommonCfg.bUseZeroToDisableFragment = TRUE;
1166 }
1167 else if (FragThresh % 2 == 1)
1168 {
1169 // The length of each fragment shall always be an even number of octets, except for the last fragment
1170 // of an MSDU or MMPDU, which may be either an even or an odd number of octets.
1171 pAd->CommonCfg.FragmentThreshold = (USHORT)(FragThresh - 1);
1172 }
1173 else
1174 {
1175 pAd->CommonCfg.FragmentThreshold = (USHORT)FragThresh;
1176 }
1177 //pAd->CommonCfg.AllowFragSize = (pAd->CommonCfg.FragmentThreshold) - LENGTH_802_11 - LENGTH_CRC;
1178 DBGPRINT(RT_DEBUG_TRACE, ("FragThreshold=%d\n", pAd->CommonCfg.FragmentThreshold));
1179 }
1180 //TxBurst
1181 if(RTMPGetKeyParameter("TxBurst", tmpbuf, 10, buffer))
1182 {
1183//#ifdef WIFI_TEST
1184// pAd->CommonCfg.bEnableTxBurst = FALSE;
1185//#else
1186 if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
1187 pAd->CommonCfg.bEnableTxBurst = TRUE;
1188 else //Disable
1189 pAd->CommonCfg.bEnableTxBurst = FALSE;
1190//#endif
1191 DBGPRINT(RT_DEBUG_TRACE, ("TxBurst=%d\n", pAd->CommonCfg.bEnableTxBurst));
1192 }
1193
1194#ifdef AGGREGATION_SUPPORT
1195 //PktAggregate
1196 if(RTMPGetKeyParameter("PktAggregate", tmpbuf, 10, buffer))
1197 {
1198 if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
1199 pAd->CommonCfg.bAggregationCapable = TRUE;
1200 else //Disable
1201 pAd->CommonCfg.bAggregationCapable = FALSE;
1202#ifdef PIGGYBACK_SUPPORT
1203 pAd->CommonCfg.bPiggyBackCapable = pAd->CommonCfg.bAggregationCapable;
1204#endif // PIGGYBACK_SUPPORT //
1205 DBGPRINT(RT_DEBUG_TRACE, ("PktAggregate=%d\n", pAd->CommonCfg.bAggregationCapable));
1206 }
1207#else
1208 pAd->CommonCfg.bAggregationCapable = FALSE;
1209 pAd->CommonCfg.bPiggyBackCapable = FALSE;
1210#endif // AGGREGATION_SUPPORT //
1211
1212 // WmmCapable
1213
1214#ifdef CONFIG_STA_SUPPORT
1215 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1216 rtmp_read_sta_wmm_parms_from_file(pAd, tmpbuf, buffer);
1217#endif // CONFIG_STA_SUPPORT //
1218
1219 //ShortSlot
1220 if(RTMPGetKeyParameter("ShortSlot", tmpbuf, 10, buffer))
1221 {
1222 if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
1223 pAd->CommonCfg.bUseShortSlotTime = TRUE;
1224 else //Disable
1225 pAd->CommonCfg.bUseShortSlotTime = FALSE;
1226
1227 DBGPRINT(RT_DEBUG_TRACE, ("ShortSlot=%d\n", pAd->CommonCfg.bUseShortSlotTime));
1228 }
1229 //IEEE80211H
1230 if(RTMPGetKeyParameter("IEEE80211H", tmpbuf, 10, buffer))
1231 {
1232 for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
1233 {
1234 if(simple_strtol(macptr, 0, 10) != 0) //Enable
1235 pAd->CommonCfg.bIEEE80211H = TRUE;
1236 else //Disable
1237 pAd->CommonCfg.bIEEE80211H = FALSE;
1238
1239 DBGPRINT(RT_DEBUG_TRACE, ("IEEE80211H=%d\n", pAd->CommonCfg.bIEEE80211H));
1240 }
1241 }
1242 //CSPeriod
1243 if(RTMPGetKeyParameter("CSPeriod", tmpbuf, 10, buffer))
1244 {
1245 if(simple_strtol(tmpbuf, 0, 10) != 0)
1246 pAd->CommonCfg.RadarDetect.CSPeriod = simple_strtol(tmpbuf, 0, 10);
1247 else
1248 pAd->CommonCfg.RadarDetect.CSPeriod = 0;
1249
1250 DBGPRINT(RT_DEBUG_TRACE, ("CSPeriod=%d\n", pAd->CommonCfg.RadarDetect.CSPeriod));
1251 }
1252
1253 //RDRegion
1254 if(RTMPGetKeyParameter("RDRegion", tmpbuf, 128, buffer))
1255 {
1256 if ((strncmp(tmpbuf, "JAP_W53", 7) == 0) || (strncmp(tmpbuf, "jap_w53", 7) == 0))
1257 {
1258 pAd->CommonCfg.RadarDetect.RDDurRegion = JAP_W53;
1259 pAd->CommonCfg.RadarDetect.DfsSessionTime = 15;
1260 }
1261 else if ((strncmp(tmpbuf, "JAP_W56", 7) == 0) || (strncmp(tmpbuf, "jap_w56", 7) == 0))
1262 {
1263 pAd->CommonCfg.RadarDetect.RDDurRegion = JAP_W56;
1264 pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
1265 }
1266 else if ((strncmp(tmpbuf, "JAP", 3) == 0) || (strncmp(tmpbuf, "jap", 3) == 0))
1267 {
1268 pAd->CommonCfg.RadarDetect.RDDurRegion = JAP;
1269 pAd->CommonCfg.RadarDetect.DfsSessionTime = 5;
1270 }
1271 else if ((strncmp(tmpbuf, "FCC", 3) == 0) || (strncmp(tmpbuf, "fcc", 3) == 0))
1272 {
1273 pAd->CommonCfg.RadarDetect.RDDurRegion = FCC;
1274 pAd->CommonCfg.RadarDetect.DfsSessionTime = 5;
1275 }
1276 else if ((strncmp(tmpbuf, "CE", 2) == 0) || (strncmp(tmpbuf, "ce", 2) == 0))
1277 {
1278 pAd->CommonCfg.RadarDetect.RDDurRegion = CE;
1279 pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
1280 }
1281 else
1282 {
1283 pAd->CommonCfg.RadarDetect.RDDurRegion = CE;
1284 pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
1285 }
1286
1287 DBGPRINT(RT_DEBUG_TRACE, ("RDRegion=%d\n", pAd->CommonCfg.RadarDetect.RDDurRegion));
1288 }
1289 else
1290 {
1291 pAd->CommonCfg.RadarDetect.RDDurRegion = CE;
1292 pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
1293 }
1294
1295 //WirelessEvent
1296 if(RTMPGetKeyParameter("WirelessEvent", tmpbuf, 10, buffer))
1297 {
1298#if WIRELESS_EXT >= 15
1299 if(simple_strtol(tmpbuf, 0, 10) != 0)
1300 pAd->CommonCfg.bWirelessEvent = simple_strtol(tmpbuf, 0, 10);
1301 else
1302 pAd->CommonCfg.bWirelessEvent = 0; // disable
1303#else
1304 pAd->CommonCfg.bWirelessEvent = 0; // disable
1305#endif
1306 DBGPRINT(RT_DEBUG_TRACE, ("WirelessEvent=%d\n", pAd->CommonCfg.bWirelessEvent));
1307 }
1308 if(RTMPGetKeyParameter("WiFiTest", tmpbuf, 10, buffer))
1309 {
1310 if(simple_strtol(tmpbuf, 0, 10) != 0)
1311 pAd->CommonCfg.bWiFiTest= simple_strtol(tmpbuf, 0, 10);
1312 else
1313 pAd->CommonCfg.bWiFiTest = 0; // disable
1314
1315 DBGPRINT(RT_DEBUG_TRACE, ("WiFiTest=%d\n", pAd->CommonCfg.bWiFiTest));
1316 }
1317 //AuthMode
1318 if(RTMPGetKeyParameter("AuthMode", tmpbuf, 128, buffer))
1319 {
1320#ifdef CONFIG_STA_SUPPORT
1321 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1322 {
1323 if ((strcmp(tmpbuf, "WEPAUTO") == 0) || (strcmp(tmpbuf, "wepauto") == 0))
1324 pAd->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch;
1325 else if ((strcmp(tmpbuf, "SHARED") == 0) || (strcmp(tmpbuf, "shared") == 0))
1326 pAd->StaCfg.AuthMode = Ndis802_11AuthModeShared;
1327 else if ((strcmp(tmpbuf, "WPAPSK") == 0) || (strcmp(tmpbuf, "wpapsk") == 0))
1328 pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
1329 else if ((strcmp(tmpbuf, "WPANONE") == 0) || (strcmp(tmpbuf, "wpanone") == 0))
1330 pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
1331 else if ((strcmp(tmpbuf, "WPA2PSK") == 0) || (strcmp(tmpbuf, "wpa2psk") == 0))
1332 pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
1333#ifdef WPA_SUPPLICANT_SUPPORT
1334 else if ((strcmp(tmpbuf, "WPA") == 0) || (strcmp(tmpbuf, "wpa") == 0))
1335 pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
1336 else if ((strcmp(tmpbuf, "WPA2") == 0) || (strcmp(tmpbuf, "wpa2") == 0))
1337 pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
1338#endif // WPA_SUPPLICANT_SUPPORT //
1339 else
1340 pAd->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
1341
1342 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1343
1344 DBGPRINT(RT_DEBUG_TRACE, ("%s::(EncrypType=%d)\n", __FUNCTION__, pAd->StaCfg.WepStatus));
1345 }
1346#endif // CONFIG_STA_SUPPORT //
1347 }
1348 //EncrypType
1349 if(RTMPGetKeyParameter("EncrypType", tmpbuf, 128, buffer))
1350 {
1351
1352#ifdef CONFIG_STA_SUPPORT
1353 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1354 {
1355 if ((strcmp(tmpbuf, "WEP") == 0) || (strcmp(tmpbuf, "wep") == 0))
1356 pAd->StaCfg.WepStatus = Ndis802_11WEPEnabled;
1357 else if ((strcmp(tmpbuf, "TKIP") == 0) || (strcmp(tmpbuf, "tkip") == 0))
1358 pAd->StaCfg.WepStatus = Ndis802_11Encryption2Enabled;
1359 else if ((strcmp(tmpbuf, "AES") == 0) || (strcmp(tmpbuf, "aes") == 0))
1360 pAd->StaCfg.WepStatus = Ndis802_11Encryption3Enabled;
1361 else
1362 pAd->StaCfg.WepStatus = Ndis802_11WEPDisabled;
1363
1364 // Update all wepstatus related
1365 pAd->StaCfg.PairCipher = pAd->StaCfg.WepStatus;
1366 pAd->StaCfg.GroupCipher = pAd->StaCfg.WepStatus;
1367 pAd->StaCfg.OrigWepStatus = pAd->StaCfg.WepStatus;
1368 pAd->StaCfg.bMixCipher = FALSE;
1369
1370 //RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
1371 DBGPRINT(RT_DEBUG_TRACE, ("%s::(EncrypType=%d)\n", __FUNCTION__, pAd->StaCfg.WepStatus));
1372 }
1373#endif // CONFIG_STA_SUPPORT //
1374 }
1375
1376
1377
1378#ifdef CONFIG_STA_SUPPORT
1379 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1380 {
1381 if(RTMPGetCriticalParameter("WPAPSK", tmpbuf, 512, buffer))
1382 {
1383 int err=0;
1384
1385 tmpbuf[strlen(tmpbuf)] = '\0'; // make STA can process .$^& for WPAPSK input
1386
1387 if ((pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
1388 (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
1389 (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
1390 )
1391 {
1392 err = 1;
1393 }
1394 else if ((strlen(tmpbuf) >= 8) && (strlen(tmpbuf) < 64))
1395 {
1396 PasswordHash((char *)tmpbuf, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, keyMaterial);
1397 NdisMoveMemory(pAd->StaCfg.PMK, keyMaterial, 32);
1398
1399 }
1400 else if (strlen(tmpbuf) == 64)
1401 {
1402 AtoH(tmpbuf, keyMaterial, 32);
1403 NdisMoveMemory(pAd->StaCfg.PMK, keyMaterial, 32);
1404 }
1405 else
1406 {
1407 err = 1;
1408 DBGPRINT(RT_DEBUG_ERROR, ("%s::(WPAPSK key-string required 8 ~ 64 characters!)\n", __FUNCTION__));
1409 }
1410
1411 if (err == 0)
1412 {
1413 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
1414 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
1415 {
1416 // Start STA supplicant state machine
1417 pAd->StaCfg.WpaState = SS_START;
1418 }
1419 else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1420 {
1421 /*
1422 NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
1423 pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
1424 NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pAd->StaCfg.PMK, LEN_TKIP_EK);
1425 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_RXMICK);
1426 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_TXMICK);
1427
1428 // Decide its ChiperAlg
1429 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1430 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
1431 else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
1432 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1433 else
1434 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
1435 */
1436 pAd->StaCfg.WpaState = SS_NOTUSE;
1437 }
1438
1439 DBGPRINT(RT_DEBUG_TRACE, ("%s::(WPAPSK=%s)\n", __FUNCTION__, tmpbuf));
1440 }
1441 }
1442 }
1443#endif // CONFIG_STA_SUPPORT //
1444
1445 //DefaultKeyID, KeyType, KeyStr
1446 rtmp_read_key_parms_from_file(pAd, tmpbuf, buffer);
1447
1448
1449 //HSCounter
1450 /*if(RTMPGetKeyParameter("HSCounter", tmpbuf, 10, buffer))
1451 {
1452 switch (simple_strtol(tmpbuf, 0, 10))
1453 {
1454 case 1: //Enable
1455 pAd->CommonCfg.bEnableHSCounter = TRUE;
1456 break;
1457 case 0: //Disable
1458 default:
1459 pAd->CommonCfg.bEnableHSCounter = FALSE;
1460 break;
1461 }
1462 DBGPRINT(RT_DEBUG_TRACE, "HSCounter=%d\n", pAd->CommonCfg.bEnableHSCounter);
1463 }*/
1464
1465#ifdef DOT11_N_SUPPORT
1466 HTParametersHook(pAd, tmpbuf, buffer);
1467#endif // DOT11_N_SUPPORT //
1468
1469
1470#ifdef CARRIER_DETECTION_SUPPORT
1471 //CarrierDetect
1472 if(RTMPGetKeyParameter("CarrierDetect", tmpbuf, 128, buffer))
1473 {
1474 if ((strncmp(tmpbuf, "0", 1) == 0))
1475 pAd->CommonCfg.CarrierDetect.Enable = FALSE;
1476 else if ((strncmp(tmpbuf, "1", 1) == 0))
1477 pAd->CommonCfg.CarrierDetect.Enable = TRUE;
1478 else
1479 pAd->CommonCfg.CarrierDetect.Enable = FALSE;
1480
1481 DBGPRINT(RT_DEBUG_TRACE, ("CarrierDetect.Enable=%d\n", pAd->CommonCfg.CarrierDetect.Enable));
1482 }
1483 else
1484 pAd->CommonCfg.CarrierDetect.Enable = FALSE;
1485#endif // CARRIER_DETECTION_SUPPORT //
1486
1487#ifdef CONFIG_STA_SUPPORT
1488 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1489 {
1490 //PSMode
1491 if (RTMPGetKeyParameter("PSMode", tmpbuf, 10, buffer))
1492 {
1493 if (pAd->StaCfg.BssType == BSS_INFRA)
1494 {
1495 if ((strcmp(tmpbuf, "MAX_PSP") == 0) || (strcmp(tmpbuf, "max_psp") == 0))
1496 {
1497 // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
1498 // to exclude certain situations.
1499 // MlmeSetPsm(pAd, PWR_SAVE);
1500 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
1501 if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
1502 pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP;
1503 pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP;
1504 pAd->StaCfg.DefaultListenCount = 5;
1505 }
1506 else if ((strcmp(tmpbuf, "Fast_PSP") == 0) || (strcmp(tmpbuf, "fast_psp") == 0)
1507 || (strcmp(tmpbuf, "FAST_PSP") == 0))
1508 {
1509 // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
1510 // to exclude certain situations.
1511 // MlmeSetPsmBit(pAd, PWR_SAVE);
1512 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
1513 if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
1514 pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP;
1515 pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP;
1516 pAd->StaCfg.DefaultListenCount = 3;
1517 }
1518 else if ((strcmp(tmpbuf, "Legacy_PSP") == 0) || (strcmp(tmpbuf, "legacy_psp") == 0)
1519 || (strcmp(tmpbuf, "LEGACY_PSP") == 0))
1520 {
1521 // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
1522 // to exclude certain situations.
1523 // MlmeSetPsmBit(pAd, PWR_SAVE);
1524 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
1525 if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
1526 pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP;
1527 pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP;
1528 pAd->StaCfg.DefaultListenCount = 3;
1529 }
1530 else
1531 { //Default Ndis802_11PowerModeCAM
1532 // clear PSM bit immediately
1533 MlmeSetPsmBit(pAd, PWR_ACTIVE);
1534 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
1535 if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
1536 pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
1537 pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
1538 }
1539 DBGPRINT(RT_DEBUG_TRACE, ("PSMode=%ld\n", pAd->StaCfg.WindowsPowerMode));
1540 }
1541 }
1542 // FastRoaming
1543 if (RTMPGetKeyParameter("FastRoaming", tmpbuf, 32, buffer))
1544 {
1545 if (simple_strtol(tmpbuf, 0, 10) == 0)
1546 pAd->StaCfg.bFastRoaming = FALSE;
1547 else
1548 pAd->StaCfg.bFastRoaming = TRUE;
1549
1550 DBGPRINT(RT_DEBUG_TRACE, ("FastRoaming=%d\n", pAd->StaCfg.bFastRoaming));
1551 }
1552 // RoamThreshold
1553 if (RTMPGetKeyParameter("RoamThreshold", tmpbuf, 32, buffer))
1554 {
1555 long lInfo = simple_strtol(tmpbuf, 0, 10);
1556
1557 if (lInfo > 90 || lInfo < 60)
1558 pAd->StaCfg.dBmToRoam = -70;
1559 else
1560 pAd->StaCfg.dBmToRoam = (CHAR)(-1)*lInfo;
1561
1562 DBGPRINT(RT_DEBUG_TRACE, ("RoamThreshold=%d dBm\n", pAd->StaCfg.dBmToRoam));
1563 }
1564
1565 if(RTMPGetKeyParameter("TGnWifiTest", tmpbuf, 10, buffer))
1566 {
1567 if(simple_strtol(tmpbuf, 0, 10) == 0)
1568 pAd->StaCfg.bTGnWifiTest = FALSE;
1569 else
1570 pAd->StaCfg.bTGnWifiTest = TRUE;
1571 DBGPRINT(RT_DEBUG_TRACE, ("TGnWifiTest=%d\n", pAd->StaCfg.bTGnWifiTest));
1572 }
1573 }
1574#endif // CONFIG_STA_SUPPORT //
1575
1576
1577#ifdef RT30xx
1578#ifdef CONFIG_STA_SUPPORT
1579 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1580 {
1581 if(RTMPGetKeyParameter("AntDiversity", tmpbuf, 10, buffer))
1582 {
1583 for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
1584 {
1585 if(simple_strtol(macptr, 0, 10) != 0) //Enable
1586 pAd->CommonCfg.bRxAntDiversity = TRUE;
1587 else //Disable
1588 pAd->CommonCfg.bRxAntDiversity = FALSE;
1589
1590 DBGPRINT(RT_DEBUG_ERROR, ("AntDiversity=%d\n", pAd->CommonCfg.bRxAntDiversity));
1591 }
1592 }
1593 }
1594#endif // CONFIG_STA_SUPPORT //
1595#endif // RT30xx //
1596 }
1597 }
1598 else
1599 {
1600 DBGPRINT(RT_DEBUG_TRACE, ("--> %s does not have a write method\n", src));
1601 }
1602
1603 retval=filp_close(srcf,NULL);
1604
1605 if (retval)
1606 {
1607 DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src));
1608 }
1609 }
1610 }
1611
1612 set_fs(orgfs);
1613#if 0
1614 current->fsuid = orgfsuid;
1615 current->fsgid = orgfsgid;
1616#endif
1617
1618 kfree(buffer);
1619 kfree(tmpbuf);
1620
1621 return (NDIS_STATUS_SUCCESS);
1622}
1623
1624#ifdef DOT11_N_SUPPORT
1625static void HTParametersHook(
1626 IN PRTMP_ADAPTER pAd,
1627 IN CHAR *pValueStr,
1628 IN CHAR *pInput)
1629{
1630
1631 INT Value;
1632
1633 if (RTMPGetKeyParameter("HT_PROTECT", pValueStr, 25, pInput))
1634 {
1635 Value = simple_strtol(pValueStr, 0, 10);
1636 if (Value == 0)
1637 {
1638 pAd->CommonCfg.bHTProtect = FALSE;
1639 }
1640 else
1641 {
1642 pAd->CommonCfg.bHTProtect = TRUE;
1643 }
1644 DBGPRINT(RT_DEBUG_TRACE, ("HT: Protection = %s\n", (Value==0) ? "Disable" : "Enable"));
1645 }
1646
1647 if (RTMPGetKeyParameter("HT_MIMOPSEnable", pValueStr, 25, pInput))
1648 {
1649 Value = simple_strtol(pValueStr, 0, 10);
1650 if (Value == 0)
1651 {
1652 pAd->CommonCfg.bMIMOPSEnable = FALSE;
1653 }
1654 else
1655 {
1656 pAd->CommonCfg.bMIMOPSEnable = TRUE;
1657 }
1658 DBGPRINT(RT_DEBUG_TRACE, ("HT: MIMOPSEnable = %s\n", (Value==0) ? "Disable" : "Enable"));
1659 }
1660
1661
1662 if (RTMPGetKeyParameter("HT_MIMOPSMode", pValueStr, 25, pInput))
1663 {
1664 Value = simple_strtol(pValueStr, 0, 10);
1665 if (Value > MMPS_ENABLE)
1666 {
1667 pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
1668 }
1669 else
1670 {
1671 //TODO: add mimo power saving mechanism
1672 pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
1673 //pAd->CommonCfg.BACapability.field.MMPSmode = Value;
1674 }
1675 DBGPRINT(RT_DEBUG_TRACE, ("HT: MIMOPS Mode = %d\n", Value));
1676 }
1677
1678 if (RTMPGetKeyParameter("HT_BADecline", pValueStr, 25, pInput))
1679 {
1680 Value = simple_strtol(pValueStr, 0, 10);
1681 if (Value == 0)
1682 {
1683 pAd->CommonCfg.bBADecline = FALSE;
1684 }
1685 else
1686 {
1687 pAd->CommonCfg.bBADecline = TRUE;
1688 }
1689 DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Decline = %s\n", (Value==0) ? "Disable" : "Enable"));
1690 }
1691
1692
1693 if (RTMPGetKeyParameter("HT_DisableReordering", pValueStr, 25, pInput))
1694 {
1695 Value = simple_strtol(pValueStr, 0, 10);
1696 if (Value == 0)
1697 {
1698 pAd->CommonCfg.bDisableReordering = FALSE;
1699 }
1700 else
1701 {
1702 pAd->CommonCfg.bDisableReordering = TRUE;
1703 }
1704 DBGPRINT(RT_DEBUG_TRACE, ("HT: DisableReordering = %s\n", (Value==0) ? "Disable" : "Enable"));
1705 }
1706
1707 if (RTMPGetKeyParameter("HT_AutoBA", pValueStr, 25, pInput))
1708 {
1709 Value = simple_strtol(pValueStr, 0, 10);
1710 if (Value == 0)
1711 {
1712 pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
1713 pAd->CommonCfg.BACapability.field.Policy = BA_NOTUSE;
1714 }
1715 else
1716 {
1717 pAd->CommonCfg.BACapability.field.AutoBA = TRUE;
1718 pAd->CommonCfg.BACapability.field.Policy = IMMED_BA;
1719 }
1720 pAd->CommonCfg.REGBACapability.field.AutoBA = pAd->CommonCfg.BACapability.field.AutoBA;
1721 pAd->CommonCfg.REGBACapability.field.Policy = pAd->CommonCfg.BACapability.field.Policy;
1722 DBGPRINT(RT_DEBUG_TRACE, ("HT: Auto BA = %s\n", (Value==0) ? "Disable" : "Enable"));
1723 }
1724
1725 // Tx_+HTC frame
1726 if (RTMPGetKeyParameter("HT_HTC", pValueStr, 25, pInput))
1727 {
1728 Value = simple_strtol(pValueStr, 0, 10);
1729 if (Value == 0)
1730 {
1731 pAd->HTCEnable = FALSE;
1732 }
1733 else
1734 {
1735 pAd->HTCEnable = TRUE;
1736 }
1737 DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx +HTC frame = %s\n", (Value==0) ? "Disable" : "Enable"));
1738 }
1739
1740 // Enable HT Link Adaptation Control
1741 if (RTMPGetKeyParameter("HT_LinkAdapt", pValueStr, 25, pInput))
1742 {
1743 Value = simple_strtol(pValueStr, 0, 10);
1744 if (Value == 0)
1745 {
1746 pAd->bLinkAdapt = FALSE;
1747 }
1748 else
1749 {
1750 pAd->HTCEnable = TRUE;
1751 pAd->bLinkAdapt = TRUE;
1752 }
1753 DBGPRINT(RT_DEBUG_TRACE, ("HT: Link Adaptation Control = %s\n", (Value==0) ? "Disable" : "Enable(+HTC)"));
1754 }
1755
1756 // Reverse Direction Mechanism
1757 if (RTMPGetKeyParameter("HT_RDG", pValueStr, 25, pInput))
1758 {
1759 Value = simple_strtol(pValueStr, 0, 10);
1760 if (Value == 0)
1761 {
1762 pAd->CommonCfg.bRdg = FALSE;
1763 }
1764 else
1765 {
1766 pAd->HTCEnable = TRUE;
1767 pAd->CommonCfg.bRdg = TRUE;
1768 }
1769 DBGPRINT(RT_DEBUG_TRACE, ("HT: RDG = %s\n", (Value==0) ? "Disable" : "Enable(+HTC)"));
1770 }
1771
1772
1773
1774
1775 // Tx A-MSUD ?
1776 if (RTMPGetKeyParameter("HT_AMSDU", pValueStr, 25, pInput))
1777 {
1778 Value = simple_strtol(pValueStr, 0, 10);
1779 if (Value == 0)
1780 {
1781 pAd->CommonCfg.BACapability.field.AmsduEnable = FALSE;
1782 }
1783 else
1784 {
1785 pAd->CommonCfg.BACapability.field.AmsduEnable = TRUE;
1786 }
1787 DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx A-MSDU = %s\n", (Value==0) ? "Disable" : "Enable"));
1788 }
1789
1790 // MPDU Density
1791 if (RTMPGetKeyParameter("HT_MpduDensity", pValueStr, 25, pInput))
1792 {
1793 Value = simple_strtol(pValueStr, 0, 10);
1794 if (Value <=7 && Value >= 0)
1795 {
1796 pAd->CommonCfg.BACapability.field.MpduDensity = Value;
1797 DBGPRINT(RT_DEBUG_TRACE, ("HT: MPDU Density = %d\n", Value));
1798 }
1799 else
1800 {
1801 pAd->CommonCfg.BACapability.field.MpduDensity = 4;
1802 DBGPRINT(RT_DEBUG_TRACE, ("HT: MPDU Density = %d (Default)\n", 4));
1803 }
1804 }
1805
1806 // Max Rx BA Window Size
1807 if (RTMPGetKeyParameter("HT_BAWinSize", pValueStr, 25, pInput))
1808 {
1809 Value = simple_strtol(pValueStr, 0, 10);
1810
1811 if (Value >=1 && Value <= 64)
1812 {
1813 pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = Value;
1814 pAd->CommonCfg.BACapability.field.RxBAWinLimit = Value;
1815 DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Windw Size = %d\n", Value));
1816 }
1817 else
1818 {
1819 pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = 64;
1820 pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64;
1821 DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Windw Size = 64 (Defualt)\n"));
1822 }
1823
1824 }
1825
1826 // Guard Interval
1827 if (RTMPGetKeyParameter("HT_GI", pValueStr, 25, pInput))
1828 {
1829 Value = simple_strtol(pValueStr, 0, 10);
1830
1831 if (Value == GI_400)
1832 {
1833 pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_400;
1834 }
1835 else
1836 {
1837 pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_800;
1838 }
1839
1840 DBGPRINT(RT_DEBUG_TRACE, ("HT: Guard Interval = %s\n", (Value==GI_400) ? "400" : "800" ));
1841 }
1842
1843 // HT Operation Mode : Mixed Mode , Green Field
1844 if (RTMPGetKeyParameter("HT_OpMode", pValueStr, 25, pInput))
1845 {
1846 Value = simple_strtol(pValueStr, 0, 10);
1847
1848 if (Value == HTMODE_GF)
1849 {
1850
1851 pAd->CommonCfg.RegTransmitSetting.field.HTMODE = HTMODE_GF;
1852 }
1853 else
1854 {
1855 pAd->CommonCfg.RegTransmitSetting.field.HTMODE = HTMODE_MM;
1856 }
1857
1858 DBGPRINT(RT_DEBUG_TRACE, ("HT: Operate Mode = %s\n", (Value==HTMODE_GF) ? "Green Field" : "Mixed Mode" ));
1859 }
1860
1861 // Fixed Tx mode : CCK, OFDM
1862 if (RTMPGetKeyParameter("FixedTxMode", pValueStr, 25, pInput))
1863 {
1864 UCHAR fix_tx_mode;
1865
1866#ifdef CONFIG_STA_SUPPORT
1867 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1868 {
1869 fix_tx_mode = FIXED_TXMODE_HT;
1870
1871 if (strcmp(pValueStr, "OFDM") == 0 || strcmp(pValueStr, "ofdm") == 0)
1872 {
1873 fix_tx_mode = FIXED_TXMODE_OFDM;
1874 }
1875 else if (strcmp(pValueStr, "CCK") == 0 || strcmp(pValueStr, "cck") == 0)
1876 {
1877 fix_tx_mode = FIXED_TXMODE_CCK;
1878 }
1879 else if (strcmp(pValueStr, "HT") == 0 || strcmp(pValueStr, "ht") == 0)
1880 {
1881 fix_tx_mode = FIXED_TXMODE_HT;
1882 }
1883 else
1884 {
1885 Value = simple_strtol(pValueStr, 0, 10);
1886 // 1 : CCK
1887 // 2 : OFDM
1888 // otherwise : HT
1889 if (Value == FIXED_TXMODE_CCK || Value == FIXED_TXMODE_OFDM)
1890 fix_tx_mode = Value;
1891 else
1892 fix_tx_mode = FIXED_TXMODE_HT;
1893 }
1894
1895 pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode = fix_tx_mode;
1896 DBGPRINT(RT_DEBUG_TRACE, ("Fixed Tx Mode = %d\n", fix_tx_mode));
1897
1898 }
1899#endif // CONFIG_STA_SUPPORT //
1900 }
1901
1902
1903 // Channel Width
1904 if (RTMPGetKeyParameter("HT_BW", pValueStr, 25, pInput))
1905 {
1906 Value = simple_strtol(pValueStr, 0, 10);
1907
1908 if (Value == BW_40)
1909 {
1910 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
1911 }
1912 else
1913 {
1914 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
1915 }
1916
1917#ifdef MCAST_RATE_SPECIFIC
1918 pAd->CommonCfg.MCastPhyMode.field.BW = pAd->CommonCfg.RegTransmitSetting.field.BW;
1919#endif // MCAST_RATE_SPECIFIC //
1920
1921 DBGPRINT(RT_DEBUG_TRACE, ("HT: Channel Width = %s\n", (Value==BW_40) ? "40 MHz" : "20 MHz" ));
1922 }
1923
1924 if (RTMPGetKeyParameter("HT_EXTCHA", pValueStr, 25, pInput))
1925 {
1926 Value = simple_strtol(pValueStr, 0, 10);
1927
1928 if (Value == 0)
1929 {
1930
1931 pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_BELOW;
1932 }
1933 else
1934 {
1935 pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE;
1936 }
1937
1938 DBGPRINT(RT_DEBUG_TRACE, ("HT: Ext Channel = %s\n", (Value==0) ? "BELOW" : "ABOVE" ));
1939 }
1940
1941 // MSC
1942 if (RTMPGetKeyParameter("HT_MCS", pValueStr, 50, pInput))
1943 {
1944
1945#ifdef CONFIG_STA_SUPPORT
1946 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1947 {
1948 Value = simple_strtol(pValueStr, 0, 10);
1949
1950// if ((Value >= 0 && Value <= 15) || (Value == 32))
1951 if ((Value >= 0 && Value <= 23) || (Value == 32)) // 3*3
1952 {
1953 pAd->StaCfg.DesiredTransmitSetting.field.MCS = Value;
1954 pAd->StaCfg.bAutoTxRateSwitch = FALSE;
1955 DBGPRINT(RT_DEBUG_TRACE, ("HT: MCS = %d\n", pAd->StaCfg.DesiredTransmitSetting.field.MCS));
1956 }
1957 else
1958 {
1959 pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
1960 pAd->StaCfg.bAutoTxRateSwitch = TRUE;
1961 DBGPRINT(RT_DEBUG_TRACE, ("HT: MCS = AUTO\n"));
1962 }
1963 }
1964#endif // CONFIG_STA_SUPPORT //
1965 }
1966
1967 // STBC
1968 if (RTMPGetKeyParameter("HT_STBC", pValueStr, 25, pInput))
1969 {
1970 Value = simple_strtol(pValueStr, 0, 10);
1971 if (Value == STBC_USE)
1972 {
1973 pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_USE;
1974 }
1975 else
1976 {
1977 pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_NONE;
1978 }
1979 DBGPRINT(RT_DEBUG_TRACE, ("HT: STBC = %d\n", pAd->CommonCfg.RegTransmitSetting.field.STBC));
1980 }
1981
1982 // 40_Mhz_Intolerant
1983 if (RTMPGetKeyParameter("HT_40MHZ_INTOLERANT", pValueStr, 25, pInput))
1984 {
1985 Value = simple_strtol(pValueStr, 0, 10);
1986 if (Value == 0)
1987 {
1988 pAd->CommonCfg.bForty_Mhz_Intolerant = FALSE;
1989 }
1990 else
1991 {
1992 pAd->CommonCfg.bForty_Mhz_Intolerant = TRUE;
1993 }
1994 DBGPRINT(RT_DEBUG_TRACE, ("HT: 40MHZ INTOLERANT = %d\n", pAd->CommonCfg.bForty_Mhz_Intolerant));
1995 }
1996 //HT_TxStream
1997 if(RTMPGetKeyParameter("HT_TxStream", pValueStr, 10, pInput))
1998 {
1999 switch (simple_strtol(pValueStr, 0, 10))
2000 {
2001 case 1:
2002 pAd->CommonCfg.TxStream = 1;
2003 break;
2004 case 2:
2005 pAd->CommonCfg.TxStream = 2;
2006 break;
2007 case 3: // 3*3
2008 default:
2009 pAd->CommonCfg.TxStream = 3;
2010
2011 if (pAd->MACVersion < RALINK_2883_VERSION)
2012 pAd->CommonCfg.TxStream = 2; // only 2 tx streams for RT2860 series
2013 break;
2014 }
2015 DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx Stream = %d\n", pAd->CommonCfg.TxStream));
2016 }
2017 //HT_RxStream
2018 if(RTMPGetKeyParameter("HT_RxStream", pValueStr, 10, pInput))
2019 {
2020 switch (simple_strtol(pValueStr, 0, 10))
2021 {
2022 case 1:
2023 pAd->CommonCfg.RxStream = 1;
2024 break;
2025 case 2:
2026 pAd->CommonCfg.RxStream = 2;
2027 break;
2028 case 3:
2029 default:
2030 pAd->CommonCfg.RxStream = 3;
2031
2032 if (pAd->MACVersion < RALINK_2883_VERSION)
2033 pAd->CommonCfg.RxStream = 2; // only 2 rx streams for RT2860 series
2034 break;
2035 }
2036 DBGPRINT(RT_DEBUG_TRACE, ("HT: Rx Stream = %d\n", pAd->CommonCfg.RxStream));
2037 }
2038
2039}
2040#endif // DOT11_N_SUPPORT //
2041
diff --git a/drivers/staging/rt3070/rtmp.h b/drivers/staging/rt3070/rtmp.h
new file mode 100644
index 000000000000..d80d74ffbc89
--- /dev/null
+++ b/drivers/staging/rt3070/rtmp.h
@@ -0,0 +1,7728 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 rtmp.h
29
30 Abstract:
31 Miniport generic portion header file
32
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36 Paul Lin 2002-08-01 created
37 James Tan 2002-09-06 modified (Revise NTCRegTable)
38 John Chang 2004-09-06 modified for RT2600
39*/
40#ifndef __RTMP_H__
41#define __RTMP_H__
42
43#include "link_list.h"
44#include "spectrum_def.h"
45
46#ifdef MLME_EX
47#include "mlme_ex_def.h"
48#endif // MLME_EX //
49
50#ifdef CONFIG_STA_SUPPORT
51#include "aironet.h"
52#endif // CONFIG_STA_SUPPORT //
53
54#undef AP_WSC_INCLUDED
55#undef STA_WSC_INCLUDED
56#undef WSC_INCLUDED
57
58
59#ifdef CONFIG_STA_SUPPORT
60#endif // CONFIG_STA_SUPPORT //
61
62#if defined(AP_WSC_INCLUDED) || defined(STA_WSC_INCLUDED)
63#define WSC_INCLUDED
64#endif
65
66
67
68
69
70//#define DBG 1
71
72//#define DBG_DIAGNOSE 1
73
74#if defined(CONFIG_AP_SUPPORT) && defined(CONFIG_STA_SUPPORT)
75#define IF_DEV_CONFIG_OPMODE_ON_AP(_pAd) if(_pAd->OpMode == OPMODE_AP)
76#define IF_DEV_CONFIG_OPMODE_ON_STA(_pAd) if(_pAd->OpMode == OPMODE_STA)
77#else
78#define IF_DEV_CONFIG_OPMODE_ON_AP(_pAd)
79#define IF_DEV_CONFIG_OPMODE_ON_STA(_pAd)
80#endif
81
82#define VIRTUAL_IF_INC(__pAd) ((__pAd)->VirtualIfCnt++)
83#define VIRTUAL_IF_DEC(__pAd) ((__pAd)->VirtualIfCnt--)
84#define VIRTUAL_IF_NUM(__pAd) ((__pAd)->VirtualIfCnt)
85
86#ifdef RT2870
87////////////////////////////////////////////////////////////////////////////
88// The TX_BUFFER structure forms the transmitted USB packet to the device
89////////////////////////////////////////////////////////////////////////////
90typedef struct __TX_BUFFER{
91 union {
92 UCHAR WirelessPacket[TX_BUFFER_NORMSIZE];
93 HEADER_802_11 NullFrame;
94 PSPOLL_FRAME PsPollPacket;
95 RTS_FRAME RTSFrame;
96 }field;
97 UCHAR Aggregation[4]; //Buffer for save Aggregation size.
98} TX_BUFFER, *PTX_BUFFER;
99
100typedef struct __HTTX_BUFFER{
101 union {
102 UCHAR WirelessPacket[MAX_TXBULK_SIZE];
103 HEADER_802_11 NullFrame;
104 PSPOLL_FRAME PsPollPacket;
105 RTS_FRAME RTSFrame;
106 }field;
107 UCHAR Aggregation[4]; //Buffer for save Aggregation size.
108} HTTX_BUFFER, *PHTTX_BUFFER;
109
110
111// used to track driver-generated write irps
112typedef struct _TX_CONTEXT
113{
114 PVOID pAd; //Initialized in MiniportInitialize
115 PURB pUrb; //Initialized in MiniportInitialize
116 PIRP pIrp; //used to cancel pending bulk out.
117 //Initialized in MiniportInitialize
118 PTX_BUFFER TransferBuffer; //Initialized in MiniportInitialize
119 ULONG BulkOutSize;
120 UCHAR BulkOutPipeId;
121 UCHAR SelfIdx;
122 BOOLEAN InUse;
123 BOOLEAN bWaitingBulkOut; // at least one packet is in this TxContext, ready for making IRP anytime.
124 BOOLEAN bFullForBulkOut; // all tx buffer are full , so waiting for tx bulkout.
125 BOOLEAN IRPPending;
126 BOOLEAN LastOne;
127 BOOLEAN bAggregatible;
128 UCHAR Header_802_3[LENGTH_802_3];
129 UCHAR Rsv[2];
130 ULONG DataOffset;
131 UINT TxRate;
132 dma_addr_t data_dma; // urb dma on linux
133
134} TX_CONTEXT, *PTX_CONTEXT, **PPTX_CONTEXT;
135
136
137// used to track driver-generated write irps
138typedef struct _HT_TX_CONTEXT
139{
140 PVOID pAd; //Initialized in MiniportInitialize
141 PURB pUrb; //Initialized in MiniportInitialize
142 PIRP pIrp; //used to cancel pending bulk out.
143 //Initialized in MiniportInitialize
144 PHTTX_BUFFER TransferBuffer; //Initialized in MiniportInitialize
145 ULONG BulkOutSize; // Indicate the total bulk-out size in bytes in one bulk-transmission
146 UCHAR BulkOutPipeId;
147 BOOLEAN IRPPending;
148 BOOLEAN LastOne;
149 BOOLEAN bCurWriting;
150 BOOLEAN bRingEmpty;
151 BOOLEAN bCopySavePad;
152 UCHAR SavedPad[8];
153 UCHAR Header_802_3[LENGTH_802_3];
154 ULONG CurWritePosition; // Indicate the buffer offset which packet will be inserted start from.
155 ULONG CurWriteRealPos; // Indicate the buffer offset which packet now are writing to.
156 ULONG NextBulkOutPosition; // Indicate the buffer start offset of a bulk-transmission
157 ULONG ENextBulkOutPosition; // Indicate the buffer end offset of a bulk-transmission
158 UINT TxRate;
159 dma_addr_t data_dma; // urb dma on linux
160} HT_TX_CONTEXT, *PHT_TX_CONTEXT, **PPHT_TX_CONTEXT;
161
162
163//
164// Structure to keep track of receive packets and buffers to indicate
165// receive data to the protocol.
166//
167typedef struct _RX_CONTEXT
168{
169 PUCHAR TransferBuffer;
170 PVOID pAd;
171 PIRP pIrp;//used to cancel pending bulk in.
172 PURB pUrb;
173 //These 2 Boolean shouldn't both be 1 at the same time.
174 ULONG BulkInOffset; // number of packets waiting for reordering .
175// BOOLEAN ReorderInUse; // At least one packet in this buffer are in reordering buffer and wait for receive indication
176 BOOLEAN bRxHandling; // Notify this packet is being process now.
177 BOOLEAN InUse; // USB Hardware Occupied. Wait for USB HW to put packet.
178 BOOLEAN Readable; // Receive Complete back. OK for driver to indicate receiving packet.
179 BOOLEAN IRPPending; // TODO: To be removed
180 atomic_t IrpLock;
181 NDIS_SPIN_LOCK RxContextLock;
182 dma_addr_t data_dma; // urb dma on linux
183} RX_CONTEXT, *PRX_CONTEXT;
184#endif // RT2870 //
185
186
187//
188// NDIS Version definitions
189//
190#ifdef NDIS50_MINIPORT
191#define RTMP_NDIS_MAJOR_VERSION 5
192#define RTMP_NDIS_MINOR_VERSION 0
193#endif
194
195#ifdef NDIS51_MINIPORT
196#define RTMP_NDIS_MAJOR_VERSION 5
197#define RTMP_NDIS_MINOR_VERSION 1
198#endif
199
200extern char NIC_VENDOR_DESC[];
201extern int NIC_VENDOR_DESC_LEN;
202
203extern unsigned char SNAP_AIRONET[];
204extern unsigned char CipherSuiteCiscoCCKM[];
205extern unsigned char CipherSuiteCiscoCCKMLen;
206extern unsigned char CipherSuiteCiscoCCKM24[];
207extern unsigned char CipherSuiteCiscoCCKM24Len;
208extern unsigned char CipherSuiteCCXTkip[];
209extern unsigned char CipherSuiteCCXTkipLen;
210extern unsigned char CISCO_OUI[];
211extern UCHAR BaSizeArray[4];
212
213extern UCHAR BROADCAST_ADDR[MAC_ADDR_LEN];
214extern UCHAR MULTICAST_ADDR[MAC_ADDR_LEN];
215extern UCHAR ZERO_MAC_ADDR[MAC_ADDR_LEN];
216extern ULONG BIT32[32];
217extern UCHAR BIT8[8];
218extern char* CipherName[];
219extern char* MCSToMbps[];
220extern UCHAR RxwiMCSToOfdmRate[12];
221extern UCHAR SNAP_802_1H[6];
222extern UCHAR SNAP_BRIDGE_TUNNEL[6];
223extern UCHAR SNAP_AIRONET[8];
224extern UCHAR CKIP_LLC_SNAP[8];
225extern UCHAR EAPOL_LLC_SNAP[8];
226extern UCHAR EAPOL[2];
227extern UCHAR IPX[2];
228extern UCHAR APPLE_TALK[2];
229extern UCHAR RateIdToPlcpSignal[12]; // see IEEE802.11a-1999 p.14
230extern UCHAR OfdmRateToRxwiMCS[];
231extern UCHAR OfdmSignalToRateId[16] ;
232extern UCHAR default_cwmin[4];
233extern UCHAR default_cwmax[4];
234extern UCHAR default_sta_aifsn[4];
235extern UCHAR MapUserPriorityToAccessCategory[8];
236
237extern USHORT RateUpPER[];
238extern USHORT RateDownPER[];
239extern UCHAR Phy11BNextRateDownward[];
240extern UCHAR Phy11BNextRateUpward[];
241extern UCHAR Phy11BGNextRateDownward[];
242extern UCHAR Phy11BGNextRateUpward[];
243extern UCHAR Phy11ANextRateDownward[];
244extern UCHAR Phy11ANextRateUpward[];
245extern CHAR RssiSafeLevelForTxRate[];
246extern UCHAR RateIdToMbps[];
247extern USHORT RateIdTo500Kbps[];
248
249extern UCHAR CipherSuiteWpaNoneTkip[];
250extern UCHAR CipherSuiteWpaNoneTkipLen;
251
252extern UCHAR CipherSuiteWpaNoneAes[];
253extern UCHAR CipherSuiteWpaNoneAesLen;
254
255extern UCHAR SsidIe;
256extern UCHAR SupRateIe;
257extern UCHAR ExtRateIe;
258
259#ifdef DOT11_N_SUPPORT
260extern UCHAR HtCapIe;
261extern UCHAR AddHtInfoIe;
262extern UCHAR NewExtChanIe;
263#ifdef DOT11N_DRAFT3
264extern UCHAR ExtHtCapIe;
265#endif // DOT11N_DRAFT3 //
266#endif // DOT11_N_SUPPORT //
267
268extern UCHAR ErpIe;
269extern UCHAR DsIe;
270extern UCHAR TimIe;
271extern UCHAR WpaIe;
272extern UCHAR Wpa2Ie;
273extern UCHAR IbssIe;
274extern UCHAR Ccx2Ie;
275extern UCHAR WapiIe;
276
277extern UCHAR WPA_OUI[];
278extern UCHAR RSN_OUI[];
279extern UCHAR WAPI_OUI[];
280extern UCHAR WME_INFO_ELEM[];
281extern UCHAR WME_PARM_ELEM[];
282extern UCHAR Ccx2QosInfo[];
283extern UCHAR Ccx2IeInfo[];
284extern UCHAR RALINK_OUI[];
285extern UCHAR PowerConstraintIE[];
286
287
288extern UCHAR RateSwitchTable[];
289extern UCHAR RateSwitchTable11B[];
290extern UCHAR RateSwitchTable11G[];
291extern UCHAR RateSwitchTable11BG[];
292
293#ifdef DOT11_N_SUPPORT
294extern UCHAR RateSwitchTable11BGN1S[];
295extern UCHAR RateSwitchTable11BGN2S[];
296extern UCHAR RateSwitchTable11BGN2SForABand[];
297extern UCHAR RateSwitchTable11N1S[];
298extern UCHAR RateSwitchTable11N2S[];
299extern UCHAR RateSwitchTable11N2SForABand[];
300
301#ifdef CONFIG_STA_SUPPORT
302extern UCHAR PRE_N_HT_OUI[];
303#endif // CONFIG_STA_SUPPORT //
304#endif // DOT11_N_SUPPORT //
305
306#define MAXSEQ (0xFFF)
307
308#ifdef RALINK_ATE
309typedef struct _ATE_INFO {
310 UCHAR Mode;
311 CHAR TxPower0;
312 CHAR TxPower1;
313 CHAR TxAntennaSel;
314 CHAR RxAntennaSel;
315 TXWI_STRUC TxWI; // TXWI
316 USHORT QID;
317 UCHAR Addr1[MAC_ADDR_LEN];
318 UCHAR Addr2[MAC_ADDR_LEN];
319 UCHAR Addr3[MAC_ADDR_LEN];
320 UCHAR Channel;
321 UINT32 TxLength;
322 UINT32 TxCount;
323 UINT32 TxDoneCount; // Tx DMA Done
324 UINT32 RFFreqOffset;
325 BOOLEAN bRxFer;
326 BOOLEAN bQATxStart; // Have compiled QA in and use it to ATE tx.
327 BOOLEAN bQARxStart; // Have compiled QA in and use it to ATE rx.
328 UINT32 RxTotalCnt;
329 UINT32 RxCntPerSec;
330
331 CHAR LastSNR0; // last received SNR
332 CHAR LastSNR1; // last received SNR for 2nd antenna
333 CHAR LastRssi0; // last received RSSI
334 CHAR LastRssi1; // last received RSSI for 2nd antenna
335 CHAR LastRssi2; // last received RSSI for 3rd antenna
336 CHAR AvgRssi0; // last 8 frames' average RSSI
337 CHAR AvgRssi1; // last 8 frames' average RSSI
338 CHAR AvgRssi2; // last 8 frames' average RSSI
339 SHORT AvgRssi0X8; // sum of last 8 frames' RSSI
340 SHORT AvgRssi1X8; // sum of last 8 frames' RSSI
341 SHORT AvgRssi2X8; // sum of last 8 frames' RSSI
342
343 UINT32 NumOfAvgRssiSample;
344
345#ifdef RALINK_28xx_QA
346 // Tx frame
347#ifdef RT2870
348 /* not used in RT2860 */
349 TXINFO_STRUC TxInfo; // TxInfo
350#endif // RT2870 //
351 USHORT HLen; // Header Length
352 USHORT PLen; // Pattern Length
353 UCHAR Header[32]; // Header buffer
354 UCHAR Pattern[32]; // Pattern buffer
355 USHORT DLen; // Data Length
356 USHORT seq;
357 UINT32 CID;
358 pid_t AtePid;
359 // counters
360 UINT32 U2M;
361 UINT32 OtherData;
362 UINT32 Beacon;
363 UINT32 OtherCount;
364 UINT32 TxAc0;
365 UINT32 TxAc1;
366 UINT32 TxAc2;
367 UINT32 TxAc3;
368 UINT32 TxHCCA;
369 UINT32 TxMgmt;
370 UINT32 RSSI0;
371 UINT32 RSSI1;
372 UINT32 RSSI2;
373 UINT32 SNR0;
374 UINT32 SNR1;
375 // control
376 //UINT32 Repeat; // Tx Cpu count
377 UCHAR TxStatus; // task Tx status // 0 --> task is idle, 1 --> task is running
378#endif // RALINK_28xx_QA //
379} ATE_INFO, *PATE_INFO;
380
381#ifdef RALINK_28xx_QA
382struct ate_racfghdr {
383 UINT32 magic_no;
384 USHORT command_type;
385 USHORT command_id;
386 USHORT length;
387 USHORT sequence;
388 USHORT status;
389 UCHAR data[2046];
390} __attribute__((packed));
391#endif // RALINK_28xx_QA //
392#endif // RALINK_ATE //
393
394#ifdef DOT11_N_SUPPORT
395struct reordering_mpdu
396{
397 struct reordering_mpdu *next;
398 PNDIS_PACKET pPacket; /* coverted to 802.3 frame */
399 int Sequence; /* sequence number of MPDU */
400 BOOLEAN bAMSDU;
401};
402
403struct reordering_list
404{
405 struct reordering_mpdu *next;
406 int qlen;
407};
408
409struct reordering_mpdu_pool
410{
411 PVOID mem;
412 NDIS_SPIN_LOCK lock;
413 struct reordering_list freelist;
414};
415#endif // DOT11_N_SUPPORT //
416
417typedef struct _RSSI_SAMPLE {
418 CHAR LastRssi0; // last received RSSI
419 CHAR LastRssi1; // last received RSSI
420 CHAR LastRssi2; // last received RSSI
421 CHAR AvgRssi0;
422 CHAR AvgRssi1;
423 CHAR AvgRssi2;
424 SHORT AvgRssi0X8;
425 SHORT AvgRssi1X8;
426 SHORT AvgRssi2X8;
427} RSSI_SAMPLE;
428
429//
430// Queue structure and macros
431//
432typedef struct _QUEUE_ENTRY {
433 struct _QUEUE_ENTRY *Next;
434} QUEUE_ENTRY, *PQUEUE_ENTRY;
435
436// Queue structure
437typedef struct _QUEUE_HEADER {
438 PQUEUE_ENTRY Head;
439 PQUEUE_ENTRY Tail;
440 ULONG Number;
441} QUEUE_HEADER, *PQUEUE_HEADER;
442
443#define InitializeQueueHeader(QueueHeader) \
444{ \
445 (QueueHeader)->Head = (QueueHeader)->Tail = NULL; \
446 (QueueHeader)->Number = 0; \
447}
448
449#define RemoveHeadQueue(QueueHeader) \
450(QueueHeader)->Head; \
451{ \
452 PQUEUE_ENTRY pNext; \
453 if ((QueueHeader)->Head != NULL) \
454 { \
455 pNext = (QueueHeader)->Head->Next; \
456 (QueueHeader)->Head = pNext; \
457 if (pNext == NULL) \
458 (QueueHeader)->Tail = NULL; \
459 (QueueHeader)->Number--; \
460 } \
461}
462
463#define InsertHeadQueue(QueueHeader, QueueEntry) \
464{ \
465 ((PQUEUE_ENTRY)QueueEntry)->Next = (QueueHeader)->Head; \
466 (QueueHeader)->Head = (PQUEUE_ENTRY)(QueueEntry); \
467 if ((QueueHeader)->Tail == NULL) \
468 (QueueHeader)->Tail = (PQUEUE_ENTRY)(QueueEntry); \
469 (QueueHeader)->Number++; \
470}
471
472#define InsertTailQueue(QueueHeader, QueueEntry) \
473{ \
474 ((PQUEUE_ENTRY)QueueEntry)->Next = NULL; \
475 if ((QueueHeader)->Tail) \
476 (QueueHeader)->Tail->Next = (PQUEUE_ENTRY)(QueueEntry); \
477 else \
478 (QueueHeader)->Head = (PQUEUE_ENTRY)(QueueEntry); \
479 (QueueHeader)->Tail = (PQUEUE_ENTRY)(QueueEntry); \
480 (QueueHeader)->Number++; \
481}
482
483//
484// Macros for flag and ref count operations
485//
486#define RTMP_SET_FLAG(_M, _F) ((_M)->Flags |= (_F))
487#define RTMP_CLEAR_FLAG(_M, _F) ((_M)->Flags &= ~(_F))
488#define RTMP_CLEAR_FLAGS(_M) ((_M)->Flags = 0)
489#define RTMP_TEST_FLAG(_M, _F) (((_M)->Flags & (_F)) != 0)
490#define RTMP_TEST_FLAGS(_M, _F) (((_M)->Flags & (_F)) == (_F))
491
492#define OPSTATUS_SET_FLAG(_pAd, _F) ((_pAd)->CommonCfg.OpStatusFlags |= (_F))
493#define OPSTATUS_CLEAR_FLAG(_pAd, _F) ((_pAd)->CommonCfg.OpStatusFlags &= ~(_F))
494#define OPSTATUS_TEST_FLAG(_pAd, _F) (((_pAd)->CommonCfg.OpStatusFlags & (_F)) != 0)
495
496#define CLIENT_STATUS_SET_FLAG(_pEntry,_F) ((_pEntry)->ClientStatusFlags |= (_F))
497#define CLIENT_STATUS_CLEAR_FLAG(_pEntry,_F) ((_pEntry)->ClientStatusFlags &= ~(_F))
498#define CLIENT_STATUS_TEST_FLAG(_pEntry,_F) (((_pEntry)->ClientStatusFlags & (_F)) != 0)
499
500#define RX_FILTER_SET_FLAG(_pAd, _F) ((_pAd)->CommonCfg.PacketFilter |= (_F))
501#define RX_FILTER_CLEAR_FLAG(_pAd, _F) ((_pAd)->CommonCfg.PacketFilter &= ~(_F))
502#define RX_FILTER_TEST_FLAG(_pAd, _F) (((_pAd)->CommonCfg.PacketFilter & (_F)) != 0)
503
504#ifdef CONFIG_STA_SUPPORT
505#define STA_NO_SECURITY_ON(_p) (_p->StaCfg.WepStatus == Ndis802_11EncryptionDisabled)
506#define STA_WEP_ON(_p) (_p->StaCfg.WepStatus == Ndis802_11Encryption1Enabled)
507#define STA_TKIP_ON(_p) (_p->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
508#define STA_AES_ON(_p) (_p->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
509
510#define STA_TGN_WIFI_ON(_p) (_p->StaCfg.bTGnWifiTest == TRUE)
511#endif // CONFIG_STA_SUPPORT //
512
513#define CKIP_KP_ON(_p) ((((_p)->StaCfg.CkipFlag) & 0x10) && ((_p)->StaCfg.bCkipCmicOn == TRUE))
514#define CKIP_CMIC_ON(_p) ((((_p)->StaCfg.CkipFlag) & 0x08) && ((_p)->StaCfg.bCkipCmicOn == TRUE))
515
516
517#define INC_RING_INDEX(_idx, _RingSize) \
518{ \
519 (_idx) = (_idx+1) % (_RingSize); \
520}
521
522// We will have a cost down version which mac version is 0x3090xxxx
523#define IS_RT3090(_pAd) ((((_pAd)->MACVersion & 0xffff0000) == 0x30710000) || (((_pAd)->MACVersion & 0xffff0000) == 0x30900000))
524
525#define IS_RT3070(_pAd) (((_pAd)->MACVersion & 0xffff0000) == 0x30700000)
526#define IS_RT3071(_pAd) (((_pAd)->MACVersion & 0xffff0000) == 0x30710000)
527#define IS_RT2070(_pAd) (((_pAd)->RfIcType == RFIC_2020) || ((_pAd)->EFuseTag == 0x27))
528
529#define IS_RT30xx(_pAd) (((_pAd)->MACVersion & 0xfff00000) == 0x30700000)
530
531#define RING_PACKET_INIT(_TxRing, _idx) \
532{ \
533 _TxRing->Cell[_idx].pNdisPacket = NULL; \
534 _TxRing->Cell[_idx].pNextNdisPacket = NULL; \
535}
536
537#define TXDT_INIT(_TxD) \
538{ \
539 NdisZeroMemory(_TxD, TXD_SIZE); \
540 _TxD->DMADONE = 1; \
541}
542
543//Set last data segment
544#define RING_SET_LASTDS(_TxD, _IsSD0) \
545{ \
546 if (_IsSD0) {_TxD->LastSec0 = 1;} \
547 else {_TxD->LastSec1 = 1;} \
548}
549
550// Increase TxTsc value for next transmission
551// TODO:
552// When i==6, means TSC has done one full cycle, do re-keying stuff follow specs
553// Should send a special event microsoft defined to request re-key
554#define INC_TX_TSC(_tsc) \
555{ \
556 int i=0; \
557 while (++_tsc[i] == 0x0) \
558 { \
559 i++; \
560 if (i == 6) \
561 break; \
562 } \
563}
564
565#ifdef DOT11_N_SUPPORT
566// StaActive.SupportedHtPhy.MCSSet is copied from AP beacon. Don't need to update here.
567#define COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd) \
568{ \
569 _pAd->StaActive.SupportedHtPhy.ChannelWidth = _pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth; \
570 _pAd->StaActive.SupportedHtPhy.MimoPs = _pAd->MlmeAux.HtCapability.HtCapInfo.MimoPs; \
571 _pAd->StaActive.SupportedHtPhy.GF = _pAd->MlmeAux.HtCapability.HtCapInfo.GF; \
572 _pAd->StaActive.SupportedHtPhy.ShortGIfor20 = _pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor20; \
573 _pAd->StaActive.SupportedHtPhy.ShortGIfor40 = _pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor40; \
574 _pAd->StaActive.SupportedHtPhy.TxSTBC = _pAd->MlmeAux.HtCapability.HtCapInfo.TxSTBC; \
575 _pAd->StaActive.SupportedHtPhy.RxSTBC = _pAd->MlmeAux.HtCapability.HtCapInfo.RxSTBC; \
576 _pAd->StaActive.SupportedHtPhy.ExtChanOffset = _pAd->MlmeAux.AddHtInfo.AddHtInfo.ExtChanOffset; \
577 _pAd->StaActive.SupportedHtPhy.RecomWidth = _pAd->MlmeAux.AddHtInfo.AddHtInfo.RecomWidth; \
578 _pAd->StaActive.SupportedHtPhy.OperaionMode = _pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode; \
579 _pAd->StaActive.SupportedHtPhy.NonGfPresent = _pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent; \
580 NdisMoveMemory((_pAd)->MacTab.Content[BSSID_WCID].HTCapability.MCSSet, (_pAd)->StaActive.SupportedPhyInfo.MCSSet, sizeof(UCHAR) * 16);\
581}
582
583#define COPY_AP_HTSETTINGS_FROM_BEACON(_pAd, _pHtCapability) \
584{ \
585 _pAd->MacTab.Content[BSSID_WCID].AMsduSize = (UCHAR)(_pHtCapability->HtCapInfo.AMsduSize); \
586 _pAd->MacTab.Content[BSSID_WCID].MmpsMode= (UCHAR)(_pHtCapability->HtCapInfo.MimoPs); \
587 _pAd->MacTab.Content[BSSID_WCID].MaxRAmpduFactor = (UCHAR)(_pHtCapability->HtCapParm.MaxRAmpduFactor); \
588}
589#endif // DOT11_N_SUPPORT //
590
591//
592// MACRO for 32-bit PCI register read / write
593//
594// Usage : RTMP_IO_READ32(
595// PRTMP_ADAPTER pAd,
596// ULONG Register_Offset,
597// PULONG pValue)
598//
599// RTMP_IO_WRITE32(
600// PRTMP_ADAPTER pAd,
601// ULONG Register_Offset,
602// ULONG Value)
603//
604
605//
606// BBP & RF are using indirect access. Before write any value into it.
607// We have to make sure there is no outstanding command pending via checking busy bit.
608//
609#define MAX_BUSY_COUNT 100 // Number of retry before failing access BBP & RF indirect register
610//
611
612#ifdef RT2870
613#define RTMP_RF_IO_WRITE32(_A, _V) RTUSBWriteRFRegister(_A, _V)
614#define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) RTUSBReadBBPRegister(_A, _I, _pV)
615#define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) RTUSBWriteBBPRegister(_A, _I, _V)
616
617#define BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) RTUSBWriteBBPRegister(_A, _I, _V)
618#define BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) RTUSBReadBBPRegister(_A, _I, _pV)
619#endif // RT2870 //
620
621#ifdef RT30xx
622#define RTMP_RF_IO_READ8_BY_REG_ID(_A, _I, _pV) RT30xxReadRFRegister(_A, _I, _pV)
623#define RTMP_RF_IO_WRITE8_BY_REG_ID(_A, _I, _V) RT30xxWriteRFRegister(_A, _I, _V)
624#endif // RT30xx //
625
626#define MAP_CHANNEL_ID_TO_KHZ(ch, khz) { \
627 switch (ch) \
628 { \
629 case 1: khz = 2412000; break; \
630 case 2: khz = 2417000; break; \
631 case 3: khz = 2422000; break; \
632 case 4: khz = 2427000; break; \
633 case 5: khz = 2432000; break; \
634 case 6: khz = 2437000; break; \
635 case 7: khz = 2442000; break; \
636 case 8: khz = 2447000; break; \
637 case 9: khz = 2452000; break; \
638 case 10: khz = 2457000; break; \
639 case 11: khz = 2462000; break; \
640 case 12: khz = 2467000; break; \
641 case 13: khz = 2472000; break; \
642 case 14: khz = 2484000; break; \
643 case 36: /* UNII */ khz = 5180000; break; \
644 case 40: /* UNII */ khz = 5200000; break; \
645 case 44: /* UNII */ khz = 5220000; break; \
646 case 48: /* UNII */ khz = 5240000; break; \
647 case 52: /* UNII */ khz = 5260000; break; \
648 case 56: /* UNII */ khz = 5280000; break; \
649 case 60: /* UNII */ khz = 5300000; break; \
650 case 64: /* UNII */ khz = 5320000; break; \
651 case 149: /* UNII */ khz = 5745000; break; \
652 case 153: /* UNII */ khz = 5765000; break; \
653 case 157: /* UNII */ khz = 5785000; break; \
654 case 161: /* UNII */ khz = 5805000; break; \
655 case 165: /* UNII */ khz = 5825000; break; \
656 case 100: /* HiperLAN2 */ khz = 5500000; break; \
657 case 104: /* HiperLAN2 */ khz = 5520000; break; \
658 case 108: /* HiperLAN2 */ khz = 5540000; break; \
659 case 112: /* HiperLAN2 */ khz = 5560000; break; \
660 case 116: /* HiperLAN2 */ khz = 5580000; break; \
661 case 120: /* HiperLAN2 */ khz = 5600000; break; \
662 case 124: /* HiperLAN2 */ khz = 5620000; break; \
663 case 128: /* HiperLAN2 */ khz = 5640000; break; \
664 case 132: /* HiperLAN2 */ khz = 5660000; break; \
665 case 136: /* HiperLAN2 */ khz = 5680000; break; \
666 case 140: /* HiperLAN2 */ khz = 5700000; break; \
667 case 34: /* Japan MMAC */ khz = 5170000; break; \
668 case 38: /* Japan MMAC */ khz = 5190000; break; \
669 case 42: /* Japan MMAC */ khz = 5210000; break; \
670 case 46: /* Japan MMAC */ khz = 5230000; break; \
671 case 184: /* Japan */ khz = 4920000; break; \
672 case 188: /* Japan */ khz = 4940000; break; \
673 case 192: /* Japan */ khz = 4960000; break; \
674 case 196: /* Japan */ khz = 4980000; break; \
675 case 208: /* Japan, means J08 */ khz = 5040000; break; \
676 case 212: /* Japan, means J12 */ khz = 5060000; break; \
677 case 216: /* Japan, means J16 */ khz = 5080000; break; \
678 default: khz = 2412000; break; \
679 } \
680 }
681
682#define MAP_KHZ_TO_CHANNEL_ID(khz, ch) { \
683 switch (khz) \
684 { \
685 case 2412000: ch = 1; break; \
686 case 2417000: ch = 2; break; \
687 case 2422000: ch = 3; break; \
688 case 2427000: ch = 4; break; \
689 case 2432000: ch = 5; break; \
690 case 2437000: ch = 6; break; \
691 case 2442000: ch = 7; break; \
692 case 2447000: ch = 8; break; \
693 case 2452000: ch = 9; break; \
694 case 2457000: ch = 10; break; \
695 case 2462000: ch = 11; break; \
696 case 2467000: ch = 12; break; \
697 case 2472000: ch = 13; break; \
698 case 2484000: ch = 14; break; \
699 case 5180000: ch = 36; /* UNII */ break; \
700 case 5200000: ch = 40; /* UNII */ break; \
701 case 5220000: ch = 44; /* UNII */ break; \
702 case 5240000: ch = 48; /* UNII */ break; \
703 case 5260000: ch = 52; /* UNII */ break; \
704 case 5280000: ch = 56; /* UNII */ break; \
705 case 5300000: ch = 60; /* UNII */ break; \
706 case 5320000: ch = 64; /* UNII */ break; \
707 case 5745000: ch = 149; /* UNII */ break; \
708 case 5765000: ch = 153; /* UNII */ break; \
709 case 5785000: ch = 157; /* UNII */ break; \
710 case 5805000: ch = 161; /* UNII */ break; \
711 case 5825000: ch = 165; /* UNII */ break; \
712 case 5500000: ch = 100; /* HiperLAN2 */ break; \
713 case 5520000: ch = 104; /* HiperLAN2 */ break; \
714 case 5540000: ch = 108; /* HiperLAN2 */ break; \
715 case 5560000: ch = 112; /* HiperLAN2 */ break; \
716 case 5580000: ch = 116; /* HiperLAN2 */ break; \
717 case 5600000: ch = 120; /* HiperLAN2 */ break; \
718 case 5620000: ch = 124; /* HiperLAN2 */ break; \
719 case 5640000: ch = 128; /* HiperLAN2 */ break; \
720 case 5660000: ch = 132; /* HiperLAN2 */ break; \
721 case 5680000: ch = 136; /* HiperLAN2 */ break; \
722 case 5700000: ch = 140; /* HiperLAN2 */ break; \
723 case 5170000: ch = 34; /* Japan MMAC */ break; \
724 case 5190000: ch = 38; /* Japan MMAC */ break; \
725 case 5210000: ch = 42; /* Japan MMAC */ break; \
726 case 5230000: ch = 46; /* Japan MMAC */ break; \
727 case 4920000: ch = 184; /* Japan */ break; \
728 case 4940000: ch = 188; /* Japan */ break; \
729 case 4960000: ch = 192; /* Japan */ break; \
730 case 4980000: ch = 196; /* Japan */ break; \
731 case 5040000: ch = 208; /* Japan, means J08 */ break; \
732 case 5060000: ch = 212; /* Japan, means J12 */ break; \
733 case 5080000: ch = 216; /* Japan, means J16 */ break; \
734 default: ch = 1; break; \
735 } \
736 }
737
738//
739// Common fragment list structure - Identical to the scatter gather frag list structure
740//
741//#define RTMP_SCATTER_GATHER_ELEMENT SCATTER_GATHER_ELEMENT
742//#define PRTMP_SCATTER_GATHER_ELEMENT PSCATTER_GATHER_ELEMENT
743#define NIC_MAX_PHYS_BUF_COUNT 8
744
745typedef struct _RTMP_SCATTER_GATHER_ELEMENT {
746 PVOID Address;
747 ULONG Length;
748 PULONG Reserved;
749} RTMP_SCATTER_GATHER_ELEMENT, *PRTMP_SCATTER_GATHER_ELEMENT;
750
751
752typedef struct _RTMP_SCATTER_GATHER_LIST {
753 ULONG NumberOfElements;
754 PULONG Reserved;
755 RTMP_SCATTER_GATHER_ELEMENT Elements[NIC_MAX_PHYS_BUF_COUNT];
756} RTMP_SCATTER_GATHER_LIST, *PRTMP_SCATTER_GATHER_LIST;
757
758//
759// Some utility macros
760//
761#ifndef min
762#define min(_a, _b) (((_a) < (_b)) ? (_a) : (_b))
763#endif
764
765#ifndef max
766#define max(_a, _b) (((_a) > (_b)) ? (_a) : (_b))
767#endif
768
769#define GET_LNA_GAIN(_pAd) ((_pAd->LatchRfRegs.Channel <= 14) ? (_pAd->BLNAGain) : ((_pAd->LatchRfRegs.Channel <= 64) ? (_pAd->ALNAGain0) : ((_pAd->LatchRfRegs.Channel <= 128) ? (_pAd->ALNAGain1) : (_pAd->ALNAGain2))))
770
771#define INC_COUNTER64(Val) (Val.QuadPart++)
772
773#define INFRA_ON(_p) (OPSTATUS_TEST_FLAG(_p, fOP_STATUS_INFRA_ON))
774#define ADHOC_ON(_p) (OPSTATUS_TEST_FLAG(_p, fOP_STATUS_ADHOC_ON))
775#define MONITOR_ON(_p) (((_p)->StaCfg.BssType) == BSS_MONITOR)
776#define IDLE_ON(_p) (!INFRA_ON(_p) && !ADHOC_ON(_p))
777
778// Check LEAP & CCKM flags
779#define LEAP_ON(_p) (((_p)->StaCfg.LeapAuthMode) == CISCO_AuthModeLEAP)
780#define LEAP_CCKM_ON(_p) ((((_p)->StaCfg.LeapAuthMode) == CISCO_AuthModeLEAP) && ((_p)->StaCfg.LeapAuthInfo.CCKM == TRUE))
781
782// if orginal Ethernet frame contains no LLC/SNAP, then an extra LLC/SNAP encap is required
783#define EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(_pBufVA, _pExtraLlcSnapEncap) \
784{ \
785 if (((*(_pBufVA + 12) << 8) + *(_pBufVA + 13)) > 1500) \
786 { \
787 _pExtraLlcSnapEncap = SNAP_802_1H; \
788 if (NdisEqualMemory(IPX, _pBufVA + 12, 2) || \
789 NdisEqualMemory(APPLE_TALK, _pBufVA + 12, 2)) \
790 { \
791 _pExtraLlcSnapEncap = SNAP_BRIDGE_TUNNEL; \
792 } \
793 } \
794 else \
795 { \
796 _pExtraLlcSnapEncap = NULL; \
797 } \
798}
799
800// New Define for new Tx Path.
801#define EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(_pBufVA, _pExtraLlcSnapEncap) \
802{ \
803 if (((*(_pBufVA) << 8) + *(_pBufVA + 1)) > 1500) \
804 { \
805 _pExtraLlcSnapEncap = SNAP_802_1H; \
806 if (NdisEqualMemory(IPX, _pBufVA, 2) || \
807 NdisEqualMemory(APPLE_TALK, _pBufVA, 2)) \
808 { \
809 _pExtraLlcSnapEncap = SNAP_BRIDGE_TUNNEL; \
810 } \
811 } \
812 else \
813 { \
814 _pExtraLlcSnapEncap = NULL; \
815 } \
816}
817
818
819#define MAKE_802_3_HEADER(_p, _pMac1, _pMac2, _pType) \
820{ \
821 NdisMoveMemory(_p, _pMac1, MAC_ADDR_LEN); \
822 NdisMoveMemory((_p + MAC_ADDR_LEN), _pMac2, MAC_ADDR_LEN); \
823 NdisMoveMemory((_p + MAC_ADDR_LEN * 2), _pType, LENGTH_802_3_TYPE); \
824}
825
826// if pData has no LLC/SNAP (neither RFC1042 nor Bridge tunnel), keep it that way.
827// else if the received frame is LLC/SNAP-encaped IPX or APPLETALK, preserve the LLC/SNAP field
828// else remove the LLC/SNAP field from the result Ethernet frame
829// Patch for WHQL only, which did not turn on Netbios but use IPX within its payload
830// Note:
831// _pData & _DataSize may be altered (remove 8-byte LLC/SNAP) by this MACRO
832// _pRemovedLLCSNAP: pointer to removed LLC/SNAP; NULL is not removed
833#define CONVERT_TO_802_3(_p8023hdr, _pDA, _pSA, _pData, _DataSize, _pRemovedLLCSNAP) \
834{ \
835 char LLC_Len[2]; \
836 \
837 _pRemovedLLCSNAP = NULL; \
838 if (NdisEqualMemory(SNAP_802_1H, _pData, 6) || \
839 NdisEqualMemory(SNAP_BRIDGE_TUNNEL, _pData, 6)) \
840 { \
841 PUCHAR pProto = _pData + 6; \
842 \
843 if ((NdisEqualMemory(IPX, pProto, 2) || NdisEqualMemory(APPLE_TALK, pProto, 2)) && \
844 NdisEqualMemory(SNAP_802_1H, _pData, 6)) \
845 { \
846 LLC_Len[0] = (UCHAR)(_DataSize / 256); \
847 LLC_Len[1] = (UCHAR)(_DataSize % 256); \
848 MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, LLC_Len); \
849 } \
850 else \
851 { \
852 MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, pProto); \
853 _pRemovedLLCSNAP = _pData; \
854 _DataSize -= LENGTH_802_1_H; \
855 _pData += LENGTH_802_1_H; \
856 } \
857 } \
858 else \
859 { \
860 LLC_Len[0] = (UCHAR)(_DataSize / 256); \
861 LLC_Len[1] = (UCHAR)(_DataSize % 256); \
862 MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, LLC_Len); \
863 } \
864}
865
866#define SWITCH_AB( _pAA, _pBB) \
867{ \
868 PVOID pCC; \
869 pCC = _pBB; \
870 _pBB = _pAA; \
871 _pAA = pCC; \
872}
873
874// Enqueue this frame to MLME engine
875// We need to enqueue the whole frame because MLME need to pass data type
876// information from 802.11 header
877#ifdef RT2870
878#define REPORT_MGMT_FRAME_TO_MLME(_pAd, Wcid, _pFrame, _FrameSize, _Rssi0, _Rssi1, _Rssi2, _PlcpSignal) \
879{ \
880 UINT32 High32TSF=0, Low32TSF=0; \
881 MlmeEnqueueForRecv(_pAd, Wcid, High32TSF, Low32TSF, (UCHAR)_Rssi0, (UCHAR)_Rssi1,(UCHAR)_Rssi2,_FrameSize, _pFrame, (UCHAR)_PlcpSignal); \
882}
883#endif // RT2870 //
884
885#ifdef RT30xx
886//Need to collect each ant's rssi concurrently
887//rssi1 is report to pair2 Ant and rss2 is reprot to pair1 Ant when 4 Ant
888#define COLLECT_RX_ANTENNA_AVERAGE_RSSI(_pAd, _rssi1, _rssi2) \
889{ \
890 SHORT AvgRssi; \
891 UCHAR UsedAnt; \
892 if (_pAd->RxAnt.EvaluatePeriod == 0) \
893 { \
894 UsedAnt = _pAd->RxAnt.Pair1PrimaryRxAnt; \
895 AvgRssi = _pAd->RxAnt.Pair1AvgRssi[UsedAnt]; \
896 if (AvgRssi < 0) \
897 AvgRssi = AvgRssi - (AvgRssi >> 3) + _rssi1; \
898 else \
899 AvgRssi = _rssi1 << 3; \
900 _pAd->RxAnt.Pair1AvgRssi[UsedAnt] = AvgRssi; \
901 } \
902 else \
903 { \
904 UsedAnt = _pAd->RxAnt.Pair1SecondaryRxAnt; \
905 AvgRssi = _pAd->RxAnt.Pair1AvgRssi[UsedAnt]; \
906 if ((AvgRssi < 0) && (_pAd->RxAnt.FirstPktArrivedWhenEvaluate)) \
907 AvgRssi = AvgRssi - (AvgRssi >> 3) + _rssi1; \
908 else \
909 { \
910 _pAd->RxAnt.FirstPktArrivedWhenEvaluate = TRUE; \
911 AvgRssi = _rssi1 << 3; \
912 } \
913 _pAd->RxAnt.Pair1AvgRssi[UsedAnt] = AvgRssi; \
914 _pAd->RxAnt.RcvPktNumWhenEvaluate++; \
915 } \
916}
917#endif // RT30xx //
918
919
920#define NDIS_QUERY_BUFFER(_NdisBuf, _ppVA, _pBufLen) \
921 NdisQueryBuffer(_NdisBuf, _ppVA, _pBufLen)
922
923#define MAC_ADDR_EQUAL(pAddr1,pAddr2) RTMPEqualMemory((PVOID)(pAddr1), (PVOID)(pAddr2), MAC_ADDR_LEN)
924#define SSID_EQUAL(ssid1, len1, ssid2, len2) ((len1==len2) && (RTMPEqualMemory(ssid1, ssid2, len1)))
925
926//
927// Check if it is Japan W53(ch52,56,60,64) channel.
928//
929#define JapanChannelCheck(channel) ((channel == 52) || (channel == 56) || (channel == 60) || (channel == 64))
930
931#ifdef CONFIG_STA_SUPPORT
932#define STA_PORT_SECURED(_pAd) \
933{ \
934 _pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; \
935 NdisAcquireSpinLock(&_pAd->MacTabLock); \
936 _pAd->MacTab.Content[BSSID_WCID].PortSecured = _pAd->StaCfg.PortSecured; \
937 NdisReleaseSpinLock(&_pAd->MacTabLock); \
938}
939#endif // CONFIG_STA_SUPPORT //
940
941
942//
943// Register set pair for initialzation register set definition
944//
945typedef struct _RTMP_REG_PAIR
946{
947 ULONG Register;
948 ULONG Value;
949} RTMP_REG_PAIR, *PRTMP_REG_PAIR;
950
951typedef struct _REG_PAIR
952{
953 UCHAR Register;
954 UCHAR Value;
955} REG_PAIR, *PREG_PAIR;
956
957//
958// Register set pair for initialzation register set definition
959//
960typedef struct _RTMP_RF_REGS
961{
962 UCHAR Channel;
963 ULONG R1;
964 ULONG R2;
965 ULONG R3;
966 ULONG R4;
967} RTMP_RF_REGS, *PRTMP_RF_REGS;
968
969typedef struct _FREQUENCY_ITEM {
970 UCHAR Channel;
971 UCHAR N;
972 UCHAR R;
973 UCHAR K;
974} FREQUENCY_ITEM, *PFREQUENCY_ITEM;
975
976//
977// Data buffer for DMA operation, the buffer must be contiguous physical memory
978// Both DMA to / from CPU use the same structure.
979//
980typedef struct _RTMP_DMABUF
981{
982 ULONG AllocSize;
983 PVOID AllocVa; // TxBuf virtual address
984 NDIS_PHYSICAL_ADDRESS AllocPa; // TxBuf physical address
985} RTMP_DMABUF, *PRTMP_DMABUF;
986
987
988typedef union _HEADER_802_11_SEQ{
989#ifdef RT_BIG_ENDIAN
990 struct {
991 USHORT Sequence:12;
992 USHORT Frag:4;
993 } field;
994#else
995 struct {
996 USHORT Frag:4;
997 USHORT Sequence:12;
998 } field;
999#endif
1000 USHORT value;
1001} HEADER_802_11_SEQ, *PHEADER_802_11_SEQ;
1002
1003//
1004// Data buffer for DMA operation, the buffer must be contiguous physical memory
1005// Both DMA to / from CPU use the same structure.
1006//
1007typedef struct _RTMP_REORDERBUF
1008{
1009 BOOLEAN IsFull;
1010 PVOID AllocVa; // TxBuf virtual address
1011 UCHAR Header802_3[14];
1012 HEADER_802_11_SEQ Sequence; //support compressed bitmap BA, so no consider fragment in BA
1013 UCHAR DataOffset;
1014 USHORT Datasize;
1015 ULONG AllocSize;
1016#ifdef RT2870
1017 PUCHAR AllocPa;
1018#endif // RT2870 //
1019} RTMP_REORDERBUF, *PRTMP_REORDERBUF;
1020
1021//
1022// Control block (Descriptor) for all ring descriptor DMA operation, buffer must be
1023// contiguous physical memory. NDIS_PACKET stored the binding Rx packet descriptor
1024// which won't be released, driver has to wait until upper layer return the packet
1025// before giveing up this rx ring descriptor to ASIC. NDIS_BUFFER is assocaited pair
1026// to describe the packet buffer. For Tx, NDIS_PACKET stored the tx packet descriptor
1027// which driver should ACK upper layer when the tx is physically done or failed.
1028//
1029typedef struct _RTMP_DMACB
1030{
1031 ULONG AllocSize; // Control block size
1032 PVOID AllocVa; // Control block virtual address
1033 NDIS_PHYSICAL_ADDRESS AllocPa; // Control block physical address
1034 PNDIS_PACKET pNdisPacket;
1035 PNDIS_PACKET pNextNdisPacket;
1036
1037 RTMP_DMABUF DmaBuf; // Associated DMA buffer structure
1038} RTMP_DMACB, *PRTMP_DMACB;
1039
1040typedef struct _RTMP_TX_BUF
1041{
1042 PQUEUE_ENTRY Next;
1043 UCHAR Index;
1044 ULONG AllocSize; // Control block size
1045 PVOID AllocVa; // Control block virtual address
1046 NDIS_PHYSICAL_ADDRESS AllocPa; // Control block physical address
1047} RTMP_TXBUF, *PRTMP_TXBUF;
1048
1049typedef struct _RTMP_RX_BUF
1050{
1051 BOOLEAN InUse;
1052 ULONG ByBaRecIndex;
1053 RTMP_REORDERBUF MAP_RXBuf[MAX_RX_REORDERBUF];
1054} RTMP_RXBUF, *PRTMP_RXBUF;
1055typedef struct _RTMP_TX_RING
1056{
1057 RTMP_DMACB Cell[TX_RING_SIZE];
1058 UINT32 TxCpuIdx;
1059 UINT32 TxDmaIdx;
1060 UINT32 TxSwFreeIdx; // software next free tx index
1061} RTMP_TX_RING, *PRTMP_TX_RING;
1062
1063typedef struct _RTMP_RX_RING
1064{
1065 RTMP_DMACB Cell[RX_RING_SIZE];
1066 UINT32 RxCpuIdx;
1067 UINT32 RxDmaIdx;
1068 INT32 RxSwReadIdx; // software next read index
1069} RTMP_RX_RING, *PRTMP_RX_RING;
1070
1071typedef struct _RTMP_MGMT_RING
1072{
1073 RTMP_DMACB Cell[MGMT_RING_SIZE];
1074 UINT32 TxCpuIdx;
1075 UINT32 TxDmaIdx;
1076 UINT32 TxSwFreeIdx; // software next free tx index
1077} RTMP_MGMT_RING, *PRTMP_MGMT_RING;
1078
1079//
1080// Statistic counter structure
1081//
1082typedef struct _COUNTER_802_3
1083{
1084 // General Stats
1085 ULONG GoodTransmits;
1086 ULONG GoodReceives;
1087 ULONG TxErrors;
1088 ULONG RxErrors;
1089 ULONG RxNoBuffer;
1090
1091 // Ethernet Stats
1092 ULONG RcvAlignmentErrors;
1093 ULONG OneCollision;
1094 ULONG MoreCollisions;
1095
1096} COUNTER_802_3, *PCOUNTER_802_3;
1097
1098typedef struct _COUNTER_802_11 {
1099 ULONG Length;
1100 LARGE_INTEGER LastTransmittedFragmentCount;
1101 LARGE_INTEGER TransmittedFragmentCount;
1102 LARGE_INTEGER MulticastTransmittedFrameCount;
1103 LARGE_INTEGER FailedCount;
1104 LARGE_INTEGER RetryCount;
1105 LARGE_INTEGER MultipleRetryCount;
1106 LARGE_INTEGER RTSSuccessCount;
1107 LARGE_INTEGER RTSFailureCount;
1108 LARGE_INTEGER ACKFailureCount;
1109 LARGE_INTEGER FrameDuplicateCount;
1110 LARGE_INTEGER ReceivedFragmentCount;
1111 LARGE_INTEGER MulticastReceivedFrameCount;
1112 LARGE_INTEGER FCSErrorCount;
1113} COUNTER_802_11, *PCOUNTER_802_11;
1114
1115typedef struct _COUNTER_RALINK {
1116 ULONG TransmittedByteCount; // both successful and failure, used to calculate TX throughput
1117 ULONG ReceivedByteCount; // both CRC okay and CRC error, used to calculate RX throughput
1118 ULONG BeenDisassociatedCount;
1119 ULONG BadCQIAutoRecoveryCount;
1120 ULONG PoorCQIRoamingCount;
1121 ULONG MgmtRingFullCount;
1122 ULONG RxCountSinceLastNULL;
1123 ULONG RxCount;
1124 ULONG RxRingErrCount;
1125 ULONG KickTxCount;
1126 ULONG TxRingErrCount;
1127 LARGE_INTEGER RealFcsErrCount;
1128 ULONG PendingNdisPacketCount;
1129
1130 ULONG OneSecOsTxCount[NUM_OF_TX_RING];
1131 ULONG OneSecDmaDoneCount[NUM_OF_TX_RING];
1132 UINT32 OneSecTxDoneCount;
1133 ULONG OneSecRxCount;
1134 UINT32 OneSecTxAggregationCount;
1135 UINT32 OneSecRxAggregationCount;
1136
1137 UINT32 OneSecFrameDuplicateCount;
1138
1139#ifdef RT2870
1140 ULONG OneSecTransmittedByteCount; // both successful and failure, used to calculate TX throughput
1141#endif // RT2870 //
1142
1143 UINT32 OneSecTxNoRetryOkCount;
1144 UINT32 OneSecTxRetryOkCount;
1145 UINT32 OneSecTxFailCount;
1146 UINT32 OneSecFalseCCACnt; // CCA error count, for debug purpose, might move to global counter
1147 UINT32 OneSecRxOkCnt; // RX without error
1148 UINT32 OneSecRxOkDataCnt; // unicast-to-me DATA frame count
1149 UINT32 OneSecRxFcsErrCnt; // CRC error
1150 UINT32 OneSecBeaconSentCnt;
1151 UINT32 LastOneSecTotalTxCount; // OneSecTxNoRetryOkCount + OneSecTxRetryOkCount + OneSecTxFailCount
1152 UINT32 LastOneSecRxOkDataCnt; // OneSecRxOkDataCnt
1153 ULONG DuplicateRcv;
1154 ULONG TxAggCount;
1155 ULONG TxNonAggCount;
1156 ULONG TxAgg1MPDUCount;
1157 ULONG TxAgg2MPDUCount;
1158 ULONG TxAgg3MPDUCount;
1159 ULONG TxAgg4MPDUCount;
1160 ULONG TxAgg5MPDUCount;
1161 ULONG TxAgg6MPDUCount;
1162 ULONG TxAgg7MPDUCount;
1163 ULONG TxAgg8MPDUCount;
1164 ULONG TxAgg9MPDUCount;
1165 ULONG TxAgg10MPDUCount;
1166 ULONG TxAgg11MPDUCount;
1167 ULONG TxAgg12MPDUCount;
1168 ULONG TxAgg13MPDUCount;
1169 ULONG TxAgg14MPDUCount;
1170 ULONG TxAgg15MPDUCount;
1171 ULONG TxAgg16MPDUCount;
1172
1173 LARGE_INTEGER TransmittedOctetsInAMSDU;
1174 LARGE_INTEGER TransmittedAMSDUCount;
1175 LARGE_INTEGER ReceivedOctesInAMSDUCount;
1176 LARGE_INTEGER ReceivedAMSDUCount;
1177 LARGE_INTEGER TransmittedAMPDUCount;
1178 LARGE_INTEGER TransmittedMPDUsInAMPDUCount;
1179 LARGE_INTEGER TransmittedOctetsInAMPDUCount;
1180 LARGE_INTEGER MPDUInReceivedAMPDUCount;
1181} COUNTER_RALINK, *PCOUNTER_RALINK;
1182
1183typedef struct _PID_COUNTER {
1184 ULONG TxAckRequiredCount; // CRC error
1185 ULONG TxAggreCount;
1186 ULONG TxSuccessCount; // OneSecTxNoRetryOkCount + OneSecTxRetryOkCount + OneSecTxFailCount
1187 ULONG LastSuccessRate;
1188} PID_COUNTER, *PPID_COUNTER;
1189
1190typedef struct _COUNTER_DRS {
1191 // to record the each TX rate's quality. 0 is best, the bigger the worse.
1192 USHORT TxQuality[MAX_STEP_OF_TX_RATE_SWITCH];
1193 UCHAR PER[MAX_STEP_OF_TX_RATE_SWITCH];
1194 UCHAR TxRateUpPenalty; // extra # of second penalty due to last unstable condition
1195 ULONG CurrTxRateStableTime; // # of second in current TX rate
1196 BOOLEAN fNoisyEnvironment;
1197 BOOLEAN fLastSecAccordingRSSI;
1198 UCHAR LastSecTxRateChangeAction; // 0: no change, 1:rate UP, 2:rate down
1199 UCHAR LastTimeTxRateChangeAction; //Keep last time value of LastSecTxRateChangeAction
1200 ULONG LastTxOkCount;
1201} COUNTER_DRS, *PCOUNTER_DRS;
1202
1203//
1204// Arcfour Structure Added by PaulWu
1205//
1206typedef struct _ARCFOUR
1207{
1208 UINT X;
1209 UINT Y;
1210 UCHAR STATE[256];
1211} ARCFOURCONTEXT, *PARCFOURCONTEXT;
1212
1213// MIMO Tx parameter, ShortGI, MCS, STBC, etc. these are fields in TXWI too. just copy to TXWI.
1214typedef struct _RECEIVE_SETTING {
1215#ifdef RT_BIG_ENDIAN
1216 USHORT MIMO:1;
1217 USHORT OFDM:1;
1218 USHORT rsv:3;
1219 USHORT STBC:2; //SPACE
1220 USHORT ShortGI:1;
1221 USHORT Mode:2; //channel bandwidth 20MHz or 40 MHz
1222 USHORT NumOfRX:2; // MIMO. WE HAVE 3R
1223#else
1224 USHORT NumOfRX:2; // MIMO. WE HAVE 3R
1225 USHORT Mode:2; //channel bandwidth 20MHz or 40 MHz
1226 USHORT ShortGI:1;
1227 USHORT STBC:2; //SPACE
1228 USHORT rsv:3;
1229 USHORT OFDM:1;
1230 USHORT MIMO:1;
1231#endif
1232 } RECEIVE_SETTING, *PRECEIVE_SETTING;
1233
1234// Shared key data structure
1235typedef struct _WEP_KEY {
1236 UCHAR KeyLen; // Key length for each key, 0: entry is invalid
1237 UCHAR Key[MAX_LEN_OF_KEY]; // right now we implement 4 keys, 128 bits max
1238} WEP_KEY, *PWEP_KEY;
1239
1240typedef struct _CIPHER_KEY {
1241 UCHAR Key[16]; // right now we implement 4 keys, 128 bits max
1242 UCHAR RxMic[8]; // make alignment
1243 UCHAR TxMic[8];
1244 UCHAR TxTsc[6]; // 48bit TSC value
1245 UCHAR RxTsc[6]; // 48bit TSC value
1246 UCHAR CipherAlg; // 0-none, 1:WEP64, 2:WEP128, 3:TKIP, 4:AES, 5:CKIP64, 6:CKIP128
1247 UCHAR KeyLen;
1248#ifdef CONFIG_STA_SUPPORT
1249 UCHAR BssId[6];
1250#endif // CONFIG_STA_SUPPORT //
1251 // Key length for each key, 0: entry is invalid
1252 UCHAR Type; // Indicate Pairwise/Group when reporting MIC error
1253} CIPHER_KEY, *PCIPHER_KEY;
1254
1255typedef struct _BBP_TUNING_STRUCT {
1256 BOOLEAN Enable;
1257 UCHAR FalseCcaCountUpperBound; // 100 per sec
1258 UCHAR FalseCcaCountLowerBound; // 10 per sec
1259 UCHAR R17LowerBound; // specified in E2PROM
1260 UCHAR R17UpperBound; // 0x68 according to David Tung
1261 UCHAR CurrentR17Value;
1262} BBP_TUNING, *PBBP_TUNING;
1263
1264typedef struct _SOFT_RX_ANT_DIVERSITY_STRUCT {
1265 UCHAR EvaluatePeriod; // 0:not evalute status, 1: evaluate status, 2: switching status
1266 UCHAR EvaluateStableCnt;
1267 UCHAR Pair1PrimaryRxAnt; // 0:Ant-E1, 1:Ant-E2
1268 UCHAR Pair1SecondaryRxAnt; // 0:Ant-E1, 1:Ant-E2
1269 UCHAR Pair2PrimaryRxAnt; // 0:Ant-E3, 1:Ant-E4
1270 UCHAR Pair2SecondaryRxAnt; // 0:Ant-E3, 1:Ant-E4
1271 SHORT Pair1AvgRssi[2]; // AvgRssi[0]:E1, AvgRssi[1]:E2
1272 SHORT Pair2AvgRssi[2]; // AvgRssi[0]:E3, AvgRssi[1]:E4
1273 SHORT Pair1LastAvgRssi; //
1274 SHORT Pair2LastAvgRssi; //
1275 ULONG RcvPktNumWhenEvaluate;
1276 BOOLEAN FirstPktArrivedWhenEvaluate;
1277 RALINK_TIMER_STRUCT RxAntDiversityTimer;
1278} SOFT_RX_ANT_DIVERSITY, *PSOFT_RX_ANT_DIVERSITY;
1279
1280typedef struct _LEAP_AUTH_INFO {
1281 BOOLEAN Enabled; //Ture: Enable LEAP Authentication
1282 BOOLEAN CCKM; //Ture: Use Fast Reauthentication with CCKM
1283 UCHAR Reserve[2];
1284 UCHAR UserName[256]; //LEAP, User name
1285 ULONG UserNameLen;
1286 UCHAR Password[256]; //LEAP, User Password
1287 ULONG PasswordLen;
1288} LEAP_AUTH_INFO, *PLEAP_AUTH_INFO;
1289
1290typedef struct {
1291 UCHAR Addr[MAC_ADDR_LEN];
1292 UCHAR ErrorCode[2]; //00 01-Invalid authentication type
1293 //00 02-Authentication timeout
1294 //00 03-Challenge from AP failed
1295 //00 04-Challenge to AP failed
1296 BOOLEAN Reported;
1297} ROGUEAP_ENTRY, *PROGUEAP_ENTRY;
1298
1299typedef struct {
1300 UCHAR RogueApNr;
1301 ROGUEAP_ENTRY RogueApEntry[MAX_LEN_OF_BSS_TABLE];
1302} ROGUEAP_TABLE, *PROGUEAP_TABLE;
1303
1304typedef struct {
1305 BOOLEAN Enable;
1306 UCHAR Delta;
1307 BOOLEAN PlusSign;
1308} CCK_TX_POWER_CALIBRATE, *PCCK_TX_POWER_CALIBRATE;
1309
1310//
1311// Receive Tuple Cache Format
1312//
1313typedef struct _TUPLE_CACHE {
1314 BOOLEAN Valid;
1315 UCHAR MacAddress[MAC_ADDR_LEN];
1316 USHORT Sequence;
1317 USHORT Frag;
1318} TUPLE_CACHE, *PTUPLE_CACHE;
1319
1320//
1321// Fragment Frame structure
1322//
1323typedef struct _FRAGMENT_FRAME {
1324 PNDIS_PACKET pFragPacket;
1325 ULONG RxSize;
1326 USHORT Sequence;
1327 USHORT LastFrag;
1328 ULONG Flags; // Some extra frame information. bit 0: LLC presented
1329} FRAGMENT_FRAME, *PFRAGMENT_FRAME;
1330
1331
1332//
1333// Packet information for NdisQueryPacket
1334//
1335typedef struct _PACKET_INFO {
1336 UINT PhysicalBufferCount; // Physical breaks of buffer descripor chained
1337 UINT BufferCount ; // Number of Buffer descriptor chained
1338 UINT TotalPacketLength ; // Self explained
1339 PNDIS_BUFFER pFirstBuffer; // Pointer to first buffer descriptor
1340} PACKET_INFO, *PPACKET_INFO;
1341
1342//
1343// Tkip Key structure which RC4 key & MIC calculation
1344//
1345typedef struct _TKIP_KEY_INFO {
1346 UINT nBytesInM; // # bytes in M for MICKEY
1347 ULONG IV16;
1348 ULONG IV32;
1349 ULONG K0; // for MICKEY Low
1350 ULONG K1; // for MICKEY Hig
1351 ULONG L; // Current state for MICKEY
1352 ULONG R; // Current state for MICKEY
1353 ULONG M; // Message accumulator for MICKEY
1354 UCHAR RC4KEY[16];
1355 UCHAR MIC[8];
1356} TKIP_KEY_INFO, *PTKIP_KEY_INFO;
1357
1358//
1359// Private / Misc data, counters for driver internal use
1360//
1361typedef struct __PRIVATE_STRUC {
1362 UINT SystemResetCnt; // System reset counter
1363 UINT TxRingFullCnt; // Tx ring full occurrance number
1364 UINT PhyRxErrCnt; // PHY Rx error count, for debug purpose, might move to global counter
1365 // Variables for WEP encryption / decryption in rtmp_wep.c
1366 UINT FCSCRC32;
1367 ARCFOURCONTEXT WEPCONTEXT;
1368 // Tkip stuff
1369 TKIP_KEY_INFO Tx;
1370 TKIP_KEY_INFO Rx;
1371} PRIVATE_STRUC, *PPRIVATE_STRUC;
1372
1373// structure to tune BBP R66 (BBP TUNING)
1374typedef struct _BBP_R66_TUNING {
1375 BOOLEAN bEnable;
1376 USHORT FalseCcaLowerThreshold; // default 100
1377 USHORT FalseCcaUpperThreshold; // default 512
1378 UCHAR R66Delta;
1379 UCHAR R66CurrentValue;
1380 BOOLEAN R66LowerUpperSelect; //Before LinkUp, Used LowerBound or UpperBound as R66 value.
1381} BBP_R66_TUNING, *PBBP_R66_TUNING;
1382
1383// structure to store channel TX power
1384typedef struct _CHANNEL_TX_POWER {
1385 USHORT RemainingTimeForUse; //unit: sec
1386 UCHAR Channel;
1387#ifdef DOT11N_DRAFT3
1388 BOOLEAN bEffectedChannel; // For BW 40 operating in 2.4GHz , the "effected channel" is the channel that is covered in 40Mhz.
1389#endif // DOT11N_DRAFT3 //
1390 CHAR Power;
1391 CHAR Power2;
1392 UCHAR MaxTxPwr;
1393 UCHAR DfsReq;
1394} CHANNEL_TX_POWER, *PCHANNEL_TX_POWER;
1395
1396// structure to store 802.11j channel TX power
1397typedef struct _CHANNEL_11J_TX_POWER {
1398 UCHAR Channel;
1399 UCHAR BW; // BW_10 or BW_20
1400 CHAR Power;
1401 CHAR Power2;
1402 USHORT RemainingTimeForUse; //unit: sec
1403} CHANNEL_11J_TX_POWER, *PCHANNEL_11J_TX_POWER;
1404
1405typedef enum _ABGBAND_STATE_ {
1406 UNKNOWN_BAND,
1407 BG_BAND,
1408 A_BAND,
1409} ABGBAND_STATE;
1410
1411typedef struct _MLME_STRUCT {
1412#ifdef CONFIG_STA_SUPPORT
1413 // STA state machines
1414 STATE_MACHINE CntlMachine;
1415 STATE_MACHINE AssocMachine;
1416 STATE_MACHINE AuthMachine;
1417 STATE_MACHINE AuthRspMachine;
1418 STATE_MACHINE SyncMachine;
1419 STATE_MACHINE WpaPskMachine;
1420 STATE_MACHINE LeapMachine;
1421 STATE_MACHINE AironetMachine;
1422 STATE_MACHINE_FUNC AssocFunc[ASSOC_FUNC_SIZE];
1423 STATE_MACHINE_FUNC AuthFunc[AUTH_FUNC_SIZE];
1424 STATE_MACHINE_FUNC AuthRspFunc[AUTH_RSP_FUNC_SIZE];
1425 STATE_MACHINE_FUNC SyncFunc[SYNC_FUNC_SIZE];
1426 STATE_MACHINE_FUNC WpaPskFunc[WPA_PSK_FUNC_SIZE];
1427 STATE_MACHINE_FUNC AironetFunc[AIRONET_FUNC_SIZE];
1428#endif // CONFIG_STA_SUPPORT //
1429 STATE_MACHINE_FUNC ActFunc[ACT_FUNC_SIZE];
1430 // Action
1431 STATE_MACHINE ActMachine;
1432
1433
1434#ifdef QOS_DLS_SUPPORT
1435 STATE_MACHINE DlsMachine;
1436 STATE_MACHINE_FUNC DlsFunc[DLS_FUNC_SIZE];
1437#endif // QOS_DLS_SUPPORT //
1438
1439
1440
1441
1442 ULONG ChannelQuality; // 0..100, Channel Quality Indication for Roaming
1443 ULONG Now32; // latch the value of NdisGetSystemUpTime()
1444 ULONG LastSendNULLpsmTime;
1445
1446 BOOLEAN bRunning;
1447 NDIS_SPIN_LOCK TaskLock;
1448 MLME_QUEUE Queue;
1449
1450 UINT ShiftReg;
1451
1452 RALINK_TIMER_STRUCT PeriodicTimer;
1453 RALINK_TIMER_STRUCT APSDPeriodicTimer;
1454 RALINK_TIMER_STRUCT LinkDownTimer;
1455 RALINK_TIMER_STRUCT LinkUpTimer;
1456 ULONG PeriodicRound;
1457 ULONG OneSecPeriodicRound;
1458
1459 UCHAR RealRxPath;
1460 BOOLEAN bLowThroughput;
1461 BOOLEAN bEnableAutoAntennaCheck;
1462 RALINK_TIMER_STRUCT RxAntEvalTimer;
1463
1464#ifdef RT30xx
1465 UCHAR CaliBW40RfR24;
1466 UCHAR CaliBW20RfR24;
1467#endif // RT30xx //
1468
1469} MLME_STRUCT, *PMLME_STRUCT;
1470
1471// structure for radar detection and channel switch
1472typedef struct _RADAR_DETECT_STRUCT {
1473 //BOOLEAN IEEE80211H; // 0: disable, 1: enable IEEE802.11h
1474 UCHAR CSCount; //Channel switch counter
1475 UCHAR CSPeriod; //Channel switch period (beacon count)
1476 UCHAR RDCount; //Radar detection counter
1477 UCHAR RDMode; //Radar Detection mode
1478 UCHAR RDDurRegion; //Radar detection duration region
1479 UCHAR BBPR16;
1480 UCHAR BBPR17;
1481 UCHAR BBPR18;
1482 UCHAR BBPR21;
1483 UCHAR BBPR22;
1484 UCHAR BBPR64;
1485 ULONG InServiceMonitorCount; // unit: sec
1486 UINT8 DfsSessionTime;
1487 BOOLEAN bFastDfs;
1488 UINT8 ChMovingTime;
1489 UINT8 LongPulseRadarTh;
1490} RADAR_DETECT_STRUCT, *PRADAR_DETECT_STRUCT;
1491
1492#ifdef CARRIER_DETECTION_SUPPORT
1493typedef enum CD_STATE_n
1494{
1495 CD_NORMAL,
1496 CD_SILENCE,
1497 CD_MAX_STATE
1498} CD_STATE;
1499
1500typedef struct CARRIER_DETECTION_s
1501{
1502 BOOLEAN Enable;
1503 UINT8 CDSessionTime;
1504 UINT8 CDPeriod;
1505 CD_STATE CD_State;
1506} CARRIER_DETECTION, *PCARRIER_DETECTION;
1507#endif // CARRIER_DETECTION_SUPPORT //
1508
1509typedef enum _REC_BLOCKACK_STATUS
1510{
1511 Recipient_NONE=0,
1512 Recipient_USED,
1513 Recipient_HandleRes,
1514 Recipient_Accept
1515} REC_BLOCKACK_STATUS, *PREC_BLOCKACK_STATUS;
1516
1517typedef enum _ORI_BLOCKACK_STATUS
1518{
1519 Originator_NONE=0,
1520 Originator_USED,
1521 Originator_WaitRes,
1522 Originator_Done
1523} ORI_BLOCKACK_STATUS, *PORI_BLOCKACK_STATUS;
1524
1525#ifdef DOT11_N_SUPPORT
1526typedef struct _BA_ORI_ENTRY{
1527 UCHAR Wcid;
1528 UCHAR TID;
1529 UCHAR BAWinSize;
1530 UCHAR Token;
1531// Sequence is to fill every outgoing QoS DATA frame's sequence field in 802.11 header.
1532 USHORT Sequence;
1533 USHORT TimeOutValue;
1534 ORI_BLOCKACK_STATUS ORI_BA_Status;
1535 RALINK_TIMER_STRUCT ORIBATimer;
1536 PVOID pAdapter;
1537} BA_ORI_ENTRY, *PBA_ORI_ENTRY;
1538
1539typedef struct _BA_REC_ENTRY {
1540 UCHAR Wcid;
1541 UCHAR TID;
1542 UCHAR BAWinSize; // 7.3.1.14. each buffer is capable of holding a max AMSDU or MSDU.
1543 //UCHAR NumOfRxPkt;
1544 //UCHAR Curindidx; // the head in the RX reordering buffer
1545 USHORT LastIndSeq;
1546// USHORT LastIndSeqAtTimer;
1547 USHORT TimeOutValue;
1548 RALINK_TIMER_STRUCT RECBATimer;
1549 ULONG LastIndSeqAtTimer;
1550 ULONG nDropPacket;
1551 ULONG rcvSeq;
1552 REC_BLOCKACK_STATUS REC_BA_Status;
1553// UCHAR RxBufIdxUsed;
1554 // corresponding virtual address for RX reordering packet storage.
1555 //RTMP_REORDERDMABUF MAP_RXBuf[MAX_RX_REORDERBUF];
1556 NDIS_SPIN_LOCK RxReRingLock; // Rx Ring spinlock
1557// struct _BA_REC_ENTRY *pNext;
1558 PVOID pAdapter;
1559 struct reordering_list list;
1560} BA_REC_ENTRY, *PBA_REC_ENTRY;
1561
1562
1563typedef struct {
1564 ULONG numAsRecipient; // I am recipient of numAsRecipient clients. These client are in the BARecEntry[]
1565 ULONG numAsOriginator; // I am originator of numAsOriginator clients. These clients are in the BAOriEntry[]
1566 BA_ORI_ENTRY BAOriEntry[MAX_LEN_OF_BA_ORI_TABLE];
1567 BA_REC_ENTRY BARecEntry[MAX_LEN_OF_BA_REC_TABLE];
1568} BA_TABLE, *PBA_TABLE;
1569
1570//For QureyBATableOID use;
1571typedef struct PACKED _OID_BA_REC_ENTRY{
1572 UCHAR MACAddr[MAC_ADDR_LEN];
1573 UCHAR BaBitmap; // if (BaBitmap&(1<<TID)), this session with{MACAddr, TID}exists, so read BufSize[TID] for BufferSize
1574 UCHAR rsv;
1575 UCHAR BufSize[8];
1576 REC_BLOCKACK_STATUS REC_BA_Status[8];
1577} OID_BA_REC_ENTRY, *POID_BA_REC_ENTRY;
1578
1579//For QureyBATableOID use;
1580typedef struct PACKED _OID_BA_ORI_ENTRY{
1581 UCHAR MACAddr[MAC_ADDR_LEN];
1582 UCHAR BaBitmap; // if (BaBitmap&(1<<TID)), this session with{MACAddr, TID}exists, so read BufSize[TID] for BufferSize, read ORI_BA_Status[TID] for status
1583 UCHAR rsv;
1584 UCHAR BufSize[8];
1585 ORI_BLOCKACK_STATUS ORI_BA_Status[8];
1586} OID_BA_ORI_ENTRY, *POID_BA_ORI_ENTRY;
1587
1588typedef struct _QUERYBA_TABLE{
1589 OID_BA_ORI_ENTRY BAOriEntry[32];
1590 OID_BA_REC_ENTRY BARecEntry[32];
1591 UCHAR OriNum;// Number of below BAOriEntry
1592 UCHAR RecNum;// Number of below BARecEntry
1593} QUERYBA_TABLE, *PQUERYBA_TABLE;
1594
1595typedef union _BACAP_STRUC {
1596#ifdef RT_BIG_ENDIAN
1597 struct {
1598 UINT32 :4;
1599 UINT32 b2040CoexistScanSup:1; //As Sta, support do 2040 coexistence scan for AP. As Ap, support monitor trigger event to check if can use BW 40MHz.
1600 UINT32 bHtAdhoc:1; // adhoc can use ht rate.
1601 UINT32 MMPSmode:2; // MIMO power save more, 0:static, 1:dynamic, 2:rsv, 3:mimo enable
1602 UINT32 AmsduSize:1; // 0:3839, 1:7935 bytes. UINT MSDUSizeToBytes[] = { 3839, 7935};
1603 UINT32 AmsduEnable:1; //Enable AMSDU transmisstion
1604 UINT32 MpduDensity:3;
1605 UINT32 Policy:2; // 0: DELAY_BA 1:IMMED_BA (//BA Policy subfiled value in ADDBA frame) 2:BA-not use
1606 UINT32 AutoBA:1; // automatically BA
1607 UINT32 TxBAWinLimit:8;
1608 UINT32 RxBAWinLimit:8;
1609 } field;
1610#else
1611 struct {
1612 UINT32 RxBAWinLimit:8;
1613 UINT32 TxBAWinLimit:8;
1614 UINT32 AutoBA:1; // automatically BA
1615 UINT32 Policy:2; // 0: DELAY_BA 1:IMMED_BA (//BA Policy subfiled value in ADDBA frame) 2:BA-not use
1616 UINT32 MpduDensity:3;
1617 UINT32 AmsduEnable:1; //Enable AMSDU transmisstion
1618 UINT32 AmsduSize:1; // 0:3839, 1:7935 bytes. UINT MSDUSizeToBytes[] = { 3839, 7935};
1619 UINT32 MMPSmode:2; // MIMO power save more, 0:static, 1:dynamic, 2:rsv, 3:mimo enable
1620 UINT32 bHtAdhoc:1; // adhoc can use ht rate.
1621 UINT32 b2040CoexistScanSup:1; //As Sta, support do 2040 coexistence scan for AP. As Ap, support monitor trigger event to check if can use BW 40MHz.
1622 UINT32 :4;
1623 } field;
1624#endif
1625 UINT32 word;
1626} BACAP_STRUC, *PBACAP_STRUC;
1627#endif // DOT11_N_SUPPORT //
1628
1629//This structure is for all 802.11n card InterOptibilityTest action. Reset all Num every n second. (Details see MLMEPeriodic)
1630typedef struct _IOT_STRUC {
1631 UCHAR Threshold[2];
1632 UCHAR ReorderTimeOutNum[MAX_LEN_OF_BA_REC_TABLE]; // compare with threshold[0]
1633 UCHAR RefreshNum[MAX_LEN_OF_BA_REC_TABLE]; // compare with threshold[1]
1634 ULONG OneSecInWindowCount;
1635 ULONG OneSecFrameDuplicateCount;
1636 ULONG OneSecOutWindowCount;
1637 UCHAR DelOriAct;
1638 UCHAR DelRecAct;
1639 UCHAR RTSShortProt;
1640 UCHAR RTSLongProt;
1641 BOOLEAN bRTSLongProtOn;
1642#ifdef CONFIG_STA_SUPPORT
1643 BOOLEAN bLastAtheros;
1644 BOOLEAN bCurrentAtheros;
1645 BOOLEAN bNowAtherosBurstOn;
1646 BOOLEAN bNextDisableRxBA;
1647 BOOLEAN bToggle;
1648#endif // CONFIG_STA_SUPPORT //
1649} IOT_STRUC, *PIOT_STRUC;
1650
1651// This is the registry setting for 802.11n transmit setting. Used in advanced page.
1652typedef union _REG_TRANSMIT_SETTING {
1653#ifdef RT_BIG_ENDIAN
1654 struct {
1655 UINT32 rsv:13;
1656 UINT32 EXTCHA:2;
1657 UINT32 HTMODE:1;
1658 UINT32 TRANSNO:2;
1659 UINT32 STBC:1; //SPACE
1660 UINT32 ShortGI:1;
1661 UINT32 BW:1; //channel bandwidth 20MHz or 40 MHz
1662 UINT32 TxBF:1; // 3*3
1663 UINT32 rsv0:10;
1664 //UINT32 MCS:7; // MCS
1665 //UINT32 PhyMode:4;
1666 } field;
1667#else
1668 struct {
1669 //UINT32 PhyMode:4;
1670 //UINT32 MCS:7; // MCS
1671 UINT32 rsv0:10;
1672 UINT32 TxBF:1;
1673 UINT32 BW:1; //channel bandwidth 20MHz or 40 MHz
1674 UINT32 ShortGI:1;
1675 UINT32 STBC:1; //SPACE
1676 UINT32 TRANSNO:2;
1677 UINT32 HTMODE:1;
1678 UINT32 EXTCHA:2;
1679 UINT32 rsv:13;
1680 } field;
1681#endif
1682 UINT32 word;
1683} REG_TRANSMIT_SETTING, *PREG_TRANSMIT_SETTING;
1684
1685typedef union _DESIRED_TRANSMIT_SETTING {
1686#ifdef RT_BIG_ENDIAN
1687 struct {
1688 USHORT rsv:3;
1689 USHORT FixedTxMode:2; // If MCS isn't AUTO, fix rate in CCK, OFDM or HT mode.
1690 USHORT PhyMode:4;
1691 USHORT MCS:7; // MCS
1692 } field;
1693#else
1694 struct {
1695 USHORT MCS:7; // MCS
1696 USHORT PhyMode:4;
1697 USHORT FixedTxMode:2; // If MCS isn't AUTO, fix rate in CCK, OFDM or HT mode.
1698 USHORT rsv:3;
1699 } field;
1700#endif
1701 USHORT word;
1702 } DESIRED_TRANSMIT_SETTING, *PDESIRED_TRANSMIT_SETTING;
1703
1704typedef struct {
1705 BOOLEAN IsRecipient;
1706 UCHAR MACAddr[MAC_ADDR_LEN];
1707 UCHAR TID;
1708 UCHAR nMSDU;
1709 USHORT TimeOut;
1710 BOOLEAN bAllTid; // If True, delete all TID for BA sessions with this MACaddr.
1711} OID_ADD_BA_ENTRY, *POID_ADD_BA_ENTRY;
1712
1713//
1714// Multiple SSID structure
1715//
1716#define WLAN_MAX_NUM_OF_TIM ((MAX_LEN_OF_MAC_TABLE >> 3) + 1) /* /8 + 1 */
1717#define WLAN_CT_TIM_BCMC_OFFSET 0 /* unit: 32B */
1718
1719/* clear bcmc TIM bit */
1720#define WLAN_MR_TIM_BCMC_CLEAR(apidx) \
1721 pAd->ApCfg.MBSSID[apidx].TimBitmaps[WLAN_CT_TIM_BCMC_OFFSET] &= ~BIT8[0];
1722
1723/* set bcmc TIM bit */
1724#define WLAN_MR_TIM_BCMC_SET(apidx) \
1725 pAd->ApCfg.MBSSID[apidx].TimBitmaps[WLAN_CT_TIM_BCMC_OFFSET] |= BIT8[0];
1726
1727/* clear a station PS TIM bit */
1728#define WLAN_MR_TIM_BIT_CLEAR(ad_p, apidx, wcid) \
1729 { UCHAR tim_offset = wcid >> 3; \
1730 UCHAR bit_offset = wcid & 0x7; \
1731 ad_p->ApCfg.MBSSID[apidx].TimBitmaps[tim_offset] &= (~BIT8[bit_offset]); }
1732
1733/* set a station PS TIM bit */
1734#define WLAN_MR_TIM_BIT_SET(ad_p, apidx, wcid) \
1735 { UCHAR tim_offset = wcid >> 3; \
1736 UCHAR bit_offset = wcid & 0x7; \
1737 ad_p->ApCfg.MBSSID[apidx].TimBitmaps[tim_offset] |= BIT8[bit_offset]; }
1738
1739#ifdef RT2870
1740#define BEACON_BITMAP_MASK 0xff
1741typedef struct _BEACON_SYNC_STRUCT_
1742{
1743 UCHAR BeaconBuf[HW_BEACON_MAX_COUNT][HW_BEACON_OFFSET];
1744 UCHAR BeaconTxWI[HW_BEACON_MAX_COUNT][TXWI_SIZE];
1745 ULONG TimIELocationInBeacon[HW_BEACON_MAX_COUNT];
1746 ULONG CapabilityInfoLocationInBeacon[HW_BEACON_MAX_COUNT];
1747 BOOLEAN EnableBeacon; // trigger to enable beacon transmission.
1748 UCHAR BeaconBitMap; // NOTE: If the MAX_MBSSID_NUM is larger than 8, this parameter need to change.
1749 UCHAR DtimBitOn; // NOTE: If the MAX_MBSSID_NUM is larger than 8, this parameter need to change.
1750}BEACON_SYNC_STRUCT;
1751#endif // RT2870 //
1752
1753typedef struct _MULTISSID_STRUCT {
1754 UCHAR Bssid[MAC_ADDR_LEN];
1755 UCHAR SsidLen;
1756 CHAR Ssid[MAX_LEN_OF_SSID];
1757 USHORT CapabilityInfo;
1758
1759 PNET_DEV MSSIDDev;
1760
1761 NDIS_802_11_AUTHENTICATION_MODE AuthMode;
1762 NDIS_802_11_WEP_STATUS WepStatus;
1763 NDIS_802_11_WEP_STATUS GroupKeyWepStatus;
1764 WPA_MIX_PAIR_CIPHER WpaMixPairCipher;
1765
1766 ULONG TxCount;
1767 ULONG RxCount;
1768 ULONG ReceivedByteCount;
1769 ULONG TransmittedByteCount;
1770 ULONG RxErrorCount;
1771 ULONG RxDropCount;
1772
1773 HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;// For transmit phy setting in TXWI.
1774 RT_HT_PHY_INFO DesiredHtPhyInfo;
1775 DESIRED_TRANSMIT_SETTING DesiredTransmitSetting; // Desired transmit setting. this is for reading registry setting only. not useful.
1776 BOOLEAN bAutoTxRateSwitch;
1777
1778 //CIPHER_KEY SharedKey[SHARE_KEY_NUM]; // ref pAd->SharedKey[BSS][4]
1779 UCHAR DefaultKeyId;
1780
1781 UCHAR TxRate; // RATE_1, RATE_2, RATE_5_5, RATE_11, ...
1782 UCHAR DesiredRates[MAX_LEN_OF_SUPPORTED_RATES];// OID_802_11_DESIRED_RATES
1783 UCHAR DesiredRatesIndex;
1784 UCHAR MaxTxRate; // RATE_1, RATE_2, RATE_5_5, RATE_11
1785
1786// ULONG TimBitmap; // bit0 for broadcast, 1 for AID1, 2 for AID2, ...so on
1787// ULONG TimBitmap2; // b0 for AID32, b1 for AID33, ... and so on
1788 UCHAR TimBitmaps[WLAN_MAX_NUM_OF_TIM];
1789
1790 // WPA
1791 UCHAR GMK[32];
1792 UCHAR PMK[32];
1793 UCHAR GTK[32];
1794 BOOLEAN IEEE8021X;
1795 BOOLEAN PreAuth;
1796 UCHAR GNonce[32];
1797 UCHAR PortSecured;
1798 NDIS_802_11_PRIVACY_FILTER PrivacyFilter;
1799 UCHAR BANClass3Data;
1800 ULONG IsolateInterStaTraffic;
1801
1802 UCHAR RSNIE_Len[2];
1803 UCHAR RSN_IE[2][MAX_LEN_OF_RSNIE];
1804
1805
1806 UCHAR TimIELocationInBeacon;
1807 UCHAR CapabilityInfoLocationInBeacon;
1808 // outgoing BEACON frame buffer and corresponding TXWI
1809 // PTXWI_STRUC BeaconTxWI; //
1810 CHAR BeaconBuf[MAX_BEACON_SIZE]; // NOTE: BeaconBuf should be 4-byte aligned
1811
1812 BOOLEAN bHideSsid;
1813 UINT16 StationKeepAliveTime; // unit: second
1814
1815 USHORT VLAN_VID;
1816 USHORT VLAN_Priority;
1817
1818 RT_802_11_ACL AccessControlList;
1819
1820 // EDCA Qos
1821 BOOLEAN bWmmCapable; // 0:disable WMM, 1:enable WMM
1822 BOOLEAN bDLSCapable; // 0:disable DLS, 1:enable DLS
1823
1824 UCHAR DlsPTK[64]; // Due to windows dirver count on meetinghouse to handle 4-way shake
1825
1826 // For 802.1x daemon setting per BSS
1827 UCHAR radius_srv_num;
1828 RADIUS_SRV_INFO radius_srv_info[MAX_RADIUS_SRV_NUM];
1829
1830#ifdef RTL865X_SOC
1831 unsigned int mylinkid;
1832#endif
1833
1834
1835 UINT32 RcvdConflictSsidCount;
1836 UINT32 RcvdSpoofedAssocRespCount;
1837 UINT32 RcvdSpoofedReassocRespCount;
1838 UINT32 RcvdSpoofedProbeRespCount;
1839 UINT32 RcvdSpoofedBeaconCount;
1840 UINT32 RcvdSpoofedDisassocCount;
1841 UINT32 RcvdSpoofedAuthCount;
1842 UINT32 RcvdSpoofedDeauthCount;
1843 UINT32 RcvdSpoofedUnknownMgmtCount;
1844 UINT32 RcvdReplayAttackCount;
1845
1846 CHAR RssiOfRcvdConflictSsid;
1847 CHAR RssiOfRcvdSpoofedAssocResp;
1848 CHAR RssiOfRcvdSpoofedReassocResp;
1849 CHAR RssiOfRcvdSpoofedProbeResp;
1850 CHAR RssiOfRcvdSpoofedBeacon;
1851 CHAR RssiOfRcvdSpoofedDisassoc;
1852 CHAR RssiOfRcvdSpoofedAuth;
1853 CHAR RssiOfRcvdSpoofedDeauth;
1854 CHAR RssiOfRcvdSpoofedUnknownMgmt;
1855 CHAR RssiOfRcvdReplayAttack;
1856
1857 BOOLEAN bBcnSntReq;
1858 UCHAR BcnBufIdx;
1859} MULTISSID_STRUCT, *PMULTISSID_STRUCT;
1860
1861
1862
1863#ifdef DOT11N_DRAFT3
1864typedef enum _BSS2040COEXIST_FLAG{
1865 BSS_2040_COEXIST_DISABLE = 0,
1866 BSS_2040_COEXIST_TIMER_FIRED = 1,
1867 BSS_2040_COEXIST_INFO_SYNC = 2,
1868 BSS_2040_COEXIST_INFO_NOTIFY = 4,
1869}BSS2040COEXIST_FLAG;
1870#endif // DOT11N_DRAFT3 //
1871
1872// configuration common to OPMODE_AP as well as OPMODE_STA
1873typedef struct _COMMON_CONFIG {
1874
1875 BOOLEAN bCountryFlag;
1876 UCHAR CountryCode[3];
1877 UCHAR Geography;
1878 UCHAR CountryRegion; // Enum of country region, 0:FCC, 1:IC, 2:ETSI, 3:SPAIN, 4:France, 5:MKK, 6:MKK1, 7:Israel
1879 UCHAR CountryRegionForABand; // Enum of country region for A band
1880 UCHAR PhyMode; // PHY_11A, PHY_11B, PHY_11BG_MIXED, PHY_ABG_MIXED
1881 USHORT Dsifs; // in units of usec
1882 ULONG PacketFilter; // Packet filter for receiving
1883
1884 CHAR Ssid[MAX_LEN_OF_SSID]; // NOT NULL-terminated
1885 UCHAR SsidLen; // the actual ssid length in used
1886 UCHAR LastSsidLen; // the actual ssid length in used
1887 CHAR LastSsid[MAX_LEN_OF_SSID]; // NOT NULL-terminated
1888 UCHAR LastBssid[MAC_ADDR_LEN];
1889
1890 UCHAR Bssid[MAC_ADDR_LEN];
1891 USHORT BeaconPeriod;
1892 UCHAR Channel;
1893 UCHAR CentralChannel; // Central Channel when using 40MHz is indicating. not real channel.
1894
1895 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
1896 UCHAR SupRateLen;
1897 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
1898 UCHAR ExtRateLen;
1899 UCHAR DesireRate[MAX_LEN_OF_SUPPORTED_RATES]; // OID_802_11_DESIRED_RATES
1900 UCHAR MaxDesiredRate;
1901 UCHAR ExpectedACKRate[MAX_LEN_OF_SUPPORTED_RATES];
1902
1903 ULONG BasicRateBitmap; // backup basic ratebitmap
1904
1905 BOOLEAN bAPSDCapable;
1906 BOOLEAN bInServicePeriod;
1907 BOOLEAN bAPSDAC_BE;
1908 BOOLEAN bAPSDAC_BK;
1909 BOOLEAN bAPSDAC_VI;
1910 BOOLEAN bAPSDAC_VO;
1911 BOOLEAN bNeedSendTriggerFrame;
1912 BOOLEAN bAPSDForcePowerSave; // Force power save mode, should only use in APSD-STAUT
1913 ULONG TriggerTimerCount;
1914 UCHAR MaxSPLength;
1915 UCHAR BBPCurrentBW; // BW_10, BW_20, BW_40
1916 // move to MULTISSID_STRUCT for MBSS
1917 //HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;// For transmit phy setting in TXWI.
1918 REG_TRANSMIT_SETTING RegTransmitSetting; //registry transmit setting. this is for reading registry setting only. not useful.
1919 //UCHAR FixedTxMode; // Fixed Tx Mode (CCK, OFDM), for HT fixed tx mode (GF, MIX) , refer to RegTransmitSetting.field.HTMode
1920 UCHAR TxRate; // Same value to fill in TXD. TxRate is 6-bit
1921 UCHAR MaxTxRate; // RATE_1, RATE_2, RATE_5_5, RATE_11
1922 UCHAR TxRateIndex; // Tx rate index in RateSwitchTable
1923 UCHAR TxRateTableSize; // Valid Tx rate table size in RateSwitchTable
1924 //BOOLEAN bAutoTxRateSwitch;
1925 UCHAR MinTxRate; // RATE_1, RATE_2, RATE_5_5, RATE_11
1926 UCHAR RtsRate; // RATE_xxx
1927 HTTRANSMIT_SETTING MlmeTransmit; // MGMT frame PHY rate setting when operatin at Ht rate.
1928 UCHAR MlmeRate; // RATE_xxx, used to send MLME frames
1929 UCHAR BasicMlmeRate; // Default Rate for sending MLME frames
1930
1931 USHORT RtsThreshold; // in unit of BYTE
1932 USHORT FragmentThreshold; // in unit of BYTE
1933
1934 UCHAR TxPower; // in unit of mW
1935 ULONG TxPowerPercentage; // 0~100 %
1936 ULONG TxPowerDefault; // keep for TxPowerPercentage
1937
1938#ifdef DOT11_N_SUPPORT
1939 BACAP_STRUC BACapability; // NO USE = 0XFF ; IMMED_BA =1 ; DELAY_BA=0
1940 BACAP_STRUC REGBACapability; // NO USE = 0XFF ; IMMED_BA =1 ; DELAY_BA=0
1941#endif // DOT11_N_SUPPORT //
1942 IOT_STRUC IOTestParm; // 802.11n InterOpbility Test Parameter;
1943 ULONG TxPreamble; // Rt802_11PreambleLong, Rt802_11PreambleShort, Rt802_11PreambleAuto
1944 BOOLEAN bUseZeroToDisableFragment; // Microsoft use 0 as disable
1945 ULONG UseBGProtection; // 0: auto, 1: always use, 2: always not use
1946 BOOLEAN bUseShortSlotTime; // 0: disable, 1 - use short slot (9us)
1947 BOOLEAN bEnableTxBurst; // 1: enble TX PACKET BURST, 0: disable TX PACKET BURST
1948 BOOLEAN bAggregationCapable; // 1: enable TX aggregation when the peer supports it
1949 BOOLEAN bPiggyBackCapable; // 1: enable TX piggy-back according MAC's version
1950 BOOLEAN bIEEE80211H; // 1: enable IEEE802.11h spec.
1951 ULONG DisableOLBCDetect; // 0: enable OLBC detect; 1 disable OLBC detect
1952
1953#ifdef DOT11_N_SUPPORT
1954 BOOLEAN bRdg;
1955#endif // DOT11_N_SUPPORT //
1956 BOOLEAN bWmmCapable; // 0:disable WMM, 1:enable WMM
1957 QOS_CAPABILITY_PARM APQosCapability; // QOS capability of the current associated AP
1958 EDCA_PARM APEdcaParm; // EDCA parameters of the current associated AP
1959 QBSS_LOAD_PARM APQbssLoad; // QBSS load of the current associated AP
1960 UCHAR AckPolicy[4]; // ACK policy of the specified AC. see ACK_xxx
1961#ifdef CONFIG_STA_SUPPORT
1962 BOOLEAN bDLSCapable; // 0:disable DLS, 1:enable DLS
1963#endif // CONFIG_STA_SUPPORT //
1964 // a bitmap of BOOLEAN flags. each bit represent an operation status of a particular
1965 // BOOLEAN control, either ON or OFF. These flags should always be accessed via
1966 // OPSTATUS_TEST_FLAG(), OPSTATUS_SET_FLAG(), OP_STATUS_CLEAR_FLAG() macros.
1967 // see fOP_STATUS_xxx in RTMP_DEF.C for detail bit definition
1968 ULONG OpStatusFlags;
1969
1970 BOOLEAN NdisRadioStateOff; //For HCT 12.0, set this flag to TRUE instead of called MlmeRadioOff.
1971 ABGBAND_STATE BandState; // For setting BBP used on B/G or A mode.
1972 BOOLEAN bRxAntDiversity; // 0:disable, 1:enable Software Rx Antenna Diversity.
1973
1974 // IEEE802.11H--DFS.
1975 RADAR_DETECT_STRUCT RadarDetect;
1976
1977#ifdef CARRIER_DETECTION_SUPPORT
1978 CARRIER_DETECTION CarrierDetect;
1979#endif // CARRIER_DETECTION_SUPPORT //
1980
1981#ifdef DOT11_N_SUPPORT
1982 // HT
1983 UCHAR BASize; // USer desired BAWindowSize. Should not exceed our max capability
1984 //RT_HT_CAPABILITY SupportedHtPhy;
1985 RT_HT_CAPABILITY DesiredHtPhy;
1986 HT_CAPABILITY_IE HtCapability;
1987 ADD_HT_INFO_IE AddHTInfo; // Useful as AP.
1988 //This IE is used with channel switch announcement element when changing to a new 40MHz.
1989 //This IE is included in channel switch ammouncement frames 7.4.1.5, beacons, probe Rsp.
1990 NEW_EXT_CHAN_IE NewExtChanOffset; //7.3.2.20A, 1 if extension channel is above the control channel, 3 if below, 0 if not present
1991
1992#ifdef DOT11N_DRAFT3
1993 UCHAR Bss2040CoexistFlag; // bit 0: bBssCoexistTimerRunning, bit 1: NeedSyncAddHtInfo.
1994 RALINK_TIMER_STRUCT Bss2040CoexistTimer;
1995
1996 //This IE is used for 20/40 BSS Coexistence.
1997 BSS_2040_COEXIST_IE BSS2040CoexistInfo;
1998 // ====== 11n D3.0 =======================>
1999 USHORT Dot11OBssScanPassiveDwell; // Unit : TU. 5~1000
2000 USHORT Dot11OBssScanActiveDwell; // Unit : TU. 10~1000
2001 USHORT Dot11BssWidthTriggerScanInt; // Unit : Second
2002 USHORT Dot11OBssScanPassiveTotalPerChannel; // Unit : TU. 200~10000
2003 USHORT Dot11OBssScanActiveTotalPerChannel; // Unit : TU. 20~10000
2004 USHORT Dot11BssWidthChanTranDelayFactor;
2005 USHORT Dot11OBssScanActivityThre; // Unit : percentage
2006
2007 ULONG Dot11BssWidthChanTranDelay; // multiple of (Dot11BssWidthTriggerScanInt * Dot11BssWidthChanTranDelayFactor)
2008 ULONG CountDownCtr; // CountDown Counter from (Dot11BssWidthTriggerScanInt * Dot11BssWidthChanTranDelayFactor)
2009
2010 NDIS_SPIN_LOCK TriggerEventTabLock;
2011 BSS_2040_COEXIST_IE LastBSSCoexist2040;
2012 BSS_2040_COEXIST_IE BSSCoexist2040;
2013 TRIGGER_EVENT_TAB TriggerEventTab;
2014 UCHAR ChannelListIdx;
2015 // <====== 11n D3.0 =======================
2016 BOOLEAN bOverlapScanning;
2017#endif // DOT11N_DRAFT3 //
2018
2019 BOOLEAN bHTProtect;
2020 BOOLEAN bMIMOPSEnable;
2021 BOOLEAN bBADecline;
2022 BOOLEAN bDisableReordering;
2023 BOOLEAN bForty_Mhz_Intolerant;
2024 BOOLEAN bExtChannelSwitchAnnouncement;
2025 BOOLEAN bRcvBSSWidthTriggerEvents;
2026 ULONG LastRcvBSSWidthTriggerEventsTime;
2027
2028 UCHAR TxBASize;
2029#endif // DOT11_N_SUPPORT //
2030
2031 // Enable wireless event
2032 BOOLEAN bWirelessEvent;
2033 BOOLEAN bWiFiTest; // Enable this parameter for WiFi test
2034
2035 // Tx & Rx Stream number selection
2036 UCHAR TxStream;
2037 UCHAR RxStream;
2038
2039 // transmit phy mode, trasmit rate for Multicast.
2040#ifdef MCAST_RATE_SPECIFIC
2041 UCHAR McastTransmitMcs;
2042 UCHAR McastTransmitPhyMode;
2043#endif // MCAST_RATE_SPECIFIC //
2044
2045 BOOLEAN bHardwareRadio; // Hardware controlled Radio enabled
2046
2047#ifdef RT2870
2048 BOOLEAN bMultipleIRP; // Multiple Bulk IN flag
2049 UCHAR NumOfBulkInIRP; // if bMultipleIRP == TRUE, NumOfBulkInIRP will be 4 otherwise be 1
2050 RT_HT_CAPABILITY SupportedHtPhy;
2051 ULONG MaxPktOneTxBulk;
2052 UCHAR TxBulkFactor;
2053 UCHAR RxBulkFactor;
2054
2055 BEACON_SYNC_STRUCT *pBeaconSync;
2056 RALINK_TIMER_STRUCT BeaconUpdateTimer;
2057 UINT32 BeaconAdjust;
2058 UINT32 BeaconFactor;
2059 UINT32 BeaconRemain;
2060#endif // RT2870 //
2061
2062
2063 NDIS_SPIN_LOCK MeasureReqTabLock;
2064 PMEASURE_REQ_TAB pMeasureReqTab;
2065
2066 NDIS_SPIN_LOCK TpcReqTabLock;
2067 PTPC_REQ_TAB pTpcReqTab;
2068
2069 // transmit phy mode, trasmit rate for Multicast.
2070#ifdef MCAST_RATE_SPECIFIC
2071 HTTRANSMIT_SETTING MCastPhyMode;
2072#endif // MCAST_RATE_SPECIFIC //
2073
2074#ifdef SINGLE_SKU
2075 UINT16 DefineMaxTxPwr;
2076#endif // SINGLE_SKU //
2077
2078
2079} COMMON_CONFIG, *PCOMMON_CONFIG;
2080
2081
2082#ifdef CONFIG_STA_SUPPORT
2083/* Modified by Wu Xi-Kun 4/21/2006 */
2084// STA configuration and status
2085typedef struct _STA_ADMIN_CONFIG {
2086 // GROUP 1 -
2087 // User configuration loaded from Registry, E2PROM or OID_xxx. These settings describe
2088 // the user intended configuration, but not necessary fully equal to the final
2089 // settings in ACTIVE BSS after negotiation/compromize with the BSS holder (either
2090 // AP or IBSS holder).
2091 // Once initialized, user configuration can only be changed via OID_xxx
2092 UCHAR BssType; // BSS_INFRA or BSS_ADHOC
2093 USHORT AtimWin; // used when starting a new IBSS
2094
2095 // GROUP 2 -
2096 // User configuration loaded from Registry, E2PROM or OID_xxx. These settings describe
2097 // the user intended configuration, and should be always applied to the final
2098 // settings in ACTIVE BSS without compromising with the BSS holder.
2099 // Once initialized, user configuration can only be changed via OID_xxx
2100 UCHAR RssiTrigger;
2101 UCHAR RssiTriggerMode; // RSSI_TRIGGERED_UPON_BELOW_THRESHOLD or RSSI_TRIGGERED_UPON_EXCCEED_THRESHOLD
2102 USHORT DefaultListenCount; // default listen count;
2103 ULONG WindowsPowerMode; // Power mode for AC power
2104 ULONG WindowsBatteryPowerMode; // Power mode for battery if exists
2105 BOOLEAN bWindowsACCAMEnable; // Enable CAM power mode when AC on
2106 BOOLEAN bAutoReconnect; // Set to TRUE when setting OID_802_11_SSID with no matching BSSID
2107 ULONG WindowsPowerProfile; // Windows power profile, for NDIS5.1 PnP
2108
2109 // MIB:ieee802dot11.dot11smt(1).dot11StationConfigTable(1)
2110 USHORT Psm; // power management mode (PWR_ACTIVE|PWR_SAVE)
2111 USHORT DisassocReason;
2112 UCHAR DisassocSta[MAC_ADDR_LEN];
2113 USHORT DeauthReason;
2114 UCHAR DeauthSta[MAC_ADDR_LEN];
2115 USHORT AuthFailReason;
2116 UCHAR AuthFailSta[MAC_ADDR_LEN];
2117
2118 NDIS_802_11_PRIVACY_FILTER PrivacyFilter; // PrivacyFilter enum for 802.1X
2119 NDIS_802_11_AUTHENTICATION_MODE AuthMode; // This should match to whatever microsoft defined
2120 NDIS_802_11_WEP_STATUS WepStatus;
2121 NDIS_802_11_WEP_STATUS OrigWepStatus; // Original wep status set from OID
2122
2123 // Add to support different cipher suite for WPA2/WPA mode
2124 NDIS_802_11_ENCRYPTION_STATUS GroupCipher; // Multicast cipher suite
2125 NDIS_802_11_ENCRYPTION_STATUS PairCipher; // Unicast cipher suite
2126 BOOLEAN bMixCipher; // Indicate current Pair & Group use different cipher suites
2127 USHORT RsnCapability;
2128
2129 NDIS_802_11_WEP_STATUS GroupKeyWepStatus;
2130
2131 UCHAR PMK[32]; // WPA PSK mode PMK
2132 UCHAR PTK[64]; // WPA PSK mode PTK
2133 UCHAR GTK[32]; // GTK from authenticator
2134 BSSID_INFO SavedPMK[PMKID_NO];
2135 UINT SavedPMKNum; // Saved PMKID number
2136
2137 UCHAR DefaultKeyId;
2138
2139
2140 // WPA 802.1x port control, WPA_802_1X_PORT_SECURED, WPA_802_1X_PORT_NOT_SECURED
2141 UCHAR PortSecured;
2142
2143 // For WPA countermeasures
2144 ULONG LastMicErrorTime; // record last MIC error time
2145 ULONG MicErrCnt; // Should be 0, 1, 2, then reset to zero (after disassoiciation).
2146 BOOLEAN bBlockAssoc; // Block associate attempt for 60 seconds after counter measure occurred.
2147 // For WPA-PSK supplicant state
2148 WPA_STATE WpaState; // Default is SS_NOTUSE and handled by microsoft 802.1x
2149 UCHAR ReplayCounter[8];
2150 UCHAR ANonce[32]; // ANonce for WPA-PSK from aurhenticator
2151 UCHAR SNonce[32]; // SNonce for WPA-PSK
2152
2153 UCHAR LastSNR0; // last received BEACON's SNR
2154 UCHAR LastSNR1; // last received BEACON's SNR for 2nd antenna
2155 RSSI_SAMPLE RssiSample;
2156 ULONG NumOfAvgRssiSample;
2157
2158 ULONG LastBeaconRxTime; // OS's timestamp of the last BEACON RX time
2159 ULONG Last11bBeaconRxTime; // OS's timestamp of the last 11B BEACON RX time
2160 ULONG Last11gBeaconRxTime; // OS's timestamp of the last 11G BEACON RX time
2161 ULONG Last20NBeaconRxTime; // OS's timestamp of the last 20MHz N BEACON RX time
2162
2163 ULONG LastScanTime; // Record last scan time for issue BSSID_SCAN_LIST
2164 ULONG ScanCnt; // Scan counts since most recent SSID, BSSID, SCAN OID request
2165 BOOLEAN bSwRadio; // Software controlled Radio On/Off, TRUE: On
2166 BOOLEAN bHwRadio; // Hardware controlled Radio On/Off, TRUE: On
2167 BOOLEAN bRadio; // Radio state, And of Sw & Hw radio state
2168 BOOLEAN bHardwareRadio; // Hardware controlled Radio enabled
2169 BOOLEAN bShowHiddenSSID; // Show all known SSID in SSID list get operation
2170
2171 //BOOLEAN AdhocBOnlyJoined; // Indicate Adhoc B Join.
2172 //BOOLEAN AdhocBGJoined; // Indicate Adhoc B/G Join.
2173 //BOOLEAN Adhoc20NJoined; // Indicate Adhoc 20MHz N Join.
2174
2175 // New for WPA, windows want us to to keep association information and
2176 // Fixed IEs from last association response
2177 NDIS_802_11_ASSOCIATION_INFORMATION AssocInfo;
2178 USHORT ReqVarIELen; // Length of next VIE include EID & Length
2179 UCHAR ReqVarIEs[MAX_VIE_LEN]; // The content saved here should be little-endian format.
2180 USHORT ResVarIELen; // Length of next VIE include EID & Length
2181 UCHAR ResVarIEs[MAX_VIE_LEN];
2182
2183 UCHAR RSNIE_Len;
2184 UCHAR RSN_IE[MAX_LEN_OF_RSNIE]; // The content saved here should be little-endian format.
2185
2186 // New variables used for CCX 1.0
2187 BOOLEAN bCkipOn;
2188 BOOLEAN bCkipCmicOn;
2189 UCHAR CkipFlag;
2190 UCHAR GIV[3]; //for CCX iv
2191 UCHAR RxSEQ[4];
2192 UCHAR TxSEQ[4];
2193 UCHAR CKIPMIC[4];
2194 UCHAR LeapAuthMode;
2195 LEAP_AUTH_INFO LeapAuthInfo;
2196 UCHAR HashPwd[16];
2197 UCHAR NetworkChallenge[8];
2198 UCHAR NetworkChallengeResponse[24];
2199 UCHAR PeerChallenge[8];
2200
2201 UCHAR PeerChallengeResponse[24];
2202 UCHAR SessionKey[16]; //Network session keys (NSK)
2203 RALINK_TIMER_STRUCT LeapAuthTimer;
2204 ROGUEAP_TABLE RogueApTab; //Cisco CCX1 Rogue AP Detection
2205
2206 // New control flags for CCX
2207 CCX_CONTROL CCXControl; // Master administration state
2208 BOOLEAN CCXEnable; // Actual CCX state
2209 UCHAR CCXScanChannel; // Selected channel for CCX beacon request
2210 USHORT CCXScanTime; // Time out to wait for beacon and probe response
2211 UCHAR CCXReqType; // Current processing CCX request type
2212 BSS_TABLE CCXBssTab; // BSS Table
2213 UCHAR FrameReportBuf[2048]; // Buffer for creating frame report
2214 USHORT FrameReportLen; // Current Frame report length
2215 ULONG CLBusyBytes; // Save the total bytes received durning channel load scan time
2216 USHORT RPIDensity[8]; // Array for RPI density collection
2217 // Start address of each BSS table within FrameReportBuf
2218 // It's important to update the RxPower of the corresponding Bss
2219 USHORT BssReportOffset[MAX_LEN_OF_BSS_TABLE];
2220 USHORT BeaconToken; // Token for beacon report
2221 ULONG LastBssIndex; // Most current reported Bss index
2222 RM_REQUEST_ACTION MeasurementRequest[16]; // Saved measurement request
2223 UCHAR RMReqCnt; // Number of measurement request saved.
2224 UCHAR CurrentRMReqIdx; // Number of measurement request saved.
2225 BOOLEAN ParallelReq; // Parallel measurement, only one request performed,
2226 // It must be the same channel with maximum duration
2227 USHORT ParallelDuration; // Maximum duration for parallel measurement
2228 UCHAR ParallelChannel; // Only one channel with parallel measurement
2229 USHORT IAPPToken; // IAPP dialog token
2230 UCHAR CCXQosECWMin; // Cisco QOS ECWMin for AC 0
2231 UCHAR CCXQosECWMax; // Cisco QOS ECWMax for AC 0
2232 // Hack for channel load and noise histogram parameters
2233 UCHAR NHFactor; // Parameter for Noise histogram
2234 UCHAR CLFactor; // Parameter for channel load
2235
2236 UCHAR KRK[16]; //Key Refresh Key.
2237 UCHAR BTK[32]; //Base Transient Key
2238 BOOLEAN CCKMLinkUpFlag;
2239 ULONG CCKMRN; //(Re)Association request number.
2240 LARGE_INTEGER CCKMBeaconAtJoinTimeStamp; //TSF timer for Re-assocaite to the new AP
2241 UCHAR AironetCellPowerLimit; //in dBm
2242 UCHAR AironetIPAddress[4]; //eg. 192.168.1.1
2243 BOOLEAN CCXAdjacentAPReportFlag; //flag for determining report Assoc Lost time
2244 CHAR CCXAdjacentAPSsid[MAX_LEN_OF_SSID]; //Adjacent AP's SSID report
2245 UCHAR CCXAdjacentAPSsidLen; // the actual ssid length in used
2246 UCHAR CCXAdjacentAPBssid[MAC_ADDR_LEN]; //Adjacent AP's BSSID report
2247 USHORT CCXAdjacentAPChannel;
2248 ULONG CCXAdjacentAPLinkDownTime; //for Spec S32.
2249
2250 RALINK_TIMER_STRUCT StaQuickResponeForRateUpTimer;
2251 BOOLEAN StaQuickResponeForRateUpTimerRunning;
2252
2253 UCHAR DtimCount; // 0.. DtimPeriod-1
2254 UCHAR DtimPeriod; // default = 3
2255
2256#ifdef QOS_DLS_SUPPORT
2257 RT_802_11_DLS DLSEntry[MAX_NUM_OF_DLS_ENTRY];
2258 UCHAR DlsReplayCounter[8];
2259#endif // QOS_DLS_SUPPORT //
2260 ////////////////////////////////////////////////////////////////////////////////////////
2261 // This is only for WHQL test.
2262 BOOLEAN WhqlTest;
2263 ////////////////////////////////////////////////////////////////////////////////////////
2264
2265 RALINK_TIMER_STRUCT WpaDisassocAndBlockAssocTimer;
2266 // Fast Roaming
2267 BOOLEAN bFastRoaming; // 0:disable fast roaming, 1:enable fast roaming
2268 CHAR dBmToRoam; // the condition to roam when receiving Rssi less than this value. It's negative value.
2269
2270#ifdef WPA_SUPPLICANT_SUPPORT
2271 BOOLEAN IEEE8021X;
2272 BOOLEAN IEEE8021x_required_keys;
2273 CIPHER_KEY DesireSharedKey[4]; // Record user desired WEP keys
2274 UCHAR DesireSharedKeyId;
2275
2276 // 0: driver ignores wpa_supplicant
2277 // 1: wpa_supplicant initiates scanning and AP selection
2278 // 2: driver takes care of scanning, AP selection, and IEEE 802.11 association parameters
2279 UCHAR WpaSupplicantUP;
2280 UCHAR WpaSupplicantScanCount;
2281#endif // WPA_SUPPLICANT_SUPPORT //
2282
2283 CHAR dev_name[16];
2284 USHORT OriDevType;
2285
2286 BOOLEAN bTGnWifiTest;
2287 BOOLEAN bScanReqIsFromWebUI;
2288
2289 HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;// For transmit phy setting in TXWI.
2290 DESIRED_TRANSMIT_SETTING DesiredTransmitSetting;
2291 RT_HT_PHY_INFO DesiredHtPhyInfo;
2292 BOOLEAN bAutoTxRateSwitch;
2293
2294
2295#ifdef EXT_BUILD_CHANNEL_LIST
2296 UCHAR IEEE80211dClientMode;
2297 UCHAR StaOriCountryCode[3];
2298 UCHAR StaOriGeography;
2299#endif // EXT_BUILD_CHANNEL_LIST //
2300} STA_ADMIN_CONFIG, *PSTA_ADMIN_CONFIG;
2301
2302// This data structure keep the current active BSS/IBSS's configuration that this STA
2303// had agreed upon joining the network. Which means these parameters are usually decided
2304// by the BSS/IBSS creator instead of user configuration. Data in this data structurre
2305// is valid only when either ADHOC_ON(pAd) or INFRA_ON(pAd) is TRUE.
2306// Normally, after SCAN or failed roaming attempts, we need to recover back to
2307// the current active settings.
2308typedef struct _STA_ACTIVE_CONFIG {
2309 USHORT Aid;
2310 USHORT AtimWin; // in kusec; IBSS parameter set element
2311 USHORT CapabilityInfo;
2312 USHORT CfpMaxDuration;
2313 USHORT CfpPeriod;
2314
2315 // Copy supported rate from desired AP's beacon. We are trying to match
2316 // AP's supported and extended rate settings.
2317 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
2318 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
2319 UCHAR SupRateLen;
2320 UCHAR ExtRateLen;
2321 // Copy supported ht from desired AP's beacon. We are trying to match
2322 RT_HT_PHY_INFO SupportedPhyInfo;
2323 RT_HT_CAPABILITY SupportedHtPhy;
2324} STA_ACTIVE_CONFIG, *PSTA_ACTIVE_CONFIG;
2325#endif // CONFIG_STA_SUPPORT //
2326
2327#ifdef RT2870
2328typedef struct RT_ADD_PAIRWISE_KEY_ENTRY {
2329 NDIS_802_11_MAC_ADDRESS MacAddr;
2330 USHORT MacTabMatchWCID; // ASIC
2331 CIPHER_KEY CipherKey;
2332} RT_ADD_PAIRWISE_KEY_ENTRY,*PRT_ADD_PAIRWISE_KEY_ENTRY;
2333#endif // RT2870 //
2334
2335// ----------- start of AP --------------------------
2336// AUTH-RSP State Machine Aux data structure
2337typedef struct _AP_MLME_AUX {
2338 UCHAR Addr[MAC_ADDR_LEN];
2339 USHORT Alg;
2340 CHAR Challenge[CIPHER_TEXT_LEN];
2341} AP_MLME_AUX, *PAP_MLME_AUX;
2342
2343// structure to define WPA Group Key Rekey Interval
2344typedef struct PACKED _RT_802_11_WPA_REKEY {
2345 ULONG ReKeyMethod; // mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based
2346 ULONG ReKeyInterval; // time-based: seconds, packet-based: kilo-packets
2347} RT_WPA_REKEY,*PRT_WPA_REKEY, RT_802_11_WPA_REKEY, *PRT_802_11_WPA_REKEY;
2348
2349typedef struct _MAC_TABLE_ENTRY {
2350 //Choose 1 from ValidAsWDS and ValidAsCLI to validize.
2351 BOOLEAN ValidAsCLI; // Sta mode, set this TRUE after Linkup,too.
2352 BOOLEAN ValidAsWDS; // This is WDS Entry. only for AP mode.
2353 BOOLEAN ValidAsApCli; //This is a AP-Client entry, only for AP mode which enable AP-Client functions.
2354 BOOLEAN ValidAsMesh;
2355 BOOLEAN ValidAsDls; // This is DLS Entry. only for STA mode.
2356 BOOLEAN isCached;
2357 BOOLEAN bIAmBadAtheros;
2358
2359 UCHAR EnqueueEapolStartTimerRunning; // Enqueue EAPoL-Start for triggering EAP SM
2360 //jan for wpa
2361 // record which entry revoke MIC Failure , if it leaves the BSS itself, AP won't update aMICFailTime MIB
2362 UCHAR CMTimerRunning;
2363 UCHAR apidx; // MBSS number
2364 UCHAR RSNIE_Len;
2365 UCHAR RSN_IE[MAX_LEN_OF_RSNIE];
2366 UCHAR ANonce[LEN_KEY_DESC_NONCE];
2367 UCHAR R_Counter[LEN_KEY_DESC_REPLAY];
2368 UCHAR PTK[64];
2369 UCHAR ReTryCounter;
2370 RALINK_TIMER_STRUCT RetryTimer;
2371 RALINK_TIMER_STRUCT EnqueueStartForPSKTimer; // A timer which enqueue EAPoL-Start for triggering PSK SM
2372 NDIS_802_11_AUTHENTICATION_MODE AuthMode; // This should match to whatever microsoft defined
2373 NDIS_802_11_WEP_STATUS WepStatus;
2374 AP_WPA_STATE WpaState;
2375 GTK_STATE GTKState;
2376 USHORT PortSecured;
2377 NDIS_802_11_PRIVACY_FILTER PrivacyFilter; // PrivacyFilter enum for 802.1X
2378 CIPHER_KEY PairwiseKey;
2379 PVOID pAd;
2380 INT PMKID_CacheIdx;
2381 UCHAR PMKID[LEN_PMKID];
2382
2383
2384 UCHAR Addr[MAC_ADDR_LEN];
2385 UCHAR PsMode;
2386 SST Sst;
2387 AUTH_STATE AuthState; // for SHARED KEY authentication state machine used only
2388 BOOLEAN IsReassocSta; // Indicate whether this is a reassociation procedure
2389 USHORT Aid;
2390 USHORT CapabilityInfo;
2391 UCHAR LastRssi;
2392 ULONG NoDataIdleCount;
2393 UINT16 StationKeepAliveCount; // unit: second
2394 ULONG PsQIdleCount;
2395 QUEUE_HEADER PsQueue;
2396
2397 UINT32 StaConnectTime; // the live time of this station since associated with AP
2398
2399
2400#ifdef DOT11_N_SUPPORT
2401 BOOLEAN bSendBAR;
2402 USHORT NoBADataCountDown;
2403
2404 UINT32 CachedBuf[16]; // UINT (4 bytes) for alignment
2405 UINT TxBFCount; // 3*3
2406#endif // DOT11_N_SUPPORT //
2407 UINT FIFOCount;
2408 UINT DebugFIFOCount;
2409 UINT DebugTxCount;
2410 BOOLEAN bDlsInit;
2411
2412
2413//====================================================
2414//WDS entry needs these
2415// rt2860 add this. if ValidAsWDS==TRUE, MatchWDSTabIdx is the index in WdsTab.MacTab
2416 UINT MatchWDSTabIdx;
2417 UCHAR MaxSupportedRate;
2418 UCHAR CurrTxRate;
2419 UCHAR CurrTxRateIndex;
2420 // to record the each TX rate's quality. 0 is best, the bigger the worse.
2421 USHORT TxQuality[MAX_STEP_OF_TX_RATE_SWITCH];
2422// USHORT OneSecTxOkCount;
2423 UINT32 OneSecTxNoRetryOkCount;
2424 UINT32 OneSecTxRetryOkCount;
2425 UINT32 OneSecTxFailCount;
2426 UINT32 ContinueTxFailCnt;
2427 UINT32 CurrTxRateStableTime; // # of second in current TX rate
2428 UCHAR TxRateUpPenalty; // extra # of second penalty due to last unstable condition
2429//====================================================
2430
2431
2432
2433#ifdef CONFIG_STA_SUPPORT
2434#ifdef QOS_DLS_SUPPORT
2435 UINT MatchDlsEntryIdx; // indicate the index in pAd->StaCfg.DLSEntry
2436#endif // QOS_DLS_SUPPORT //
2437#endif // CONFIG_STA_SUPPORT //
2438
2439 BOOLEAN fNoisyEnvironment;
2440 BOOLEAN fLastSecAccordingRSSI;
2441 UCHAR LastSecTxRateChangeAction; // 0: no change, 1:rate UP, 2:rate down
2442 CHAR LastTimeTxRateChangeAction; //Keep last time value of LastSecTxRateChangeAction
2443 ULONG LastTxOkCount;
2444 UCHAR PER[MAX_STEP_OF_TX_RATE_SWITCH];
2445
2446 // a bitmap of BOOLEAN flags. each bit represent an operation status of a particular
2447 // BOOLEAN control, either ON or OFF. These flags should always be accessed via
2448 // CLIENT_STATUS_TEST_FLAG(), CLIENT_STATUS_SET_FLAG(), CLIENT_STATUS_CLEAR_FLAG() macros.
2449 // see fOP_STATUS_xxx in RTMP_DEF.C for detail bit definition. fCLIENT_STATUS_AMSDU_INUSED
2450 ULONG ClientStatusFlags;
2451
2452 // TODO: Shall we move that to DOT11_N_SUPPORT???
2453 HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;// For transmit phy setting in TXWI.
2454
2455#ifdef DOT11_N_SUPPORT
2456 // HT EWC MIMO-N used parameters
2457 USHORT RXBAbitmap; // fill to on-chip RXWI_BA_BITMASK in 8.1.3RX attribute entry format
2458 USHORT TXBAbitmap; // This bitmap as originator, only keep in software used to mark AMPDU bit in TXWI
2459 USHORT TXAutoBAbitmap;
2460 USHORT BADeclineBitmap;
2461 USHORT BARecWcidArray[NUM_OF_TID]; // The mapping wcid of recipient session. if RXBAbitmap bit is masked
2462 USHORT BAOriWcidArray[NUM_OF_TID]; // The mapping wcid of originator session. if TXBAbitmap bit is masked
2463 USHORT BAOriSequence[NUM_OF_TID]; // The mapping wcid of originator session. if TXBAbitmap bit is masked
2464
2465 // 802.11n features.
2466 UCHAR MpduDensity;
2467 UCHAR MaxRAmpduFactor;
2468 UCHAR AMsduSize;
2469 UCHAR MmpsMode; // MIMO power save more.
2470
2471 HT_CAPABILITY_IE HTCapability;
2472
2473#ifdef DOT11N_DRAFT3
2474 UCHAR BSS2040CoexistenceMgmtSupport;
2475#endif // DOT11N_DRAFT3 //
2476#endif // DOT11_N_SUPPORT //
2477
2478 BOOLEAN bAutoTxRateSwitch;
2479
2480 UCHAR RateLen;
2481 struct _MAC_TABLE_ENTRY *pNext;
2482 USHORT TxSeq[NUM_OF_TID];
2483 USHORT NonQosDataSeq;
2484
2485 RSSI_SAMPLE RssiSample;
2486
2487 UINT32 TXMCSExpected[16];
2488 UINT32 TXMCSSuccessful[16];
2489 UINT32 TXMCSFailed[16];
2490 UINT32 TXMCSAutoFallBack[16][16];
2491
2492#ifdef CONFIG_STA_SUPPORT
2493 ULONG LastBeaconRxTime;
2494#endif // CONFIG_STA_SUPPORT //
2495} MAC_TABLE_ENTRY, *PMAC_TABLE_ENTRY;
2496
2497typedef struct _MAC_TABLE {
2498 USHORT Size;
2499 MAC_TABLE_ENTRY *Hash[HASH_TABLE_SIZE];
2500 MAC_TABLE_ENTRY Content[MAX_LEN_OF_MAC_TABLE];
2501 QUEUE_HEADER McastPsQueue;
2502 ULONG PsQIdleCount;
2503 BOOLEAN fAnyStationInPsm;
2504 BOOLEAN fAnyStationBadAtheros; // Check if any Station is atheros 802.11n Chip. We need to use RTS/CTS with Atheros 802,.11n chip.
2505 BOOLEAN fAnyTxOPForceDisable; // Check if it is necessary to disable BE TxOP
2506 BOOLEAN fAllStationAsRalink; // Check if all stations are ralink-chipset
2507#ifdef DOT11_N_SUPPORT
2508 BOOLEAN fAnyStationIsLegacy; // Check if I use legacy rate to transmit to my BSS Station/
2509 BOOLEAN fAnyStationNonGF; // Check if any Station can't support GF.
2510 BOOLEAN fAnyStation20Only; // Check if any Station can't support GF.
2511 BOOLEAN fAnyStationMIMOPSDynamic; // Check if any Station is MIMO Dynamic
2512 BOOLEAN fAnyBASession; // Check if there is BA session. Force turn on RTS/CTS
2513#endif // DOT11_N_SUPPORT //
2514} MAC_TABLE, *PMAC_TABLE;
2515
2516#ifdef DOT11_N_SUPPORT
2517#define IS_HT_STA(_pMacEntry) \
2518 (_pMacEntry->MaxHTPhyMode.field.MODE >= MODE_HTMIX)
2519
2520#define IS_HT_RATE(_pMacEntry) \
2521 (_pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
2522
2523#define PEER_IS_HT_RATE(_pMacEntry) \
2524 (_pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
2525#endif // DOT11_N_SUPPORT //
2526
2527typedef struct _WDS_ENTRY {
2528 BOOLEAN Valid;
2529 UCHAR Addr[MAC_ADDR_LEN];
2530 ULONG NoDataIdleCount;
2531 struct _WDS_ENTRY *pNext;
2532} WDS_ENTRY, *PWDS_ENTRY;
2533
2534typedef struct _WDS_TABLE_ENTRY {
2535 USHORT Size;
2536 UCHAR WdsAddr[MAC_ADDR_LEN];
2537 WDS_ENTRY *Hash[HASH_TABLE_SIZE];
2538 WDS_ENTRY Content[MAX_LEN_OF_MAC_TABLE];
2539 UCHAR MaxSupportedRate;
2540 UCHAR CurrTxRate;
2541 USHORT TxQuality[MAX_LEN_OF_SUPPORTED_RATES];
2542 USHORT OneSecTxOkCount;
2543 USHORT OneSecTxRetryOkCount;
2544 USHORT OneSecTxFailCount;
2545 ULONG CurrTxRateStableTime; // # of second in current TX rate
2546 UCHAR TxRateUpPenalty; // extra # of second penalty due to last unstable condition
2547} WDS_TABLE_ENTRY, *PWDS_TABLE_ENTRY;
2548
2549typedef struct _RT_802_11_WDS_ENTRY {
2550 PNET_DEV dev;
2551 UCHAR Valid;
2552 UCHAR PhyMode;
2553 UCHAR PeerWdsAddr[MAC_ADDR_LEN];
2554 UCHAR MacTabMatchWCID; // ASIC
2555 NDIS_802_11_WEP_STATUS WepStatus;
2556 UCHAR KeyIdx;
2557 CIPHER_KEY WdsKey;
2558 HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;
2559 RT_HT_PHY_INFO DesiredHtPhyInfo;
2560 BOOLEAN bAutoTxRateSwitch;
2561 DESIRED_TRANSMIT_SETTING DesiredTransmitSetting; // Desired transmit setting.
2562} RT_802_11_WDS_ENTRY, *PRT_802_11_WDS_ENTRY;
2563
2564typedef struct _WDS_TABLE {
2565 UCHAR Mode;
2566 ULONG Size;
2567 RT_802_11_WDS_ENTRY WdsEntry[MAX_WDS_ENTRY];
2568} WDS_TABLE, *PWDS_TABLE;
2569
2570typedef struct _APCLI_STRUCT {
2571 PNET_DEV dev;
2572#ifdef RTL865X_SOC
2573 unsigned int mylinkid;
2574#endif
2575 BOOLEAN Enable; // Set it as 1 if the apcli interface was configured to "1" or by iwpriv cmd "ApCliEnable"
2576 BOOLEAN Valid; // Set it as 1 if the apcli interface associated success to remote AP.
2577 UCHAR MacTabWCID; //WCID value, which point to the entry of ASIC Mac table.
2578 UCHAR SsidLen;
2579 CHAR Ssid[MAX_LEN_OF_SSID];
2580
2581 UCHAR CfgSsidLen;
2582 CHAR CfgSsid[MAX_LEN_OF_SSID];
2583 UCHAR CfgApCliBssid[ETH_LENGTH_OF_ADDRESS];
2584 UCHAR CurrentAddress[ETH_LENGTH_OF_ADDRESS];
2585
2586 ULONG ApCliRcvBeaconTime;
2587
2588 ULONG CtrlCurrState;
2589 ULONG SyncCurrState;
2590 ULONG AuthCurrState;
2591 ULONG AssocCurrState;
2592 ULONG WpaPskCurrState;
2593
2594 USHORT AuthReqCnt;
2595 USHORT AssocReqCnt;
2596
2597 ULONG ClientStatusFlags;
2598 UCHAR MpduDensity;
2599
2600 NDIS_802_11_AUTHENTICATION_MODE AuthMode; // This should match to whatever microsoft defined
2601 NDIS_802_11_WEP_STATUS WepStatus;
2602
2603 // Add to support different cipher suite for WPA2/WPA mode
2604 NDIS_802_11_ENCRYPTION_STATUS GroupCipher; // Multicast cipher suite
2605 NDIS_802_11_ENCRYPTION_STATUS PairCipher; // Unicast cipher suite
2606 BOOLEAN bMixCipher; // Indicate current Pair & Group use different cipher suites
2607 USHORT RsnCapability;
2608
2609 UCHAR PSK[100]; // reserve PSK key material
2610 UCHAR PSKLen;
2611 UCHAR PMK[32]; // WPA PSK mode PMK
2612 //UCHAR PTK[64]; // WPA PSK mode PTK
2613 UCHAR GTK[32]; // GTK from authenticator
2614
2615 //CIPHER_KEY PairwiseKey;
2616 CIPHER_KEY SharedKey[SHARE_KEY_NUM];
2617 UCHAR DefaultKeyId;
2618
2619 // WPA 802.1x port control, WPA_802_1X_PORT_SECURED, WPA_802_1X_PORT_NOT_SECURED
2620 //UCHAR PortSecured;
2621
2622 // store RSN_IE built by driver
2623 UCHAR RSN_IE[MAX_LEN_OF_RSNIE]; // The content saved here should be convert to little-endian format.
2624 UCHAR RSNIE_Len;
2625
2626 // For WPA countermeasures
2627 ULONG LastMicErrorTime; // record last MIC error time
2628 //ULONG MicErrCnt; // Should be 0, 1, 2, then reset to zero (after disassoiciation).
2629 BOOLEAN bBlockAssoc; // Block associate attempt for 60 seconds after counter measure occurred.
2630
2631 // For WPA-PSK supplicant state
2632 //WPA_STATE WpaState; // Default is SS_NOTUSE
2633 //UCHAR ReplayCounter[8];
2634 //UCHAR ANonce[32]; // ANonce for WPA-PSK from authenticator
2635 UCHAR SNonce[32]; // SNonce for WPA-PSK
2636 UCHAR GNonce[32]; // GNonce for WPA-PSK from authenticator
2637
2638 HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;
2639 RT_HT_PHY_INFO DesiredHtPhyInfo;
2640 BOOLEAN bAutoTxRateSwitch;
2641 DESIRED_TRANSMIT_SETTING DesiredTransmitSetting; // Desired transmit setting.
2642} APCLI_STRUCT, *PAPCLI_STRUCT;
2643
2644// ----------- end of AP ----------------------------
2645
2646#ifdef BLOCK_NET_IF
2647typedef struct _BLOCK_QUEUE_ENTRY
2648{
2649 BOOLEAN SwTxQueueBlockFlag;
2650 LIST_HEADER NetIfList;
2651} BLOCK_QUEUE_ENTRY, *PBLOCK_QUEUE_ENTRY;
2652#endif // BLOCK_NET_IF //
2653
2654
2655struct wificonf
2656{
2657 BOOLEAN bShortGI;
2658 BOOLEAN bGreenField;
2659};
2660
2661
2662
2663
2664typedef struct _INF_PCI_CONFIG
2665{
2666 PUCHAR CSRBaseAddress; // PCI MMIO Base Address, all access will use
2667}INF_PCI_CONFIG;
2668
2669typedef struct _INF_USB_CONFIG
2670{
2671 UINT BulkInEpAddr; // bulk-in endpoint address
2672 UINT BulkOutEpAddr[6]; // bulk-out endpoint address
2673
2674}INF_USB_CONFIG;
2675
2676#ifdef IKANOS_VX_1X0
2677 typedef void (*IkanosWlanTxCbFuncP)(void *, void *);
2678
2679 struct IKANOS_TX_INFO
2680 {
2681 struct net_device *netdev;
2682 IkanosWlanTxCbFuncP *fp;
2683 };
2684#endif // IKANOS_VX_1X0 //
2685
2686#ifdef NINTENDO_AP
2687typedef struct _NINDO_CTRL_BLOCK {
2688
2689 RT_NINTENDO_TABLE DS_TABLE;
2690
2691#ifdef CHIP25XX
2692 spinlock_t NINTENDO_TABLE_Lock;
2693#else
2694 NDIS_SPIN_LOCK NINTENDO_TABLE_Lock;
2695#endif // CHIP25XX //
2696
2697 UCHAR NINTENDO_UP_BUFFER[512];
2698 UCHAR Local_KeyIdx;
2699 CIPHER_KEY Local_SharedKey;
2700 UCHAR Local_bHideSsid;
2701 UCHAR Local_AuthMode;
2702 UCHAR Local_WepStatus;
2703 USHORT Local_CapabilityInfo;
2704} NINDO_CTRL_BLOCK;
2705#endif // NINTENDO_AP //
2706
2707
2708#ifdef DBG_DIAGNOSE
2709#define DIAGNOSE_TIME 10 // 10 sec
2710typedef struct _RtmpDiagStrcut_
2711{ // Diagnosis Related element
2712 unsigned char inited;
2713 unsigned char qIdx;
2714 unsigned char ArrayStartIdx;
2715 unsigned char ArrayCurIdx;
2716 // Tx Related Count
2717 USHORT TxDataCnt[DIAGNOSE_TIME];
2718 USHORT TxFailCnt[DIAGNOSE_TIME];
2719// USHORT TxDescCnt[DIAGNOSE_TIME][16]; // TxDesc queue length in scale of 0~14, >=15
2720 USHORT TxDescCnt[DIAGNOSE_TIME][24]; // 3*3 // TxDesc queue length in scale of 0~14, >=15
2721// USHORT TxMcsCnt[DIAGNOSE_TIME][16]; // TxDate MCS Count in range from 0 to 15, step in 1.
2722 USHORT TxMcsCnt[DIAGNOSE_TIME][24]; // 3*3
2723 USHORT TxSWQueCnt[DIAGNOSE_TIME][9]; // TxSwQueue length in scale of 0, 1, 2, 3, 4, 5, 6, 7, >=8
2724
2725 USHORT TxAggCnt[DIAGNOSE_TIME];
2726 USHORT TxNonAggCnt[DIAGNOSE_TIME];
2727// USHORT TxAMPDUCnt[DIAGNOSE_TIME][16]; // 10 sec, TxDMA APMDU Aggregation count in range from 0 to 15, in setp of 1.
2728 USHORT TxAMPDUCnt[DIAGNOSE_TIME][24]; // 3*3 // 10 sec, TxDMA APMDU Aggregation count in range from 0 to 15, in setp of 1.
2729 USHORT TxRalinkCnt[DIAGNOSE_TIME]; // TxRalink Aggregation Count in 1 sec scale.
2730 USHORT TxAMSDUCnt[DIAGNOSE_TIME]; // TxAMSUD Aggregation Count in 1 sec scale.
2731
2732 // Rx Related Count
2733 USHORT RxDataCnt[DIAGNOSE_TIME]; // Rx Total Data count.
2734 USHORT RxCrcErrCnt[DIAGNOSE_TIME];
2735// USHORT RxMcsCnt[DIAGNOSE_TIME][16]; // Rx MCS Count in range from 0 to 15, step in 1.
2736 USHORT RxMcsCnt[DIAGNOSE_TIME][24]; // 3*3
2737}RtmpDiagStruct;
2738#endif // DBG_DIAGNOSE //
2739
2740
2741//
2742// The miniport adapter structure
2743//
2744typedef struct _RTMP_ADAPTER
2745{
2746 PVOID OS_Cookie; // save specific structure relative to OS
2747 PNET_DEV net_dev;
2748 ULONG VirtualIfCnt;
2749
2750
2751
2752 NDIS_SPIN_LOCK irq_lock;
2753 UCHAR irq_disabled;
2754
2755#ifdef RT2870
2756/*****************************************************************************************/
2757/* USB related parameters */
2758/*****************************************************************************************/
2759 struct usb_config_descriptor *config;
2760 UINT BulkInEpAddr; // bulk-in endpoint address
2761 UINT BulkOutEpAddr[6]; // bulk-out endpoint address
2762
2763 UINT NumberOfPipes;
2764 USHORT BulkOutMaxPacketSize;
2765 USHORT BulkInMaxPacketSize;
2766
2767 //======Control Flags
2768 LONG PendingIoCount;
2769 ULONG BulkFlags;
2770 BOOLEAN bUsbTxBulkAggre; // Flags for bulk out data priority
2771
2772
2773 //======Timer Thread
2774 RT2870_TIMER_QUEUE TimerQ;
2775 NDIS_SPIN_LOCK TimerQLock;
2776
2777
2778 //======Cmd Thread
2779 CmdQ CmdQ;
2780 NDIS_SPIN_LOCK CmdQLock; // CmdQLock spinlock
2781
2782 BOOLEAN TimerFunc_kill;
2783 BOOLEAN mlme_kill;
2784
2785
2786 //======Semaphores (event)
2787 struct semaphore mlme_semaphore; /* to sleep thread on */
2788 struct semaphore RTUSBCmd_semaphore; /* to sleep thread on */
2789 struct semaphore RTUSBTimer_semaphore;
2790#ifdef INF_AMAZON_SE
2791 struct semaphore UsbVendorReq_semaphore;
2792 PVOID UsbVendorReqBuf;
2793#endif // INF_AMAZON_SE //
2794 struct completion TimerQComplete;
2795 struct completion mlmeComplete;
2796 struct completion CmdQComplete;
2797 wait_queue_head_t *wait;
2798
2799 //======Lock for 2870 ATE
2800#ifdef RALINK_ATE
2801 NDIS_SPIN_LOCK GenericLock; // ATE Tx/Rx generic spinlock
2802#endif // RALINK_ATE //
2803
2804#endif // RT2870 //
2805
2806
2807/*****************************************************************************************/
2808 /* Both PCI/USB related parameters */
2809/*****************************************************************************************/
2810
2811
2812/*****************************************************************************************/
2813/* Tx related parameters */
2814/*****************************************************************************************/
2815 BOOLEAN DeQueueRunning[NUM_OF_TX_RING]; // for ensuring RTUSBDeQueuePacket get call once
2816 NDIS_SPIN_LOCK DeQueueLock[NUM_OF_TX_RING];
2817
2818#ifdef RT2870
2819 // Data related context and AC specified, 4 AC supported
2820 NDIS_SPIN_LOCK BulkOutLock[6]; // BulkOut spinlock for 4 ACs
2821 NDIS_SPIN_LOCK MLMEBulkOutLock; // MLME BulkOut lock
2822
2823 HT_TX_CONTEXT TxContext[NUM_OF_TX_RING];
2824 NDIS_SPIN_LOCK TxContextQueueLock[NUM_OF_TX_RING]; // TxContextQueue spinlock
2825
2826 // 4 sets of Bulk Out index and pending flag
2827 UCHAR NextBulkOutIndex[4]; // only used for 4 EDCA bulkout pipe
2828
2829 BOOLEAN BulkOutPending[6]; // used for total 6 bulkout pipe
2830 UCHAR bulkResetPipeid;
2831 BOOLEAN MgmtBulkPending;
2832 ULONG bulkResetReq[6];
2833#endif // RT2870 //
2834
2835 // resource for software backlog queues
2836 QUEUE_HEADER TxSwQueue[NUM_OF_TX_RING]; // 4 AC + 1 HCCA
2837 NDIS_SPIN_LOCK TxSwQueueLock[NUM_OF_TX_RING]; // TxSwQueue spinlock
2838
2839 RTMP_DMABUF MgmtDescRing; // Shared memory for MGMT descriptors
2840 RTMP_MGMT_RING MgmtRing;
2841 NDIS_SPIN_LOCK MgmtRingLock; // Prio Ring spinlock
2842
2843
2844/*****************************************************************************************/
2845/* Rx related parameters */
2846/*****************************************************************************************/
2847
2848
2849#ifdef RT2870
2850 RX_CONTEXT RxContext[RX_RING_SIZE]; // 1 for redundant multiple IRP bulk in.
2851 NDIS_SPIN_LOCK BulkInLock; // BulkIn spinlock for 4 ACs
2852 UCHAR PendingRx; // The Maxima pending Rx value should be RX_RING_SIZE.
2853 UCHAR NextRxBulkInIndex; // Indicate the current RxContext Index which hold by Host controller.
2854 UCHAR NextRxBulkInReadIndex; // Indicate the current RxContext Index which driver can read & process it.
2855 ULONG NextRxBulkInPosition; // Want to contatenate 2 URB buffer while 1st is bulkin failed URB. This Position is 1st URB TransferLength.
2856 ULONG TransferBufferLength; // current length of the packet buffer
2857 ULONG ReadPosition; // current read position in a packet buffer
2858#endif // RT2870 //
2859
2860
2861/*****************************************************************************************/
2862/* ASIC related parameters */
2863/*****************************************************************************************/
2864 UINT32 MACVersion; // MAC version. Record rt2860C(0x28600100) or rt2860D (0x28600101)..
2865
2866 // ---------------------------
2867 // E2PROM
2868 // ---------------------------
2869 ULONG EepromVersion; // byte 0: version, byte 1: revision, byte 2~3: unused
2870 UCHAR EEPROMAddressNum; // 93c46=6 93c66=8
2871 USHORT EEPROMDefaultValue[NUM_EEPROM_BBP_PARMS];
2872 BOOLEAN EepromAccess;
2873 UCHAR EFuseTag;
2874 ULONG FirmwareVersion; // byte 0: Minor version, byte 1: Major version, otherwise unused.
2875
2876 // ---------------------------
2877 // BBP Control
2878 // ---------------------------
2879 UCHAR BbpWriteLatch[140]; // record last BBP register value written via BBP_IO_WRITE/BBP_IO_WRITE_VY_REG_ID
2880 UCHAR BbpRssiToDbmDelta;
2881 BBP_R66_TUNING BbpTuning;
2882
2883 // ----------------------------
2884 // RFIC control
2885 // ----------------------------
2886 UCHAR RfIcType; // RFIC_xxx
2887 ULONG RfFreqOffset; // Frequency offset for channel switching
2888 RTMP_RF_REGS LatchRfRegs; // latch th latest RF programming value since RF IC doesn't support READ
2889
2890 EEPROM_ANTENNA_STRUC Antenna; // Since ANtenna definition is different for a & g. We need to save it for future reference.
2891 EEPROM_NIC_CONFIG2_STRUC NicConfig2;
2892
2893 // This soft Rx Antenna Diversity mechanism is used only when user set
2894 // RX Antenna = DIVERSITY ON
2895 SOFT_RX_ANT_DIVERSITY RxAnt;
2896
2897 UCHAR RFProgSeq;
2898 CHANNEL_TX_POWER TxPower[MAX_NUM_OF_CHANNELS]; // Store Tx power value for all channels.
2899 CHANNEL_TX_POWER ChannelList[MAX_NUM_OF_CHANNELS]; // list all supported channels for site survey
2900 CHANNEL_11J_TX_POWER TxPower11J[MAX_NUM_OF_11JCHANNELS]; // 802.11j channel and bw
2901 CHANNEL_11J_TX_POWER ChannelList11J[MAX_NUM_OF_11JCHANNELS]; // list all supported channels for site survey
2902
2903 UCHAR ChannelListNum; // number of channel in ChannelList[]
2904 UCHAR Bbp94;
2905 BOOLEAN BbpForCCK;
2906 ULONG Tx20MPwrCfgABand[5];
2907 ULONG Tx20MPwrCfgGBand[5];
2908 ULONG Tx40MPwrCfgABand[5];
2909 ULONG Tx40MPwrCfgGBand[5];
2910
2911 BOOLEAN bAutoTxAgcA; // Enable driver auto Tx Agc control
2912 UCHAR TssiRefA; // Store Tssi reference value as 25 temperature.
2913 UCHAR TssiPlusBoundaryA[5]; // Tssi boundary for increase Tx power to compensate.
2914 UCHAR TssiMinusBoundaryA[5]; // Tssi boundary for decrease Tx power to compensate.
2915 UCHAR TxAgcStepA; // Store Tx TSSI delta increment / decrement value
2916 CHAR TxAgcCompensateA; // Store the compensation (TxAgcStep * (idx-1))
2917
2918 BOOLEAN bAutoTxAgcG; // Enable driver auto Tx Agc control
2919 UCHAR TssiRefG; // Store Tssi reference value as 25 temperature.
2920 UCHAR TssiPlusBoundaryG[5]; // Tssi boundary for increase Tx power to compensate.
2921 UCHAR TssiMinusBoundaryG[5]; // Tssi boundary for decrease Tx power to compensate.
2922 UCHAR TxAgcStepG; // Store Tx TSSI delta increment / decrement value
2923 CHAR TxAgcCompensateG; // Store the compensation (TxAgcStep * (idx-1))
2924
2925 //+++For RT2870, the parameteres is start from BGRssiOffset1 ~ BGRssiOffset3
2926 CHAR BGRssiOffset0; // Store B/G RSSI#0 Offset value on EEPROM 0x46h
2927 CHAR BGRssiOffset1; // Store B/G RSSI#1 Offset value
2928 CHAR BGRssiOffset2; // Store B/G RSSI#2 Offset value
2929 //---
2930
2931 //+++For RT2870, the parameteres is start from ARssiOffset1 ~ ARssiOffset3
2932 CHAR ARssiOffset0; // Store A RSSI#0 Offset value on EEPROM 0x4Ah
2933 CHAR ARssiOffset1; // Store A RSSI#1 Offset value
2934 CHAR ARssiOffset2; // Store A RSSI#2 Offset value
2935 //---
2936
2937 CHAR BLNAGain; // Store B/G external LNA#0 value on EEPROM 0x44h
2938 CHAR ALNAGain0; // Store A external LNA#0 value for ch36~64
2939 CHAR ALNAGain1; // Store A external LNA#1 value for ch100~128
2940 CHAR ALNAGain2; // Store A external LNA#2 value for ch132~165
2941
2942 // ----------------------------
2943 // LED control
2944 // ----------------------------
2945 MCU_LEDCS_STRUC LedCntl;
2946 USHORT Led1; // read from EEPROM 0x3c
2947 USHORT Led2; // EEPROM 0x3e
2948 USHORT Led3; // EEPROM 0x40
2949 UCHAR LedIndicatorStregth;
2950 UCHAR RssiSingalstrengthOffet;
2951 BOOLEAN bLedOnScanning;
2952 UCHAR LedStatus;
2953
2954/*****************************************************************************************/
2955/* 802.11 related parameters */
2956/*****************************************************************************************/
2957 // outgoing BEACON frame buffer and corresponding TXD
2958 TXWI_STRUC BeaconTxWI;
2959 PUCHAR BeaconBuf;
2960 USHORT BeaconOffset[HW_BEACON_MAX_COUNT];
2961
2962 // pre-build PS-POLL and NULL frame upon link up. for efficiency purpose.
2963 PSPOLL_FRAME PsPollFrame;
2964 HEADER_802_11 NullFrame;
2965
2966#ifdef RT2870
2967 TX_CONTEXT BeaconContext[BEACON_RING_SIZE];
2968 TX_CONTEXT NullContext;
2969 TX_CONTEXT PsPollContext;
2970 TX_CONTEXT RTSContext;
2971#endif // RT2870 //
2972
2973
2974
2975//=========AP===========
2976
2977
2978//=======STA===========
2979#ifdef CONFIG_STA_SUPPORT
2980/* Modified by Wu Xi-Kun 4/21/2006 */
2981 // -----------------------------------------------
2982 // STA specific configuration & operation status
2983 // used only when pAd->OpMode == OPMODE_STA
2984 // -----------------------------------------------
2985 STA_ADMIN_CONFIG StaCfg; // user desired settings
2986 STA_ACTIVE_CONFIG StaActive; // valid only when ADHOC_ON(pAd) || INFRA_ON(pAd)
2987 CHAR nickname[IW_ESSID_MAX_SIZE+1]; // nickname, only used in the iwconfig i/f
2988 NDIS_MEDIA_STATE PreMediaState;
2989#endif // CONFIG_STA_SUPPORT //
2990
2991//=======Common===========
2992 // OP mode: either AP or STA
2993 UCHAR OpMode; // OPMODE_STA, OPMODE_AP
2994
2995 NDIS_MEDIA_STATE IndicateMediaState; // Base on Indication state, default is NdisMediaStateDisConnected
2996
2997
2998 // MAT related parameters
2999
3000 // configuration: read from Registry & E2PROM
3001 BOOLEAN bLocalAdminMAC; // Use user changed MAC
3002 UCHAR PermanentAddress[MAC_ADDR_LEN]; // Factory default MAC address
3003 UCHAR CurrentAddress[MAC_ADDR_LEN]; // User changed MAC address
3004
3005 // ------------------------------------------------------
3006 // common configuration to both OPMODE_STA and OPMODE_AP
3007 // ------------------------------------------------------
3008 COMMON_CONFIG CommonCfg;
3009 MLME_STRUCT Mlme;
3010
3011 // AP needs those vaiables for site survey feature.
3012 MLME_AUX MlmeAux; // temporary settings used during MLME state machine
3013 BSS_TABLE ScanTab; // store the latest SCAN result
3014
3015 //About MacTab, the sta driver will use #0 and #1 for multicast and AP.
3016 MAC_TABLE MacTab; // ASIC on-chip WCID entry table. At TX, ASIC always use key according to this on-chip table.
3017 NDIS_SPIN_LOCK MacTabLock;
3018
3019#ifdef DOT11_N_SUPPORT
3020 BA_TABLE BATable;
3021#endif // DOT11_N_SUPPORT //
3022 NDIS_SPIN_LOCK BATabLock;
3023 RALINK_TIMER_STRUCT RECBATimer;
3024
3025 // encryption/decryption KEY tables
3026 CIPHER_KEY SharedKey[MAX_MBSSID_NUM][4]; // STA always use SharedKey[BSS0][0..3]
3027
3028 // RX re-assembly buffer for fragmentation
3029 FRAGMENT_FRAME FragFrame; // Frame storage for fragment frame
3030
3031 // various Counters
3032 COUNTER_802_3 Counters8023; // 802.3 counters
3033 COUNTER_802_11 WlanCounters; // 802.11 MIB counters
3034 COUNTER_RALINK RalinkCounters; // Ralink propriety counters
3035 COUNTER_DRS DrsCounters; // counters for Dynamic TX Rate Switching
3036 PRIVATE_STRUC PrivateInfo; // Private information & counters
3037
3038 // flags, see fRTMP_ADAPTER_xxx flags
3039 ULONG Flags; // Represent current device status
3040
3041 // current TX sequence #
3042 USHORT Sequence;
3043
3044#ifdef UNDER_CE
3045 NDIS_HANDLE hGiISR;
3046#endif
3047
3048
3049 // Control disconnect / connect event generation
3050 //+++Didn't used anymore
3051 ULONG LinkDownTime;
3052 //---
3053 ULONG LastRxRate;
3054 ULONG LastTxRate;
3055 //+++Used only for Station
3056 BOOLEAN bConfigChanged; // Config Change flag for the same SSID setting
3057 //---
3058
3059 ULONG ExtraInfo; // Extra information for displaying status
3060 ULONG SystemErrorBitmap; // b0: E2PROM version error
3061
3062 //+++Didn't used anymore
3063 ULONG MacIcVersion; // MAC/BBP serial interface issue solved after ver.D
3064 //---
3065
3066 // ---------------------------
3067 // System event log
3068 // ---------------------------
3069 RT_802_11_EVENT_TABLE EventTab;
3070
3071
3072 BOOLEAN HTCEnable;
3073
3074 /*****************************************************************************************/
3075 /* Statistic related parameters */
3076 /*****************************************************************************************/
3077#ifdef RT2870
3078 ULONG BulkOutDataOneSecCount;
3079 ULONG BulkInDataOneSecCount;
3080 ULONG BulkLastOneSecCount; // BulkOutDataOneSecCount + BulkInDataOneSecCount
3081 ULONG watchDogRxCnt;
3082 ULONG watchDogRxOverFlowCnt;
3083 ULONG watchDogTxPendingCnt[NUM_OF_TX_RING];
3084#endif // RT2870 //
3085
3086 BOOLEAN bUpdateBcnCntDone;
3087 ULONG watchDogMacDeadlock; // prevent MAC/BBP into deadlock condition
3088 // ----------------------------
3089 // DEBUG paramerts
3090 // ----------------------------
3091 //ULONG DebugSetting[4];
3092 BOOLEAN bBanAllBaSetup;
3093 BOOLEAN bPromiscuous;
3094
3095 // ----------------------------
3096 // rt2860c emulation-use Parameters
3097 // ----------------------------
3098 ULONG rtsaccu[30];
3099 ULONG ctsaccu[30];
3100 ULONG cfendaccu[30];
3101 ULONG bacontent[16];
3102 ULONG rxint[RX_RING_SIZE+1];
3103 UCHAR rcvba[60];
3104 BOOLEAN bLinkAdapt;
3105 BOOLEAN bForcePrintTX;
3106 BOOLEAN bForcePrintRX;
3107 BOOLEAN bDisablescanning; //defined in RT2870 USB
3108 BOOLEAN bStaFifoTest;
3109 BOOLEAN bProtectionTest;
3110 BOOLEAN bHCCATest;
3111 BOOLEAN bGenOneHCCA;
3112 BOOLEAN bBroadComHT;
3113 //+++Following add from RT2870 USB.
3114 ULONG BulkOutReq;
3115 ULONG BulkOutComplete;
3116 ULONG BulkOutCompleteOther;
3117 ULONG BulkOutCompleteCancel; // seems not use now?
3118 ULONG BulkInReq;
3119 ULONG BulkInComplete;
3120 ULONG BulkInCompleteFail;
3121 //---
3122
3123 struct wificonf WIFItestbed;
3124
3125#ifdef RALINK_ATE
3126 ATE_INFO ate;
3127#ifdef RT2870
3128 BOOLEAN ContinBulkOut; //ATE bulk out control
3129 BOOLEAN ContinBulkIn; //ATE bulk in control
3130 atomic_t BulkOutRemained;
3131 atomic_t BulkInRemained;
3132#endif // RT2870 //
3133#endif // RALINK_ATE //
3134
3135#ifdef DOT11_N_SUPPORT
3136 struct reordering_mpdu_pool mpdu_blk_pool;
3137#endif // DOT11_N_SUPPORT //
3138
3139 ULONG OneSecondnonBEpackets; // record non BE packets per second
3140
3141#if WIRELESS_EXT >= 12
3142 struct iw_statistics iw_stats;
3143#endif
3144
3145 struct net_device_stats stats;
3146
3147#ifdef BLOCK_NET_IF
3148 BLOCK_QUEUE_ENTRY blockQueueTab[NUM_OF_TX_RING];
3149#endif // BLOCK_NET_IF //
3150
3151
3152
3153#ifdef MULTIPLE_CARD_SUPPORT
3154 INT32 MC_RowID;
3155 UCHAR MC_FileName[256];
3156#endif // MULTIPLE_CARD_SUPPORT //
3157
3158 ULONG TbttTickCount;
3159#ifdef PCI_MSI_SUPPORT
3160 BOOLEAN HaveMsi;
3161#endif // PCI_MSI_SUPPORT //
3162
3163
3164 UCHAR is_on;
3165
3166#define TIME_BASE (1000000/OS_HZ)
3167#define TIME_ONE_SECOND (1000000/TIME_BASE)
3168 UCHAR flg_be_adjust;
3169 ULONG be_adjust_last_time;
3170
3171#ifdef NINTENDO_AP
3172 NINDO_CTRL_BLOCK nindo_ctrl_block;
3173#endif // NINTENDO_AP //
3174
3175
3176#ifdef IKANOS_VX_1X0
3177 struct IKANOS_TX_INFO IkanosTxInfo;
3178 struct IKANOS_TX_INFO IkanosRxInfo[MAX_MBSSID_NUM + MAX_WDS_ENTRY + MAX_APCLI_NUM + MAX_MESH_NUM];
3179#endif // IKANOS_VX_1X0 //
3180
3181
3182#ifdef DBG_DIAGNOSE
3183 RtmpDiagStruct DiagStruct;
3184#endif // DBG_DIAGNOSE //
3185
3186
3187 UINT8 PM_FlgSuspend;
3188
3189#ifdef RT30xx
3190//======efuse
3191 BOOLEAN bUseEfuse;
3192 BOOLEAN bEEPROMFile;
3193#endif // RT30xx //
3194
3195} RTMP_ADAPTER, *PRTMP_ADAPTER;
3196
3197//
3198// Cisco IAPP format
3199//
3200typedef struct _CISCO_IAPP_CONTENT_
3201{
3202 USHORT Length; //IAPP Length
3203 UCHAR MessageType; //IAPP type
3204 UCHAR FunctionCode; //IAPP function type
3205 UCHAR DestinaionMAC[MAC_ADDR_LEN];
3206 UCHAR SourceMAC[MAC_ADDR_LEN];
3207 USHORT Tag; //Tag(element IE) - Adjacent AP report
3208 USHORT TagLength; //Length of element not including 4 byte header
3209 UCHAR OUI[4]; //0x00, 0x40, 0x96, 0x00
3210 UCHAR PreviousAP[MAC_ADDR_LEN]; //MAC Address of access point
3211 USHORT Channel;
3212 USHORT SsidLen;
3213 UCHAR Ssid[MAX_LEN_OF_SSID];
3214 USHORT Seconds; //Seconds that the client has been disassociated.
3215} CISCO_IAPP_CONTENT, *PCISCO_IAPP_CONTENT;
3216
3217#define DELAYINTMASK 0x0003fffb
3218#define INTMASK 0x0003fffb
3219#define IndMask 0x0003fffc
3220#define RxINT 0x00000005 // Delayed Rx or indivi rx
3221#define TxDataInt 0x000000fa // Delayed Tx or indivi tx
3222#define TxMgmtInt 0x00000102 // Delayed Tx or indivi tx
3223#define TxCoherent 0x00020000 // tx coherent
3224#define RxCoherent 0x00010000 // rx coherent
3225#define McuCommand 0x00000200 // mcu
3226#define PreTBTTInt 0x00001000 // Pre-TBTT interrupt
3227#define TBTTInt 0x00000800 // TBTT interrupt
3228#define GPTimeOutInt 0x00008000 // GPtimeout interrupt
3229#define AutoWakeupInt 0x00004000 // AutoWakeupInt interrupt
3230#define FifoStaFullInt 0x00002000 // fifo statistics full interrupt
3231
3232
3233typedef struct _RX_BLK_
3234{
3235// RXD_STRUC RxD; // sample
3236 RT28XX_RXD_STRUC RxD;
3237 PRXWI_STRUC pRxWI;
3238 PHEADER_802_11 pHeader;
3239 PNDIS_PACKET pRxPacket;
3240 UCHAR *pData;
3241 USHORT DataSize;
3242 USHORT Flags;
3243 UCHAR UserPriority; // for calculate TKIP MIC using
3244} RX_BLK;
3245
3246
3247#define RX_BLK_SET_FLAG(_pRxBlk, _flag) (_pRxBlk->Flags |= _flag)
3248#define RX_BLK_TEST_FLAG(_pRxBlk, _flag) (_pRxBlk->Flags & _flag)
3249#define RX_BLK_CLEAR_FLAG(_pRxBlk, _flag) (_pRxBlk->Flags &= ~(_flag))
3250
3251
3252#define fRX_WDS 0x0001
3253#define fRX_AMSDU 0x0002
3254#define fRX_ARALINK 0x0004
3255#define fRX_HTC 0x0008
3256#define fRX_PAD 0x0010
3257#define fRX_AMPDU 0x0020
3258#define fRX_QOS 0x0040
3259#define fRX_INFRA 0x0080
3260#define fRX_EAP 0x0100
3261#define fRX_MESH 0x0200
3262#define fRX_APCLI 0x0400
3263#define fRX_DLS 0x0800
3264#define fRX_WPI 0x1000
3265
3266#define LENGTH_AMSDU_SUBFRAMEHEAD 14
3267#define LENGTH_ARALINK_SUBFRAMEHEAD 14
3268#define LENGTH_ARALINK_HEADER_FIELD 2
3269
3270#define TX_UNKOWN_FRAME 0x00
3271#define TX_MCAST_FRAME 0x01
3272#define TX_LEGACY_FRAME 0x02
3273#define TX_AMPDU_FRAME 0x04
3274#define TX_AMSDU_FRAME 0x08
3275#define TX_RALINK_FRAME 0x10
3276#define TX_FRAG_FRAME 0x20
3277
3278
3279// Currently the sizeof(TX_BLK) is 148 bytes.
3280typedef struct _TX_BLK_
3281{
3282 UCHAR QueIdx;
3283 UCHAR TxFrameType; // Indicate the Transmission type of the all frames in one batch
3284 UCHAR TotalFrameNum; // Total frame number want to send-out in one batch
3285 USHORT TotalFragNum; // Total frame fragments required in one batch
3286 USHORT TotalFrameLen; // Total length of all frames want to send-out in one batch
3287
3288 QUEUE_HEADER TxPacketList;
3289 MAC_TABLE_ENTRY *pMacEntry; // NULL: packet with 802.11 RA field is multicast/broadcast address
3290 HTTRANSMIT_SETTING *pTransmit;
3291
3292 // Following structure used for the characteristics of a specific packet.
3293 PNDIS_PACKET pPacket;
3294 PUCHAR pSrcBufHeader; // Reference to the head of sk_buff->data
3295 PUCHAR pSrcBufData; // Reference to the sk_buff->data, will changed depends on hanlding progresss
3296 UINT SrcBufLen; // Length of packet payload which not including Layer 2 header
3297 PUCHAR pExtraLlcSnapEncap; // NULL means no extra LLC/SNAP is required
3298 UCHAR HeaderBuf[80]; // TempBuffer for TX_INFO + TX_WI + 802.11 Header + padding + AMSDU SubHeader + LLC/SNAP
3299 UCHAR MpduHeaderLen; // 802.11 header length NOT including the padding
3300 UCHAR HdrPadLen; // recording Header Padding Length;
3301 UCHAR apidx; // The interface associated to this packet
3302 UCHAR Wcid; // The MAC entry associated to this packet
3303 UCHAR UserPriority; // priority class of packet
3304 UCHAR FrameGap; // what kind of IFS this packet use
3305 UCHAR MpduReqNum; // number of fragments of this frame
3306 UCHAR TxRate; // TODO: Obsoleted? Should change to MCS?
3307 UCHAR CipherAlg; // cipher alogrithm
3308 PCIPHER_KEY pKey;
3309
3310
3311
3312 USHORT Flags; //See following definitions for detail.
3313
3314 //YOU SHOULD NOT TOUCH IT! Following parameters are used for hardware-depended layer.
3315 ULONG Priv; // Hardware specific value saved in here.
3316} TX_BLK, *PTX_BLK;
3317
3318
3319#define fTX_bRtsRequired 0x0001 // Indicate if need send RTS frame for protection. Not used in RT2860/RT2870.
3320#define fTX_bAckRequired 0x0002 // the packet need ack response
3321#define fTX_bPiggyBack 0x0004 // Legacy device use Piggback or not
3322#define fTX_bHTRate 0x0008 // allow to use HT rate
3323//#define fTX_bForceLowRate 0x0010 // force to use Low Rate
3324#define fTX_bForceNonQoS 0x0010 // force to transmit frame without WMM-QoS in HT mode
3325#define fTX_bAllowFrag 0x0020 // allow to fragment the packet, A-MPDU, A-MSDU, A-Ralink is not allowed to fragment
3326#define fTX_bMoreData 0x0040 // there are more data packets in PowerSave Queue
3327#define fTX_bWMM 0x0080 // QOS Data
3328
3329#define fTX_bClearEAPFrame 0x0100
3330
3331
3332#ifdef CONFIG_STA_SUPPORT
3333#endif // CONFIG_STA_SUPPORT //
3334
3335
3336
3337#define TX_BLK_ASSIGN_FLAG(_pTxBlk, _flag, value) \
3338 do { \
3339 if (value) \
3340 (_pTxBlk->Flags |= _flag) \
3341 else \
3342 (_pTxBlk->Flags &= ~(_flag)) \
3343 }while(0)
3344
3345#define TX_BLK_SET_FLAG(_pTxBlk, _flag) (_pTxBlk->Flags |= _flag)
3346#define TX_BLK_TEST_FLAG(_pTxBlk, _flag) (((_pTxBlk->Flags & _flag) == _flag) ? 1 : 0)
3347#define TX_BLK_CLEAR_FLAG(_pTxBlk, _flag) (_pTxBlk->Flags &= ~(_flag))
3348
3349
3350
3351
3352
3353//------------------------------------------------------------------------------------------
3354
3355
3356
3357#ifdef RT_BIG_ENDIAN
3358static inline VOID WriteBackToDescriptor(
3359 IN PUCHAR Dest,
3360 IN PUCHAR Src,
3361 IN BOOLEAN DoEncrypt,
3362 IN ULONG DescriptorType)
3363{
3364 UINT32 *p1, *p2;
3365
3366 p1 = ((UINT32 *)Dest);
3367 p2 = ((UINT32 *)Src);
3368
3369 *p1 = *p2;
3370 *(p1+2) = *(p2+2);
3371 *(p1+3) = *(p2+3);
3372 *(p1+1) = *(p2+1); // Word 1; this must be written back last
3373}
3374
3375/*
3376 ========================================================================
3377
3378 Routine Description:
3379 Endian conversion of Tx/Rx descriptor .
3380
3381 Arguments:
3382 pAd Pointer to our adapter
3383 pData Pointer to Tx/Rx descriptor
3384 DescriptorType Direction of the frame
3385
3386 Return Value:
3387 None
3388
3389 Note:
3390 Call this function when read or update descriptor
3391 ========================================================================
3392*/
3393static inline VOID RTMPWIEndianChange(
3394 IN PUCHAR pData,
3395 IN ULONG DescriptorType)
3396{
3397 int size;
3398 int i;
3399
3400 size = ((DescriptorType == TYPE_TXWI) ? TXWI_SIZE : RXWI_SIZE);
3401
3402 if(DescriptorType == TYPE_TXWI)
3403 {
3404 *((UINT32 *)(pData)) = SWAP32(*((UINT32 *)(pData))); // Byte 0~3
3405 *((UINT32 *)(pData + 4)) = SWAP32(*((UINT32 *)(pData+4))); // Byte 4~7
3406 }
3407 else
3408 {
3409 for(i=0; i < size/4 ; i++)
3410 *(((UINT32 *)pData) +i) = SWAP32(*(((UINT32 *)pData)+i));
3411 }
3412}
3413
3414/*
3415 ========================================================================
3416
3417 Routine Description:
3418 Endian conversion of Tx/Rx descriptor .
3419
3420 Arguments:
3421 pAd Pointer to our adapter
3422 pData Pointer to Tx/Rx descriptor
3423 DescriptorType Direction of the frame
3424
3425 Return Value:
3426 None
3427
3428 Note:
3429 Call this function when read or update descriptor
3430 ========================================================================
3431*/
3432
3433#ifdef RT2870
3434static inline VOID RTMPDescriptorEndianChange(
3435 IN PUCHAR pData,
3436 IN ULONG DescriptorType)
3437{
3438 *((UINT32 *)(pData)) = SWAP32(*((UINT32 *)(pData)));
3439}
3440#endif // RT2870 //
3441/*
3442 ========================================================================
3443
3444 Routine Description:
3445 Endian conversion of all kinds of 802.11 frames .
3446
3447 Arguments:
3448 pAd Pointer to our adapter
3449 pData Pointer to the 802.11 frame structure
3450 Dir Direction of the frame
3451 FromRxDoneInt Caller is from RxDone interrupt
3452
3453 Return Value:
3454 None
3455
3456 Note:
3457 Call this function when read or update buffer data
3458 ========================================================================
3459*/
3460static inline VOID RTMPFrameEndianChange(
3461 IN PRTMP_ADAPTER pAd,
3462 IN PUCHAR pData,
3463 IN ULONG Dir,
3464 IN BOOLEAN FromRxDoneInt)
3465{
3466 PHEADER_802_11 pFrame;
3467 PUCHAR pMacHdr;
3468
3469 // swab 16 bit fields - Frame Control field
3470 if(Dir == DIR_READ)
3471 {
3472 *(USHORT *)pData = SWAP16(*(USHORT *)pData);
3473 }
3474
3475 pFrame = (PHEADER_802_11) pData;
3476 pMacHdr = (PUCHAR) pFrame;
3477
3478 // swab 16 bit fields - Duration/ID field
3479 *(USHORT *)(pMacHdr + 2) = SWAP16(*(USHORT *)(pMacHdr + 2));
3480
3481 // swab 16 bit fields - Sequence Control field
3482 *(USHORT *)(pMacHdr + 22) = SWAP16(*(USHORT *)(pMacHdr + 22));
3483
3484 if(pFrame->FC.Type == BTYPE_MGMT)
3485 {
3486 switch(pFrame->FC.SubType)
3487 {
3488 case SUBTYPE_ASSOC_REQ:
3489 case SUBTYPE_REASSOC_REQ:
3490 // swab 16 bit fields - CapabilityInfo field
3491 pMacHdr += sizeof(HEADER_802_11);
3492 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3493
3494 // swab 16 bit fields - Listen Interval field
3495 pMacHdr += 2;
3496 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3497 break;
3498
3499 case SUBTYPE_ASSOC_RSP:
3500 case SUBTYPE_REASSOC_RSP:
3501 // swab 16 bit fields - CapabilityInfo field
3502 pMacHdr += sizeof(HEADER_802_11);
3503 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3504
3505 // swab 16 bit fields - Status Code field
3506 pMacHdr += 2;
3507 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3508
3509 // swab 16 bit fields - AID field
3510 pMacHdr += 2;
3511 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3512 break;
3513
3514 case SUBTYPE_AUTH:
3515 // If from APHandleRxDoneInterrupt routine, it is still a encrypt format.
3516 // The convertion is delayed to RTMPHandleDecryptionDoneInterrupt.
3517 if(!FromRxDoneInt && pFrame->FC.Wep == 1)
3518 break;
3519 else
3520 {
3521 // swab 16 bit fields - Auth Alg No. field
3522 pMacHdr += sizeof(HEADER_802_11);
3523 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3524
3525 // swab 16 bit fields - Auth Seq No. field
3526 pMacHdr += 2;
3527 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3528
3529 // swab 16 bit fields - Status Code field
3530 pMacHdr += 2;
3531 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3532 }
3533 break;
3534
3535 case SUBTYPE_BEACON:
3536 case SUBTYPE_PROBE_RSP:
3537 // swab 16 bit fields - BeaconInterval field
3538 pMacHdr += (sizeof(HEADER_802_11) + TIMESTAMP_LEN);
3539 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3540
3541 // swab 16 bit fields - CapabilityInfo field
3542 pMacHdr += sizeof(USHORT);
3543 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3544 break;
3545
3546 case SUBTYPE_DEAUTH:
3547 case SUBTYPE_DISASSOC:
3548 // swab 16 bit fields - Reason code field
3549 pMacHdr += sizeof(HEADER_802_11);
3550 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3551 break;
3552 }
3553 }
3554 else if( pFrame->FC.Type == BTYPE_DATA )
3555 {
3556 }
3557 else if(pFrame->FC.Type == BTYPE_CNTL)
3558 {
3559 switch(pFrame->FC.SubType)
3560 {
3561 case SUBTYPE_BLOCK_ACK_REQ:
3562 {
3563 PFRAME_BA_REQ pBAReq = (PFRAME_BA_REQ)pFrame;
3564 *(USHORT *)(&pBAReq->BARControl) = SWAP16(*(USHORT *)(&pBAReq->BARControl));
3565 pBAReq->BAStartingSeq.word = SWAP16(pBAReq->BAStartingSeq.word);
3566 }
3567 break;
3568 case SUBTYPE_BLOCK_ACK:
3569 // For Block Ack packet, the HT_CONTROL field is in the same offset with Addr3
3570 *(UINT32 *)(&pFrame->Addr3[0]) = SWAP32(*(UINT32 *)(&pFrame->Addr3[0]));
3571 break;
3572
3573 case SUBTYPE_ACK:
3574 //For ACK packet, the HT_CONTROL field is in the same offset with Addr2
3575 *(UINT32 *)(&pFrame->Addr2[0])= SWAP32(*(UINT32 *)(&pFrame->Addr2[0]));
3576 break;
3577 }
3578 }
3579 else
3580 {
3581 DBGPRINT(RT_DEBUG_ERROR,("Invalid Frame Type!!!\n"));
3582 }
3583
3584 // swab 16 bit fields - Frame Control
3585 if(Dir == DIR_WRITE)
3586 {
3587 *(USHORT *)pData = SWAP16(*(USHORT *)pData);
3588 }
3589}
3590#endif // RT_BIG_ENDIAN //
3591
3592
3593static inline VOID ConvertMulticastIP2MAC(
3594 IN PUCHAR pIpAddr,
3595 IN PUCHAR *ppMacAddr,
3596 IN UINT16 ProtoType)
3597{
3598 if (pIpAddr == NULL)
3599 return;
3600
3601 if (ppMacAddr == NULL || *ppMacAddr == NULL)
3602 return;
3603
3604 switch (ProtoType)
3605 {
3606 case ETH_P_IPV6:
3607// memset(*ppMacAddr, 0, ETH_LENGTH_OF_ADDRESS);
3608 *(*ppMacAddr) = 0x33;
3609 *(*ppMacAddr + 1) = 0x33;
3610 *(*ppMacAddr + 2) = pIpAddr[12];
3611 *(*ppMacAddr + 3) = pIpAddr[13];
3612 *(*ppMacAddr + 4) = pIpAddr[14];
3613 *(*ppMacAddr + 5) = pIpAddr[15];
3614 break;
3615
3616 case ETH_P_IP:
3617 default:
3618// memset(*ppMacAddr, 0, ETH_LENGTH_OF_ADDRESS);
3619 *(*ppMacAddr) = 0x01;
3620 *(*ppMacAddr + 1) = 0x00;
3621 *(*ppMacAddr + 2) = 0x5e;
3622 *(*ppMacAddr + 3) = pIpAddr[1] & 0x7f;
3623 *(*ppMacAddr + 4) = pIpAddr[2];
3624 *(*ppMacAddr + 5) = pIpAddr[3];
3625 break;
3626 }
3627
3628 return;
3629}
3630
3631BOOLEAN RTMPCheckForHang(
3632 IN NDIS_HANDLE MiniportAdapterContext
3633 );
3634
3635VOID RTMPHalt(
3636 IN NDIS_HANDLE MiniportAdapterContext
3637 );
3638
3639//
3640// Private routines in rtmp_init.c
3641//
3642NDIS_STATUS RTMPAllocAdapterBlock(
3643 IN PVOID handle,
3644 OUT PRTMP_ADAPTER *ppAdapter
3645 );
3646
3647NDIS_STATUS RTMPAllocTxRxRingMemory(
3648 IN PRTMP_ADAPTER pAd
3649 );
3650
3651NDIS_STATUS RTMPFindAdapter(
3652 IN PRTMP_ADAPTER pAd,
3653 IN NDIS_HANDLE WrapperConfigurationContext
3654 );
3655
3656NDIS_STATUS RTMPReadParametersHook(
3657 IN PRTMP_ADAPTER pAd
3658 );
3659
3660VOID RTMPFreeAdapter(
3661 IN PRTMP_ADAPTER pAd
3662 );
3663
3664NDIS_STATUS NICReadRegParameters(
3665 IN PRTMP_ADAPTER pAd,
3666 IN NDIS_HANDLE WrapperConfigurationContext
3667 );
3668
3669#ifdef RT30xx
3670VOID NICInitRT30xxRFRegisters(
3671 IN PRTMP_ADAPTER pAd);
3672#endif // RT30xx //
3673
3674VOID NICReadEEPROMParameters(
3675 IN PRTMP_ADAPTER pAd,
3676 IN PUCHAR mac_addr);
3677
3678VOID NICInitAsicFromEEPROM(
3679 IN PRTMP_ADAPTER pAd);
3680
3681VOID NICInitTxRxRingAndBacklogQueue(
3682 IN PRTMP_ADAPTER pAd);
3683
3684NDIS_STATUS NICInitializeAdapter(
3685 IN PRTMP_ADAPTER pAd,
3686 IN BOOLEAN bHardReset);
3687
3688NDIS_STATUS NICInitializeAsic(
3689 IN PRTMP_ADAPTER pAd,
3690 IN BOOLEAN bHardReset);
3691
3692VOID NICIssueReset(
3693 IN PRTMP_ADAPTER pAd);
3694
3695VOID RTMPRingCleanUp(
3696 IN PRTMP_ADAPTER pAd,
3697 IN UCHAR RingType);
3698
3699VOID RxTest(
3700 IN PRTMP_ADAPTER pAd);
3701
3702NDIS_STATUS DbgSendPacket(
3703 IN PRTMP_ADAPTER pAd,
3704 IN PNDIS_PACKET pPacket);
3705
3706VOID UserCfgInit(
3707 IN PRTMP_ADAPTER pAd);
3708
3709VOID NICResetFromError(
3710 IN PRTMP_ADAPTER pAd);
3711
3712VOID NICEraseFirmware(
3713 IN PRTMP_ADAPTER pAd);
3714
3715NDIS_STATUS NICLoadFirmware(
3716 IN PRTMP_ADAPTER pAd);
3717
3718NDIS_STATUS NICLoadRateSwitchingParams(
3719 IN PRTMP_ADAPTER pAd);
3720
3721BOOLEAN NICCheckForHang(
3722 IN PRTMP_ADAPTER pAd);
3723
3724VOID NICUpdateFifoStaCounters(
3725 IN PRTMP_ADAPTER pAd);
3726
3727VOID NICUpdateRawCounters(
3728 IN PRTMP_ADAPTER pAd);
3729
3730ULONG RTMPNotAllZero(
3731 IN PVOID pSrc1,
3732 IN ULONG Length);
3733
3734VOID RTMPZeroMemory(
3735 IN PVOID pSrc,
3736 IN ULONG Length);
3737
3738ULONG RTMPCompareMemory(
3739 IN PVOID pSrc1,
3740 IN PVOID pSrc2,
3741 IN ULONG Length);
3742
3743VOID RTMPMoveMemory(
3744 OUT PVOID pDest,
3745 IN PVOID pSrc,
3746 IN ULONG Length);
3747
3748VOID AtoH(
3749 char *src,
3750 UCHAR *dest,
3751 int destlen);
3752
3753UCHAR BtoH(
3754 char ch);
3755
3756VOID RTMPPatchMacBbpBug(
3757 IN PRTMP_ADAPTER pAd);
3758
3759VOID RTMPPatchCardBus(
3760 IN PRTMP_ADAPTER pAdapter);
3761
3762VOID RTMPPatchRalinkCardBus(
3763 IN PRTMP_ADAPTER pAdapter,
3764 IN ULONG Bus);
3765
3766ULONG RTMPReadCBConfig(
3767 IN ULONG Bus,
3768 IN ULONG Slot,
3769 IN ULONG Func,
3770 IN ULONG Offset);
3771
3772VOID RTMPWriteCBConfig(
3773 IN ULONG Bus,
3774 IN ULONG Slot,
3775 IN ULONG Func,
3776 IN ULONG Offset,
3777 IN ULONG Value);
3778
3779VOID RTMPInitTimer(
3780 IN PRTMP_ADAPTER pAd,
3781 IN PRALINK_TIMER_STRUCT pTimer,
3782 IN PVOID pTimerFunc,
3783 IN PVOID pData,
3784 IN BOOLEAN Repeat);
3785
3786VOID RTMPSetTimer(
3787 IN PRALINK_TIMER_STRUCT pTimer,
3788 IN ULONG Value);
3789
3790
3791VOID RTMPModTimer(
3792 IN PRALINK_TIMER_STRUCT pTimer,
3793 IN ULONG Value);
3794
3795VOID RTMPCancelTimer(
3796 IN PRALINK_TIMER_STRUCT pTimer,
3797 OUT BOOLEAN *pCancelled);
3798
3799VOID RTMPSetLED(
3800 IN PRTMP_ADAPTER pAd,
3801 IN UCHAR Status);
3802
3803VOID RTMPSetSignalLED(
3804 IN PRTMP_ADAPTER pAd,
3805 IN NDIS_802_11_RSSI Dbm);
3806
3807VOID RTMPEnableRxTx(
3808 IN PRTMP_ADAPTER pAd);
3809
3810//
3811// prototype in action.c
3812//
3813VOID ActionStateMachineInit(
3814 IN PRTMP_ADAPTER pAd,
3815 IN STATE_MACHINE *S,
3816 OUT STATE_MACHINE_FUNC Trans[]);
3817
3818VOID MlmeADDBAAction(
3819 IN PRTMP_ADAPTER pAd,
3820 IN MLME_QUEUE_ELEM *Elem);
3821
3822VOID MlmeDELBAAction(
3823 IN PRTMP_ADAPTER pAd,
3824 IN MLME_QUEUE_ELEM *Elem);
3825
3826VOID MlmeDLSAction(
3827 IN PRTMP_ADAPTER pAd,
3828 IN MLME_QUEUE_ELEM *Elem);
3829
3830VOID MlmeInvalidAction(
3831 IN PRTMP_ADAPTER pAd,
3832 IN MLME_QUEUE_ELEM *Elem);
3833
3834VOID MlmeQOSAction(
3835 IN PRTMP_ADAPTER pAd,
3836 IN MLME_QUEUE_ELEM *Elem);
3837
3838#ifdef DOT11_N_SUPPORT
3839VOID PeerAddBAReqAction(
3840 IN PRTMP_ADAPTER pAd,
3841 IN MLME_QUEUE_ELEM *Elem);
3842
3843VOID PeerAddBARspAction(
3844 IN PRTMP_ADAPTER pAd,
3845 IN MLME_QUEUE_ELEM *Elem);
3846
3847VOID PeerDelBAAction(
3848 IN PRTMP_ADAPTER pAd,
3849 IN MLME_QUEUE_ELEM *Elem);
3850
3851VOID PeerBAAction(
3852 IN PRTMP_ADAPTER pAd,
3853 IN MLME_QUEUE_ELEM *Elem);
3854#endif // DOT11_N_SUPPORT //
3855
3856VOID SendPSMPAction(
3857 IN PRTMP_ADAPTER pAd,
3858 IN UCHAR Wcid,
3859 IN UCHAR Psmp);
3860
3861
3862#ifdef DOT11N_DRAFT3
3863VOID SendBSS2040CoexistMgmtAction(
3864 IN PRTMP_ADAPTER pAd,
3865 IN UCHAR Wcid,
3866 IN UCHAR apidx,
3867 IN UCHAR InfoReq);
3868
3869VOID SendNotifyBWActionFrame(
3870 IN PRTMP_ADAPTER pAd,
3871 IN UCHAR Wcid,
3872 IN UCHAR apidx);
3873
3874BOOLEAN ChannelSwitchSanityCheck(
3875 IN PRTMP_ADAPTER pAd,
3876 IN UCHAR Wcid,
3877 IN UCHAR NewChannel,
3878 IN UCHAR Secondary);
3879
3880VOID ChannelSwitchAction(
3881 IN PRTMP_ADAPTER pAd,
3882 IN UCHAR Wcid,
3883 IN UCHAR Channel,
3884 IN UCHAR Secondary);
3885
3886ULONG BuildIntolerantChannelRep(
3887 IN PRTMP_ADAPTER pAd,
3888 IN PUCHAR pDest);
3889
3890VOID Update2040CoexistFrameAndNotify(
3891 IN PRTMP_ADAPTER pAd,
3892 IN UCHAR Wcid,
3893 IN BOOLEAN bAddIntolerantCha);
3894
3895VOID Send2040CoexistAction(
3896 IN PRTMP_ADAPTER pAd,
3897 IN UCHAR Wcid,
3898 IN BOOLEAN bAddIntolerantCha);
3899#endif // DOT11N_DRAFT3 //
3900
3901VOID PeerRMAction(
3902 IN PRTMP_ADAPTER pAd,
3903 IN MLME_QUEUE_ELEM *Elem);
3904
3905VOID PeerPublicAction(
3906 IN PRTMP_ADAPTER pAd,
3907 IN MLME_QUEUE_ELEM *Elem);
3908
3909#ifdef CONFIG_STA_SUPPORT
3910VOID StaPublicAction(
3911 IN PRTMP_ADAPTER pAd,
3912 IN UCHAR Bss2040Coexist);
3913#endif // CONFIG_STA_SUPPORT //
3914
3915
3916VOID PeerBSSTranAction(
3917 IN PRTMP_ADAPTER pAd,
3918 IN MLME_QUEUE_ELEM *Elem);
3919
3920#ifdef DOT11_N_SUPPORT
3921VOID PeerHTAction(
3922 IN PRTMP_ADAPTER pAd,
3923 IN MLME_QUEUE_ELEM *Elem);
3924#endif // DOT11_N_SUPPORT //
3925
3926VOID PeerQOSAction(
3927 IN PRTMP_ADAPTER pAd,
3928 IN MLME_QUEUE_ELEM *Elem);
3929
3930#ifdef QOS_DLS_SUPPORT
3931VOID PeerDLSAction(
3932 IN PRTMP_ADAPTER pAd,
3933 IN MLME_QUEUE_ELEM *Elem);
3934#endif // QOS_DLS_SUPPORT //
3935
3936#ifdef CONFIG_STA_SUPPORT
3937#ifdef QOS_DLS_SUPPORT
3938VOID DlsParmFill(
3939 IN PRTMP_ADAPTER pAd,
3940 IN OUT MLME_DLS_REQ_STRUCT *pDlsReq,
3941 IN PRT_802_11_DLS pDls,
3942 IN USHORT reason);
3943#endif // QOS_DLS_SUPPORT //
3944#endif // CONFIG_STA_SUPPORT //
3945
3946#ifdef DOT11_N_SUPPORT
3947VOID RECBATimerTimeout(
3948 IN PVOID SystemSpecific1,
3949 IN PVOID FunctionContext,
3950 IN PVOID SystemSpecific2,
3951 IN PVOID SystemSpecific3);
3952
3953VOID ORIBATimerTimeout(
3954 IN PRTMP_ADAPTER pAd);
3955
3956VOID SendRefreshBAR(
3957 IN PRTMP_ADAPTER pAd,
3958 IN MAC_TABLE_ENTRY *pEntry);
3959#endif // DOT11_N_SUPPORT //
3960
3961VOID ActHeaderInit(
3962 IN PRTMP_ADAPTER pAd,
3963 IN OUT PHEADER_802_11 pHdr80211,
3964 IN PUCHAR Addr1,
3965 IN PUCHAR Addr2,
3966 IN PUCHAR Addr3);
3967
3968VOID BarHeaderInit(
3969 IN PRTMP_ADAPTER pAd,
3970 IN OUT PFRAME_BAR pCntlBar,
3971 IN PUCHAR pDA,
3972 IN PUCHAR pSA);
3973
3974VOID InsertActField(
3975 IN PRTMP_ADAPTER pAd,
3976 OUT PUCHAR pFrameBuf,
3977 OUT PULONG pFrameLen,
3978 IN UINT8 Category,
3979 IN UINT8 ActCode);
3980
3981BOOLEAN QosBADataParse(
3982 IN PRTMP_ADAPTER pAd,
3983 IN BOOLEAN bAMSDU,
3984 IN PUCHAR p8023Header,
3985 IN UCHAR WCID,
3986 IN UCHAR TID,
3987 IN USHORT Sequence,
3988 IN UCHAR DataOffset,
3989 IN USHORT Datasize,
3990 IN UINT CurRxIndex);
3991
3992#ifdef DOT11_N_SUPPORT
3993BOOLEAN CntlEnqueueForRecv(
3994 IN PRTMP_ADAPTER pAd,
3995 IN ULONG Wcid,
3996 IN ULONG MsgLen,
3997 IN PFRAME_BA_REQ pMsg);
3998
3999VOID BaAutoManSwitch(
4000 IN PRTMP_ADAPTER pAd);
4001#endif // DOT11_N_SUPPORT //
4002
4003VOID HTIOTCheck(
4004 IN PRTMP_ADAPTER pAd,
4005 IN UCHAR BatRecIdx);
4006
4007//
4008// Private routines in rtmp_data.c
4009//
4010BOOLEAN RTMPHandleRxDoneInterrupt(
4011 IN PRTMP_ADAPTER pAd);
4012
4013VOID RTMPHandleTxDoneInterrupt(
4014 IN PRTMP_ADAPTER pAd);
4015
4016BOOLEAN RTMPHandleTxRingDmaDoneInterrupt(
4017 IN PRTMP_ADAPTER pAd,
4018 IN INT_SOURCE_CSR_STRUC TxRingBitmap);
4019
4020VOID RTMPHandleMgmtRingDmaDoneInterrupt(
4021 IN PRTMP_ADAPTER pAd);
4022
4023VOID RTMPHandleTBTTInterrupt(
4024 IN PRTMP_ADAPTER pAd);
4025
4026VOID RTMPHandlePreTBTTInterrupt(
4027 IN PRTMP_ADAPTER pAd);
4028
4029void RTMPHandleTwakeupInterrupt(
4030 IN PRTMP_ADAPTER pAd);
4031
4032VOID RTMPHandleRxCoherentInterrupt(
4033 IN PRTMP_ADAPTER pAd);
4034
4035BOOLEAN TxFrameIsAggregatible(
4036 IN PRTMP_ADAPTER pAd,
4037 IN PUCHAR pPrevAddr1,
4038 IN PUCHAR p8023hdr);
4039
4040BOOLEAN PeerIsAggreOn(
4041 IN PRTMP_ADAPTER pAd,
4042 IN ULONG TxRate,
4043 IN PMAC_TABLE_ENTRY pMacEntry);
4044
4045NDIS_STATUS Sniff2BytesFromNdisBuffer(
4046 IN PNDIS_BUFFER pFirstBuffer,
4047 IN UCHAR DesiredOffset,
4048 OUT PUCHAR pByte0,
4049 OUT PUCHAR pByte1);
4050
4051NDIS_STATUS STASendPacket(
4052 IN PRTMP_ADAPTER pAd,
4053 IN PNDIS_PACKET pPacket);
4054
4055VOID STASendPackets(
4056 IN NDIS_HANDLE MiniportAdapterContext,
4057 IN PPNDIS_PACKET ppPacketArray,
4058 IN UINT NumberOfPackets);
4059
4060VOID RTMPDeQueuePacket(
4061 IN PRTMP_ADAPTER pAd,
4062 IN BOOLEAN bIntContext,
4063 IN UCHAR QueIdx,
4064 IN UCHAR Max_Tx_Packets);
4065
4066NDIS_STATUS RTMPHardTransmit(
4067 IN PRTMP_ADAPTER pAd,
4068 IN PNDIS_PACKET pPacket,
4069 IN UCHAR QueIdx,
4070 OUT PULONG pFreeTXDLeft);
4071
4072NDIS_STATUS STAHardTransmit(
4073 IN PRTMP_ADAPTER pAd,
4074 IN TX_BLK *pTxBlk,
4075 IN UCHAR QueIdx);
4076
4077VOID STARxEAPOLFrameIndicate(
4078 IN PRTMP_ADAPTER pAd,
4079 IN MAC_TABLE_ENTRY *pEntry,
4080 IN RX_BLK *pRxBlk,
4081 IN UCHAR FromWhichBSSID);
4082
4083NDIS_STATUS RTMPFreeTXDRequest(
4084 IN PRTMP_ADAPTER pAd,
4085 IN UCHAR RingType,
4086 IN UCHAR NumberRequired,
4087 IN PUCHAR FreeNumberIs);
4088
4089NDIS_STATUS MlmeHardTransmit(
4090 IN PRTMP_ADAPTER pAd,
4091 IN UCHAR QueIdx,
4092 IN PNDIS_PACKET pPacket);
4093
4094NDIS_STATUS MlmeHardTransmitMgmtRing(
4095 IN PRTMP_ADAPTER pAd,
4096 IN UCHAR QueIdx,
4097 IN PNDIS_PACKET pPacket);
4098
4099NDIS_STATUS MlmeHardTransmitTxRing(
4100 IN PRTMP_ADAPTER pAd,
4101 IN UCHAR QueIdx,
4102 IN PNDIS_PACKET pPacket);
4103
4104USHORT RTMPCalcDuration(
4105 IN PRTMP_ADAPTER pAd,
4106 IN UCHAR Rate,
4107 IN ULONG Size);
4108
4109VOID RTMPWriteTxWI(
4110 IN PRTMP_ADAPTER pAd,
4111 IN PTXWI_STRUC pTxWI,
4112 IN BOOLEAN FRAG,
4113 IN BOOLEAN CFACK,
4114 IN BOOLEAN InsTimestamp,
4115 IN BOOLEAN AMPDU,
4116 IN BOOLEAN Ack,
4117 IN BOOLEAN NSeq, // HW new a sequence.
4118 IN UCHAR BASize,
4119 IN UCHAR WCID,
4120 IN ULONG Length,
4121 IN UCHAR PID,
4122 IN UCHAR TID,
4123 IN UCHAR TxRate,
4124 IN UCHAR Txopmode,
4125 IN BOOLEAN CfAck,
4126 IN HTTRANSMIT_SETTING *pTransmit);
4127
4128
4129VOID RTMPWriteTxWI_Data(
4130 IN PRTMP_ADAPTER pAd,
4131 IN OUT PTXWI_STRUC pTxWI,
4132 IN TX_BLK *pTxBlk);
4133
4134
4135VOID RTMPWriteTxWI_Cache(
4136 IN PRTMP_ADAPTER pAd,
4137 IN OUT PTXWI_STRUC pTxWI,
4138 IN TX_BLK *pTxBlk);
4139
4140VOID RTMPWriteTxDescriptor(
4141 IN PRTMP_ADAPTER pAd,
4142 IN PTXD_STRUC pTxD,
4143 IN BOOLEAN bWIV,
4144 IN UCHAR QSEL);
4145
4146VOID RTMPSuspendMsduTransmission(
4147 IN PRTMP_ADAPTER pAd);
4148
4149VOID RTMPResumeMsduTransmission(
4150 IN PRTMP_ADAPTER pAd);
4151
4152NDIS_STATUS MiniportMMRequest(
4153 IN PRTMP_ADAPTER pAd,
4154 IN UCHAR QueIdx,
4155 IN PUCHAR pData,
4156 IN UINT Length);
4157
4158NDIS_STATUS MiniportDataMMRequest(
4159 IN PRTMP_ADAPTER pAd,
4160 IN UCHAR QueIdx,
4161 IN PUCHAR pData,
4162 IN UINT Length);
4163
4164VOID RTMPSendNullFrame(
4165 IN PRTMP_ADAPTER pAd,
4166 IN UCHAR TxRate,
4167 IN BOOLEAN bQosNull);
4168
4169VOID RTMPSendDisassociationFrame(
4170 IN PRTMP_ADAPTER pAd);
4171
4172VOID RTMPSendRTSFrame(
4173 IN PRTMP_ADAPTER pAd,
4174 IN PUCHAR pDA,
4175 IN unsigned int NextMpduSize,
4176 IN UCHAR TxRate,
4177 IN UCHAR RTSRate,
4178 IN USHORT AckDuration,
4179 IN UCHAR QueIdx,
4180 IN UCHAR FrameGap);
4181
4182
4183NDIS_STATUS RTMPApplyPacketFilter(
4184 IN PRTMP_ADAPTER pAd,
4185 IN PRT28XX_RXD_STRUC pRxD,
4186 IN PHEADER_802_11 pHeader);
4187
4188PQUEUE_HEADER RTMPCheckTxSwQueue(
4189 IN PRTMP_ADAPTER pAd,
4190 OUT UCHAR *QueIdx);
4191
4192#ifdef CONFIG_STA_SUPPORT
4193VOID RTMPReportMicError(
4194 IN PRTMP_ADAPTER pAd,
4195 IN PCIPHER_KEY pWpaKey);
4196
4197VOID WpaMicFailureReportFrame(
4198 IN PRTMP_ADAPTER pAd,
4199 IN MLME_QUEUE_ELEM *Elem);
4200
4201VOID WpaDisassocApAndBlockAssoc(
4202 IN PVOID SystemSpecific1,
4203 IN PVOID FunctionContext,
4204 IN PVOID SystemSpecific2,
4205 IN PVOID SystemSpecific3);
4206#endif // CONFIG_STA_SUPPORT //
4207
4208NDIS_STATUS RTMPCloneNdisPacket(
4209 IN PRTMP_ADAPTER pAd,
4210 IN BOOLEAN pInsAMSDUHdr,
4211 IN PNDIS_PACKET pInPacket,
4212 OUT PNDIS_PACKET *ppOutPacket);
4213
4214NDIS_STATUS RTMPAllocateNdisPacket(
4215 IN PRTMP_ADAPTER pAd,
4216 IN PNDIS_PACKET *pPacket,
4217 IN PUCHAR pHeader,
4218 IN UINT HeaderLen,
4219 IN PUCHAR pData,
4220 IN UINT DataLen);
4221
4222VOID RTMPFreeNdisPacket(
4223 IN PRTMP_ADAPTER pAd,
4224 IN PNDIS_PACKET pPacket);
4225
4226BOOLEAN RTMPFreeTXDUponTxDmaDone(
4227 IN PRTMP_ADAPTER pAd,
4228 IN UCHAR QueIdx);
4229
4230BOOLEAN RTMPCheckDHCPFrame(
4231 IN PRTMP_ADAPTER pAd,
4232 IN PNDIS_PACKET pPacket);
4233
4234
4235BOOLEAN RTMPCheckEtherType(
4236 IN PRTMP_ADAPTER pAd,
4237 IN PNDIS_PACKET pPacket);
4238
4239
4240VOID RTMPCckBbpTuning(
4241 IN PRTMP_ADAPTER pAd,
4242 IN UINT TxRate);
4243
4244//
4245// Private routines in rtmp_wep.c
4246//
4247VOID RTMPInitWepEngine(
4248 IN PRTMP_ADAPTER pAd,
4249 IN PUCHAR pKey,
4250 IN UCHAR KeyId,
4251 IN UCHAR KeyLen,
4252 IN PUCHAR pDest);
4253
4254VOID RTMPEncryptData(
4255 IN PRTMP_ADAPTER pAd,
4256 IN PUCHAR pSrc,
4257 IN PUCHAR pDest,
4258 IN UINT Len);
4259
4260BOOLEAN RTMPDecryptData(
4261 IN PRTMP_ADAPTER pAdapter,
4262 IN PUCHAR pSrc,
4263 IN UINT Len,
4264 IN UINT idx);
4265
4266BOOLEAN RTMPSoftDecryptWEP(
4267 IN PRTMP_ADAPTER pAd,
4268 IN PUCHAR pData,
4269 IN ULONG DataByteCnt,
4270 IN PCIPHER_KEY pGroupKey);
4271
4272VOID RTMPSetICV(
4273 IN PRTMP_ADAPTER pAd,
4274 IN PUCHAR pDest);
4275
4276VOID ARCFOUR_INIT(
4277 IN PARCFOURCONTEXT Ctx,
4278 IN PUCHAR pKey,
4279 IN UINT KeyLen);
4280
4281UCHAR ARCFOUR_BYTE(
4282 IN PARCFOURCONTEXT Ctx);
4283
4284VOID ARCFOUR_DECRYPT(
4285 IN PARCFOURCONTEXT Ctx,
4286 IN PUCHAR pDest,
4287 IN PUCHAR pSrc,
4288 IN UINT Len);
4289
4290VOID ARCFOUR_ENCRYPT(
4291 IN PARCFOURCONTEXT Ctx,
4292 IN PUCHAR pDest,
4293 IN PUCHAR pSrc,
4294 IN UINT Len);
4295
4296VOID WPAARCFOUR_ENCRYPT(
4297 IN PARCFOURCONTEXT Ctx,
4298 IN PUCHAR pDest,
4299 IN PUCHAR pSrc,
4300 IN UINT Len);
4301
4302UINT RTMP_CALC_FCS32(
4303 IN UINT Fcs,
4304 IN PUCHAR Cp,
4305 IN INT Len);
4306
4307//
4308// MLME routines
4309//
4310
4311// Asic/RF/BBP related functions
4312
4313VOID AsicAdjustTxPower(
4314 IN PRTMP_ADAPTER pAd);
4315
4316VOID AsicUpdateProtect(
4317 IN PRTMP_ADAPTER pAd,
4318 IN USHORT OperaionMode,
4319 IN UCHAR SetMask,
4320 IN BOOLEAN bDisableBGProtect,
4321 IN BOOLEAN bNonGFExist);
4322
4323VOID AsicSwitchChannel(
4324 IN PRTMP_ADAPTER pAd,
4325 IN UCHAR Channel,
4326 IN BOOLEAN bScan);
4327
4328VOID AsicLockChannel(
4329 IN PRTMP_ADAPTER pAd,
4330 IN UCHAR Channel) ;
4331
4332VOID AsicAntennaSelect(
4333 IN PRTMP_ADAPTER pAd,
4334 IN UCHAR Channel);
4335
4336VOID AsicAntennaSetting(
4337 IN PRTMP_ADAPTER pAd,
4338 IN ABGBAND_STATE BandState);
4339
4340VOID AsicRfTuningExec(
4341 IN PVOID SystemSpecific1,
4342 IN PVOID FunctionContext,
4343 IN PVOID SystemSpecific2,
4344 IN PVOID SystemSpecific3);
4345
4346#ifdef CONFIG_STA_SUPPORT
4347VOID AsicSleepThenAutoWakeup(
4348 IN PRTMP_ADAPTER pAd,
4349 IN USHORT TbttNumToNextWakeUp);
4350
4351VOID AsicForceSleep(
4352 IN PRTMP_ADAPTER pAd);
4353
4354VOID AsicForceWakeup(
4355 IN PRTMP_ADAPTER pAd,
4356 IN BOOLEAN bFromTx);
4357#endif // CONFIG_STA_SUPPORT //
4358
4359VOID AsicSetBssid(
4360 IN PRTMP_ADAPTER pAd,
4361 IN PUCHAR pBssid);
4362
4363VOID AsicSetMcastWC(
4364 IN PRTMP_ADAPTER pAd);
4365
4366VOID AsicDelWcidTab(
4367 IN PRTMP_ADAPTER pAd,
4368 IN UCHAR Wcid);
4369
4370VOID AsicEnableRDG(
4371 IN PRTMP_ADAPTER pAd);
4372
4373VOID AsicDisableRDG(
4374 IN PRTMP_ADAPTER pAd);
4375
4376VOID AsicDisableSync(
4377 IN PRTMP_ADAPTER pAd);
4378
4379VOID AsicEnableBssSync(
4380 IN PRTMP_ADAPTER pAd);
4381
4382VOID AsicEnableIbssSync(
4383 IN PRTMP_ADAPTER pAd);
4384
4385VOID AsicSetEdcaParm(
4386 IN PRTMP_ADAPTER pAd,
4387 IN PEDCA_PARM pEdcaParm);
4388
4389VOID AsicSetSlotTime(
4390 IN PRTMP_ADAPTER pAd,
4391 IN BOOLEAN bUseShortSlotTime);
4392
4393VOID AsicAddSharedKeyEntry(
4394 IN PRTMP_ADAPTER pAd,
4395 IN UCHAR BssIndex,
4396 IN UCHAR KeyIdx,
4397 IN UCHAR CipherAlg,
4398 IN PUCHAR pKey,
4399 IN PUCHAR pTxMic,
4400 IN PUCHAR pRxMic);
4401
4402VOID AsicRemoveSharedKeyEntry(
4403 IN PRTMP_ADAPTER pAd,
4404 IN UCHAR BssIndex,
4405 IN UCHAR KeyIdx);
4406
4407VOID AsicUpdateWCIDAttribute(
4408 IN PRTMP_ADAPTER pAd,
4409 IN USHORT WCID,
4410 IN UCHAR BssIndex,
4411 IN UCHAR CipherAlg,
4412 IN BOOLEAN bUsePairewiseKeyTable);
4413
4414VOID AsicUpdateWCIDIVEIV(
4415 IN PRTMP_ADAPTER pAd,
4416 IN USHORT WCID,
4417 IN ULONG uIV,
4418 IN ULONG uEIV);
4419
4420VOID AsicUpdateRxWCIDTable(
4421 IN PRTMP_ADAPTER pAd,
4422 IN USHORT WCID,
4423 IN PUCHAR pAddr);
4424
4425VOID AsicAddKeyEntry(
4426 IN PRTMP_ADAPTER pAd,
4427 IN USHORT WCID,
4428 IN UCHAR BssIndex,
4429 IN UCHAR KeyIdx,
4430 IN PCIPHER_KEY pCipherKey,
4431 IN BOOLEAN bUsePairewiseKeyTable,
4432 IN BOOLEAN bTxKey);
4433
4434VOID AsicAddPairwiseKeyEntry(
4435 IN PRTMP_ADAPTER pAd,
4436 IN PUCHAR pAddr,
4437 IN UCHAR WCID,
4438 IN CIPHER_KEY *pCipherKey);
4439
4440VOID AsicRemovePairwiseKeyEntry(
4441 IN PRTMP_ADAPTER pAd,
4442 IN UCHAR BssIdx,
4443 IN UCHAR Wcid);
4444
4445BOOLEAN AsicSendCommandToMcu(
4446 IN PRTMP_ADAPTER pAd,
4447 IN UCHAR Command,
4448 IN UCHAR Token,
4449 IN UCHAR Arg0,
4450 IN UCHAR Arg1);
4451
4452
4453VOID MacAddrRandomBssid(
4454 IN PRTMP_ADAPTER pAd,
4455 OUT PUCHAR pAddr);
4456
4457VOID MgtMacHeaderInit(
4458 IN PRTMP_ADAPTER pAd,
4459 IN OUT PHEADER_802_11 pHdr80211,
4460 IN UCHAR SubType,
4461 IN UCHAR ToDs,
4462 IN PUCHAR pDA,
4463 IN PUCHAR pBssid);
4464
4465VOID MlmeRadioOff(
4466 IN PRTMP_ADAPTER pAd);
4467
4468VOID MlmeRadioOn(
4469 IN PRTMP_ADAPTER pAd);
4470
4471
4472VOID BssTableInit(
4473 IN BSS_TABLE *Tab);
4474
4475#ifdef DOT11_N_SUPPORT
4476VOID BATableInit(
4477 IN PRTMP_ADAPTER pAd,
4478 IN BA_TABLE *Tab);
4479#endif // DOT11_N_SUPPORT //
4480
4481ULONG BssTableSearch(
4482 IN BSS_TABLE *Tab,
4483 IN PUCHAR pBssid,
4484 IN UCHAR Channel);
4485
4486ULONG BssSsidTableSearch(
4487 IN BSS_TABLE *Tab,
4488 IN PUCHAR pBssid,
4489 IN PUCHAR pSsid,
4490 IN UCHAR SsidLen,
4491 IN UCHAR Channel);
4492
4493ULONG BssTableSearchWithSSID(
4494 IN BSS_TABLE *Tab,
4495 IN PUCHAR Bssid,
4496 IN PUCHAR pSsid,
4497 IN UCHAR SsidLen,
4498 IN UCHAR Channel);
4499
4500VOID BssTableDeleteEntry(
4501 IN OUT PBSS_TABLE pTab,
4502 IN PUCHAR pBssid,
4503 IN UCHAR Channel);
4504
4505#ifdef DOT11_N_SUPPORT
4506VOID BATableDeleteORIEntry(
4507 IN OUT PRTMP_ADAPTER pAd,
4508 IN BA_ORI_ENTRY *pBAORIEntry);
4509
4510VOID BATableDeleteRECEntry(
4511 IN OUT PRTMP_ADAPTER pAd,
4512 IN BA_REC_ENTRY *pBARECEntry);
4513
4514VOID BATableTearORIEntry(
4515 IN OUT PRTMP_ADAPTER pAd,
4516 IN UCHAR TID,
4517 IN UCHAR Wcid,
4518 IN BOOLEAN bForceDelete,
4519 IN BOOLEAN ALL);
4520
4521VOID BATableTearRECEntry(
4522 IN OUT PRTMP_ADAPTER pAd,
4523 IN UCHAR TID,
4524 IN UCHAR WCID,
4525 IN BOOLEAN ALL);
4526#endif // DOT11_N_SUPPORT //
4527
4528VOID BssEntrySet(
4529 IN PRTMP_ADAPTER pAd,
4530 OUT PBSS_ENTRY pBss,
4531 IN PUCHAR pBssid,
4532 IN CHAR Ssid[],
4533 IN UCHAR SsidLen,
4534 IN UCHAR BssType,
4535 IN USHORT BeaconPeriod,
4536 IN PCF_PARM CfParm,
4537 IN USHORT AtimWin,
4538 IN USHORT CapabilityInfo,
4539 IN UCHAR SupRate[],
4540 IN UCHAR SupRateLen,
4541 IN UCHAR ExtRate[],
4542 IN UCHAR ExtRateLen,
4543 IN HT_CAPABILITY_IE *pHtCapability,
4544 IN ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
4545 IN UCHAR HtCapabilityLen,
4546 IN UCHAR AddHtInfoLen,
4547 IN UCHAR NewExtChanOffset,
4548 IN UCHAR Channel,
4549 IN CHAR Rssi,
4550 IN LARGE_INTEGER TimeStamp,
4551 IN UCHAR CkipFlag,
4552 IN PEDCA_PARM pEdcaParm,
4553 IN PQOS_CAPABILITY_PARM pQosCapability,
4554 IN PQBSS_LOAD_PARM pQbssLoad,
4555 IN USHORT LengthVIE,
4556 IN PNDIS_802_11_VARIABLE_IEs pVIE);
4557
4558ULONG BssTableSetEntry(
4559 IN PRTMP_ADAPTER pAd,
4560 OUT PBSS_TABLE pTab,
4561 IN PUCHAR pBssid,
4562 IN CHAR Ssid[],
4563 IN UCHAR SsidLen,
4564 IN UCHAR BssType,
4565 IN USHORT BeaconPeriod,
4566 IN CF_PARM *CfParm,
4567 IN USHORT AtimWin,
4568 IN USHORT CapabilityInfo,
4569 IN UCHAR SupRate[],
4570 IN UCHAR SupRateLen,
4571 IN UCHAR ExtRate[],
4572 IN UCHAR ExtRateLen,
4573 IN HT_CAPABILITY_IE *pHtCapability,
4574 IN ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
4575 IN UCHAR HtCapabilityLen,
4576 IN UCHAR AddHtInfoLen,
4577 IN UCHAR NewExtChanOffset,
4578 IN UCHAR Channel,
4579 IN CHAR Rssi,
4580 IN LARGE_INTEGER TimeStamp,
4581 IN UCHAR CkipFlag,
4582 IN PEDCA_PARM pEdcaParm,
4583 IN PQOS_CAPABILITY_PARM pQosCapability,
4584 IN PQBSS_LOAD_PARM pQbssLoad,
4585 IN USHORT LengthVIE,
4586 IN PNDIS_802_11_VARIABLE_IEs pVIE);
4587
4588#ifdef DOT11_N_SUPPORT
4589VOID BATableInsertEntry(
4590 IN PRTMP_ADAPTER pAd,
4591 IN USHORT Aid,
4592 IN USHORT TimeOutValue,
4593 IN USHORT StartingSeq,
4594 IN UCHAR TID,
4595 IN UCHAR BAWinSize,
4596 IN UCHAR OriginatorStatus,
4597 IN BOOLEAN IsRecipient);
4598
4599#ifdef DOT11N_DRAFT3
4600VOID Bss2040CoexistTimeOut(
4601 IN PVOID SystemSpecific1,
4602 IN PVOID FunctionContext,
4603 IN PVOID SystemSpecific2,
4604 IN PVOID SystemSpecific3);
4605
4606
4607VOID TriEventInit(
4608 IN PRTMP_ADAPTER pAd);
4609
4610ULONG TriEventTableSetEntry(
4611 IN PRTMP_ADAPTER pAd,
4612 OUT TRIGGER_EVENT_TAB *Tab,
4613 IN PUCHAR pBssid,
4614 IN HT_CAPABILITY_IE *pHtCapability,
4615 IN UCHAR HtCapabilityLen,
4616 IN UCHAR RegClass,
4617 IN UCHAR ChannelNo);
4618
4619VOID TriEventCounterMaintenance(
4620 IN PRTMP_ADAPTER pAd);
4621#endif // DOT11N_DRAFT3 //
4622#endif // DOT11_N_SUPPORT //
4623
4624VOID BssTableSsidSort(
4625 IN PRTMP_ADAPTER pAd,
4626 OUT BSS_TABLE *OutTab,
4627 IN CHAR Ssid[],
4628 IN UCHAR SsidLen);
4629
4630VOID BssTableSortByRssi(
4631 IN OUT BSS_TABLE *OutTab);
4632
4633VOID BssCipherParse(
4634 IN OUT PBSS_ENTRY pBss);
4635
4636NDIS_STATUS MlmeQueueInit(
4637 IN MLME_QUEUE *Queue);
4638
4639VOID MlmeQueueDestroy(
4640 IN MLME_QUEUE *Queue);
4641
4642BOOLEAN MlmeEnqueue(
4643 IN PRTMP_ADAPTER pAd,
4644 IN ULONG Machine,
4645 IN ULONG MsgType,
4646 IN ULONG MsgLen,
4647 IN VOID *Msg);
4648
4649BOOLEAN MlmeEnqueueForRecv(
4650 IN PRTMP_ADAPTER pAd,
4651 IN ULONG Wcid,
4652 IN ULONG TimeStampHigh,
4653 IN ULONG TimeStampLow,
4654 IN UCHAR Rssi0,
4655 IN UCHAR Rssi1,
4656 IN UCHAR Rssi2,
4657 IN ULONG MsgLen,
4658 IN PVOID Msg,
4659 IN UCHAR Signal);
4660
4661
4662BOOLEAN MlmeDequeue(
4663 IN MLME_QUEUE *Queue,
4664 OUT MLME_QUEUE_ELEM **Elem);
4665
4666VOID MlmeRestartStateMachine(
4667 IN PRTMP_ADAPTER pAd);
4668
4669BOOLEAN MlmeQueueEmpty(
4670 IN MLME_QUEUE *Queue);
4671
4672BOOLEAN MlmeQueueFull(
4673 IN MLME_QUEUE *Queue);
4674
4675BOOLEAN MsgTypeSubst(
4676 IN PRTMP_ADAPTER pAd,
4677 IN PFRAME_802_11 pFrame,
4678 OUT INT *Machine,
4679 OUT INT *MsgType);
4680
4681VOID StateMachineInit(
4682 IN STATE_MACHINE *Sm,
4683 IN STATE_MACHINE_FUNC Trans[],
4684 IN ULONG StNr,
4685 IN ULONG MsgNr,
4686 IN STATE_MACHINE_FUNC DefFunc,
4687 IN ULONG InitState,
4688 IN ULONG Base);
4689
4690VOID StateMachineSetAction(
4691 IN STATE_MACHINE *S,
4692 IN ULONG St,
4693 ULONG Msg,
4694 IN STATE_MACHINE_FUNC F);
4695
4696VOID StateMachinePerformAction(
4697 IN PRTMP_ADAPTER pAd,
4698 IN STATE_MACHINE *S,
4699 IN MLME_QUEUE_ELEM *Elem);
4700
4701VOID Drop(
4702 IN PRTMP_ADAPTER pAd,
4703 IN MLME_QUEUE_ELEM *Elem);
4704
4705VOID AssocStateMachineInit(
4706 IN PRTMP_ADAPTER pAd,
4707 IN STATE_MACHINE *Sm,
4708 OUT STATE_MACHINE_FUNC Trans[]);
4709
4710VOID ReassocTimeout(
4711 IN PVOID SystemSpecific1,
4712 IN PVOID FunctionContext,
4713 IN PVOID SystemSpecific2,
4714 IN PVOID SystemSpecific3);
4715
4716VOID AssocTimeout(
4717 IN PVOID SystemSpecific1,
4718 IN PVOID FunctionContext,
4719 IN PVOID SystemSpecific2,
4720 IN PVOID SystemSpecific3);
4721
4722VOID DisassocTimeout(
4723 IN PVOID SystemSpecific1,
4724 IN PVOID FunctionContext,
4725 IN PVOID SystemSpecific2,
4726 IN PVOID SystemSpecific3);
4727
4728//----------------------------------------------
4729VOID MlmeDisassocReqAction(
4730 IN PRTMP_ADAPTER pAd,
4731 IN MLME_QUEUE_ELEM *Elem);
4732
4733VOID MlmeAssocReqAction(
4734 IN PRTMP_ADAPTER pAd,
4735 IN MLME_QUEUE_ELEM *Elem);
4736
4737VOID MlmeReassocReqAction(
4738 IN PRTMP_ADAPTER pAd,
4739 IN MLME_QUEUE_ELEM *Elem);
4740
4741VOID MlmeDisassocReqAction(
4742 IN PRTMP_ADAPTER pAd,
4743 IN MLME_QUEUE_ELEM *Elem);
4744
4745VOID PeerAssocRspAction(
4746 IN PRTMP_ADAPTER pAd,
4747 IN MLME_QUEUE_ELEM *Elem);
4748
4749VOID PeerReassocRspAction(
4750 IN PRTMP_ADAPTER pAd,
4751 IN MLME_QUEUE_ELEM *Elem);
4752
4753VOID PeerDisassocAction(
4754 IN PRTMP_ADAPTER pAd,
4755 IN MLME_QUEUE_ELEM *Elem);
4756
4757VOID DisassocTimeoutAction(
4758 IN PRTMP_ADAPTER pAd,
4759 IN MLME_QUEUE_ELEM *Elem);
4760
4761VOID AssocTimeoutAction(
4762 IN PRTMP_ADAPTER pAd,
4763 IN MLME_QUEUE_ELEM *Elem);
4764
4765VOID ReassocTimeoutAction(
4766 IN PRTMP_ADAPTER pAd,
4767 IN MLME_QUEUE_ELEM *Elem);
4768
4769VOID Cls3errAction(
4770 IN PRTMP_ADAPTER pAd,
4771 IN PUCHAR pAddr);
4772
4773VOID SwitchBetweenWepAndCkip(
4774 IN PRTMP_ADAPTER pAd);
4775
4776VOID InvalidStateWhenAssoc(
4777 IN PRTMP_ADAPTER pAd,
4778 IN MLME_QUEUE_ELEM *Elem);
4779
4780VOID InvalidStateWhenReassoc(
4781 IN PRTMP_ADAPTER pAd,
4782 IN MLME_QUEUE_ELEM *Elem);
4783
4784VOID InvalidStateWhenDisassociate(
4785 IN PRTMP_ADAPTER pAd,
4786 IN MLME_QUEUE_ELEM *Elem);
4787
4788#ifdef RT2870
4789VOID MlmeCntlConfirm(
4790 IN PRTMP_ADAPTER pAd,
4791 IN ULONG MsgType,
4792 IN USHORT Msg);
4793#endif // RT2870 //
4794
4795VOID ComposePsPoll(
4796 IN PRTMP_ADAPTER pAd);
4797
4798VOID ComposeNullFrame(
4799 IN PRTMP_ADAPTER pAd);
4800
4801VOID AssocPostProc(
4802 IN PRTMP_ADAPTER pAd,
4803 IN PUCHAR pAddr2,
4804 IN USHORT CapabilityInfo,
4805 IN USHORT Aid,
4806 IN UCHAR SupRate[],
4807 IN UCHAR SupRateLen,
4808 IN UCHAR ExtRate[],
4809 IN UCHAR ExtRateLen,
4810 IN PEDCA_PARM pEdcaParm,
4811 IN HT_CAPABILITY_IE *pHtCapability,
4812 IN UCHAR HtCapabilityLen,
4813 IN ADD_HT_INFO_IE *pAddHtInfo);
4814
4815VOID AuthStateMachineInit(
4816 IN PRTMP_ADAPTER pAd,
4817 IN PSTATE_MACHINE sm,
4818 OUT STATE_MACHINE_FUNC Trans[]);
4819
4820VOID AuthTimeout(
4821 IN PVOID SystemSpecific1,
4822 IN PVOID FunctionContext,
4823 IN PVOID SystemSpecific2,
4824 IN PVOID SystemSpecific3);
4825
4826VOID MlmeAuthReqAction(
4827 IN PRTMP_ADAPTER pAd,
4828 IN MLME_QUEUE_ELEM *Elem);
4829
4830VOID PeerAuthRspAtSeq2Action(
4831 IN PRTMP_ADAPTER pAd,
4832 IN MLME_QUEUE_ELEM *Elem);
4833
4834VOID PeerAuthRspAtSeq4Action(
4835 IN PRTMP_ADAPTER pAd,
4836 IN MLME_QUEUE_ELEM *Elem);
4837
4838VOID AuthTimeoutAction(
4839 IN PRTMP_ADAPTER pAd,
4840 IN MLME_QUEUE_ELEM *Elem);
4841
4842VOID Cls2errAction(
4843 IN PRTMP_ADAPTER pAd,
4844 IN PUCHAR pAddr);
4845
4846VOID MlmeDeauthReqAction(
4847 IN PRTMP_ADAPTER pAd,
4848 IN MLME_QUEUE_ELEM *Elem);
4849
4850VOID InvalidStateWhenAuth(
4851 IN PRTMP_ADAPTER pAd,
4852 IN MLME_QUEUE_ELEM *Elem);
4853
4854//=============================================
4855
4856VOID AuthRspStateMachineInit(
4857 IN PRTMP_ADAPTER pAd,
4858 IN PSTATE_MACHINE Sm,
4859 IN STATE_MACHINE_FUNC Trans[]);
4860
4861VOID PeerDeauthAction(
4862 IN PRTMP_ADAPTER pAd,
4863 IN MLME_QUEUE_ELEM *Elem);
4864
4865VOID PeerAuthSimpleRspGenAndSend(
4866 IN PRTMP_ADAPTER pAd,
4867 IN PHEADER_802_11 pHdr80211,
4868 IN USHORT Alg,
4869 IN USHORT Seq,
4870 IN USHORT Reason,
4871 IN USHORT Status);
4872
4873//
4874// Private routines in dls.c
4875//
4876
4877#ifdef CONFIG_STA_SUPPORT
4878#ifdef QOS_DLS_SUPPORT
4879void DlsStateMachineInit(
4880 IN PRTMP_ADAPTER pAd,
4881 IN STATE_MACHINE *Sm,
4882 OUT STATE_MACHINE_FUNC Trans[]);
4883
4884VOID MlmeDlsReqAction(
4885 IN PRTMP_ADAPTER pAd,
4886 IN MLME_QUEUE_ELEM *Elem);
4887
4888VOID PeerDlsReqAction(
4889 IN PRTMP_ADAPTER pAd,
4890 IN MLME_QUEUE_ELEM *Elem);
4891
4892VOID PeerDlsRspAction(
4893 IN PRTMP_ADAPTER pAd,
4894 IN MLME_QUEUE_ELEM *Elem);
4895
4896VOID MlmeDlsTearDownAction(
4897 IN PRTMP_ADAPTER pAd,
4898 IN MLME_QUEUE_ELEM *Elem);
4899
4900VOID PeerDlsTearDownAction(
4901 IN PRTMP_ADAPTER pAd,
4902 IN MLME_QUEUE_ELEM *Elem);
4903
4904VOID RTMPCheckDLSTimeOut(
4905 IN PRTMP_ADAPTER pAd);
4906
4907BOOLEAN RTMPRcvFrameDLSCheck(
4908 IN PRTMP_ADAPTER pAd,
4909 IN PHEADER_802_11 pHeader,
4910 IN ULONG Len,
4911 IN PRT28XX_RXD_STRUC pRxD);
4912
4913INT RTMPCheckDLSFrame(
4914 IN PRTMP_ADAPTER pAd,
4915 IN PUCHAR pDA);
4916
4917VOID RTMPSendDLSTearDownFrame(
4918 IN PRTMP_ADAPTER pAd,
4919 IN PUCHAR pDA);
4920
4921NDIS_STATUS RTMPSendSTAKeyRequest(
4922 IN PRTMP_ADAPTER pAd,
4923 IN PUCHAR pDA);
4924
4925NDIS_STATUS RTMPSendSTAKeyHandShake(
4926 IN PRTMP_ADAPTER pAd,
4927 IN PUCHAR pDA);
4928
4929VOID DlsTimeoutAction(
4930 IN PVOID SystemSpecific1,
4931 IN PVOID FunctionContext,
4932 IN PVOID SystemSpecific2,
4933 IN PVOID SystemSpecific3);
4934
4935BOOLEAN MlmeDlsReqSanity(
4936 IN PRTMP_ADAPTER pAd,
4937 IN VOID *Msg,
4938 IN ULONG MsgLen,
4939 OUT PRT_802_11_DLS *pDLS,
4940 OUT PUSHORT pReason);
4941
4942INT Set_DlsEntryInfo_Display_Proc(
4943 IN PRTMP_ADAPTER pAd,
4944 IN PUCHAR arg);
4945
4946MAC_TABLE_ENTRY *MacTableInsertDlsEntry(
4947 IN PRTMP_ADAPTER pAd,
4948 IN PUCHAR pAddr,
4949 IN UINT DlsEntryIdx);
4950
4951BOOLEAN MacTableDeleteDlsEntry(
4952 IN PRTMP_ADAPTER pAd,
4953 IN USHORT wcid,
4954 IN PUCHAR pAddr);
4955
4956MAC_TABLE_ENTRY *DlsEntryTableLookup(
4957 IN PRTMP_ADAPTER pAd,
4958 IN PUCHAR pAddr,
4959 IN BOOLEAN bResetIdelCount);
4960
4961MAC_TABLE_ENTRY *DlsEntryTableLookupByWcid(
4962 IN PRTMP_ADAPTER pAd,
4963 IN UCHAR wcid,
4964 IN PUCHAR pAddr,
4965 IN BOOLEAN bResetIdelCount);
4966
4967INT Set_DlsAddEntry_Proc(
4968 IN PRTMP_ADAPTER pAd,
4969 IN PUCHAR arg);
4970
4971INT Set_DlsTearDownEntry_Proc(
4972 IN PRTMP_ADAPTER pAd,
4973 IN PUCHAR arg);
4974#endif // QOS_DLS_SUPPORT //
4975#endif // CONFIG_STA_SUPPORT //
4976
4977#ifdef QOS_DLS_SUPPORT
4978BOOLEAN PeerDlsReqSanity(
4979 IN PRTMP_ADAPTER pAd,
4980 IN VOID *Msg,
4981 IN ULONG MsgLen,
4982 OUT PUCHAR pDA,
4983 OUT PUCHAR pSA,
4984 OUT USHORT *pCapabilityInfo,
4985 OUT USHORT *pDlsTimeout,
4986 OUT UCHAR *pRatesLen,
4987 OUT UCHAR Rates[],
4988 OUT UCHAR *pHtCapabilityLen,
4989 OUT HT_CAPABILITY_IE *pHtCapability);
4990
4991BOOLEAN PeerDlsRspSanity(
4992 IN PRTMP_ADAPTER pAd,
4993 IN VOID *Msg,
4994 IN ULONG MsgLen,
4995 OUT PUCHAR pDA,
4996 OUT PUCHAR pSA,
4997 OUT USHORT *pCapabilityInfo,
4998 OUT USHORT *pStatus,
4999 OUT UCHAR *pRatesLen,
5000 OUT UCHAR Rates[],
5001 OUT UCHAR *pHtCapabilityLen,
5002 OUT HT_CAPABILITY_IE *pHtCapability);
5003
5004BOOLEAN PeerDlsTearDownSanity(
5005 IN PRTMP_ADAPTER pAd,
5006 IN VOID *Msg,
5007 IN ULONG MsgLen,
5008 OUT PUCHAR pDA,
5009 OUT PUCHAR pSA,
5010 OUT USHORT *pReason);
5011#endif // QOS_DLS_SUPPORT //
5012
5013//========================================
5014
5015VOID SyncStateMachineInit(
5016 IN PRTMP_ADAPTER pAd,
5017 IN STATE_MACHINE *Sm,
5018 OUT STATE_MACHINE_FUNC Trans[]);
5019
5020VOID BeaconTimeout(
5021 IN PVOID SystemSpecific1,
5022 IN PVOID FunctionContext,
5023 IN PVOID SystemSpecific2,
5024 IN PVOID SystemSpecific3);
5025
5026VOID ScanTimeout(
5027 IN PVOID SystemSpecific1,
5028 IN PVOID FunctionContext,
5029 IN PVOID SystemSpecific2,
5030 IN PVOID SystemSpecific3);
5031
5032VOID MlmeScanReqAction(
5033 IN PRTMP_ADAPTER pAd,
5034 IN MLME_QUEUE_ELEM *Elem);
5035
5036VOID InvalidStateWhenScan(
5037 IN PRTMP_ADAPTER pAd,
5038 IN MLME_QUEUE_ELEM *Elem);
5039
5040VOID InvalidStateWhenJoin(
5041 IN PRTMP_ADAPTER pAd,
5042 IN MLME_QUEUE_ELEM *Elem);
5043
5044VOID InvalidStateWhenStart(
5045 IN PRTMP_ADAPTER pAd,
5046 IN MLME_QUEUE_ELEM *Elem);
5047
5048VOID PeerBeacon(
5049 IN PRTMP_ADAPTER pAd,
5050 IN MLME_QUEUE_ELEM *Elem);
5051
5052VOID EnqueueProbeRequest(
5053 IN PRTMP_ADAPTER pAd);
5054
5055BOOLEAN ScanRunning(
5056 IN PRTMP_ADAPTER pAd);
5057//=========================================
5058
5059VOID MlmeCntlInit(
5060 IN PRTMP_ADAPTER pAd,
5061 IN STATE_MACHINE *S,
5062 OUT STATE_MACHINE_FUNC Trans[]);
5063
5064VOID MlmeCntlMachinePerformAction(
5065 IN PRTMP_ADAPTER pAd,
5066 IN STATE_MACHINE *S,
5067 IN MLME_QUEUE_ELEM *Elem);
5068
5069VOID CntlIdleProc(
5070 IN PRTMP_ADAPTER pAd,
5071 IN MLME_QUEUE_ELEM *Elem);
5072
5073VOID CntlOidScanProc(
5074 IN PRTMP_ADAPTER pAd,
5075 IN MLME_QUEUE_ELEM *Elem);
5076
5077VOID CntlOidSsidProc(
5078 IN PRTMP_ADAPTER pAd,
5079 IN MLME_QUEUE_ELEM * Elem);
5080
5081VOID CntlOidRTBssidProc(
5082 IN PRTMP_ADAPTER pAd,
5083 IN MLME_QUEUE_ELEM * Elem);
5084
5085VOID CntlMlmeRoamingProc(
5086 IN PRTMP_ADAPTER pAd,
5087 IN MLME_QUEUE_ELEM * Elem);
5088
5089VOID CntlWaitDisassocProc(
5090 IN PRTMP_ADAPTER pAd,
5091 IN MLME_QUEUE_ELEM *Elem);
5092
5093VOID CntlWaitJoinProc(
5094 IN PRTMP_ADAPTER pAd,
5095 IN MLME_QUEUE_ELEM *Elem);
5096
5097VOID CntlWaitReassocProc(
5098 IN PRTMP_ADAPTER pAd,
5099 IN MLME_QUEUE_ELEM *Elem);
5100
5101VOID CntlWaitStartProc(
5102 IN PRTMP_ADAPTER pAd,
5103 IN MLME_QUEUE_ELEM *Elem);
5104
5105VOID CntlWaitAuthProc(
5106 IN PRTMP_ADAPTER pAd,
5107 IN MLME_QUEUE_ELEM *Elem);
5108
5109VOID CntlWaitAuthProc2(
5110 IN PRTMP_ADAPTER pAd,
5111 IN MLME_QUEUE_ELEM *Elem);
5112
5113VOID CntlWaitAssocProc(
5114 IN PRTMP_ADAPTER pAd,
5115 IN MLME_QUEUE_ELEM *Elem);
5116
5117#ifdef QOS_DLS_SUPPORT
5118VOID CntlOidDLSSetupProc(
5119 IN PRTMP_ADAPTER pAd,
5120 IN MLME_QUEUE_ELEM *Elem);
5121#endif // QOS_DLS_SUPPORT //
5122
5123VOID LinkUp(
5124 IN PRTMP_ADAPTER pAd,
5125 IN UCHAR BssType);
5126
5127VOID LinkDown(
5128 IN PRTMP_ADAPTER pAd,
5129 IN BOOLEAN IsReqFromAP);
5130
5131VOID IterateOnBssTab(
5132 IN PRTMP_ADAPTER pAd);
5133
5134VOID IterateOnBssTab2(
5135 IN PRTMP_ADAPTER pAd);;
5136
5137VOID JoinParmFill(
5138 IN PRTMP_ADAPTER pAd,
5139 IN OUT MLME_JOIN_REQ_STRUCT *JoinReq,
5140 IN ULONG BssIdx);
5141
5142VOID AssocParmFill(
5143 IN PRTMP_ADAPTER pAd,
5144 IN OUT MLME_ASSOC_REQ_STRUCT *AssocReq,
5145 IN PUCHAR pAddr,
5146 IN USHORT CapabilityInfo,
5147 IN ULONG Timeout,
5148 IN USHORT ListenIntv);
5149
5150VOID ScanParmFill(
5151 IN PRTMP_ADAPTER pAd,
5152 IN OUT MLME_SCAN_REQ_STRUCT *ScanReq,
5153 IN CHAR Ssid[],
5154 IN UCHAR SsidLen,
5155 IN UCHAR BssType,
5156 IN UCHAR ScanType);
5157
5158VOID DisassocParmFill(
5159 IN PRTMP_ADAPTER pAd,
5160 IN OUT MLME_DISASSOC_REQ_STRUCT *DisassocReq,
5161 IN PUCHAR pAddr,
5162 IN USHORT Reason);
5163
5164VOID StartParmFill(
5165 IN PRTMP_ADAPTER pAd,
5166 IN OUT MLME_START_REQ_STRUCT *StartReq,
5167 IN CHAR Ssid[],
5168 IN UCHAR SsidLen);
5169
5170VOID AuthParmFill(
5171 IN PRTMP_ADAPTER pAd,
5172 IN OUT MLME_AUTH_REQ_STRUCT *AuthReq,
5173 IN PUCHAR pAddr,
5174 IN USHORT Alg);
5175
5176VOID EnqueuePsPoll(
5177 IN PRTMP_ADAPTER pAd);
5178
5179VOID EnqueueBeaconFrame(
5180 IN PRTMP_ADAPTER pAd);
5181
5182VOID MlmeJoinReqAction(
5183 IN PRTMP_ADAPTER pAd,
5184 IN MLME_QUEUE_ELEM *Elem);
5185
5186VOID MlmeScanReqAction(
5187 IN PRTMP_ADAPTER pAd,
5188 IN MLME_QUEUE_ELEM *Elem);
5189
5190VOID MlmeStartReqAction(
5191 IN PRTMP_ADAPTER pAd,
5192 IN MLME_QUEUE_ELEM *Elem);
5193
5194VOID ScanTimeoutAction(
5195 IN PRTMP_ADAPTER pAd,
5196 IN MLME_QUEUE_ELEM *Elem);
5197
5198VOID BeaconTimeoutAtJoinAction(
5199 IN PRTMP_ADAPTER pAd,
5200 IN MLME_QUEUE_ELEM *Elem);
5201
5202VOID PeerBeaconAtScanAction(
5203 IN PRTMP_ADAPTER pAd,
5204 IN MLME_QUEUE_ELEM *Elem);
5205
5206VOID PeerBeaconAtJoinAction(
5207 IN PRTMP_ADAPTER pAd,
5208 IN MLME_QUEUE_ELEM *Elem);
5209
5210VOID PeerBeacon(
5211 IN PRTMP_ADAPTER pAd,
5212 IN MLME_QUEUE_ELEM *Elem);
5213
5214VOID PeerProbeReqAction(
5215 IN PRTMP_ADAPTER pAd,
5216 IN MLME_QUEUE_ELEM *Elem);
5217
5218VOID ScanNextChannel(
5219 IN PRTMP_ADAPTER pAd);
5220
5221ULONG MakeIbssBeacon(
5222 IN PRTMP_ADAPTER pAd);
5223
5224VOID CCXAdjacentAPReport(
5225 IN PRTMP_ADAPTER pAd);
5226
5227BOOLEAN MlmeScanReqSanity(
5228 IN PRTMP_ADAPTER pAd,
5229 IN VOID *Msg,
5230 IN ULONG MsgLen,
5231 OUT UCHAR *BssType,
5232 OUT CHAR ssid[],
5233 OUT UCHAR *SsidLen,
5234 OUT UCHAR *ScanType);
5235
5236BOOLEAN PeerBeaconAndProbeRspSanity(
5237 IN PRTMP_ADAPTER pAd,
5238 IN VOID *Msg,
5239 IN ULONG MsgLen,
5240 IN UCHAR MsgChannel,
5241 OUT PUCHAR pAddr2,
5242 OUT PUCHAR pBssid,
5243 OUT CHAR Ssid[],
5244 OUT UCHAR *pSsidLen,
5245 OUT UCHAR *pBssType,
5246 OUT USHORT *pBeaconPeriod,
5247 OUT UCHAR *pChannel,
5248 OUT UCHAR *pNewChannel,
5249 OUT LARGE_INTEGER *pTimestamp,
5250 OUT CF_PARM *pCfParm,
5251 OUT USHORT *pAtimWin,
5252 OUT USHORT *pCapabilityInfo,
5253 OUT UCHAR *pErp,
5254 OUT UCHAR *pDtimCount,
5255 OUT UCHAR *pDtimPeriod,
5256 OUT UCHAR *pBcastFlag,
5257 OUT UCHAR *pMessageToMe,
5258 OUT UCHAR SupRate[],
5259 OUT UCHAR *pSupRateLen,
5260 OUT UCHAR ExtRate[],
5261 OUT UCHAR *pExtRateLen,
5262 OUT UCHAR *pCkipFlag,
5263 OUT UCHAR *pAironetCellPowerLimit,
5264 OUT PEDCA_PARM pEdcaParm,
5265 OUT PQBSS_LOAD_PARM pQbssLoad,
5266 OUT PQOS_CAPABILITY_PARM pQosCapability,
5267 OUT ULONG *pRalinkIe,
5268 OUT UCHAR *pHtCapabilityLen,
5269#ifdef CONFIG_STA_SUPPORT
5270 OUT UCHAR *pPreNHtCapabilityLen,
5271#endif // CONFIG_STA_SUPPORT //
5272 OUT HT_CAPABILITY_IE *pHtCapability,
5273 OUT UCHAR *AddHtInfoLen,
5274 OUT ADD_HT_INFO_IE *AddHtInfo,
5275 OUT UCHAR *NewExtChannel,
5276 OUT USHORT *LengthVIE,
5277 OUT PNDIS_802_11_VARIABLE_IEs pVIE);
5278
5279BOOLEAN PeerAddBAReqActionSanity(
5280 IN PRTMP_ADAPTER pAd,
5281 IN VOID *pMsg,
5282 IN ULONG MsgLen,
5283 OUT PUCHAR pAddr2);
5284
5285BOOLEAN PeerAddBARspActionSanity(
5286 IN PRTMP_ADAPTER pAd,
5287 IN VOID *pMsg,
5288 IN ULONG MsgLen);
5289
5290BOOLEAN PeerDelBAActionSanity(
5291 IN PRTMP_ADAPTER pAd,
5292 IN UCHAR Wcid,
5293 IN VOID *pMsg,
5294 IN ULONG MsgLen);
5295
5296BOOLEAN MlmeAssocReqSanity(
5297 IN PRTMP_ADAPTER pAd,
5298 IN VOID *Msg,
5299 IN ULONG MsgLen,
5300 OUT PUCHAR pApAddr,
5301 OUT USHORT *CapabilityInfo,
5302 OUT ULONG *Timeout,
5303 OUT USHORT *ListenIntv);
5304
5305BOOLEAN MlmeAuthReqSanity(
5306 IN PRTMP_ADAPTER pAd,
5307 IN VOID *Msg,
5308 IN ULONG MsgLen,
5309 OUT PUCHAR pAddr,
5310 OUT ULONG *Timeout,
5311 OUT USHORT *Alg);
5312
5313BOOLEAN MlmeStartReqSanity(
5314 IN PRTMP_ADAPTER pAd,
5315 IN VOID *Msg,
5316 IN ULONG MsgLen,
5317 OUT CHAR Ssid[],
5318 OUT UCHAR *Ssidlen);
5319
5320BOOLEAN PeerAuthSanity(
5321 IN PRTMP_ADAPTER pAd,
5322 IN VOID *Msg,
5323 IN ULONG MsgLen,
5324 OUT PUCHAR pAddr,
5325 OUT USHORT *Alg,
5326 OUT USHORT *Seq,
5327 OUT USHORT *Status,
5328 OUT CHAR ChlgText[]);
5329
5330BOOLEAN PeerAssocRspSanity(
5331 IN PRTMP_ADAPTER pAd,
5332 IN VOID *pMsg,
5333 IN ULONG MsgLen,
5334 OUT PUCHAR pAddr2,
5335 OUT USHORT *pCapabilityInfo,
5336 OUT USHORT *pStatus,
5337 OUT USHORT *pAid,
5338 OUT UCHAR SupRate[],
5339 OUT UCHAR *pSupRateLen,
5340 OUT UCHAR ExtRate[],
5341 OUT UCHAR *pExtRateLen,
5342 OUT HT_CAPABILITY_IE *pHtCapability,
5343 OUT ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
5344 OUT UCHAR *pHtCapabilityLen,
5345 OUT UCHAR *pAddHtInfoLen,
5346 OUT UCHAR *pNewExtChannelOffset,
5347 OUT PEDCA_PARM pEdcaParm,
5348 OUT UCHAR *pCkipFlag);
5349
5350BOOLEAN PeerDisassocSanity(
5351 IN PRTMP_ADAPTER pAd,
5352 IN VOID *Msg,
5353 IN ULONG MsgLen,
5354 OUT PUCHAR pAddr2,
5355 OUT USHORT *Reason);
5356
5357BOOLEAN PeerWpaMessageSanity(
5358 IN PRTMP_ADAPTER pAd,
5359 IN PEAPOL_PACKET pMsg,
5360 IN ULONG MsgLen,
5361 IN UCHAR MsgType,
5362 IN MAC_TABLE_ENTRY *pEntry);
5363
5364BOOLEAN PeerDeauthSanity(
5365 IN PRTMP_ADAPTER pAd,
5366 IN VOID *Msg,
5367 IN ULONG MsgLen,
5368 OUT PUCHAR pAddr2,
5369 OUT USHORT *Reason);
5370
5371BOOLEAN PeerProbeReqSanity(
5372 IN PRTMP_ADAPTER pAd,
5373 IN VOID *Msg,
5374 IN ULONG MsgLen,
5375 OUT PUCHAR pAddr2,
5376 OUT CHAR Ssid[],
5377 OUT UCHAR *pSsidLen);
5378
5379BOOLEAN GetTimBit(
5380 IN CHAR *Ptr,
5381 IN USHORT Aid,
5382 OUT UCHAR *TimLen,
5383 OUT UCHAR *BcastFlag,
5384 OUT UCHAR *DtimCount,
5385 OUT UCHAR *DtimPeriod,
5386 OUT UCHAR *MessageToMe);
5387
5388UCHAR ChannelSanity(
5389 IN PRTMP_ADAPTER pAd,
5390 IN UCHAR channel);
5391
5392NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity(
5393 IN PBSS_ENTRY pBss);
5394
5395BOOLEAN MlmeDelBAReqSanity(
5396 IN PRTMP_ADAPTER pAd,
5397 IN VOID *Msg,
5398 IN ULONG MsgLen);
5399
5400BOOLEAN MlmeAddBAReqSanity(
5401 IN PRTMP_ADAPTER pAd,
5402 IN VOID *Msg,
5403 IN ULONG MsgLen,
5404 OUT PUCHAR pAddr2);
5405
5406ULONG MakeOutgoingFrame(
5407 OUT CHAR *Buffer,
5408 OUT ULONG *Length, ...);
5409
5410VOID LfsrInit(
5411 IN PRTMP_ADAPTER pAd,
5412 IN ULONG Seed);
5413
5414UCHAR RandomByte(
5415 IN PRTMP_ADAPTER pAd);
5416
5417VOID AsicUpdateAutoFallBackTable(
5418 IN PRTMP_ADAPTER pAd,
5419 IN PUCHAR pTxRate);
5420
5421VOID MlmePeriodicExec(
5422 IN PVOID SystemSpecific1,
5423 IN PVOID FunctionContext,
5424 IN PVOID SystemSpecific2,
5425 IN PVOID SystemSpecific3);
5426
5427VOID LinkDownExec(
5428 IN PVOID SystemSpecific1,
5429 IN PVOID FunctionContext,
5430 IN PVOID SystemSpecific2,
5431 IN PVOID SystemSpecific3);
5432
5433VOID LinkUpExec(
5434 IN PVOID SystemSpecific1,
5435 IN PVOID FunctionContext,
5436 IN PVOID SystemSpecific2,
5437 IN PVOID SystemSpecific3);
5438
5439VOID STAMlmePeriodicExec(
5440 PRTMP_ADAPTER pAd);
5441
5442VOID MlmeAutoScan(
5443 IN PRTMP_ADAPTER pAd);
5444
5445VOID MlmeAutoReconnectLastSSID(
5446 IN PRTMP_ADAPTER pAd);
5447
5448BOOLEAN MlmeValidateSSID(
5449 IN PUCHAR pSsid,
5450 IN UCHAR SsidLen);
5451
5452VOID MlmeCheckForRoaming(
5453 IN PRTMP_ADAPTER pAd,
5454 IN ULONG Now32);
5455
5456VOID MlmeCheckForFastRoaming(
5457 IN PRTMP_ADAPTER pAd,
5458 IN ULONG Now);
5459
5460VOID MlmeDynamicTxRateSwitching(
5461 IN PRTMP_ADAPTER pAd);
5462
5463VOID MlmeSetTxRate(
5464 IN PRTMP_ADAPTER pAd,
5465 IN PMAC_TABLE_ENTRY pEntry,
5466 IN PRTMP_TX_RATE_SWITCH pTxRate);
5467
5468VOID MlmeSelectTxRateTable(
5469 IN PRTMP_ADAPTER pAd,
5470 IN PMAC_TABLE_ENTRY pEntry,
5471 IN PUCHAR *ppTable,
5472 IN PUCHAR pTableSize,
5473 IN PUCHAR pInitTxRateIdx);
5474
5475VOID MlmeCalculateChannelQuality(
5476 IN PRTMP_ADAPTER pAd,
5477 IN ULONG Now);
5478
5479VOID MlmeCheckPsmChange(
5480 IN PRTMP_ADAPTER pAd,
5481 IN ULONG Now32);
5482
5483VOID MlmeSetPsmBit(
5484 IN PRTMP_ADAPTER pAd,
5485 IN USHORT psm);
5486
5487VOID MlmeSetTxPreamble(
5488 IN PRTMP_ADAPTER pAd,
5489 IN USHORT TxPreamble);
5490
5491VOID UpdateBasicRateBitmap(
5492 IN PRTMP_ADAPTER pAd);
5493
5494VOID MlmeUpdateTxRates(
5495 IN PRTMP_ADAPTER pAd,
5496 IN BOOLEAN bLinkUp,
5497 IN UCHAR apidx);
5498
5499#ifdef DOT11_N_SUPPORT
5500VOID MlmeUpdateHtTxRates(
5501 IN PRTMP_ADAPTER pAd,
5502 IN UCHAR apidx);
5503#endif // DOT11_N_SUPPORT //
5504
5505VOID RTMPCheckRates(
5506 IN PRTMP_ADAPTER pAd,
5507 IN OUT UCHAR SupRate[],
5508 IN OUT UCHAR *SupRateLen);
5509
5510#ifdef CONFIG_STA_SUPPORT
5511BOOLEAN RTMPCheckChannel(
5512 IN PRTMP_ADAPTER pAd,
5513 IN UCHAR CentralChannel,
5514 IN UCHAR Channel);
5515#endif // CONFIG_STA_SUPPORT //
5516
5517BOOLEAN RTMPCheckHt(
5518 IN PRTMP_ADAPTER pAd,
5519 IN UCHAR Wcid,
5520 IN OUT HT_CAPABILITY_IE *pHtCapability,
5521 IN OUT ADD_HT_INFO_IE *pAddHtInfo);
5522
5523VOID StaQuickResponeForRateUpExec(
5524 IN PVOID SystemSpecific1,
5525 IN PVOID FunctionContext,
5526 IN PVOID SystemSpecific2,
5527 IN PVOID SystemSpecific3);
5528
5529VOID AsicBbpTuning1(
5530 IN PRTMP_ADAPTER pAd);
5531
5532VOID AsicBbpTuning2(
5533 IN PRTMP_ADAPTER pAd);
5534
5535VOID RTMPUpdateMlmeRate(
5536 IN PRTMP_ADAPTER pAd);
5537
5538CHAR RTMPMaxRssi(
5539 IN PRTMP_ADAPTER pAd,
5540 IN CHAR Rssi0,
5541 IN CHAR Rssi1,
5542 IN CHAR Rssi2);
5543
5544VOID AsicSetRxAnt(
5545 IN PRTMP_ADAPTER pAd,
5546 IN UCHAR Ant);
5547
5548VOID AsicEvaluateRxAnt(
5549 IN PRTMP_ADAPTER pAd);
5550
5551VOID AsicRxAntEvalTimeout(
5552 IN PVOID SystemSpecific1,
5553 IN PVOID FunctionContext,
5554 IN PVOID SystemSpecific2,
5555 IN PVOID SystemSpecific3);
5556
5557VOID APSDPeriodicExec(
5558 IN PVOID SystemSpecific1,
5559 IN PVOID FunctionContext,
5560 IN PVOID SystemSpecific2,
5561 IN PVOID SystemSpecific3);
5562
5563BOOLEAN RTMPCheckEntryEnableAutoRateSwitch(
5564 IN PRTMP_ADAPTER pAd,
5565 IN PMAC_TABLE_ENTRY pEntry);
5566
5567UCHAR RTMPStaFixedTxMode(
5568 IN PRTMP_ADAPTER pAd,
5569 IN PMAC_TABLE_ENTRY pEntry);
5570
5571VOID RTMPUpdateLegacyTxSetting(
5572 UCHAR fixed_tx_mode,
5573 PMAC_TABLE_ENTRY pEntry);
5574
5575BOOLEAN RTMPAutoRateSwitchCheck(
5576 IN PRTMP_ADAPTER pAd);
5577
5578NDIS_STATUS MlmeInit(
5579 IN PRTMP_ADAPTER pAd);
5580
5581VOID MlmeHandler(
5582 IN PRTMP_ADAPTER pAd);
5583
5584VOID MlmeHalt(
5585 IN PRTMP_ADAPTER pAd);
5586
5587VOID MlmeResetRalinkCounters(
5588 IN PRTMP_ADAPTER pAd);
5589
5590VOID BuildChannelList(
5591 IN PRTMP_ADAPTER pAd);
5592
5593UCHAR FirstChannel(
5594 IN PRTMP_ADAPTER pAd);
5595
5596UCHAR NextChannel(
5597 IN PRTMP_ADAPTER pAd,
5598 IN UCHAR channel);
5599
5600VOID ChangeToCellPowerLimit(
5601 IN PRTMP_ADAPTER pAd,
5602 IN UCHAR AironetCellPowerLimit);
5603
5604VOID RaiseClock(
5605 IN PRTMP_ADAPTER pAd,
5606 IN UINT32 *x);
5607
5608VOID LowerClock(
5609 IN PRTMP_ADAPTER pAd,
5610 IN UINT32 *x);
5611
5612USHORT ShiftInBits(
5613 IN PRTMP_ADAPTER pAd);
5614
5615VOID ShiftOutBits(
5616 IN PRTMP_ADAPTER pAd,
5617 IN USHORT data,
5618 IN USHORT count);
5619
5620VOID EEpromCleanup(
5621 IN PRTMP_ADAPTER pAd);
5622
5623VOID EWDS(
5624 IN PRTMP_ADAPTER pAd);
5625
5626VOID EWEN(
5627 IN PRTMP_ADAPTER pAd);
5628
5629USHORT RTMP_EEPROM_READ16(
5630 IN PRTMP_ADAPTER pAd,
5631 IN USHORT Offset);
5632
5633VOID RTMP_EEPROM_WRITE16(
5634 IN PRTMP_ADAPTER pAd,
5635 IN USHORT Offset,
5636 IN USHORT Data);
5637
5638//
5639// Prototypes of function definition in rtmp_tkip.c
5640//
5641VOID RTMPInitTkipEngine(
5642 IN PRTMP_ADAPTER pAd,
5643 IN PUCHAR pTKey,
5644 IN UCHAR KeyId,
5645 IN PUCHAR pTA,
5646 IN PUCHAR pMICKey,
5647 IN PUCHAR pTSC,
5648 OUT PULONG pIV16,
5649 OUT PULONG pIV32);
5650
5651VOID RTMPInitMICEngine(
5652 IN PRTMP_ADAPTER pAd,
5653 IN PUCHAR pKey,
5654 IN PUCHAR pDA,
5655 IN PUCHAR pSA,
5656 IN UCHAR UserPriority,
5657 IN PUCHAR pMICKey);
5658
5659BOOLEAN RTMPTkipCompareMICValue(
5660 IN PRTMP_ADAPTER pAd,
5661 IN PUCHAR pSrc,
5662 IN PUCHAR pDA,
5663 IN PUCHAR pSA,
5664 IN PUCHAR pMICKey,
5665 IN UCHAR UserPriority,
5666 IN UINT Len);
5667
5668VOID RTMPCalculateMICValue(
5669 IN PRTMP_ADAPTER pAd,
5670 IN PNDIS_PACKET pPacket,
5671 IN PUCHAR pEncap,
5672 IN PCIPHER_KEY pKey,
5673 IN UCHAR apidx);
5674
5675BOOLEAN RTMPTkipCompareMICValueWithLLC(
5676 IN PRTMP_ADAPTER pAd,
5677 IN PUCHAR pLLC,
5678 IN PUCHAR pSrc,
5679 IN PUCHAR pDA,
5680 IN PUCHAR pSA,
5681 IN PUCHAR pMICKey,
5682 IN UINT Len);
5683
5684VOID RTMPTkipAppendByte(
5685 IN PTKIP_KEY_INFO pTkip,
5686 IN UCHAR uChar);
5687
5688VOID RTMPTkipAppend(
5689 IN PTKIP_KEY_INFO pTkip,
5690 IN PUCHAR pSrc,
5691 IN UINT nBytes);
5692
5693VOID RTMPTkipGetMIC(
5694 IN PTKIP_KEY_INFO pTkip);
5695
5696BOOLEAN RTMPSoftDecryptTKIP(
5697 IN PRTMP_ADAPTER pAd,
5698 IN PUCHAR pData,
5699 IN ULONG DataByteCnt,
5700 IN UCHAR UserPriority,
5701 IN PCIPHER_KEY pWpaKey);
5702
5703BOOLEAN RTMPSoftDecryptAES(
5704 IN PRTMP_ADAPTER pAd,
5705 IN PUCHAR pData,
5706 IN ULONG DataByteCnt,
5707 IN PCIPHER_KEY pWpaKey);
5708
5709//
5710// Prototypes of function definition in cmm_info.c
5711//
5712NDIS_STATUS RTMPWPARemoveKeyProc(
5713 IN PRTMP_ADAPTER pAd,
5714 IN PVOID pBuf);
5715
5716VOID RTMPWPARemoveAllKeys(
5717 IN PRTMP_ADAPTER pAd);
5718
5719BOOLEAN RTMPCheckStrPrintAble(
5720 IN CHAR *pInPutStr,
5721 IN UCHAR strLen);
5722
5723VOID RTMPSetPhyMode(
5724 IN PRTMP_ADAPTER pAd,
5725 IN ULONG phymode);
5726
5727VOID RTMPUpdateHTIE(
5728 IN RT_HT_CAPABILITY *pRtHt,
5729 IN UCHAR *pMcsSet,
5730 OUT HT_CAPABILITY_IE *pHtCapability,
5731 OUT ADD_HT_INFO_IE *pAddHtInfo);
5732
5733VOID RTMPAddWcidAttributeEntry(
5734 IN PRTMP_ADAPTER pAd,
5735 IN UCHAR BssIdx,
5736 IN UCHAR KeyIdx,
5737 IN UCHAR CipherAlg,
5738 IN MAC_TABLE_ENTRY *pEntry);
5739
5740CHAR *GetEncryptType(
5741 CHAR enc);
5742
5743CHAR *GetAuthMode(
5744 CHAR auth);
5745
5746VOID RTMPIoctlGetSiteSurvey(
5747 IN PRTMP_ADAPTER pAdapter,
5748 IN struct iwreq *wrq);
5749
5750VOID RTMPIoctlGetMacTable(
5751 IN PRTMP_ADAPTER pAd,
5752 IN struct iwreq *wrq);
5753
5754VOID RTMPIndicateWPA2Status(
5755 IN PRTMP_ADAPTER pAdapter);
5756
5757VOID RTMPOPModeSwitching(
5758 IN PRTMP_ADAPTER pAd);
5759
5760#ifdef CONFIG_STA_SUPPORT
5761VOID RTMPAddBSSIDCipher(
5762 IN PRTMP_ADAPTER pAd,
5763 IN UCHAR Aid,
5764 IN PNDIS_802_11_KEY pKey,
5765 IN UCHAR CipherAlg);
5766#endif // CONFIG_STA_SUPPORT //
5767
5768#ifdef DOT11_N_SUPPORT
5769VOID RTMPSetHT(
5770 IN PRTMP_ADAPTER pAd,
5771 IN OID_SET_HT_PHYMODE *pHTPhyMode);
5772
5773VOID RTMPSetIndividualHT(
5774 IN PRTMP_ADAPTER pAd,
5775 IN UCHAR apidx);
5776#endif // DOT11_N_SUPPORT //
5777
5778VOID RTMPSendWirelessEvent(
5779 IN PRTMP_ADAPTER pAd,
5780 IN USHORT Event_flag,
5781 IN PUCHAR pAddr,
5782 IN UCHAR BssIdx,
5783 IN CHAR Rssi);
5784
5785VOID NICUpdateCntlCounters(
5786 IN PRTMP_ADAPTER pAd,
5787 IN PHEADER_802_11 pHeader,
5788 IN UCHAR SubType,
5789 IN PRXWI_STRUC pRxWI);
5790//
5791// prototype in wpa.c
5792//
5793BOOLEAN WpaMsgTypeSubst(
5794 IN UCHAR EAPType,
5795 OUT INT *MsgType);
5796
5797VOID WpaPskStateMachineInit(
5798 IN PRTMP_ADAPTER pAd,
5799 IN STATE_MACHINE *S,
5800 OUT STATE_MACHINE_FUNC Trans[]);
5801
5802VOID WpaEAPOLKeyAction(
5803 IN PRTMP_ADAPTER pAd,
5804 IN MLME_QUEUE_ELEM *Elem);
5805
5806VOID WpaPairMsg1Action(
5807 IN PRTMP_ADAPTER pAd,
5808 IN MLME_QUEUE_ELEM *Elem);
5809
5810VOID WpaPairMsg3Action(
5811 IN PRTMP_ADAPTER pAd,
5812 IN MLME_QUEUE_ELEM *Elem);
5813
5814VOID WpaGroupMsg1Action(
5815 IN PRTMP_ADAPTER pAd,
5816 IN MLME_QUEUE_ELEM *Elem);
5817
5818VOID WpaMacHeaderInit(
5819 IN PRTMP_ADAPTER pAd,
5820 IN OUT PHEADER_802_11 pHdr80211,
5821 IN UCHAR wep,
5822 IN PUCHAR pAddr1);
5823
5824VOID Wpa2PairMsg1Action(
5825 IN PRTMP_ADAPTER pAd,
5826 IN MLME_QUEUE_ELEM *Elem);
5827
5828VOID Wpa2PairMsg3Action(
5829 IN PRTMP_ADAPTER pAd,
5830 IN MLME_QUEUE_ELEM *Elem);
5831
5832BOOLEAN ParseKeyData(
5833 IN PRTMP_ADAPTER pAd,
5834 IN PUCHAR pKeyData,
5835 IN UCHAR KeyDataLen,
5836 IN UCHAR bPairewise);
5837
5838VOID RTMPToWirelessSta(
5839 IN PRTMP_ADAPTER pAd,
5840 IN PUCHAR pHeader802_3,
5841 IN UINT HdrLen,
5842 IN PUCHAR pData,
5843 IN UINT DataLen,
5844 IN BOOLEAN is4wayFrame);
5845
5846VOID HMAC_SHA1(
5847 IN UCHAR *text,
5848 IN UINT text_len,
5849 IN UCHAR *key,
5850 IN UINT key_len,
5851 IN UCHAR *digest);
5852
5853VOID PRF(
5854 IN UCHAR *key,
5855 IN INT key_len,
5856 IN UCHAR *prefix,
5857 IN INT prefix_len,
5858 IN UCHAR *data,
5859 IN INT data_len,
5860 OUT UCHAR *output,
5861 IN INT len);
5862
5863VOID CCKMPRF(
5864 IN UCHAR *key,
5865 IN INT key_len,
5866 IN UCHAR *data,
5867 IN INT data_len,
5868 OUT UCHAR *output,
5869 IN INT len);
5870
5871VOID WpaCountPTK(
5872 IN PRTMP_ADAPTER pAd,
5873 IN UCHAR *PMK,
5874 IN UCHAR *ANonce,
5875 IN UCHAR *AA,
5876 IN UCHAR *SNonce,
5877 IN UCHAR *SA,
5878 OUT UCHAR *output,
5879 IN UINT len);
5880
5881VOID GenRandom(
5882 IN PRTMP_ADAPTER pAd,
5883 IN UCHAR *macAddr,
5884 OUT UCHAR *random);
5885
5886//
5887// prototype in aironet.c
5888//
5889VOID AironetStateMachineInit(
5890 IN PRTMP_ADAPTER pAd,
5891 IN STATE_MACHINE *S,
5892 OUT STATE_MACHINE_FUNC Trans[]);
5893
5894VOID AironetMsgAction(
5895 IN PRTMP_ADAPTER pAd,
5896 IN MLME_QUEUE_ELEM *Elem);
5897
5898VOID AironetRequestAction(
5899 IN PRTMP_ADAPTER pAd,
5900 IN MLME_QUEUE_ELEM *Elem);
5901
5902VOID ChannelLoadRequestAction(
5903 IN PRTMP_ADAPTER pAd,
5904 IN UCHAR Index);
5905
5906VOID NoiseHistRequestAction(
5907 IN PRTMP_ADAPTER pAd,
5908 IN UCHAR Index);
5909
5910VOID BeaconRequestAction(
5911 IN PRTMP_ADAPTER pAd,
5912 IN UCHAR Index);
5913
5914VOID AironetReportAction(
5915 IN PRTMP_ADAPTER pAd,
5916 IN MLME_QUEUE_ELEM *Elem);
5917
5918VOID ChannelLoadReportAction(
5919 IN PRTMP_ADAPTER pAd,
5920 IN UCHAR Index);
5921
5922VOID NoiseHistReportAction(
5923 IN PRTMP_ADAPTER pAd,
5924 IN UCHAR Index);
5925
5926VOID AironetFinalReportAction(
5927 IN PRTMP_ADAPTER pAd);
5928
5929VOID BeaconReportAction(
5930 IN PRTMP_ADAPTER pAd,
5931 IN UCHAR Index);
5932
5933VOID AironetAddBeaconReport(
5934 IN PRTMP_ADAPTER pAd,
5935 IN ULONG Index,
5936 IN PMLME_QUEUE_ELEM pElem);
5937
5938VOID AironetCreateBeaconReportFromBssTable(
5939 IN PRTMP_ADAPTER pAd);
5940
5941VOID DBGPRINT_TX_RING(
5942 IN PRTMP_ADAPTER pAd,
5943 IN UCHAR QueIdx);
5944
5945VOID DBGPRINT_RX_RING(
5946 IN PRTMP_ADAPTER pAd);
5947
5948CHAR ConvertToRssi(
5949 IN PRTMP_ADAPTER pAd,
5950 IN CHAR Rssi,
5951 IN UCHAR RssiNumber);
5952
5953
5954#ifdef DOT11N_DRAFT3
5955VOID BuildEffectedChannelList(
5956 IN PRTMP_ADAPTER pAd);
5957#endif // DOT11N_DRAFT3 //
5958
5959
5960VOID APAsicEvaluateRxAnt(
5961 IN PRTMP_ADAPTER pAd);
5962
5963
5964VOID APAsicRxAntEvalTimeout(
5965 IN PRTMP_ADAPTER pAd);
5966
5967//
5968// function prototype in cmm_wpa.c
5969//
5970BOOLEAN RTMPCheckWPAframe(
5971 IN PRTMP_ADAPTER pAd,
5972 IN PMAC_TABLE_ENTRY pEntry,
5973 IN PUCHAR pData,
5974 IN ULONG DataByteCount,
5975 IN UCHAR FromWhichBSSID);
5976
5977VOID AES_GTK_KEY_UNWRAP(
5978 IN UCHAR *key,
5979 OUT UCHAR *plaintext,
5980 IN UCHAR c_len,
5981 IN UCHAR *ciphertext);
5982
5983BOOLEAN RTMPCheckRSNIE(
5984 IN PRTMP_ADAPTER pAd,
5985 IN PUCHAR pData,
5986 IN UCHAR DataLen,
5987 IN MAC_TABLE_ENTRY *pEntry,
5988 OUT UCHAR *Offset);
5989
5990BOOLEAN RTMPParseEapolKeyData(
5991 IN PRTMP_ADAPTER pAd,
5992 IN PUCHAR pKeyData,
5993 IN UCHAR KeyDataLen,
5994 IN UCHAR GroupKeyIndex,
5995 IN UCHAR MsgType,
5996 IN BOOLEAN bWPA2,
5997 IN MAC_TABLE_ENTRY *pEntry);
5998
5999VOID ConstructEapolMsg(
6000 IN PRTMP_ADAPTER pAd,
6001 IN UCHAR PeerAuthMode,
6002 IN UCHAR PeerWepStatus,
6003 IN UCHAR MyGroupKeyWepStatus,
6004 IN UCHAR MsgType,
6005 IN UCHAR DefaultKeyIdx,
6006 IN UCHAR *ReplayCounter,
6007 IN UCHAR *KeyNonce,
6008 IN UCHAR *TxRSC,
6009 IN UCHAR *PTK,
6010 IN UCHAR *GTK,
6011 IN UCHAR *RSNIE,
6012 IN UCHAR RSNIE_Len,
6013 OUT PEAPOL_PACKET pMsg);
6014
6015VOID CalculateMIC(
6016 IN PRTMP_ADAPTER pAd,
6017 IN UCHAR PeerWepStatus,
6018 IN UCHAR *PTK,
6019 OUT PEAPOL_PACKET pMsg);
6020
6021NDIS_STATUS RTMPSoftDecryptBroadCastData(
6022 IN PRTMP_ADAPTER pAd,
6023 IN RX_BLK *pRxBlk,
6024 IN NDIS_802_11_ENCRYPTION_STATUS GroupCipher,
6025 IN PCIPHER_KEY pShard_key);
6026
6027VOID ConstructEapolKeyData(
6028 IN PRTMP_ADAPTER pAd,
6029 IN UCHAR PeerAuthMode,
6030 IN UCHAR PeerWepStatus,
6031 IN UCHAR GroupKeyWepStatus,
6032 IN UCHAR MsgType,
6033 IN UCHAR DefaultKeyIdx,
6034 IN BOOLEAN bWPA2Capable,
6035 IN UCHAR *PTK,
6036 IN UCHAR *GTK,
6037 IN UCHAR *RSNIE,
6038 IN UCHAR RSNIE_LEN,
6039 OUT PEAPOL_PACKET pMsg);
6040
6041VOID RTMPMakeRSNIE(
6042 IN PRTMP_ADAPTER pAd,
6043 IN UINT AuthMode,
6044 IN UINT WepStatus,
6045 IN UCHAR apidx);
6046
6047//
6048// function prototype in ap_wpa.c
6049//
6050
6051BOOLEAN APWpaMsgTypeSubst(
6052 IN UCHAR EAPType,
6053 OUT INT *MsgType) ;
6054
6055MAC_TABLE_ENTRY *PACInquiry(
6056 IN PRTMP_ADAPTER pAd,
6057 IN ULONG Wcid);
6058
6059BOOLEAN RTMPCheckMcast(
6060 IN PRTMP_ADAPTER pAd,
6061 IN PEID_STRUCT eid_ptr,
6062 IN MAC_TABLE_ENTRY *pEntry);
6063
6064BOOLEAN RTMPCheckUcast(
6065 IN PRTMP_ADAPTER pAd,
6066 IN PEID_STRUCT eid_ptr,
6067 IN MAC_TABLE_ENTRY *pEntry);
6068
6069BOOLEAN RTMPCheckAUTH(
6070 IN PRTMP_ADAPTER pAd,
6071 IN PEID_STRUCT eid_ptr,
6072 IN MAC_TABLE_ENTRY *pEntry);
6073
6074VOID WPAStart4WayHS(
6075 IN PRTMP_ADAPTER pAd,
6076 IN MAC_TABLE_ENTRY *pEntry,
6077 IN ULONG TimeInterval);
6078
6079VOID WPAStart2WayGroupHS(
6080 IN PRTMP_ADAPTER pAd,
6081 IN MAC_TABLE_ENTRY *pEntry);
6082
6083VOID APWpaEAPPacketAction(
6084 IN PRTMP_ADAPTER pAd,
6085 IN MLME_QUEUE_ELEM *Elem);
6086
6087VOID APWpaEAPOLStartAction(
6088 IN PRTMP_ADAPTER pAd,
6089 IN MLME_QUEUE_ELEM *Elem);
6090
6091VOID APWpaEAPOLLogoffAction(
6092 IN PRTMP_ADAPTER pAd,
6093 IN MLME_QUEUE_ELEM *Elem);
6094
6095VOID APWpaEAPOLKeyAction(
6096 IN PRTMP_ADAPTER pAd,
6097 IN MLME_QUEUE_ELEM *Elem);
6098
6099VOID APWpaEAPOLASFAlertAction(
6100 IN PRTMP_ADAPTER pAd,
6101 IN MLME_QUEUE_ELEM *Elem);
6102
6103VOID HandleCounterMeasure(
6104 IN PRTMP_ADAPTER pAd,
6105 IN MAC_TABLE_ENTRY *pEntry);
6106
6107VOID PeerPairMsg2Action(
6108 IN PRTMP_ADAPTER pAd,
6109 IN MAC_TABLE_ENTRY *pEntry,
6110 IN MLME_QUEUE_ELEM *Elem);
6111
6112VOID PeerPairMsg4Action(
6113 IN PRTMP_ADAPTER pAd,
6114 IN MAC_TABLE_ENTRY *pEntry,
6115 IN MLME_QUEUE_ELEM *Elem);
6116
6117VOID CMTimerExec(
6118 IN PVOID SystemSpecific1,
6119 IN PVOID FunctionContext,
6120 IN PVOID SystemSpecific2,
6121 IN PVOID SystemSpecific3);
6122
6123VOID WPARetryExec(
6124 IN PVOID SystemSpecific1,
6125 IN PVOID FunctionContext,
6126 IN PVOID SystemSpecific2,
6127 IN PVOID SystemSpecific3);
6128
6129VOID EnqueueStartForPSKExec(
6130 IN PVOID SystemSpecific1,
6131 IN PVOID FunctionContext,
6132 IN PVOID SystemSpecific2,
6133 IN PVOID SystemSpecific3);
6134
6135VOID RTMPHandleSTAKey(
6136 IN PRTMP_ADAPTER pAdapter,
6137 IN MAC_TABLE_ENTRY *pEntry,
6138 IN MLME_QUEUE_ELEM *Elem);
6139
6140VOID PeerGroupMsg2Action(
6141 IN PRTMP_ADAPTER pAd,
6142 IN PMAC_TABLE_ENTRY pEntry,
6143 IN VOID *Msg,
6144 IN UINT MsgLen);
6145
6146VOID PairDisAssocAction(
6147 IN PRTMP_ADAPTER pAd,
6148 IN PMAC_TABLE_ENTRY pEntry,
6149 IN USHORT Reason);
6150
6151VOID MlmeDeAuthAction(
6152 IN PRTMP_ADAPTER pAd,
6153 IN PMAC_TABLE_ENTRY pEntry,
6154 IN USHORT Reason);
6155
6156VOID GREKEYPeriodicExec(
6157 IN PVOID SystemSpecific1,
6158 IN PVOID FunctionContext,
6159 IN PVOID SystemSpecific2,
6160 IN PVOID SystemSpecific3);
6161
6162VOID CountGTK(
6163 IN UCHAR *PMK,
6164 IN UCHAR *GNonce,
6165 IN UCHAR *AA,
6166 OUT UCHAR *output,
6167 IN UINT len);
6168
6169VOID GetSmall(
6170 IN PVOID pSrc1,
6171 IN PVOID pSrc2,
6172 OUT PUCHAR out,
6173 IN ULONG Length);
6174
6175VOID GetLarge(
6176 IN PVOID pSrc1,
6177 IN PVOID pSrc2,
6178 OUT PUCHAR out,
6179 IN ULONG Length);
6180
6181VOID APGenRandom(
6182 IN PRTMP_ADAPTER pAd,
6183 OUT UCHAR *random);
6184
6185VOID AES_GTK_KEY_WRAP(
6186 IN UCHAR *key,
6187 IN UCHAR *plaintext,
6188 IN UCHAR p_len,
6189 OUT UCHAR *ciphertext);
6190
6191VOID WpaSend(
6192 IN PRTMP_ADAPTER pAdapter,
6193 IN PUCHAR pPacket,
6194 IN ULONG Len);
6195
6196VOID APToWirelessSta(
6197 IN PRTMP_ADAPTER pAd,
6198 IN MAC_TABLE_ENTRY *pEntry,
6199 IN PUCHAR pHeader802_3,
6200 IN UINT HdrLen,
6201 IN PUCHAR pData,
6202 IN UINT DataLen,
6203 IN BOOLEAN bClearFrame);
6204
6205VOID RTMPAddPMKIDCache(
6206 IN PRTMP_ADAPTER pAd,
6207 IN INT apidx,
6208 IN PUCHAR pAddr,
6209 IN UCHAR *PMKID,
6210 IN UCHAR *PMK);
6211
6212INT RTMPSearchPMKIDCache(
6213 IN PRTMP_ADAPTER pAd,
6214 IN INT apidx,
6215 IN PUCHAR pAddr);
6216
6217VOID RTMPDeletePMKIDCache(
6218 IN PRTMP_ADAPTER pAd,
6219 IN INT apidx,
6220 IN INT idx);
6221
6222VOID RTMPMaintainPMKIDCache(
6223 IN PRTMP_ADAPTER pAd);
6224
6225VOID RTMPSendTriggerFrame(
6226 IN PRTMP_ADAPTER pAd,
6227 IN PVOID pBuffer,
6228 IN ULONG Length,
6229 IN UCHAR TxRate,
6230 IN BOOLEAN bQosNull);
6231
6232#ifdef RT30xx
6233VOID RTMPFilterCalibration(
6234 IN PRTMP_ADAPTER pAd);
6235#endif // RT30xx //
6236
6237
6238//typedef void (*TIMER_FUNCTION)(unsigned long);
6239
6240
6241/* timeout -- ms */
6242VOID RTMP_SetPeriodicTimer(
6243 IN NDIS_MINIPORT_TIMER *pTimer,
6244 IN unsigned long timeout);
6245
6246VOID RTMP_OS_Init_Timer(
6247 IN PRTMP_ADAPTER pAd,
6248 IN NDIS_MINIPORT_TIMER *pTimer,
6249 IN TIMER_FUNCTION function,
6250 IN PVOID data);
6251
6252VOID RTMP_OS_Add_Timer(
6253 IN NDIS_MINIPORT_TIMER *pTimer,
6254 IN unsigned long timeout);
6255
6256VOID RTMP_OS_Mod_Timer(
6257 IN NDIS_MINIPORT_TIMER *pTimer,
6258 IN unsigned long timeout);
6259
6260
6261VOID RTMP_OS_Del_Timer(
6262 IN NDIS_MINIPORT_TIMER *pTimer,
6263 OUT BOOLEAN *pCancelled);
6264
6265
6266VOID RTMP_OS_Release_Packet(
6267 IN PRTMP_ADAPTER pAd,
6268 IN PQUEUE_ENTRY pEntry);
6269
6270VOID RTMPusecDelay(
6271 IN ULONG usec);
6272
6273NDIS_STATUS os_alloc_mem(
6274 IN PRTMP_ADAPTER pAd,
6275 OUT PUCHAR *mem,
6276 IN ULONG size);
6277
6278NDIS_STATUS os_free_mem(
6279 IN PRTMP_ADAPTER pAd,
6280 IN PUCHAR mem);
6281
6282
6283void RTMP_AllocateSharedMemory(
6284 IN PRTMP_ADAPTER pAd,
6285 IN ULONG Length,
6286 IN BOOLEAN Cached,
6287 OUT PVOID *VirtualAddress,
6288 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
6289
6290VOID RTMPFreeTxRxRingMemory(
6291 IN PRTMP_ADAPTER pAd);
6292
6293NDIS_STATUS AdapterBlockAllocateMemory(
6294 IN PVOID handle,
6295 OUT PVOID *ppAd);
6296
6297void RTMP_AllocateTxDescMemory(
6298 IN PRTMP_ADAPTER pAd,
6299 IN UINT Index,
6300 IN ULONG Length,
6301 IN BOOLEAN Cached,
6302 OUT PVOID *VirtualAddress,
6303 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
6304
6305void RTMP_AllocateFirstTxBuffer(
6306 IN PRTMP_ADAPTER pAd,
6307 IN UINT Index,
6308 IN ULONG Length,
6309 IN BOOLEAN Cached,
6310 OUT PVOID *VirtualAddress,
6311 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
6312
6313void RTMP_AllocateMgmtDescMemory(
6314 IN PRTMP_ADAPTER pAd,
6315 IN ULONG Length,
6316 IN BOOLEAN Cached,
6317 OUT PVOID *VirtualAddress,
6318 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
6319
6320void RTMP_AllocateRxDescMemory(
6321 IN PRTMP_ADAPTER pAd,
6322 IN ULONG Length,
6323 IN BOOLEAN Cached,
6324 OUT PVOID *VirtualAddress,
6325 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
6326
6327PNDIS_PACKET RTMP_AllocateRxPacketBuffer(
6328 IN PRTMP_ADAPTER pAd,
6329 IN ULONG Length,
6330 IN BOOLEAN Cached,
6331 OUT PVOID *VirtualAddress,
6332 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
6333
6334PNDIS_PACKET RTMP_AllocateTxPacketBuffer(
6335 IN PRTMP_ADAPTER pAd,
6336 IN ULONG Length,
6337 IN BOOLEAN Cached,
6338 OUT PVOID *VirtualAddress);
6339
6340PNDIS_PACKET RTMP_AllocateFragPacketBuffer(
6341 IN PRTMP_ADAPTER pAd,
6342 IN ULONG Length);
6343
6344void RTMP_QueryPacketInfo(
6345 IN PNDIS_PACKET pPacket,
6346 OUT PACKET_INFO *pPacketInfo,
6347 OUT PUCHAR *pSrcBufVA,
6348 OUT UINT *pSrcBufLen);
6349
6350void RTMP_QueryNextPacketInfo(
6351 IN PNDIS_PACKET *ppPacket,
6352 OUT PACKET_INFO *pPacketInfo,
6353 OUT PUCHAR *pSrcBufVA,
6354 OUT UINT *pSrcBufLen);
6355
6356
6357BOOLEAN RTMP_FillTxBlkInfo(
6358 IN RTMP_ADAPTER *pAd,
6359 IN TX_BLK *pTxBlk);
6360
6361
6362PRTMP_SCATTER_GATHER_LIST
6363rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg);
6364
6365
6366 void announce_802_3_packet(
6367 IN PRTMP_ADAPTER pAd,
6368 IN PNDIS_PACKET pPacket);
6369
6370
6371UINT BA_Reorder_AMSDU_Annnounce(
6372 IN PRTMP_ADAPTER pAd,
6373 IN PNDIS_PACKET pPacket);
6374
6375
6376UINT Handle_AMSDU_Packet(
6377 IN PRTMP_ADAPTER pAd,
6378 IN PUCHAR pData,
6379 IN ULONG DataSize,
6380 IN UCHAR FromWhichBSSID);
6381
6382
6383void convert_802_11_to_802_3_packet(
6384 IN PRTMP_ADAPTER pAd,
6385 IN PNDIS_PACKET pPacket,
6386 IN PUCHAR p8023hdr,
6387 IN PUCHAR pData,
6388 IN ULONG DataSize,
6389 IN UCHAR FromWhichBSSID);
6390
6391
6392PNET_DEV get_netdev_from_bssid(
6393 IN PRTMP_ADAPTER pAd,
6394 IN UCHAR FromWhichBSSID);
6395
6396
6397PNDIS_PACKET duplicate_pkt(
6398 IN PRTMP_ADAPTER pAd,
6399 IN PUCHAR pHeader802_3,
6400 IN UINT HdrLen,
6401 IN PUCHAR pData,
6402 IN ULONG DataSize,
6403 IN UCHAR FromWhichBSSID);
6404
6405
6406PNDIS_PACKET duplicate_pkt_with_TKIP_MIC(
6407 IN PRTMP_ADAPTER pAd,
6408 IN PNDIS_PACKET pOldPkt);
6409
6410PNDIS_PACKET duplicate_pkt_with_VLAN(
6411 IN PRTMP_ADAPTER pAd,
6412 IN PUCHAR pHeader802_3,
6413 IN UINT HdrLen,
6414 IN PUCHAR pData,
6415 IN ULONG DataSize,
6416 IN UCHAR FromWhichBSSID);
6417
6418PNDIS_PACKET duplicate_pkt_with_WPI(
6419 IN PRTMP_ADAPTER pAd,
6420 IN PNDIS_PACKET pPacket,
6421 IN UINT32 ext_head_len,
6422 IN UINT32 ext_tail_len);
6423
6424UCHAR VLAN_8023_Header_Copy(
6425 IN PRTMP_ADAPTER pAd,
6426 IN PUCHAR pHeader802_3,
6427 IN UINT HdrLen,
6428 OUT PUCHAR pData,
6429 IN UCHAR FromWhichBSSID);
6430
6431#ifdef DOT11_N_SUPPORT
6432void ba_flush_reordering_timeout_mpdus(
6433 IN PRTMP_ADAPTER pAd,
6434 IN PBA_REC_ENTRY pBAEntry,
6435 IN ULONG Now32);
6436
6437
6438VOID BAOriSessionSetUp(
6439 IN PRTMP_ADAPTER pAd,
6440 IN MAC_TABLE_ENTRY *pEntry,
6441 IN UCHAR TID,
6442 IN USHORT TimeOut,
6443 IN ULONG DelayTime,
6444 IN BOOLEAN isForced);
6445
6446VOID BASessionTearDownALL(
6447 IN OUT PRTMP_ADAPTER pAd,
6448 IN UCHAR Wcid);
6449#endif // DOT11_N_SUPPORT //
6450
6451BOOLEAN OS_Need_Clone_Packet(void);
6452
6453
6454VOID build_tx_packet(
6455 IN PRTMP_ADAPTER pAd,
6456 IN PNDIS_PACKET pPacket,
6457 IN PUCHAR pFrame,
6458 IN ULONG FrameLen);
6459
6460
6461VOID BAOriSessionTearDown(
6462 IN OUT PRTMP_ADAPTER pAd,
6463 IN UCHAR Wcid,
6464 IN UCHAR TID,
6465 IN BOOLEAN bPassive,
6466 IN BOOLEAN bForceSend);
6467
6468VOID BARecSessionTearDown(
6469 IN OUT PRTMP_ADAPTER pAd,
6470 IN UCHAR Wcid,
6471 IN UCHAR TID,
6472 IN BOOLEAN bPassive);
6473
6474BOOLEAN ba_reordering_resource_init(PRTMP_ADAPTER pAd, int num);
6475void ba_reordering_resource_release(PRTMP_ADAPTER pAd);
6476
6477ULONG AutoChBssInsertEntry(
6478 IN PRTMP_ADAPTER pAd,
6479 IN PUCHAR pBssid,
6480 IN CHAR Ssid[],
6481 IN UCHAR SsidLen,
6482 IN UCHAR ChannelNo,
6483 IN CHAR Rssi);
6484
6485void AutoChBssTableInit(
6486 IN PRTMP_ADAPTER pAd);
6487
6488void ChannelInfoInit(
6489 IN PRTMP_ADAPTER pAd);
6490
6491void AutoChBssTableDestroy(
6492 IN PRTMP_ADAPTER pAd);
6493
6494void ChannelInfoDestroy(
6495 IN PRTMP_ADAPTER pAd);
6496
6497UCHAR New_ApAutoSelectChannel(
6498 IN PRTMP_ADAPTER pAd);
6499
6500
6501#ifdef NINTENDO_AP
6502VOID InitNINTENDO_TABLE(
6503 IN PRTMP_ADAPTER pAd);
6504
6505UCHAR CheckNINTENDO_TABLE(
6506 IN PRTMP_ADAPTER pAd,
6507 PCHAR pDS_Ssid,
6508 UCHAR DS_SsidLen,
6509 PUCHAR pDS_Addr);
6510
6511UCHAR DelNINTENDO_ENTRY(
6512 IN PRTMP_ADAPTER pAd,
6513 UCHAR * pDS_Addr);
6514
6515VOID RTMPIoctlNintendoCapable(
6516 IN PRTMP_ADAPTER pAd,
6517 IN struct iwreq *wrq);
6518
6519VOID RTMPIoctlNintendoGetTable(
6520 IN PRTMP_ADAPTER pAd,
6521 IN struct iwreq *wrq);
6522
6523VOID RTMPIoctlNintendoSetTable(
6524 IN PRTMP_ADAPTER pAd,
6525 IN struct iwreq *wrq);
6526
6527#endif // NINTENDO_AP //
6528
6529BOOLEAN rtstrmactohex(
6530 IN char *s1,
6531 IN char *s2);
6532
6533BOOLEAN rtstrcasecmp(
6534 IN char *s1,
6535 IN char *s2);
6536
6537char *rtstrstruncasecmp(
6538 IN char *s1,
6539 IN char *s2);
6540
6541char *rtstrstr(
6542 IN const char * s1,
6543 IN const char * s2);
6544
6545char *rstrtok(
6546 IN char * s,
6547 IN const char * ct);
6548
6549int rtinet_aton(
6550 const char *cp,
6551 unsigned int *addr);
6552
6553////////// common ioctl functions //////////
6554INT Set_DriverVersion_Proc(
6555 IN PRTMP_ADAPTER pAd,
6556 IN PUCHAR arg);
6557
6558INT Set_CountryRegion_Proc(
6559 IN PRTMP_ADAPTER pAd,
6560 IN PUCHAR arg);
6561
6562INT Set_CountryRegionABand_Proc(
6563 IN PRTMP_ADAPTER pAd,
6564 IN PUCHAR arg);
6565
6566INT Set_WirelessMode_Proc(
6567 IN PRTMP_ADAPTER pAd,
6568 IN PUCHAR arg);
6569
6570INT Set_Channel_Proc(
6571 IN PRTMP_ADAPTER pAd,
6572 IN PUCHAR arg);
6573
6574INT Set_ShortSlot_Proc(
6575 IN PRTMP_ADAPTER pAd,
6576 IN PUCHAR arg);
6577
6578INT Set_TxPower_Proc(
6579 IN PRTMP_ADAPTER pAd,
6580 IN PUCHAR arg);
6581
6582INT Set_BGProtection_Proc(
6583 IN PRTMP_ADAPTER pAd,
6584 IN PUCHAR arg);
6585
6586INT Set_TxPreamble_Proc(
6587 IN PRTMP_ADAPTER pAd,
6588 IN PUCHAR arg);
6589
6590INT Set_RTSThreshold_Proc(
6591 IN PRTMP_ADAPTER pAd,
6592 IN PUCHAR arg);
6593
6594INT Set_FragThreshold_Proc(
6595 IN PRTMP_ADAPTER pAd,
6596 IN PUCHAR arg);
6597
6598INT Set_TxBurst_Proc(
6599 IN PRTMP_ADAPTER pAd,
6600 IN PUCHAR arg);
6601
6602#ifdef AGGREGATION_SUPPORT
6603INT Set_PktAggregate_Proc(
6604 IN PRTMP_ADAPTER pAd,
6605 IN PUCHAR arg);
6606#endif
6607
6608INT Set_IEEE80211H_Proc(
6609 IN PRTMP_ADAPTER pAd,
6610 IN PUCHAR arg);
6611
6612#ifdef DBG
6613INT Set_Debug_Proc(
6614 IN PRTMP_ADAPTER pAd,
6615 IN PUCHAR arg);
6616#endif
6617
6618INT Show_DescInfo_Proc(
6619 IN PRTMP_ADAPTER pAd,
6620 IN PUCHAR arg);
6621
6622INT Set_ResetStatCounter_Proc(
6623 IN PRTMP_ADAPTER pAd,
6624 IN PUCHAR arg);
6625
6626#ifdef DOT11_N_SUPPORT
6627INT Set_BASetup_Proc(
6628 IN PRTMP_ADAPTER pAd,
6629 IN PUCHAR arg);
6630
6631INT Set_BADecline_Proc(
6632 IN PRTMP_ADAPTER pAd,
6633 IN PUCHAR arg);
6634
6635INT Set_BAOriTearDown_Proc(
6636 IN PRTMP_ADAPTER pAd,
6637 IN PUCHAR arg);
6638
6639INT Set_BARecTearDown_Proc(
6640 IN PRTMP_ADAPTER pAd,
6641 IN PUCHAR arg);
6642
6643INT Set_HtBw_Proc(
6644 IN PRTMP_ADAPTER pAd,
6645 IN PUCHAR arg);
6646
6647INT Set_HtMcs_Proc(
6648 IN PRTMP_ADAPTER pAd,
6649 IN PUCHAR arg);
6650
6651INT Set_HtGi_Proc(
6652 IN PRTMP_ADAPTER pAd,
6653 IN PUCHAR arg);
6654
6655INT Set_HtOpMode_Proc(
6656 IN PRTMP_ADAPTER pAd,
6657 IN PUCHAR arg);
6658
6659INT Set_HtStbc_Proc(
6660 IN PRTMP_ADAPTER pAd,
6661 IN PUCHAR arg);
6662
6663INT Set_HtHtc_Proc(
6664 IN PRTMP_ADAPTER pAd,
6665 IN PUCHAR arg);
6666
6667INT Set_HtExtcha_Proc(
6668 IN PRTMP_ADAPTER pAd,
6669 IN PUCHAR arg);
6670
6671INT Set_HtMpduDensity_Proc(
6672 IN PRTMP_ADAPTER pAd,
6673 IN PUCHAR arg);
6674
6675INT Set_HtBaWinSize_Proc(
6676 IN PRTMP_ADAPTER pAd,
6677 IN PUCHAR arg);
6678
6679INT Set_HtRdg_Proc(
6680 IN PRTMP_ADAPTER pAd,
6681 IN PUCHAR arg);
6682
6683INT Set_HtLinkAdapt_Proc(
6684 IN PRTMP_ADAPTER pAd,
6685 IN PUCHAR arg);
6686
6687INT Set_HtAmsdu_Proc(
6688 IN PRTMP_ADAPTER pAd,
6689 IN PUCHAR arg);
6690
6691INT Set_HtAutoBa_Proc(
6692 IN PRTMP_ADAPTER pAd,
6693 IN PUCHAR arg);
6694
6695INT Set_HtProtect_Proc(
6696 IN PRTMP_ADAPTER pAd,
6697 IN PUCHAR arg);
6698
6699INT Set_HtMimoPs_Proc(
6700 IN PRTMP_ADAPTER pAd,
6701 IN PUCHAR arg);
6702
6703
6704INT Set_ForceShortGI_Proc(
6705 IN PRTMP_ADAPTER pAd,
6706 IN PUCHAR arg);
6707
6708INT Set_ForceGF_Proc(
6709 IN PRTMP_ADAPTER pAd,
6710 IN PUCHAR arg);
6711
6712INT SetCommonHT(
6713 IN PRTMP_ADAPTER pAd);
6714
6715INT Set_SendPSMPAction_Proc(
6716 IN PRTMP_ADAPTER pAd,
6717 IN PUCHAR arg);
6718
6719INT Set_HtMIMOPSmode_Proc(
6720 IN PRTMP_ADAPTER pAd,
6721 IN PUCHAR arg);
6722
6723
6724INT Set_HtTxBASize_Proc(
6725 IN PRTMP_ADAPTER pAd,
6726 IN PUCHAR arg);
6727#endif // DOT11_N_SUPPORT //
6728
6729
6730
6731#ifdef CONFIG_STA_SUPPORT
6732//Dls , kathy
6733VOID RTMPSendDLSTearDownFrame(
6734 IN PRTMP_ADAPTER pAd,
6735 IN PUCHAR pDA);
6736
6737#ifdef DOT11_N_SUPPORT
6738//Block ACK
6739VOID QueryBATABLE(
6740 IN PRTMP_ADAPTER pAd,
6741 OUT PQUERYBA_TABLE pBAT);
6742#endif // DOT11_N_SUPPORT //
6743
6744#ifdef WPA_SUPPLICANT_SUPPORT
6745INT WpaCheckEapCode(
6746 IN PRTMP_ADAPTER pAd,
6747 IN PUCHAR pFrame,
6748 IN USHORT FrameLen,
6749 IN USHORT OffSet);
6750
6751VOID WpaSendMicFailureToWpaSupplicant(
6752 IN PRTMP_ADAPTER pAd,
6753 IN BOOLEAN bUnicast);
6754
6755VOID SendAssocIEsToWpaSupplicant(
6756 IN PRTMP_ADAPTER pAd);
6757#endif // WPA_SUPPLICANT_SUPPORT //
6758
6759#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
6760int wext_notify_event_assoc(
6761 IN RTMP_ADAPTER *pAd);
6762#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
6763
6764#endif // CONFIG_STA_SUPPORT //
6765
6766
6767
6768#ifdef DOT11_N_SUPPORT
6769VOID Handle_BSS_Width_Trigger_Events(
6770 IN PRTMP_ADAPTER pAd);
6771
6772void build_ext_channel_switch_ie(
6773 IN PRTMP_ADAPTER pAd,
6774 IN HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE *pIE);
6775#endif // DOT11_N_SUPPORT //
6776
6777
6778BOOLEAN APRxDoneInterruptHandle(
6779 IN PRTMP_ADAPTER pAd);
6780
6781BOOLEAN STARxDoneInterruptHandle(
6782 IN PRTMP_ADAPTER pAd,
6783 IN BOOLEAN argc);
6784
6785#ifdef DOT11_N_SUPPORT
6786// AMPDU packet indication
6787VOID Indicate_AMPDU_Packet(
6788 IN PRTMP_ADAPTER pAd,
6789 IN RX_BLK *pRxBlk,
6790 IN UCHAR FromWhichBSSID);
6791
6792// AMSDU packet indication
6793VOID Indicate_AMSDU_Packet(
6794 IN PRTMP_ADAPTER pAd,
6795 IN RX_BLK *pRxBlk,
6796 IN UCHAR FromWhichBSSID);
6797#endif // DOT11_N_SUPPORT //
6798
6799// Normal legacy Rx packet indication
6800VOID Indicate_Legacy_Packet(
6801 IN PRTMP_ADAPTER pAd,
6802 IN RX_BLK *pRxBlk,
6803 IN UCHAR FromWhichBSSID);
6804
6805VOID Indicate_EAPOL_Packet(
6806 IN PRTMP_ADAPTER pAd,
6807 IN RX_BLK *pRxBlk,
6808 IN UCHAR FromWhichBSSID);
6809
6810void update_os_packet_info(
6811 IN PRTMP_ADAPTER pAd,
6812 IN RX_BLK *pRxBlk,
6813 IN UCHAR FromWhichBSSID);
6814
6815void wlan_802_11_to_802_3_packet(
6816 IN PRTMP_ADAPTER pAd,
6817 IN RX_BLK *pRxBlk,
6818 IN PUCHAR pHeader802_3,
6819 IN UCHAR FromWhichBSSID);
6820
6821UINT deaggregate_AMSDU_announce(
6822 IN PRTMP_ADAPTER pAd,
6823 PNDIS_PACKET pPacket,
6824 IN PUCHAR pData,
6825 IN ULONG DataSize);
6826
6827
6828#ifdef CONFIG_STA_SUPPORT
6829// remove LLC and get 802_3 Header
6830#define RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(_pRxBlk, _pHeader802_3) \
6831{ \
6832 PUCHAR _pRemovedLLCSNAP = NULL, _pDA, _pSA; \
6833 \
6834 if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_MESH)) \
6835 { \
6836 _pDA = _pRxBlk->pHeader->Addr3; \
6837 _pSA = (PUCHAR)_pRxBlk->pHeader + sizeof(HEADER_802_11); \
6838 } \
6839 else \
6840 { \
6841 if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_INFRA)) \
6842 { \
6843 _pDA = _pRxBlk->pHeader->Addr1; \
6844 if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_DLS)) \
6845 _pSA = _pRxBlk->pHeader->Addr2; \
6846 else \
6847 _pSA = _pRxBlk->pHeader->Addr3; \
6848 } \
6849 else \
6850 { \
6851 _pDA = _pRxBlk->pHeader->Addr1; \
6852 _pSA = _pRxBlk->pHeader->Addr2; \
6853 } \
6854 } \
6855 \
6856 CONVERT_TO_802_3(_pHeader802_3, _pDA, _pSA, _pRxBlk->pData, \
6857 _pRxBlk->DataSize, _pRemovedLLCSNAP); \
6858}
6859#endif // CONFIG_STA_SUPPORT //
6860
6861
6862BOOLEAN APFowardWirelessStaToWirelessSta(
6863 IN PRTMP_ADAPTER pAd,
6864 IN PNDIS_PACKET pPacket,
6865 IN ULONG FromWhichBSSID);
6866
6867VOID Announce_or_Forward_802_3_Packet(
6868 IN PRTMP_ADAPTER pAd,
6869 IN PNDIS_PACKET pPacket,
6870 IN UCHAR FromWhichBSSID);
6871
6872VOID Sta_Announce_or_Forward_802_3_Packet(
6873 IN PRTMP_ADAPTER pAd,
6874 IN PNDIS_PACKET pPacket,
6875 IN UCHAR FromWhichBSSID);
6876
6877
6878#ifdef CONFIG_STA_SUPPORT
6879#define ANNOUNCE_OR_FORWARD_802_3_PACKET(_pAd, _pPacket, _FromWhichBSS)\
6880 Sta_Announce_or_Forward_802_3_Packet(_pAd, _pPacket, _FromWhichBSS);
6881 //announce_802_3_packet(_pAd, _pPacket);
6882#endif // CONFIG_STA_SUPPORT //
6883
6884
6885PNDIS_PACKET DuplicatePacket(
6886 IN PRTMP_ADAPTER pAd,
6887 IN PNDIS_PACKET pPacket,
6888 IN UCHAR FromWhichBSSID);
6889
6890
6891PNDIS_PACKET ClonePacket(
6892 IN PRTMP_ADAPTER pAd,
6893 IN PNDIS_PACKET pPacket,
6894 IN PUCHAR pData,
6895 IN ULONG DataSize);
6896
6897
6898// Normal, AMPDU or AMSDU
6899VOID CmmRxnonRalinkFrameIndicate(
6900 IN PRTMP_ADAPTER pAd,
6901 IN RX_BLK *pRxBlk,
6902 IN UCHAR FromWhichBSSID);
6903
6904VOID CmmRxRalinkFrameIndicate(
6905 IN PRTMP_ADAPTER pAd,
6906 IN MAC_TABLE_ENTRY *pEntry,
6907 IN RX_BLK *pRxBlk,
6908 IN UCHAR FromWhichBSSID);
6909
6910VOID Update_Rssi_Sample(
6911 IN PRTMP_ADAPTER pAd,
6912 IN RSSI_SAMPLE *pRssi,
6913 IN PRXWI_STRUC pRxWI);
6914
6915PNDIS_PACKET GetPacketFromRxRing(
6916 IN PRTMP_ADAPTER pAd,
6917 OUT PRT28XX_RXD_STRUC pSaveRxD,
6918 OUT BOOLEAN *pbReschedule,
6919 IN OUT UINT32 *pRxPending);
6920
6921PNDIS_PACKET RTMPDeFragmentDataFrame(
6922 IN PRTMP_ADAPTER pAd,
6923 IN RX_BLK *pRxBlk);
6924
6925////////////////////////////////////////
6926
6927
6928
6929
6930
6931#ifdef SNMP_SUPPORT
6932//for snmp , kathy
6933typedef struct _DefaultKeyIdxValue
6934{
6935 UCHAR KeyIdx;
6936 UCHAR Value[16];
6937} DefaultKeyIdxValue, *PDefaultKeyIdxValue;
6938#endif
6939
6940
6941#ifdef CONFIG_STA_SUPPORT
6942enum {
6943 DIDmsg_lnxind_wlansniffrm = 0x00000044,
6944 DIDmsg_lnxind_wlansniffrm_hosttime = 0x00010044,
6945 DIDmsg_lnxind_wlansniffrm_mactime = 0x00020044,
6946 DIDmsg_lnxind_wlansniffrm_channel = 0x00030044,
6947 DIDmsg_lnxind_wlansniffrm_rssi = 0x00040044,
6948 DIDmsg_lnxind_wlansniffrm_sq = 0x00050044,
6949 DIDmsg_lnxind_wlansniffrm_signal = 0x00060044,
6950 DIDmsg_lnxind_wlansniffrm_noise = 0x00070044,
6951 DIDmsg_lnxind_wlansniffrm_rate = 0x00080044,
6952 DIDmsg_lnxind_wlansniffrm_istx = 0x00090044,
6953 DIDmsg_lnxind_wlansniffrm_frmlen = 0x000A0044
6954};
6955enum {
6956 P80211ENUM_msgitem_status_no_value = 0x00
6957};
6958enum {
6959 P80211ENUM_truth_false = 0x00,
6960 P80211ENUM_truth_true = 0x01
6961};
6962
6963/* Definition from madwifi */
6964typedef struct {
6965 UINT32 did;
6966 UINT16 status;
6967 UINT16 len;
6968 UINT32 data;
6969} p80211item_uint32_t;
6970
6971typedef struct {
6972 UINT32 msgcode;
6973 UINT32 msglen;
6974#define WLAN_DEVNAMELEN_MAX 16
6975 UINT8 devname[WLAN_DEVNAMELEN_MAX];
6976 p80211item_uint32_t hosttime;
6977 p80211item_uint32_t mactime;
6978 p80211item_uint32_t channel;
6979 p80211item_uint32_t rssi;
6980 p80211item_uint32_t sq;
6981 p80211item_uint32_t signal;
6982 p80211item_uint32_t noise;
6983 p80211item_uint32_t rate;
6984 p80211item_uint32_t istx;
6985 p80211item_uint32_t frmlen;
6986} wlan_ng_prism2_header;
6987
6988/* The radio capture header precedes the 802.11 header. */
6989typedef struct PACKED _ieee80211_radiotap_header {
6990 UINT8 it_version; /* Version 0. Only increases
6991 * for drastic changes,
6992 * introduction of compatible
6993 * new fields does not count.
6994 */
6995 UINT8 it_pad;
6996 UINT16 it_len; /* length of the whole
6997 * header in bytes, including
6998 * it_version, it_pad,
6999 * it_len, and data fields.
7000 */
7001 UINT32 it_present; /* A bitmap telling which
7002 * fields are present. Set bit 31
7003 * (0x80000000) to extend the
7004 * bitmap by another 32 bits.
7005 * Additional extensions are made
7006 * by setting bit 31.
7007 */
7008}ieee80211_radiotap_header ;
7009
7010enum ieee80211_radiotap_type {
7011 IEEE80211_RADIOTAP_TSFT = 0,
7012 IEEE80211_RADIOTAP_FLAGS = 1,
7013 IEEE80211_RADIOTAP_RATE = 2,
7014 IEEE80211_RADIOTAP_CHANNEL = 3,
7015 IEEE80211_RADIOTAP_FHSS = 4,
7016 IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
7017 IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
7018 IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
7019 IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
7020 IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
7021 IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
7022 IEEE80211_RADIOTAP_ANTENNA = 11,
7023 IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
7024 IEEE80211_RADIOTAP_DB_ANTNOISE = 13
7025};
7026
7027#define WLAN_RADIOTAP_PRESENT ( \
7028 (1 << IEEE80211_RADIOTAP_TSFT) | \
7029 (1 << IEEE80211_RADIOTAP_FLAGS) | \
7030 (1 << IEEE80211_RADIOTAP_RATE) | \
7031 0)
7032
7033typedef struct _wlan_radiotap_header {
7034 ieee80211_radiotap_header wt_ihdr;
7035 INT64 wt_tsft;
7036 UINT8 wt_flags;
7037 UINT8 wt_rate;
7038} wlan_radiotap_header;
7039/* Definition from madwifi */
7040
7041void send_monitor_packets(
7042 IN PRTMP_ADAPTER pAd,
7043 IN RX_BLK *pRxBlk);
7044
7045#if WIRELESS_EXT >= 12
7046// This function will be called when query /proc
7047struct iw_statistics *rt28xx_get_wireless_stats(
7048 IN struct net_device *net_dev);
7049#endif
7050
7051VOID RTMPSetDesiredRates(
7052 IN PRTMP_ADAPTER pAdapter,
7053 IN LONG Rates);
7054#endif // CONFIG_STA_SUPPORT //
7055
7056INT Set_FixedTxMode_Proc(
7057 IN PRTMP_ADAPTER pAd,
7058 IN PUCHAR arg);
7059
7060#ifdef CONFIG_APSTA_MIXED_SUPPORT
7061INT Set_OpMode_Proc(
7062 IN PRTMP_ADAPTER pAd,
7063 IN PUCHAR arg);
7064#endif // CONFIG_APSTA_MIXED_SUPPORT //
7065
7066static inline char* GetPhyMode(
7067 int Mode)
7068{
7069 switch(Mode)
7070 {
7071 case MODE_CCK:
7072 return "CCK";
7073
7074 case MODE_OFDM:
7075 return "OFDM";
7076#ifdef DOT11_N_SUPPORT
7077 case MODE_HTMIX:
7078 return "HTMIX";
7079
7080 case MODE_HTGREENFIELD:
7081 return "GREEN";
7082#endif // DOT11_N_SUPPORT //
7083 default:
7084 return "N/A";
7085 }
7086}
7087
7088
7089static inline char* GetBW(
7090 int BW)
7091{
7092 switch(BW)
7093 {
7094 case BW_10:
7095 return "10M";
7096
7097 case BW_20:
7098 return "20M";
7099#ifdef DOT11_N_SUPPORT
7100 case BW_40:
7101 return "40M";
7102#endif // DOT11_N_SUPPORT //
7103 default:
7104 return "N/A";
7105 }
7106}
7107
7108
7109VOID RT28xxThreadTerminate(
7110 IN RTMP_ADAPTER *pAd);
7111
7112BOOLEAN RT28XXChipsetCheck(
7113 IN void *_dev_p);
7114
7115BOOLEAN RT28XXNetDevInit(
7116 IN void *_dev_p,
7117 IN struct net_device *net_dev,
7118 IN RTMP_ADAPTER *pAd);
7119
7120BOOLEAN RT28XXProbePostConfig(
7121 IN void *_dev_p,
7122 IN RTMP_ADAPTER *pAd,
7123 IN INT32 argc);
7124
7125VOID RT28XXDMADisable(
7126 IN RTMP_ADAPTER *pAd);
7127
7128VOID RT28XXDMAEnable(
7129 IN RTMP_ADAPTER *pAd);
7130
7131VOID RT28xx_UpdateBeaconToAsic(
7132 IN RTMP_ADAPTER * pAd,
7133 IN INT apidx,
7134 IN ULONG BeaconLen,
7135 IN ULONG UpdatePos);
7136
7137INT rt28xx_ioctl(
7138 IN struct net_device *net_dev,
7139 IN OUT struct ifreq *rq,
7140 IN INT cmd);
7141
7142
7143#ifdef CONFIG_STA_SUPPORT
7144INT rt28xx_sta_ioctl(
7145 IN struct net_device *net_dev,
7146 IN OUT struct ifreq *rq,
7147 IN INT cmd);
7148#endif // CONFIG_STA_SUPPORT //
7149
7150BOOLEAN RT28XXSecurityKeyAdd(
7151 IN PRTMP_ADAPTER pAd,
7152 IN ULONG apidx,
7153 IN ULONG KeyIdx,
7154 IN MAC_TABLE_ENTRY *pEntry);
7155
7156////////////////////////////////////////
7157PNDIS_PACKET GetPacketFromRxRing(
7158 IN PRTMP_ADAPTER pAd,
7159 OUT PRT28XX_RXD_STRUC pSaveRxD,
7160 OUT BOOLEAN *pbReschedule,
7161 IN OUT UINT32 *pRxPending);
7162
7163
7164void kill_thread_task(PRTMP_ADAPTER pAd);
7165
7166void tbtt_tasklet(unsigned long data);
7167
7168
7169VOID AsicTurnOffRFClk(
7170 IN PRTMP_ADAPTER pAd,
7171 IN UCHAR Channel);
7172
7173VOID AsicTurnOnRFClk(
7174 IN PRTMP_ADAPTER pAd,
7175 IN UCHAR Channel);
7176
7177#ifdef RT30xx
7178NTSTATUS RT30xxWriteRFRegister(
7179 IN PRTMP_ADAPTER pAd,
7180 IN UCHAR RegID,
7181 IN UCHAR Value);
7182
7183NTSTATUS RT30xxReadRFRegister(
7184 IN PRTMP_ADAPTER pAd,
7185 IN UCHAR RegID,
7186 IN PUCHAR pValue);
7187
7188//2008/09/11:KH add to support efuse<--
7189UCHAR eFuseReadRegisters(
7190 IN PRTMP_ADAPTER pAd,
7191 IN USHORT Offset,
7192 IN USHORT Length,
7193 OUT USHORT* pData);
7194
7195VOID eFuseReadPhysical(
7196 IN PRTMP_ADAPTER pAd,
7197 IN PUSHORT lpInBuffer,
7198 IN ULONG nInBufferSize,
7199 OUT PUSHORT lpOutBuffer,
7200 IN ULONG nOutBufferSize
7201);
7202
7203NTSTATUS eFuseRead(
7204 IN PRTMP_ADAPTER pAd,
7205 IN USHORT Offset,
7206 OUT PUCHAR pData,
7207 IN USHORT Length);
7208
7209VOID eFusePhysicalWriteRegisters(
7210 IN PRTMP_ADAPTER pAd,
7211 IN USHORT Offset,
7212 IN USHORT Length,
7213 OUT USHORT* pData);
7214
7215NTSTATUS eFuseWriteRegisters(
7216 IN PRTMP_ADAPTER pAd,
7217 IN USHORT Offset,
7218 IN USHORT Length,
7219 IN USHORT* pData);
7220
7221VOID eFuseWritePhysical(
7222 IN PRTMP_ADAPTER pAd,
7223 PUSHORT lpInBuffer,
7224 ULONG nInBufferSize,
7225 PUCHAR lpOutBuffer,
7226 ULONG nOutBufferSize
7227);
7228
7229NTSTATUS eFuseWrite(
7230 IN PRTMP_ADAPTER pAd,
7231 IN USHORT Offset,
7232 IN PUCHAR pData,
7233 IN USHORT length);
7234
7235INT set_eFuseGetFreeBlockCount_Proc(
7236 IN PRTMP_ADAPTER pAd,
7237 IN PUCHAR arg);
7238
7239INT set_eFusedump_Proc(
7240 IN PRTMP_ADAPTER pAd,
7241 IN PUCHAR arg);
7242
7243INT set_eFuseLoadFromBin_Proc(
7244 IN PRTMP_ADAPTER pAd,
7245 IN PUCHAR arg);
7246
7247NTSTATUS eFuseWriteRegistersFromBin(
7248 IN PRTMP_ADAPTER pAd,
7249 IN USHORT Offset,
7250 IN USHORT Length,
7251 IN USHORT* pData);
7252
7253VOID eFusePhysicalReadRegisters(
7254 IN PRTMP_ADAPTER pAd,
7255 IN USHORT Offset,
7256 IN USHORT Length,
7257 OUT USHORT* pData);
7258
7259NDIS_STATUS NICLoadEEPROM(
7260 IN PRTMP_ADAPTER pAd);
7261
7262BOOLEAN bNeedLoadEEPROM(
7263 IN PRTMP_ADAPTER pAd);
7264//2008/09/11:KH add to support efuse-->
7265#endif // RT30xx //
7266
7267#ifdef RT30xx
7268// add by johnli, RF power sequence setup
7269VOID RT30xxLoadRFNormalModeSetup(
7270 IN PRTMP_ADAPTER pAd);
7271
7272VOID RT30xxLoadRFSleepModeSetup(
7273 IN PRTMP_ADAPTER pAd);
7274
7275VOID RT30xxReverseRFSleepModeSetup(
7276 IN PRTMP_ADAPTER pAd);
7277// end johnli
7278#endif // RT30xx //
7279
7280#ifdef RT2870
7281//
7282// Function Prototype in rtusb_bulk.c
7283//
7284VOID RTUSBInitTxDesc(
7285 IN PRTMP_ADAPTER pAd,
7286 IN PTX_CONTEXT pTxContext,
7287 IN UCHAR BulkOutPipeId,
7288 IN usb_complete_t Func);
7289
7290VOID RTUSBInitHTTxDesc(
7291 IN PRTMP_ADAPTER pAd,
7292 IN PHT_TX_CONTEXT pTxContext,
7293 IN UCHAR BulkOutPipeId,
7294 IN ULONG BulkOutSize,
7295 IN usb_complete_t Func);
7296
7297VOID RTUSBInitRxDesc(
7298 IN PRTMP_ADAPTER pAd,
7299 IN PRX_CONTEXT pRxContext);
7300
7301VOID RTUSBCleanUpDataBulkOutQueue(
7302 IN PRTMP_ADAPTER pAd);
7303
7304VOID RTUSBCancelPendingBulkOutIRP(
7305 IN PRTMP_ADAPTER pAd);
7306
7307VOID RTUSBBulkOutDataPacket(
7308 IN PRTMP_ADAPTER pAd,
7309 IN UCHAR BulkOutPipeId,
7310 IN UCHAR Index);
7311
7312VOID RTUSBBulkOutNullFrame(
7313 IN PRTMP_ADAPTER pAd);
7314
7315VOID RTUSBBulkOutRTSFrame(
7316 IN PRTMP_ADAPTER pAd);
7317
7318VOID RTUSBCancelPendingBulkInIRP(
7319 IN PRTMP_ADAPTER pAd);
7320
7321VOID RTUSBCancelPendingIRPs(
7322 IN PRTMP_ADAPTER pAd);
7323
7324VOID RTUSBBulkOutMLMEPacket(
7325 IN PRTMP_ADAPTER pAd,
7326 IN UCHAR Index);
7327
7328VOID RTUSBBulkOutPsPoll(
7329 IN PRTMP_ADAPTER pAd);
7330
7331VOID RTUSBCleanUpMLMEBulkOutQueue(
7332 IN PRTMP_ADAPTER pAd);
7333
7334VOID RTUSBKickBulkOut(
7335 IN PRTMP_ADAPTER pAd);
7336
7337VOID RTUSBBulkReceive(
7338 IN PRTMP_ADAPTER pAd);
7339
7340VOID DoBulkIn(
7341 IN RTMP_ADAPTER *pAd);
7342
7343VOID RTUSBInitRxDesc(
7344 IN PRTMP_ADAPTER pAd,
7345 IN PRX_CONTEXT pRxContext);
7346
7347VOID RTUSBBulkRxHandle(
7348 IN unsigned long data);
7349
7350//
7351// Function Prototype in rtusb_io.c
7352//
7353NTSTATUS RTUSBMultiRead(
7354 IN PRTMP_ADAPTER pAd,
7355 IN USHORT Offset,
7356 OUT PUCHAR pData,
7357 IN USHORT length);
7358
7359NTSTATUS RTUSBMultiWrite(
7360 IN PRTMP_ADAPTER pAd,
7361 IN USHORT Offset,
7362 IN PUCHAR pData,
7363 IN USHORT length);
7364
7365NTSTATUS RTUSBMultiWrite_OneByte(
7366 IN PRTMP_ADAPTER pAd,
7367 IN USHORT Offset,
7368 IN PUCHAR pData);
7369
7370NTSTATUS RTUSBReadBBPRegister(
7371 IN PRTMP_ADAPTER pAd,
7372 IN UCHAR Id,
7373 IN PUCHAR pValue);
7374
7375NTSTATUS RTUSBWriteBBPRegister(
7376 IN PRTMP_ADAPTER pAd,
7377 IN UCHAR Id,
7378 IN UCHAR Value);
7379
7380NTSTATUS RTUSBWriteRFRegister(
7381 IN PRTMP_ADAPTER pAd,
7382 IN UINT32 Value);
7383
7384NTSTATUS RTUSB_VendorRequest(
7385 IN PRTMP_ADAPTER pAd,
7386 IN UINT32 TransferFlags,
7387 IN UCHAR ReservedBits,
7388 IN UCHAR Request,
7389 IN USHORT Value,
7390 IN USHORT Index,
7391 IN PVOID TransferBuffer,
7392 IN UINT32 TransferBufferLength);
7393
7394NTSTATUS RTUSBReadEEPROM(
7395 IN PRTMP_ADAPTER pAd,
7396 IN USHORT Offset,
7397 OUT PUCHAR pData,
7398 IN USHORT length);
7399
7400NTSTATUS RTUSBWriteEEPROM(
7401 IN PRTMP_ADAPTER pAd,
7402 IN USHORT Offset,
7403 IN PUCHAR pData,
7404 IN USHORT length);
7405
7406VOID RTUSBPutToSleep(
7407 IN PRTMP_ADAPTER pAd);
7408
7409NTSTATUS RTUSBWakeUp(
7410 IN PRTMP_ADAPTER pAd);
7411
7412VOID RTUSBInitializeCmdQ(
7413 IN PCmdQ cmdq);
7414
7415NDIS_STATUS RTUSBEnqueueCmdFromNdis(
7416 IN PRTMP_ADAPTER pAd,
7417 IN NDIS_OID Oid,
7418 IN BOOLEAN SetInformation,
7419 IN PVOID pInformationBuffer,
7420 IN UINT32 InformationBufferLength);
7421
7422NDIS_STATUS RTUSBEnqueueInternalCmd(
7423 IN PRTMP_ADAPTER pAd,
7424 IN NDIS_OID Oid,
7425 IN PVOID pInformationBuffer,
7426 IN UINT32 InformationBufferLength);
7427
7428VOID RTUSBDequeueCmd(
7429 IN PCmdQ cmdq,
7430 OUT PCmdQElmt *pcmdqelmt);
7431
7432INT RTUSBCmdThread(
7433 IN OUT PVOID Context);
7434
7435INT TimerQThread(
7436 IN OUT PVOID Context);
7437
7438RT2870_TIMER_ENTRY *RT2870_TimerQ_Insert(
7439 IN RTMP_ADAPTER *pAd,
7440 IN RALINK_TIMER_STRUCT *pTimer);
7441
7442BOOLEAN RT2870_TimerQ_Remove(
7443 IN RTMP_ADAPTER *pAd,
7444 IN RALINK_TIMER_STRUCT *pTimer);
7445
7446void RT2870_TimerQ_Exit(
7447 IN RTMP_ADAPTER *pAd);
7448
7449void RT2870_TimerQ_Init(
7450 IN RTMP_ADAPTER *pAd);
7451
7452VOID RT2870_BssBeaconExit(
7453 IN RTMP_ADAPTER *pAd);
7454
7455VOID RT2870_BssBeaconStop(
7456 IN RTMP_ADAPTER *pAd);
7457
7458VOID RT2870_BssBeaconStart(
7459 IN RTMP_ADAPTER * pAd);
7460
7461VOID RT2870_BssBeaconInit(
7462 IN RTMP_ADAPTER *pAd);
7463
7464VOID RT2870_WatchDog(
7465 IN RTMP_ADAPTER *pAd);
7466
7467NTSTATUS RTUSBWriteMACRegister(
7468 IN PRTMP_ADAPTER pAd,
7469 IN USHORT Offset,
7470 IN UINT32 Value);
7471
7472NTSTATUS RTUSBReadMACRegister(
7473 IN PRTMP_ADAPTER pAd,
7474 IN USHORT Offset,
7475 OUT PUINT32 pValue);
7476
7477NTSTATUS RTUSBSingleWrite(
7478 IN RTMP_ADAPTER *pAd,
7479 IN USHORT Offset,
7480 IN USHORT Value);
7481
7482NTSTATUS RTUSBFirmwareRun(
7483 IN PRTMP_ADAPTER pAd);
7484
7485NTSTATUS RTUSBFirmwareWrite(
7486 IN PRTMP_ADAPTER pAd,
7487 IN PUCHAR pFwImage,
7488 IN ULONG FwLen);
7489
7490NTSTATUS RTUSBFirmwareOpmode(
7491 IN PRTMP_ADAPTER pAd,
7492 OUT PUINT32 pValue);
7493
7494NTSTATUS RTUSBVenderReset(
7495 IN PRTMP_ADAPTER pAd);
7496
7497NDIS_STATUS RTUSBSetHardWareRegister(
7498 IN PRTMP_ADAPTER pAdapter,
7499 IN PVOID pBuf);
7500
7501NDIS_STATUS RTUSBQueryHardWareRegister(
7502 IN PRTMP_ADAPTER pAdapter,
7503 IN PVOID pBuf);
7504
7505VOID CMDHandler(
7506 IN PRTMP_ADAPTER pAd);
7507
7508
7509NDIS_STATUS CreateThreads(
7510 IN struct net_device *net_dev );
7511
7512
7513VOID MacTableInitialize(
7514 IN PRTMP_ADAPTER pAd);
7515
7516VOID MlmeSetPsm(
7517 IN PRTMP_ADAPTER pAd,
7518 IN USHORT psm);
7519
7520NDIS_STATUS RTMPWPAAddKeyProc(
7521 IN PRTMP_ADAPTER pAd,
7522 IN PVOID pBuf);
7523
7524VOID AsicRxAntEvalAction(
7525 IN PRTMP_ADAPTER pAd);
7526
7527void append_pkt(
7528 IN PRTMP_ADAPTER pAd,
7529 IN PUCHAR pHeader802_3,
7530 IN UINT HdrLen,
7531 IN PUCHAR pData,
7532 IN ULONG DataSize,
7533 OUT PNDIS_PACKET *ppPacket);
7534
7535UINT deaggregate_AMSDU_announce(
7536 IN PRTMP_ADAPTER pAd,
7537 PNDIS_PACKET pPacket,
7538 IN PUCHAR pData,
7539 IN ULONG DataSize);
7540
7541NDIS_STATUS RTMPCheckRxError(
7542 IN PRTMP_ADAPTER pAd,
7543 IN PHEADER_802_11 pHeader,
7544 IN PRXWI_STRUC pRxWI,
7545 IN PRT28XX_RXD_STRUC pRxINFO);
7546
7547
7548VOID RTUSBMlmeHardTransmit(
7549 IN PRTMP_ADAPTER pAd,
7550 IN PMGMT_STRUC pMgmt);
7551
7552INT MlmeThread(
7553 IN PVOID Context);
7554
7555//
7556// Function Prototype in rtusb_data.c
7557//
7558NDIS_STATUS RTUSBFreeDescriptorRequest(
7559 IN PRTMP_ADAPTER pAd,
7560 IN UCHAR BulkOutPipeId,
7561 IN UINT32 NumberRequired);
7562
7563
7564BOOLEAN RTUSBNeedQueueBackForAgg(
7565 IN RTMP_ADAPTER *pAd,
7566 IN UCHAR BulkOutPipeId);
7567
7568
7569VOID RTMPWriteTxInfo(
7570 IN PRTMP_ADAPTER pAd,
7571 IN PTXINFO_STRUC pTxInfo,
7572 IN USHORT USBDMApktLen,
7573 IN BOOLEAN bWiv,
7574 IN UCHAR QueueSel,
7575 IN UCHAR NextValid,
7576 IN UCHAR TxBurst);
7577
7578//
7579// Function Prototype in cmm_data_2870.c
7580//
7581USHORT RtmpUSB_WriteSubTxResource(
7582 IN PRTMP_ADAPTER pAd,
7583 IN TX_BLK *pTxBlk,
7584 IN BOOLEAN bIsLast,
7585 OUT USHORT *FreeNumber);
7586
7587USHORT RtmpUSB_WriteSingleTxResource(
7588 IN PRTMP_ADAPTER pAd,
7589 IN TX_BLK *pTxBlk,
7590 IN BOOLEAN bIsLast,
7591 OUT USHORT *FreeNumber);
7592
7593USHORT RtmpUSB_WriteFragTxResource(
7594 IN PRTMP_ADAPTER pAd,
7595 IN TX_BLK *pTxBlk,
7596 IN UCHAR fragNum,
7597 OUT USHORT *FreeNumber);
7598
7599USHORT RtmpUSB_WriteMultiTxResource(
7600 IN PRTMP_ADAPTER pAd,
7601 IN TX_BLK *pTxBlk,
7602 IN UCHAR frameNum,
7603 OUT USHORT *FreeNumber);
7604
7605VOID RtmpUSB_FinalWriteTxResource(
7606 IN PRTMP_ADAPTER pAd,
7607 IN TX_BLK *pTxBlk,
7608 IN USHORT totalMPDUSize,
7609 IN USHORT TxIdx);
7610
7611VOID RtmpUSBDataLastTxIdx(
7612 IN PRTMP_ADAPTER pAd,
7613 IN UCHAR QueIdx,
7614 IN USHORT TxIdx);
7615
7616VOID RtmpUSBDataKickOut(
7617 IN PRTMP_ADAPTER pAd,
7618 IN TX_BLK *pTxBlk,
7619 IN UCHAR QueIdx);
7620
7621
7622int RtmpUSBMgmtKickOut(
7623 IN RTMP_ADAPTER *pAd,
7624 IN UCHAR QueIdx,
7625 IN PNDIS_PACKET pPacket,
7626 IN PUCHAR pSrcBufVA,
7627 IN UINT SrcBufLen);
7628
7629VOID RtmpUSBNullFrameKickOut(
7630 IN RTMP_ADAPTER *pAd,
7631 IN UCHAR QueIdx,
7632 IN UCHAR *pNullFrame,
7633 IN UINT32 frameLen);
7634
7635VOID RT28xxUsbStaAsicForceWakeup(
7636 IN PRTMP_ADAPTER pAd,
7637 IN BOOLEAN bFromTx);
7638
7639VOID RT28xxUsbStaAsicSleepThenAutoWakeup(
7640 IN PRTMP_ADAPTER pAd,
7641 IN USHORT TbttNumToNextWakeUp);
7642
7643VOID RT28xxUsbMlmeRadioOn(
7644 IN PRTMP_ADAPTER pAd);
7645
7646VOID RT28xxUsbMlmeRadioOFF(
7647 IN PRTMP_ADAPTER pAd);
7648#endif // RT2870 //
7649
7650////////////////////////////////////////
7651
7652VOID QBSS_LoadInit(
7653 IN RTMP_ADAPTER *pAd);
7654
7655UINT32 QBSS_LoadElementAppend(
7656 IN RTMP_ADAPTER *pAd,
7657 OUT UINT8 *buf_p);
7658
7659VOID QBSS_LoadUpdate(
7660 IN RTMP_ADAPTER *pAd);
7661
7662///////////////////////////////////////
7663INT RTMPShowCfgValue(
7664 IN PRTMP_ADAPTER pAd,
7665 IN PUCHAR pName,
7666 IN PUCHAR pBuf);
7667
7668PCHAR RTMPGetRalinkAuthModeStr(
7669 IN NDIS_802_11_AUTHENTICATION_MODE authMode);
7670
7671PCHAR RTMPGetRalinkEncryModeStr(
7672 IN USHORT encryMode);
7673//////////////////////////////////////
7674
7675#ifdef CONFIG_STA_SUPPORT
7676VOID AsicStaBbpTuning(
7677 IN PRTMP_ADAPTER pAd);
7678
7679BOOLEAN StaAddMacTableEntry(
7680 IN PRTMP_ADAPTER pAd,
7681 IN PMAC_TABLE_ENTRY pEntry,
7682 IN UCHAR MaxSupportedRateIn500Kbps,
7683 IN HT_CAPABILITY_IE *pHtCapability,
7684 IN UCHAR HtCapabilityLen,
7685 IN USHORT CapabilityInfo);
7686#endif // CONFIG_STA_SUPPORT //
7687
7688void RTMP_IndicateMediaState(
7689 IN PRTMP_ADAPTER pAd);
7690
7691VOID ReSyncBeaconTime(
7692 IN PRTMP_ADAPTER pAd);
7693
7694VOID RTMPSetAGCInitValue(
7695 IN PRTMP_ADAPTER pAd,
7696 IN UCHAR BandWidth);
7697
7698int rt28xx_close(IN PNET_DEV dev);
7699int rt28xx_open(IN PNET_DEV dev);
7700
7701__inline INT VIRTUAL_IF_UP(PRTMP_ADAPTER pAd)
7702{
7703extern VOID MeshMakeBeacon(IN PRTMP_ADAPTER pAd, IN UCHAR idx);
7704extern VOID MeshUpdateBeaconFrame(IN PRTMP_ADAPTER pAd, IN UCHAR idx);
7705
7706 if (VIRTUAL_IF_NUM(pAd) == 0)
7707 {
7708 if (rt28xx_open(pAd->net_dev) != 0)
7709 return -1;
7710 }
7711 else
7712 {
7713 }
7714 VIRTUAL_IF_INC(pAd);
7715 return 0;
7716}
7717
7718__inline VOID VIRTUAL_IF_DOWN(PRTMP_ADAPTER pAd)
7719{
7720 VIRTUAL_IF_DEC(pAd);
7721 if (VIRTUAL_IF_NUM(pAd) == 0)
7722 rt28xx_close(pAd->net_dev);
7723 return;
7724}
7725
7726
7727#endif // __RTMP_H__
7728
diff --git a/drivers/staging/rt3070/rtmp_ckipmic.h b/drivers/staging/rt3070/rtmp_ckipmic.h
new file mode 100644
index 000000000000..a3d949a39d39
--- /dev/null
+++ b/drivers/staging/rt3070/rtmp_ckipmic.h
@@ -0,0 +1,113 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 rtmp_ckipmic.h
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Name Date Modification logs
36*/
37#ifndef __RTMP_CKIPMIC_H__
38#define __RTMP_CKIPMIC_H__
39
40typedef struct _MIC_CONTEXT {
41 /* --- MMH context */
42 UCHAR CK[16]; /* the key */
43 UCHAR coefficient[16]; /* current aes counter mode coefficients */
44 ULONGLONG accum; /* accumulated mic, reduced to u32 in final() */
45 UINT position; /* current position (byte offset) in message */
46 UCHAR part[4]; /* for conversion of message to u32 for mmh */
47} MIC_CONTEXT, *PMIC_CONTEXT;
48
49VOID CKIP_key_permute(
50 OUT UCHAR *PK, /* output permuted key */
51 IN UCHAR *CK, /* input CKIP key */
52 IN UCHAR toDsFromDs, /* input toDs/FromDs bits */
53 IN UCHAR *piv); /* input pointer to IV */
54
55VOID RTMPCkipMicInit(
56 IN PMIC_CONTEXT pContext,
57 IN PUCHAR CK);
58
59VOID RTMPMicUpdate(
60 IN PMIC_CONTEXT pContext,
61 IN PUCHAR pOctets,
62 IN INT len);
63
64ULONG RTMPMicGetCoefficient(
65 IN PMIC_CONTEXT pContext);
66
67VOID xor_128(
68 IN PUCHAR a,
69 IN PUCHAR b,
70 OUT PUCHAR out);
71
72UCHAR RTMPCkipSbox(
73 IN UCHAR a);
74
75VOID xor_32(
76 IN PUCHAR a,
77 IN PUCHAR b,
78 OUT PUCHAR out);
79
80VOID next_key(
81 IN PUCHAR key,
82 IN INT round);
83
84VOID byte_sub(
85 IN PUCHAR in,
86 OUT PUCHAR out);
87
88VOID shift_row(
89 IN PUCHAR in,
90 OUT PUCHAR out);
91
92VOID mix_column(
93 IN PUCHAR in,
94 OUT PUCHAR out);
95
96VOID RTMPAesEncrypt(
97 IN PUCHAR key,
98 IN PUCHAR data,
99 IN PUCHAR ciphertext);
100
101VOID RTMPMicFinal(
102 IN PMIC_CONTEXT pContext,
103 OUT UCHAR digest[4]);
104
105VOID RTMPCkipInsertCMIC(
106 IN PRTMP_ADAPTER pAd,
107 OUT PUCHAR pMIC,
108 IN PUCHAR p80211hdr,
109 IN PNDIS_PACKET pPacket,
110 IN PCIPHER_KEY pKey,
111 IN PUCHAR mic_snap);
112
113#endif //__RTMP_CKIPMIC_H__
diff --git a/drivers/staging/rt3070/rtmp_def.h b/drivers/staging/rt3070/rtmp_def.h
new file mode 100644
index 000000000000..2599f7c836e8
--- /dev/null
+++ b/drivers/staging/rt3070/rtmp_def.h
@@ -0,0 +1,1559 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 rtmp_def.h
29
30 Abstract:
31 Miniport related definition header
32
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36 Paul Lin 08-01-2002 created
37 John Chang 08-05-2003 add definition for 11g & other drafts
38*/
39#ifndef __RTMP_DEF_H__
40#define __RTMP_DEF_H__
41
42#include "oid.h"
43
44#undef AP_WSC_INCLUDED
45#undef STA_WSC_INCLUDED
46#undef WSC_INCLUDED
47
48
49#ifdef CONFIG_STA_SUPPORT
50#endif // CONFIG_STA_SUPPORT //
51
52#if defined(AP_WSC_INCLUDED) || defined(STA_WSC_INCLUDED)
53#define WSC_INCLUDED
54#endif
55//
56// Debug information verbosity: lower values indicate higher urgency
57//
58#define RT_DEBUG_OFF 0
59#define RT_DEBUG_ERROR 1
60#define RT_DEBUG_WARN 2
61#define RT_DEBUG_TRACE 3
62#define RT_DEBUG_INFO 4
63#define RT_DEBUG_LOUD 5
64
65#define NIC_TAG ((ULONG)'0682')
66#define NIC_DBG_STRING ("**RT28xx**")
67
68#ifdef SNMP_SUPPORT
69// for snmp
70// to get manufacturer OUI, kathy, 2008_0220
71#define ManufacturerOUI_LEN 3
72#define ManufacturerNAME ("Ralink Technology Company.")
73#define ResourceTypeIdName ("Ralink_ID")
74#endif
75
76
77//#define PACKED
78
79#define RALINK_2883_VERSION ((UINT32)0x28830300)
80#define RALINK_2880E_VERSION ((UINT32)0x28720200)
81#define RALINK_3070_VERSION ((UINT32)0x30700200)
82
83//
84// NDIS version in use by the NIC driver.
85// The high byte is the major version. The low byte is the minor version.
86//
87#ifdef NDIS51_MINIPORT
88#define NIC_DRIVER_VERSION 0x0501
89#else
90#define NIC_DRIVER_VERSION 0x0500
91#endif
92
93//
94// NDIS media type, current is ethernet, change if native wireless supported
95//
96#define NIC_MEDIA_TYPE NdisMedium802_3
97#define NIC_PCI_HDR_LENGTH 0xe2
98#define NIC_MAX_PACKET_SIZE 2304
99#define NIC_HEADER_SIZE 14
100#define MAX_MAP_REGISTERS_NEEDED 32
101#define MIN_MAP_REGISTERS_NEEDED 2 //Todo: should consider fragment issue.
102
103//
104// interface type, we use PCI
105//
106#define NIC_INTERFACE_TYPE NdisInterfacePci
107#define NIC_INTERRUPT_MODE NdisInterruptLevelSensitive
108
109//
110// buffer size passed in NdisMQueryAdapterResources
111// We should only need three adapter resources (IO, interrupt and memory),
112// Some devices get extra resources, so have room for 10 resources
113// UF_SIZE (sizeof(NDIS_RESOURCE_LIST) + (10*sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)))
114
115
116#define NIC_RESOURCE_B//
117// IO space length
118//
119#define NIC_MAP_IOSPACE_LENGTH sizeof(CSR_STRUC)
120
121#define MAX_RX_PKT_LEN 1520
122
123//
124// Entry number for each DMA descriptor ring
125//
126
127
128#ifdef RT2870
129#define TX_RING_SIZE 8 // 1
130#define PRIO_RING_SIZE 8
131#define MGMT_RING_SIZE 32 // PRIO_RING_SIZE
132#define RX_RING_SIZE 8
133#define MAX_TX_PROCESS 4
134#define LOCAL_TXBUF_SIZE 2048
135#endif // RT2870 //
136
137#ifdef MULTIPLE_CARD_SUPPORT
138// MC: Multple Cards
139#define MAX_NUM_OF_MULTIPLE_CARD 32
140#endif // MULTIPLE_CARD_SUPPORT //
141
142#define MAX_RX_PROCESS 128 //64 //32
143#define NUM_OF_LOCAL_TXBUF 2
144#define TXD_SIZE 16
145#define TXWI_SIZE 16
146#define RXD_SIZE 16
147#define RXWI_SIZE 16
148// TXINFO_SIZE + TXWI_SIZE + 802.11 Header Size + AMSDU sub frame header
149#define TX_DMA_1ST_BUFFER_SIZE 96 // only the 1st physical buffer is pre-allocated
150#define MGMT_DMA_BUFFER_SIZE 1536 //2048
151#define RX_BUFFER_AGGRESIZE 3840 //3904 //3968 //4096 //2048 //4096
152#define RX_BUFFER_NORMSIZE 3840 //3904 //3968 //4096 //2048 //4096
153#define TX_BUFFER_NORMSIZE RX_BUFFER_NORMSIZE
154#define MAX_FRAME_SIZE 2346 // Maximum 802.11 frame size
155#define MAX_AGGREGATION_SIZE 3840 //3904 //3968 //4096
156#define MAX_NUM_OF_TUPLE_CACHE 2
157#define MAX_MCAST_LIST_SIZE 32
158#define MAX_LEN_OF_VENDOR_DESC 64
159//#define MAX_SIZE_OF_MCAST_PSQ (NUM_OF_LOCAL_TXBUF >> 2) // AP won't spend more than 1/4 of total buffers on M/BCAST PSQ
160#define MAX_SIZE_OF_MCAST_PSQ 32
161
162#define MAX_RX_PROCESS_CNT (RX_RING_SIZE)
163
164
165#define MAX_PACKETS_IN_QUEUE (512) //(512) // to pass WMM A5-WPAPSK
166#define MAX_PACKETS_IN_MCAST_PS_QUEUE 32
167#define MAX_PACKETS_IN_PS_QUEUE 128 //32
168#define WMM_NUM_OF_AC 4 /* AC0, AC1, AC2, and AC3 */
169
170
171//2008/09/11:KH add to support efuse<--
172#define MAX_EEPROM_BIN_FILE_SIZE 1024
173//2008/09/11:KH add to support efuse-->
174
175// RxFilter
176#define STANORMAL 0x17f97
177#define APNORMAL 0x15f97
178//
179// RTMP_ADAPTER flags
180//
181#define fRTMP_ADAPTER_MAP_REGISTER 0x00000001
182#define fRTMP_ADAPTER_INTERRUPT_IN_USE 0x00000002
183#define fRTMP_ADAPTER_HARDWARE_ERROR 0x00000004
184#define fRTMP_ADAPTER_SCATTER_GATHER 0x00000008
185#define fRTMP_ADAPTER_SEND_PACKET_ERROR 0x00000010
186#define fRTMP_ADAPTER_MLME_RESET_IN_PROGRESS 0x00000020
187#define fRTMP_ADAPTER_HALT_IN_PROGRESS 0x00000040
188#define fRTMP_ADAPTER_RESET_IN_PROGRESS 0x00000080
189#define fRTMP_ADAPTER_NIC_NOT_EXIST 0x00000100
190#define fRTMP_ADAPTER_TX_RING_ALLOCATED 0x00000200
191#define fRTMP_ADAPTER_REMOVE_IN_PROGRESS 0x00000400
192#define fRTMP_ADAPTER_MIMORATE_INUSED 0x00000800
193#define fRTMP_ADAPTER_RX_RING_ALLOCATED 0x00001000
194#define fRTMP_ADAPTER_INTERRUPT_ACTIVE 0x00002000
195#define fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS 0x00004000
196#define fRTMP_ADAPTER_REASSOC_IN_PROGRESS 0x00008000
197#define fRTMP_ADAPTER_MEDIA_STATE_PENDING 0x00010000
198#define fRTMP_ADAPTER_RADIO_OFF 0x00020000
199#define fRTMP_ADAPTER_BULKOUT_RESET 0x00040000
200#define fRTMP_ADAPTER_BULKIN_RESET 0x00080000
201#define fRTMP_ADAPTER_RDG_ACTIVE 0x00100000
202#define fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE 0x00200000
203#define fRTMP_ADAPTER_SCAN_2040 0x04000000
204#define fRTMP_ADAPTER_RADIO_MEASUREMENT 0x08000000
205
206#define fRTMP_ADAPTER_START_UP 0x10000000 //Devive already initialized and enabled Tx/Rx.
207#define fRTMP_ADAPTER_MEDIA_STATE_CHANGE 0x20000000
208#define fRTMP_ADAPTER_IDLE_RADIO_OFF 0x40000000
209
210// Lock bit for accessing different ring buffers
211//#define fRTMP_ADAPTER_TX_RING_BUSY 0x80000000
212//#define fRTMP_ADAPTER_MGMT_RING_BUSY 0x40000000
213//#define fRTMP_ADAPTER_ATIM_RING_BUSY 0x20000000
214//#define fRTMP_ADAPTER_RX_RING_BUSY 0x10000000
215
216// Lock bit for accessing different queue
217//#define fRTMP_ADAPTER_TX_QUEUE_BUSY 0x08000000
218//#define fRTMP_ADAPTER_MGMT_QUEUE_BUSY 0x04000000
219
220//
221// STA operation status flags
222//
223#define fOP_STATUS_INFRA_ON 0x00000001
224#define fOP_STATUS_ADHOC_ON 0x00000002
225#define fOP_STATUS_BG_PROTECTION_INUSED 0x00000004
226#define fOP_STATUS_SHORT_SLOT_INUSED 0x00000008
227#define fOP_STATUS_SHORT_PREAMBLE_INUSED 0x00000010
228#define fOP_STATUS_RECEIVE_DTIM 0x00000020
229//#define fOP_STATUS_TX_RATE_SWITCH_ENABLED 0x00000040
230#define fOP_STATUS_MEDIA_STATE_CONNECTED 0x00000080
231#define fOP_STATUS_WMM_INUSED 0x00000100
232#define fOP_STATUS_AGGREGATION_INUSED 0x00000200
233#define fOP_STATUS_DOZE 0x00000400 // debug purpose
234#define fOP_STATUS_PIGGYBACK_INUSED 0x00000800 // piggy-back, and aggregation
235#define fOP_STATUS_APSD_INUSED 0x00001000
236#define fOP_STATUS_TX_AMSDU_INUSED 0x00002000
237#define fOP_STATUS_MAX_RETRY_ENABLED 0x00004000
238#define fOP_STATUS_WAKEUP_NOW 0x00008000
239#define fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE 0x00020000
240
241#ifdef DOT11N_DRAFT3
242#define fOP_STATUS_SCAN_2040 0x00040000
243#endif // DOT11N_DRAFT3 //
244
245#define CCKSETPROTECT 0x1
246#define OFDMSETPROTECT 0x2
247#define MM20SETPROTECT 0x4
248#define MM40SETPROTECT 0x8
249#define GF20SETPROTECT 0x10
250#define GR40SETPROTECT 0x20
251#define ALLN_SETPROTECT (GR40SETPROTECT | GF20SETPROTECT | MM40SETPROTECT | MM20SETPROTECT)
252
253//
254// AP's client table operation status flags
255//
256#define fCLIENT_STATUS_WMM_CAPABLE 0x00000001 // CLIENT can parse QOS DATA frame
257#define fCLIENT_STATUS_AGGREGATION_CAPABLE 0x00000002 // CLIENT can receive Ralink's proprietary TX aggregation frame
258#define fCLIENT_STATUS_PIGGYBACK_CAPABLE 0x00000004 // CLIENT support piggy-back
259#define fCLIENT_STATUS_AMSDU_INUSED 0x00000008
260#define fCLIENT_STATUS_SGI20_CAPABLE 0x00000010
261#define fCLIENT_STATUS_SGI40_CAPABLE 0x00000020
262#define fCLIENT_STATUS_TxSTBC_CAPABLE 0x00000040
263#define fCLIENT_STATUS_RxSTBC_CAPABLE 0x00000080
264#define fCLIENT_STATUS_HTC_CAPABLE 0x00000100
265#define fCLIENT_STATUS_RDG_CAPABLE 0x00000200
266#define fCLIENT_STATUS_MCSFEEDBACK_CAPABLE 0x00000400
267#define fCLIENT_STATUS_APSD_CAPABLE 0x00000800 /* UAPSD STATION */
268
269#ifdef DOT11N_DRAFT3
270#define fCLIENT_STATUS_BSSCOEXIST_CAPABLE 0x00001000
271#endif // DOT11N_DRAFT3 //
272
273#define fCLIENT_STATUS_RALINK_CHIPSET 0x00100000
274//
275// STA configuration flags
276//
277//#define fSTA_CFG_ENABLE_TX_BURST 0x00000001
278
279// 802.11n Operating Mode Definition. 0-3 also used in ASICUPdateProtect switch case
280#define HT_NO_PROTECT 0
281#define HT_LEGACY_PROTECT 1
282#define HT_40_PROTECT 2
283#define HT_2040_PROTECT 3
284#define HT_RTSCTS_6M 7
285//following is our own definition in order to turn on our ASIC protection register in INFRASTRUCTURE.
286#define HT_ATHEROS 8
287#define HT_FORCERTSCTS 9 // Force turn on RTS/CTS first. then go to evaluate if this force RTS is necessary.
288
289//
290// RX Packet Filter control flags. Apply on pAd->PacketFilter
291//
292#define fRX_FILTER_ACCEPT_DIRECT NDIS_PACKET_TYPE_DIRECTED
293#define fRX_FILTER_ACCEPT_MULTICAST NDIS_PACKET_TYPE_MULTICAST
294#define fRX_FILTER_ACCEPT_BROADCAST NDIS_PACKET_TYPE_BROADCAST
295#define fRX_FILTER_ACCEPT_ALL_MULTICAST NDIS_PACKET_TYPE_ALL_MULTICAST
296
297//
298// Error code section
299//
300// NDIS_ERROR_CODE_ADAPTER_NOT_FOUND
301#define ERRLOG_READ_PCI_SLOT_FAILED 0x00000101L
302#define ERRLOG_WRITE_PCI_SLOT_FAILED 0x00000102L
303#define ERRLOG_VENDOR_DEVICE_NOMATCH 0x00000103L
304
305// NDIS_ERROR_CODE_ADAPTER_DISABLED
306#define ERRLOG_BUS_MASTER_DISABLED 0x00000201L
307
308// NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION
309#define ERRLOG_INVALID_SPEED_DUPLEX 0x00000301L
310#define ERRLOG_SET_SECONDARY_FAILED 0x00000302L
311
312// NDIS_ERROR_CODE_OUT_OF_RESOURCES
313#define ERRLOG_OUT_OF_MEMORY 0x00000401L
314#define ERRLOG_OUT_OF_SHARED_MEMORY 0x00000402L
315#define ERRLOG_OUT_OF_MAP_REGISTERS 0x00000403L
316#define ERRLOG_OUT_OF_BUFFER_POOL 0x00000404L
317#define ERRLOG_OUT_OF_NDIS_BUFFER 0x00000405L
318#define ERRLOG_OUT_OF_PACKET_POOL 0x00000406L
319#define ERRLOG_OUT_OF_NDIS_PACKET 0x00000407L
320#define ERRLOG_OUT_OF_LOOKASIDE_MEMORY 0x00000408L
321
322// NDIS_ERROR_CODE_HARDWARE_FAILURE
323#define ERRLOG_SELFTEST_FAILED 0x00000501L
324#define ERRLOG_INITIALIZE_ADAPTER 0x00000502L
325#define ERRLOG_REMOVE_MINIPORT 0x00000503L
326
327// NDIS_ERROR_CODE_RESOURCE_CONFLICT
328#define ERRLOG_MAP_IO_SPACE 0x00000601L
329#define ERRLOG_QUERY_ADAPTER_RESOURCES 0x00000602L
330#define ERRLOG_NO_IO_RESOURCE 0x00000603L
331#define ERRLOG_NO_INTERRUPT_RESOURCE 0x00000604L
332#define ERRLOG_NO_MEMORY_RESOURCE 0x00000605L
333
334
335// WDS definition
336#define MAX_WDS_ENTRY 4
337#define WDS_PAIRWISE_KEY_OFFSET 60 // WDS links uses pairwise key#60 ~ 63 in ASIC pairwise key table
338
339#define WDS_DISABLE_MODE 0
340#define WDS_RESTRICT_MODE 1
341#define WDS_BRIDGE_MODE 2
342#define WDS_REPEATER_MODE 3
343#define WDS_LAZY_MODE 4
344
345
346#define MAX_MESH_NUM 0
347
348#define MAX_APCLI_NUM 0
349
350#define MAX_MBSSID_NUM 1
351#ifdef MBSS_SUPPORT
352#undef MAX_MBSSID_NUM
353#define MAX_MBSSID_NUM (8 - MAX_MESH_NUM - MAX_APCLI_NUM)
354#endif // MBSS_SUPPORT //
355
356/* sanity check for apidx */
357#define MBSS_MR_APIDX_SANITY_CHECK(apidx) \
358 { if (apidx > MAX_MBSSID_NUM) { \
359 printk("%s> Error! apidx = %d > MAX_MBSSID_NUM!\n", __FUNCTION__, apidx); \
360 apidx = MAIN_MBSSID; } }
361
362#define VALID_WCID(_wcid) ((_wcid) > 0 && (_wcid) < MAX_LEN_OF_MAC_TABLE )
363
364#define MAIN_MBSSID 0
365#define FIRST_MBSSID 1
366
367
368#define MAX_BEACON_SIZE 512
369// If the MAX_MBSSID_NUM is larger than 6,
370// it shall reserve some WCID space(wcid 222~253) for beacon frames.
371// - these wcid 238~253 are reserved for beacon#6(ra6).
372// - these wcid 222~237 are reserved for beacon#7(ra7).
373#if defined(MAX_MBSSID_NUM) && (MAX_MBSSID_NUM == 8)
374#define HW_RESERVED_WCID 222
375#elif defined(MAX_MBSSID_NUM) && (MAX_MBSSID_NUM == 7)
376#define HW_RESERVED_WCID 238
377#else
378#define HW_RESERVED_WCID 255
379#endif
380
381// Then dedicate wcid of DFS and Carrier-Sense.
382#define DFS_CTS_WCID (HW_RESERVED_WCID - 1)
383#define CS_CTS_WCID (HW_RESERVED_WCID - 2)
384#define LAST_SPECIFIC_WCID (HW_RESERVED_WCID - 2)
385
386// If MAX_MBSSID_NUM is 8, the maximum available wcid for the associated STA is 211.
387// If MAX_MBSSID_NUM is 7, the maximum available wcid for the associated STA is 228.
388#define MAX_AVAILABLE_CLIENT_WCID (LAST_SPECIFIC_WCID - MAX_MBSSID_NUM - 1)
389
390// TX need WCID to find Cipher Key
391// these wcid 212 ~ 219 are reserved for bc/mc packets if MAX_MBSSID_NUM is 8.
392#define GET_GroupKey_WCID(__wcid, __bssidx) \
393 { \
394 __wcid = LAST_SPECIFIC_WCID - (MAX_MBSSID_NUM) + __bssidx; \
395 }
396
397#define IsGroupKeyWCID(__wcid) (((__wcid) < LAST_SPECIFIC_WCID) && ((__wcid) >= (LAST_SPECIFIC_WCID - (MAX_MBSSID_NUM))))
398
399
400// definition to support multiple BSSID
401#define BSS0 0
402#define BSS1 1
403#define BSS2 2
404#define BSS3 3
405#define BSS4 4
406#define BSS5 5
407#define BSS6 6
408#define BSS7 7
409
410
411//============================================================
412// Length definitions
413#define PEER_KEY_NO 2
414#define MAC_ADDR_LEN 6
415#define TIMESTAMP_LEN 8
416#define MAX_LEN_OF_SUPPORTED_RATES MAX_LENGTH_OF_SUPPORT_RATES // 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54
417#define MAX_LEN_OF_KEY 32 // 32 octets == 256 bits, Redefine for WPA
418#define MAX_NUM_OF_CHANNELS MAX_NUM_OF_CHS // 14 channels @2.4G + 12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL termination
419#define MAX_NUM_OF_11JCHANNELS 20 // 14 channels @2.4G + 12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL termination
420#define MAX_LEN_OF_SSID 32
421#define CIPHER_TEXT_LEN 128
422#define HASH_TABLE_SIZE 256
423#define MAX_VIE_LEN 1024 // New for WPA cipher suite variable IE sizes.
424#define MAX_SUPPORT_MCS 32
425
426//============================================================
427// ASIC WCID Table definition.
428//============================================================
429#define BSSID_WCID 1 // in infra mode, always put bssid with this WCID
430#define MCAST_WCID 0x0
431#define BSS0Mcast_WCID 0x0
432#define BSS1Mcast_WCID 0xf8
433#define BSS2Mcast_WCID 0xf9
434#define BSS3Mcast_WCID 0xfa
435#define BSS4Mcast_WCID 0xfb
436#define BSS5Mcast_WCID 0xfc
437#define BSS6Mcast_WCID 0xfd
438#define BSS7Mcast_WCID 0xfe
439#define RESERVED_WCID 0xff
440
441#define MAX_NUM_OF_ACL_LIST MAX_NUMBER_OF_ACL
442
443#define MAX_LEN_OF_MAC_TABLE MAX_NUMBER_OF_MAC // if MAX_MBSSID_NUM is 8, this value can't be larger than 211
444
445#if MAX_LEN_OF_MAC_TABLE>MAX_AVAILABLE_CLIENT_WCID
446#error MAX_LEN_OF_MAC_TABLE can not be larger than MAX_AVAILABLE_CLIENT_WCID!!!!
447#endif
448
449#define MAX_NUM_OF_WDS_LINK_PERBSSID 3
450#define MAX_NUM_OF_WDS_LINK (MAX_NUM_OF_WDS_LINK_PERBSSID*MAX_MBSSID_NUM)
451#define MAX_NUM_OF_EVENT MAX_NUMBER_OF_EVENT
452#define WDS_LINK_START_WCID (MAX_LEN_OF_MAC_TABLE-1)
453
454#define NUM_OF_TID 8
455#define MAX_AID_BA 4
456#define MAX_LEN_OF_BA_REC_TABLE ((NUM_OF_TID * MAX_LEN_OF_MAC_TABLE)/2)// (NUM_OF_TID*MAX_AID_BA + 32) //Block ACK recipient
457#define MAX_LEN_OF_BA_ORI_TABLE ((NUM_OF_TID * MAX_LEN_OF_MAC_TABLE)/2)// (NUM_OF_TID*MAX_AID_BA + 32) // Block ACK originator
458#define MAX_LEN_OF_BSS_TABLE 64
459#define MAX_REORDERING_MPDU_NUM 512
460
461// key related definitions
462#define SHARE_KEY_NUM 4
463#define MAX_LEN_OF_SHARE_KEY 16 // byte count
464#define MAX_LEN_OF_PEER_KEY 16 // byte count
465#define PAIRWISE_KEY_NUM 64 // in MAC ASIC pairwise key table
466#define GROUP_KEY_NUM 4
467#define PMK_LEN 32
468#define WDS_PAIRWISE_KEY_OFFSET 60 // WDS links uses pairwise key#60 ~ 63 in ASIC pairwise key table
469#define PMKID_NO 4 // Number of PMKID saved supported
470#define MAX_LEN_OF_MLME_BUFFER 2048
471
472// power status related definitions
473#define PWR_ACTIVE 0
474#define PWR_SAVE 1
475#define PWR_MMPS 2 //MIMO power save
476//#define PWR_UNKNOWN 2
477
478// Auth and Assoc mode related definitions
479#define AUTH_MODE_OPEN 0x00
480#define AUTH_MODE_KEY 0x01
481//#define AUTH_MODE_AUTO_SWITCH 0x03
482//#define AUTH_MODE_DEAUTH 0x04
483//#define AUTH_MODE_UPLAYER 0x05 // reserved for 802.11i use
484
485// BSS Type definitions
486#define BSS_ADHOC 0 // = Ndis802_11IBSS
487#define BSS_INFRA 1 // = Ndis802_11Infrastructure
488#define BSS_ANY 2 // = Ndis802_11AutoUnknown
489#define BSS_MONITOR 3 // = Ndis802_11Monitor
490
491
492// Reason code definitions
493#define REASON_RESERVED 0
494#define REASON_UNSPECIFY 1
495#define REASON_NO_LONGER_VALID 2
496#define REASON_DEAUTH_STA_LEAVING 3
497#define REASON_DISASSOC_INACTIVE 4
498#define REASON_DISASSPC_AP_UNABLE 5
499#define REASON_CLS2ERR 6
500#define REASON_CLS3ERR 7
501#define REASON_DISASSOC_STA_LEAVING 8
502#define REASON_STA_REQ_ASSOC_NOT_AUTH 9
503#define REASON_INVALID_IE 13
504#define REASON_MIC_FAILURE 14
505#define REASON_4_WAY_TIMEOUT 15
506#define REASON_GROUP_KEY_HS_TIMEOUT 16
507#define REASON_IE_DIFFERENT 17
508#define REASON_MCIPHER_NOT_VALID 18
509#define REASON_UCIPHER_NOT_VALID 19
510#define REASON_AKMP_NOT_VALID 20
511#define REASON_UNSUPPORT_RSNE_VER 21
512#define REASON_INVALID_RSNE_CAP 22
513#define REASON_8021X_AUTH_FAIL 23
514#define REASON_CIPHER_SUITE_REJECTED 24
515#define REASON_DECLINED 37
516
517#define REASON_QOS_UNSPECIFY 32
518#define REASON_QOS_LACK_BANDWIDTH 33
519#define REASON_POOR_CHANNEL_CONDITION 34
520#define REASON_QOS_OUTSIDE_TXOP_LIMITION 35
521#define REASON_QOS_QSTA_LEAVING_QBSS 36
522#define REASON_QOS_UNWANTED_MECHANISM 37
523#define REASON_QOS_MECH_SETUP_REQUIRED 38
524#define REASON_QOS_REQUEST_TIMEOUT 39
525#define REASON_QOS_CIPHER_NOT_SUPPORT 45
526
527// Status code definitions
528#define MLME_SUCCESS 0
529#define MLME_UNSPECIFY_FAIL 1
530#define MLME_CANNOT_SUPPORT_CAP 10
531#define MLME_REASSOC_DENY_ASSOC_EXIST 11
532#define MLME_ASSOC_DENY_OUT_SCOPE 12
533#define MLME_ALG_NOT_SUPPORT 13
534#define MLME_SEQ_NR_OUT_OF_SEQUENCE 14
535#define MLME_REJ_CHALLENGE_FAILURE 15
536#define MLME_REJ_TIMEOUT 16
537#define MLME_ASSOC_REJ_UNABLE_HANDLE_STA 17
538#define MLME_ASSOC_REJ_DATA_RATE 18
539
540#define MLME_ASSOC_REJ_NO_EXT_RATE 22
541#define MLME_ASSOC_REJ_NO_EXT_RATE_PBCC 23
542#define MLME_ASSOC_REJ_NO_CCK_OFDM 24
543
544#define MLME_QOS_UNSPECIFY 32
545#define MLME_REQUEST_DECLINED 37
546#define MLME_REQUEST_WITH_INVALID_PARAM 38
547#define MLME_DLS_NOT_ALLOW_IN_QBSS 48
548#define MLME_DEST_STA_NOT_IN_QBSS 49
549#define MLME_DEST_STA_IS_NOT_A_QSTA 50
550
551#define MLME_INVALID_FORMAT 0x51
552#define MLME_FAIL_NO_RESOURCE 0x52
553#define MLME_STATE_MACHINE_REJECT 0x53
554#define MLME_MAC_TABLE_FAIL 0x54
555
556// IE code
557#define IE_SSID 0
558#define IE_SUPP_RATES 1
559#define IE_FH_PARM 2
560#define IE_DS_PARM 3
561#define IE_CF_PARM 4
562#define IE_TIM 5
563#define IE_IBSS_PARM 6
564#define IE_COUNTRY 7 // 802.11d
565#define IE_802_11D_REQUEST 10 // 802.11d
566#define IE_QBSS_LOAD 11 // 802.11e d9
567#define IE_EDCA_PARAMETER 12 // 802.11e d9
568#define IE_TSPEC 13 // 802.11e d9
569#define IE_TCLAS 14 // 802.11e d9
570#define IE_SCHEDULE 15 // 802.11e d9
571#define IE_CHALLENGE_TEXT 16
572#define IE_POWER_CONSTRAINT 32 // 802.11h d3.3
573#define IE_POWER_CAPABILITY 33 // 802.11h d3.3
574#define IE_TPC_REQUEST 34 // 802.11h d3.3
575#define IE_TPC_REPORT 35 // 802.11h d3.3
576#define IE_SUPP_CHANNELS 36 // 802.11h d3.3
577#define IE_CHANNEL_SWITCH_ANNOUNCEMENT 37 // 802.11h d3.3
578#define IE_MEASUREMENT_REQUEST 38 // 802.11h d3.3
579#define IE_MEASUREMENT_REPORT 39 // 802.11h d3.3
580#define IE_QUIET 40 // 802.11h d3.3
581#define IE_IBSS_DFS 41 // 802.11h d3.3
582#define IE_ERP 42 // 802.11g
583#define IE_TS_DELAY 43 // 802.11e d9
584#define IE_TCLAS_PROCESSING 44 // 802.11e d9
585#define IE_QOS_CAPABILITY 46 // 802.11e d6
586#define IE_HT_CAP 45 // 802.11n d1. HT CAPABILITY. ELEMENT ID TBD
587#define IE_AP_CHANNEL_REPORT 51 // 802.11k d6
588#define IE_HT_CAP2 52 // 802.11n d1. HT CAPABILITY. ELEMENT ID TBD
589#define IE_RSN 48 // 802.11i d3.0
590#define IE_WPA2 48 // WPA2
591#define IE_EXT_SUPP_RATES 50 // 802.11g
592#define IE_SUPP_REG_CLASS 59 // 802.11y. Supported regulatory classes.
593#define IE_EXT_CHANNEL_SWITCH_ANNOUNCEMENT 60 // 802.11n
594#define IE_ADD_HT 61 // 802.11n d1. ADDITIONAL HT CAPABILITY. ELEMENT ID TBD
595#define IE_ADD_HT2 53 // 802.11n d1. ADDITIONAL HT CAPABILITY. ELEMENT ID TBD
596
597
598// For 802.11n D3.03
599//#define IE_NEW_EXT_CHA_OFFSET 62 // 802.11n d1. New extension channel offset elemet
600#define IE_SECONDARY_CH_OFFSET 62 // 802.11n D3.03 Secondary Channel Offset element
601#define IE_WAPI 68 // WAPI information element
602#define IE_2040_BSS_COEXIST 72 // 802.11n D3.0.3
603#define IE_2040_BSS_INTOLERANT_REPORT 73 // 802.11n D3.03
604#define IE_OVERLAPBSS_SCAN_PARM 74 // 802.11n D3.03
605#define IE_EXT_CAPABILITY 127 // 802.11n D3.03
606
607
608#define IE_WPA 221 // WPA
609#define IE_VENDOR_SPECIFIC 221 // Wifi WMM (WME)
610
611#define OUI_BROADCOM_HT 51 //
612#define OUI_BROADCOM_HTADD 52 //
613#define OUI_PREN_HT_CAP 51 //
614#define OUI_PREN_ADD_HT 52 //
615
616// CCX information
617#define IE_AIRONET_CKIP 133 // CCX1.0 ID 85H for CKIP
618#define IE_AP_TX_POWER 150 // CCX 2.0 for AP transmit power
619#define IE_MEASUREMENT_CAPABILITY 221 // CCX 2.0
620#define IE_CCX_V2 221
621#define IE_AIRONET_IPADDRESS 149 // CCX ID 95H for IP Address
622#define IE_AIRONET_CCKMREASSOC 156 // CCX ID 9CH for CCKM Reassociation Request element
623#define CKIP_NEGOTIATION_LENGTH 30
624#define AIRONET_IPADDRESS_LENGTH 10
625#define AIRONET_CCKMREASSOC_LENGTH 24
626
627// ========================================================
628// MLME state machine definition
629// ========================================================
630
631// STA MLME state mahcines
632#define ASSOC_STATE_MACHINE 1
633#define AUTH_STATE_MACHINE 2
634#define AUTH_RSP_STATE_MACHINE 3
635#define SYNC_STATE_MACHINE 4
636#define MLME_CNTL_STATE_MACHINE 5
637#define WPA_PSK_STATE_MACHINE 6
638#define LEAP_STATE_MACHINE 7
639#define AIRONET_STATE_MACHINE 8
640#define ACTION_STATE_MACHINE 9
641
642// AP MLME state machines
643#define AP_ASSOC_STATE_MACHINE 11
644#define AP_AUTH_STATE_MACHINE 12
645#define AP_AUTH_RSP_STATE_MACHINE 13
646#define AP_SYNC_STATE_MACHINE 14
647#define AP_CNTL_STATE_MACHINE 15
648#define AP_WPA_STATE_MACHINE 16
649
650#define WSC_STATE_MACHINE 17
651#define WSC_UPNP_STATE_MACHINE 18
652
653
654
655#ifdef QOS_DLS_SUPPORT
656#define DLS_STATE_MACHINE 26
657#endif // QOS_DLS_SUPPORT //
658
659//
660// STA's CONTROL/CONNECT state machine: states, events, total function #
661//
662#define CNTL_IDLE 0
663#define CNTL_WAIT_DISASSOC 1
664#define CNTL_WAIT_JOIN 2
665#define CNTL_WAIT_REASSOC 3
666#define CNTL_WAIT_START 4
667#define CNTL_WAIT_AUTH 5
668#define CNTL_WAIT_ASSOC 6
669#define CNTL_WAIT_AUTH2 7
670#define CNTL_WAIT_OID_LIST_SCAN 8
671#define CNTL_WAIT_OID_DISASSOC 9
672#ifdef RT2870
673#define CNTL_WAIT_SCAN_FOR_CONNECT 10
674#endif // RT2870 //
675
676#define MT2_ASSOC_CONF 34
677#define MT2_AUTH_CONF 35
678#define MT2_DEAUTH_CONF 36
679#define MT2_DISASSOC_CONF 37
680#define MT2_REASSOC_CONF 38
681#define MT2_PWR_MGMT_CONF 39
682#define MT2_JOIN_CONF 40
683#define MT2_SCAN_CONF 41
684#define MT2_START_CONF 42
685#define MT2_GET_CONF 43
686#define MT2_SET_CONF 44
687#define MT2_RESET_CONF 45
688#define MT2_MLME_ROAMING_REQ 52
689
690#define CNTL_FUNC_SIZE 1
691
692//
693// STA's ASSOC state machine: states, events, total function #
694//
695#define ASSOC_IDLE 0
696#define ASSOC_WAIT_RSP 1
697#define REASSOC_WAIT_RSP 2
698#define DISASSOC_WAIT_RSP 3
699#define MAX_ASSOC_STATE 4
700
701#define ASSOC_MACHINE_BASE 0
702#define MT2_MLME_ASSOC_REQ 0
703#define MT2_MLME_REASSOC_REQ 1
704#define MT2_MLME_DISASSOC_REQ 2
705#define MT2_PEER_DISASSOC_REQ 3
706#define MT2_PEER_ASSOC_REQ 4
707#define MT2_PEER_ASSOC_RSP 5
708#define MT2_PEER_REASSOC_REQ 6
709#define MT2_PEER_REASSOC_RSP 7
710#define MT2_DISASSOC_TIMEOUT 8
711#define MT2_ASSOC_TIMEOUT 9
712#define MT2_REASSOC_TIMEOUT 10
713#define MAX_ASSOC_MSG 11
714
715#define ASSOC_FUNC_SIZE (MAX_ASSOC_STATE * MAX_ASSOC_MSG)
716
717//
718// ACT state machine: states, events, total function #
719//
720#define ACT_IDLE 0
721#define MAX_ACT_STATE 1
722
723#define ACT_MACHINE_BASE 0
724
725//Those PEER_xx_CATE number is based on real Categary value in IEEE spec. Please don'es modify it by your self.
726//Category
727#define MT2_PEER_SPECTRUM_CATE 0
728#define MT2_PEER_QOS_CATE 1
729#define MT2_PEER_DLS_CATE 2
730#define MT2_PEER_BA_CATE 3
731#define MT2_PEER_PUBLIC_CATE 4
732#define MT2_PEER_RM_CATE 5
733#define MT2_PEER_HT_CATE 7 // 7.4.7
734#define MAX_PEER_CATE_MSG 7
735#define MT2_MLME_ADD_BA_CATE 8
736#define MT2_MLME_ORI_DELBA_CATE 9
737#define MT2_MLME_REC_DELBA_CATE 10
738#define MT2_MLME_QOS_CATE 11
739#define MT2_MLME_DLS_CATE 12
740#define MT2_ACT_INVALID 13
741#define MAX_ACT_MSG 14
742
743//Category field
744#define CATEGORY_SPECTRUM 0
745#define CATEGORY_QOS 1
746#define CATEGORY_DLS 2
747#define CATEGORY_BA 3
748#define CATEGORY_PUBLIC 4
749#define CATEGORY_RM 5
750#define CATEGORY_HT 7
751
752
753// DLS Action frame definition
754#define ACTION_DLS_REQUEST 0
755#define ACTION_DLS_RESPONSE 1
756#define ACTION_DLS_TEARDOWN 2
757
758//Spectrum Action field value 802.11h 7.4.1
759#define SPEC_MRQ 0 // Request
760#define SPEC_MRP 1 //Report
761#define SPEC_TPCRQ 2
762#define SPEC_TPCRP 3
763#define SPEC_CHANNEL_SWITCH 4
764
765
766//BA Action field value
767#define ADDBA_REQ 0
768#define ADDBA_RESP 1
769#define DELBA 2
770
771//Public's Action field value in Public Category. Some in 802.11y and some in 11n
772#define ACTION_BSS_2040_COEXIST 0 // 11n
773#define ACTION_DSE_ENABLEMENT 1 // 11y D9.0
774#define ACTION_DSE_DEENABLEMENT 2 // 11y D9.0
775#define ACTION_DSE_REG_LOCATION_ANNOUNCE 3 // 11y D9.0
776#define ACTION_EXT_CH_SWITCH_ANNOUNCE 4 // 11y D9.0
777#define ACTION_DSE_MEASUREMENT_REQ 5 // 11y D9.0
778#define ACTION_DSE_MEASUREMENT_REPORT 6 // 11y D9.0
779#define ACTION_MEASUREMENT_PILOT_ACTION 7 // 11y D9.0
780#define ACTION_DSE_POWER_CONSTRAINT 8 // 11y D9.0
781
782
783//HT Action field value
784#define NOTIFY_BW_ACTION 0
785#define SMPS_ACTION 1
786#define PSMP_ACTION 2
787#define SETPCO_ACTION 3
788#define MIMO_CHA_MEASURE_ACTION 4
789#define MIMO_N_BEACONFORM 5
790#define MIMO_BEACONFORM 6
791#define ANTENNA_SELECT 7
792#define HT_INFO_EXCHANGE 8
793
794#define ACT_FUNC_SIZE (MAX_ACT_STATE * MAX_ACT_MSG)
795//
796// STA's AUTHENTICATION state machine: states, evvents, total function #
797//
798#define AUTH_REQ_IDLE 0
799#define AUTH_WAIT_SEQ2 1
800#define AUTH_WAIT_SEQ4 2
801#define MAX_AUTH_STATE 3
802
803#define AUTH_MACHINE_BASE 0
804#define MT2_MLME_AUTH_REQ 0
805#define MT2_PEER_AUTH_EVEN 1
806#define MT2_AUTH_TIMEOUT 2
807#define MAX_AUTH_MSG 3
808
809#define AUTH_FUNC_SIZE (MAX_AUTH_STATE * MAX_AUTH_MSG)
810
811//
812// STA's AUTH_RSP state machine: states, events, total function #
813//
814#define AUTH_RSP_IDLE 0
815#define AUTH_RSP_WAIT_CHAL 1
816#define MAX_AUTH_RSP_STATE 2
817
818#define AUTH_RSP_MACHINE_BASE 0
819#define MT2_AUTH_CHALLENGE_TIMEOUT 0
820#define MT2_PEER_AUTH_ODD 1
821#define MT2_PEER_DEAUTH 2
822#define MAX_AUTH_RSP_MSG 3
823
824#define AUTH_RSP_FUNC_SIZE (MAX_AUTH_RSP_STATE * MAX_AUTH_RSP_MSG)
825
826//
827// STA's SYNC state machine: states, events, total function #
828//
829#define SYNC_IDLE 0 // merge NO_BSS,IBSS_IDLE,IBSS_ACTIVE and BSS in to 1 state
830#define JOIN_WAIT_BEACON 1
831#define SCAN_LISTEN 2
832#define MAX_SYNC_STATE 3
833
834#define SYNC_MACHINE_BASE 0
835#define MT2_MLME_SCAN_REQ 0
836#define MT2_MLME_JOIN_REQ 1
837#define MT2_MLME_START_REQ 2
838#define MT2_PEER_BEACON 3
839#define MT2_PEER_PROBE_RSP 4
840#define MT2_PEER_ATIM 5
841#define MT2_SCAN_TIMEOUT 6
842#define MT2_BEACON_TIMEOUT 7
843#define MT2_ATIM_TIMEOUT 8
844#define MT2_PEER_PROBE_REQ 9
845#define MAX_SYNC_MSG 10
846
847#define SYNC_FUNC_SIZE (MAX_SYNC_STATE * MAX_SYNC_MSG)
848
849//Messages for the DLS state machine
850#define DLS_IDLE 0
851#define MAX_DLS_STATE 1
852
853#define DLS_MACHINE_BASE 0
854#define MT2_MLME_DLS_REQ 0
855#define MT2_PEER_DLS_REQ 1
856#define MT2_PEER_DLS_RSP 2
857#define MT2_MLME_DLS_TEAR_DOWN 3
858#define MT2_PEER_DLS_TEAR_DOWN 4
859#define MAX_DLS_MSG 5
860
861#define DLS_FUNC_SIZE (MAX_DLS_STATE * MAX_DLS_MSG)
862
863//
864// STA's WPA-PSK State machine: states, events, total function #
865//
866#define WPA_PSK_IDLE 0
867#define MAX_WPA_PSK_STATE 1
868
869#define WPA_MACHINE_BASE 0
870#define MT2_EAPPacket 0
871#define MT2_EAPOLStart 1
872#define MT2_EAPOLLogoff 2
873#define MT2_EAPOLKey 3
874#define MT2_EAPOLASFAlert 4
875#define MAX_WPA_PSK_MSG 5
876
877#define WPA_PSK_FUNC_SIZE (MAX_WPA_PSK_STATE * MAX_WPA_PSK_MSG)
878
879//
880// STA's CISCO-AIRONET State machine: states, events, total function #
881//
882#define AIRONET_IDLE 0
883#define AIRONET_SCANNING 1
884#define MAX_AIRONET_STATE 2
885
886#define AIRONET_MACHINE_BASE 0
887#define MT2_AIRONET_MSG 0
888#define MT2_AIRONET_SCAN_REQ 1
889#define MT2_AIRONET_SCAN_DONE 2
890#define MAX_AIRONET_MSG 3
891
892#define AIRONET_FUNC_SIZE (MAX_AIRONET_STATE * MAX_AIRONET_MSG)
893
894//
895// WSC State machine: states, events, total function #
896//
897
898//
899// AP's CONTROL/CONNECT state machine: states, events, total function #
900//
901#define AP_CNTL_FUNC_SIZE 1
902
903//
904// AP's ASSOC state machine: states, events, total function #
905//
906#define AP_ASSOC_IDLE 0
907#define AP_MAX_ASSOC_STATE 1
908
909#define AP_ASSOC_MACHINE_BASE 0
910#define APMT2_MLME_DISASSOC_REQ 0
911#define APMT2_PEER_DISASSOC_REQ 1
912#define APMT2_PEER_ASSOC_REQ 2
913#define APMT2_PEER_REASSOC_REQ 3
914#define APMT2_CLS3ERR 4
915#define AP_MAX_ASSOC_MSG 5
916
917#define AP_ASSOC_FUNC_SIZE (AP_MAX_ASSOC_STATE * AP_MAX_ASSOC_MSG)
918
919//
920// AP's AUTHENTICATION state machine: states, events, total function #
921//
922#define AP_AUTH_REQ_IDLE 0
923#define AP_MAX_AUTH_STATE 1
924
925#define AP_AUTH_MACHINE_BASE 0
926#define APMT2_MLME_DEAUTH_REQ 0
927#define APMT2_CLS2ERR 1
928#define AP_MAX_AUTH_MSG 2
929
930#define AP_AUTH_FUNC_SIZE (AP_MAX_AUTH_STATE * AP_MAX_AUTH_MSG)
931
932//
933// AP's AUTH-RSP state machine: states, events, total function #
934//
935#define AP_AUTH_RSP_IDLE 0
936#define AP_MAX_AUTH_RSP_STATE 1
937
938#define AP_AUTH_RSP_MACHINE_BASE 0
939#define APMT2_AUTH_CHALLENGE_TIMEOUT 0
940#define APMT2_PEER_AUTH_ODD 1
941#define APMT2_PEER_DEAUTH 2
942#define AP_MAX_AUTH_RSP_MSG 3
943
944#define AP_AUTH_RSP_FUNC_SIZE (AP_MAX_AUTH_RSP_STATE * AP_MAX_AUTH_RSP_MSG)
945
946//
947// AP's SYNC state machine: states, events, total function #
948//
949#define AP_SYNC_IDLE 0
950#define AP_SCAN_LISTEN 1
951#define AP_MAX_SYNC_STATE 2
952
953#define AP_SYNC_MACHINE_BASE 0
954#define APMT2_PEER_PROBE_REQ 0
955#define APMT2_PEER_BEACON 1
956#define APMT2_MLME_SCAN_REQ 2
957#define APMT2_PEER_PROBE_RSP 3
958#define APMT2_SCAN_TIMEOUT 4
959#define APMT2_MLME_SCAN_CNCL 5
960#define AP_MAX_SYNC_MSG 6
961
962#define AP_SYNC_FUNC_SIZE (AP_MAX_SYNC_STATE * AP_MAX_SYNC_MSG)
963
964//
965// AP's WPA state machine: states, events, total function #
966//
967#define AP_WPA_PTK 0
968#define AP_MAX_WPA_PTK_STATE 1
969
970#define AP_WPA_MACHINE_BASE 0
971#define APMT2_EAPPacket 0
972#define APMT2_EAPOLStart 1
973#define APMT2_EAPOLLogoff 2
974#define APMT2_EAPOLKey 3
975#define APMT2_EAPOLASFAlert 4
976#define AP_MAX_WPA_MSG 5
977
978#define AP_WPA_FUNC_SIZE (AP_MAX_WPA_PTK_STATE * AP_MAX_WPA_MSG)
979
980
981
982// =============================================================================
983
984// value domain of 802.11 header FC.Tyte, which is b3..b2 of the 1st-byte of MAC header
985#define BTYPE_MGMT 0
986#define BTYPE_CNTL 1
987#define BTYPE_DATA 2
988
989// value domain of 802.11 MGMT frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header
990#define SUBTYPE_ASSOC_REQ 0
991#define SUBTYPE_ASSOC_RSP 1
992#define SUBTYPE_REASSOC_REQ 2
993#define SUBTYPE_REASSOC_RSP 3
994#define SUBTYPE_PROBE_REQ 4
995#define SUBTYPE_PROBE_RSP 5
996#define SUBTYPE_BEACON 8
997#define SUBTYPE_ATIM 9
998#define SUBTYPE_DISASSOC 10
999#define SUBTYPE_AUTH 11
1000#define SUBTYPE_DEAUTH 12
1001#define SUBTYPE_ACTION 13
1002#define SUBTYPE_ACTION_NO_ACK 14
1003
1004// value domain of 802.11 CNTL frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header
1005#define SUBTYPE_WRAPPER 7
1006#define SUBTYPE_BLOCK_ACK_REQ 8
1007#define SUBTYPE_BLOCK_ACK 9
1008#define SUBTYPE_PS_POLL 10
1009#define SUBTYPE_RTS 11
1010#define SUBTYPE_CTS 12
1011#define SUBTYPE_ACK 13
1012#define SUBTYPE_CFEND 14
1013#define SUBTYPE_CFEND_CFACK 15
1014
1015// value domain of 802.11 DATA frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header
1016#define SUBTYPE_DATA 0
1017#define SUBTYPE_DATA_CFACK 1
1018#define SUBTYPE_DATA_CFPOLL 2
1019#define SUBTYPE_DATA_CFACK_CFPOLL 3
1020#define SUBTYPE_NULL_FUNC 4
1021#define SUBTYPE_CFACK 5
1022#define SUBTYPE_CFPOLL 6
1023#define SUBTYPE_CFACK_CFPOLL 7
1024#define SUBTYPE_QDATA 8
1025#define SUBTYPE_QDATA_CFACK 9
1026#define SUBTYPE_QDATA_CFPOLL 10
1027#define SUBTYPE_QDATA_CFACK_CFPOLL 11
1028#define SUBTYPE_QOS_NULL 12
1029#define SUBTYPE_QOS_CFACK 13
1030#define SUBTYPE_QOS_CFPOLL 14
1031#define SUBTYPE_QOS_CFACK_CFPOLL 15
1032
1033// ACK policy of QOS Control field bit 6:5
1034#define NORMAL_ACK 0x00 // b6:5 = 00
1035#define NO_ACK 0x20 // b6:5 = 01
1036#define NO_EXPLICIT_ACK 0x40 // b6:5 = 10
1037#define BLOCK_ACK 0x60 // b6:5 = 11
1038
1039//
1040// rtmp_data.c use these definition
1041//
1042#define LENGTH_802_11 24
1043#define LENGTH_802_11_AND_H 30
1044#define LENGTH_802_11_CRC_H 34
1045#define LENGTH_802_11_CRC 28
1046#define LENGTH_802_11_WITH_ADDR4 30
1047#define LENGTH_802_3 14
1048#define LENGTH_802_3_TYPE 2
1049#define LENGTH_802_1_H 8
1050#define LENGTH_EAPOL_H 4
1051#define LENGTH_WMMQOS_H 2
1052#define LENGTH_CRC 4
1053#define MAX_SEQ_NUMBER 0x0fff
1054#define LENGTH_802_3_NO_TYPE 12
1055#define LENGTH_802_1Q 4 /* VLAN related */
1056
1057// STA_CSR4.field.TxResult
1058#define TX_RESULT_SUCCESS 0
1059#define TX_RESULT_ZERO_LENGTH 1
1060#define TX_RESULT_UNDER_RUN 2
1061#define TX_RESULT_OHY_ERROR 4
1062#define TX_RESULT_RETRY_FAIL 6
1063
1064// All PHY rate summary in TXD
1065// Preamble MODE in TxD
1066#define MODE_CCK 0
1067#define MODE_OFDM 1
1068#ifdef DOT11_N_SUPPORT
1069#define MODE_HTMIX 2
1070#define MODE_HTGREENFIELD 3
1071#endif // DOT11_N_SUPPORT //
1072// MCS for CCK. BW.SGI.STBC are reserved
1073#define MCS_LONGP_RATE_1 0 // long preamble CCK 1Mbps
1074#define MCS_LONGP_RATE_2 1 // long preamble CCK 1Mbps
1075#define MCS_LONGP_RATE_5_5 2
1076#define MCS_LONGP_RATE_11 3
1077#define MCS_SHORTP_RATE_1 4 // long preamble CCK 1Mbps. short is forbidden in 1Mbps
1078#define MCS_SHORTP_RATE_2 5 // short preamble CCK 2Mbps
1079#define MCS_SHORTP_RATE_5_5 6
1080#define MCS_SHORTP_RATE_11 7
1081// To send duplicate legacy OFDM. set BW=BW_40. SGI.STBC are reserved
1082#define MCS_RATE_6 0 // legacy OFDM
1083#define MCS_RATE_9 1 // OFDM
1084#define MCS_RATE_12 2 // OFDM
1085#define MCS_RATE_18 3 // OFDM
1086#define MCS_RATE_24 4 // OFDM
1087#define MCS_RATE_36 5 // OFDM
1088#define MCS_RATE_48 6 // OFDM
1089#define MCS_RATE_54 7 // OFDM
1090// HT
1091#define MCS_0 0 // 1S
1092#define MCS_1 1
1093#define MCS_2 2
1094#define MCS_3 3
1095#define MCS_4 4
1096#define MCS_5 5
1097#define MCS_6 6
1098#define MCS_7 7
1099#define MCS_8 8 // 2S
1100#define MCS_9 9
1101#define MCS_10 10
1102#define MCS_11 11
1103#define MCS_12 12
1104#define MCS_13 13
1105#define MCS_14 14
1106#define MCS_15 15
1107#define MCS_16 16 // 3*3
1108#define MCS_17 17
1109#define MCS_18 18
1110#define MCS_19 19
1111#define MCS_20 20
1112#define MCS_21 21
1113#define MCS_22 22
1114#define MCS_23 23
1115#define MCS_32 32
1116#define MCS_AUTO 33
1117
1118#ifdef DOT11_N_SUPPORT
1119// OID_HTPHYMODE
1120// MODE
1121#define HTMODE_MM 0
1122#define HTMODE_GF 1
1123#endif // DOT11_N_SUPPORT //
1124
1125// Fixed Tx MODE - HT, CCK or OFDM
1126#define FIXED_TXMODE_HT 0
1127#define FIXED_TXMODE_CCK 1
1128#define FIXED_TXMODE_OFDM 2
1129// BW
1130#define BW_20 BAND_WIDTH_20
1131#define BW_40 BAND_WIDTH_40
1132#define BW_BOTH BAND_WIDTH_BOTH
1133#define BW_10 BAND_WIDTH_10 // 802.11j has 10MHz. This definition is for internal usage. doesn't fill in the IE or other field.
1134
1135#ifdef DOT11_N_SUPPORT
1136// SHORTGI
1137#define GI_400 GAP_INTERVAL_400 // only support in HT mode
1138#define GI_BOTH GAP_INTERVAL_BOTH
1139#endif // DOT11_N_SUPPORT //
1140#define GI_800 GAP_INTERVAL_800
1141// STBC
1142#define STBC_NONE 0
1143#ifdef DOT11_N_SUPPORT
1144#define STBC_USE 1 // limited use in rt2860b phy
1145#define RXSTBC_ONE 1 // rx support of one spatial stream
1146#define RXSTBC_TWO 2 // rx support of 1 and 2 spatial stream
1147#define RXSTBC_THR 3 // rx support of 1~3 spatial stream
1148// MCS FEEDBACK
1149#define MCSFBK_NONE 0 // not support mcs feedback /
1150#define MCSFBK_RSV 1 // reserved
1151#define MCSFBK_UNSOLICIT 2 // only support unsolict mcs feedback
1152#define MCSFBK_MRQ 3 // response to both MRQ and unsolict mcs feedback
1153
1154// MIMO power safe
1155#define MMPS_STATIC 0
1156#define MMPS_DYNAMIC 1
1157#define MMPS_RSV 2
1158#define MMPS_ENABLE 3
1159
1160
1161// A-MSDU size
1162#define AMSDU_0 0
1163#define AMSDU_1 1
1164
1165#endif // DOT11_N_SUPPORT //
1166
1167// MCS use 7 bits
1168#define TXRATEMIMO 0x80
1169#define TXRATEMCS 0x7F
1170#define TXRATEOFDM 0x7F
1171#define RATE_1 0
1172#define RATE_2 1
1173#define RATE_5_5 2
1174#define RATE_11 3
1175#define RATE_6 4 // OFDM
1176#define RATE_9 5 // OFDM
1177#define RATE_12 6 // OFDM
1178#define RATE_18 7 // OFDM
1179#define RATE_24 8 // OFDM
1180#define RATE_36 9 // OFDM
1181#define RATE_48 10 // OFDM
1182#define RATE_54 11 // OFDM
1183#define RATE_FIRST_OFDM_RATE RATE_6
1184#define RATE_LAST_OFDM_RATE RATE_54
1185#define RATE_6_5 12 // HT mix
1186#define RATE_13 13 // HT mix
1187#define RATE_19_5 14 // HT mix
1188#define RATE_26 15 // HT mix
1189#define RATE_39 16 // HT mix
1190#define RATE_52 17 // HT mix
1191#define RATE_58_5 18 // HT mix
1192#define RATE_65 19 // HT mix
1193#define RATE_78 20 // HT mix
1194#define RATE_104 21 // HT mix
1195#define RATE_117 22 // HT mix
1196#define RATE_130 23 // HT mix
1197//#define RATE_AUTO_SWITCH 255 // for StaCfg.FixedTxRate only
1198#define HTRATE_0 12
1199#define RATE_FIRST_MM_RATE HTRATE_0
1200#define RATE_FIRST_HT_RATE HTRATE_0
1201#define RATE_LAST_HT_RATE HTRATE_0
1202
1203// pTxWI->txop
1204#define IFS_HTTXOP 0 // The txop will be handles by ASIC.
1205#define IFS_PIFS 1
1206#define IFS_SIFS 2
1207#define IFS_BACKOFF 3
1208
1209// pTxD->RetryMode
1210#define LONG_RETRY 1
1211#define SHORT_RETRY 0
1212
1213// Country Region definition
1214#define REGION_MINIMUM_BG_BAND 0
1215#define REGION_0_BG_BAND 0 // 1-11
1216#define REGION_1_BG_BAND 1 // 1-13
1217#define REGION_2_BG_BAND 2 // 10-11
1218#define REGION_3_BG_BAND 3 // 10-13
1219#define REGION_4_BG_BAND 4 // 14
1220#define REGION_5_BG_BAND 5 // 1-14
1221#define REGION_6_BG_BAND 6 // 3-9
1222#define REGION_7_BG_BAND 7 // 5-13
1223#define REGION_31_BG_BAND 31 // 5-13
1224#define REGION_MAXIMUM_BG_BAND 7
1225
1226#define REGION_MINIMUM_A_BAND 0
1227#define REGION_0_A_BAND 0 // 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165
1228#define REGION_1_A_BAND 1 // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140
1229#define REGION_2_A_BAND 2 // 36, 40, 44, 48, 52, 56, 60, 64
1230#define REGION_3_A_BAND 3 // 52, 56, 60, 64, 149, 153, 157, 161
1231#define REGION_4_A_BAND 4 // 149, 153, 157, 161, 165
1232#define REGION_5_A_BAND 5 // 149, 153, 157, 161
1233#define REGION_6_A_BAND 6 // 36, 40, 44, 48
1234#define REGION_7_A_BAND 7 // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165
1235#define REGION_8_A_BAND 8 // 52, 56, 60, 64
1236#define REGION_9_A_BAND 9 // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165
1237#define REGION_10_A_BAND 10 // 36, 40, 44, 48, 149, 153, 157, 161, 165
1238#define REGION_11_A_BAND 11 // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153, 157, 161
1239#define REGION_MAXIMUM_A_BAND 11
1240
1241// pTxD->CipherAlg
1242#define CIPHER_NONE 0
1243#define CIPHER_WEP64 1
1244#define CIPHER_WEP128 2
1245#define CIPHER_TKIP 3
1246#define CIPHER_AES 4
1247#define CIPHER_CKIP64 5
1248#define CIPHER_CKIP128 6
1249#define CIPHER_TKIP_NO_MIC 7 // MIC appended by driver: not a valid value in hardware key table
1250#define CIPHER_SMS4 8
1251
1252// value domain of pAd->RfIcType
1253#define RFIC_2820 1 // 2.4G 2T3R
1254#define RFIC_2850 2 // 2.4G/5G 2T3R
1255#define RFIC_2720 3 // 2.4G 1T2R
1256#define RFIC_2750 4 // 2.4G/5G 1T2R
1257#define RFIC_3020 5 // 2.4G 1T1R
1258#define RFIC_2020 6 // 2.4G B/G
1259#define RFIC_3021 7 // 2.4G 1T2R
1260#define RFIC_3022 8 // 2.4G 2T2R
1261
1262// LED Status.
1263#define LED_LINK_DOWN 0
1264#define LED_LINK_UP 1
1265#define LED_RADIO_OFF 2
1266#define LED_RADIO_ON 3
1267#define LED_HALT 4
1268#define LED_WPS 5
1269#define LED_ON_SITE_SURVEY 6
1270#define LED_POWER_UP 7
1271
1272// value domain of pAd->LedCntl.LedMode and E2PROM
1273#define LED_MODE_DEFAULT 0
1274#define LED_MODE_TWO_LED 1
1275#define LED_MODE_SIGNAL_STREGTH 8 // EEPROM define =8
1276
1277// RC4 init value, used fro WEP & TKIP
1278#define PPPINITFCS32 0xffffffff /* Initial FCS value */
1279
1280// value domain of pAd->StaCfg.PortSecured. 802.1X controlled port definition
1281#define WPA_802_1X_PORT_SECURED 1
1282#define WPA_802_1X_PORT_NOT_SECURED 2
1283
1284#define PAIRWISE_KEY 1
1285#define GROUP_KEY 2
1286
1287//definition of DRS
1288#define MAX_STEP_OF_TX_RATE_SWITCH 32
1289
1290
1291// pre-allocated free NDIS PACKET/BUFFER poll for internal usage
1292#define MAX_NUM_OF_FREE_NDIS_PACKET 128
1293
1294//Block ACK
1295#define MAX_TX_REORDERBUF 64
1296#define MAX_RX_REORDERBUF 64
1297#define DEFAULT_TX_TIMEOUT 30
1298#define DEFAULT_RX_TIMEOUT 30
1299
1300// definition of Recipient or Originator
1301#define I_RECIPIENT TRUE
1302#define I_ORIGINATOR FALSE
1303
1304#define DEFAULT_BBP_TX_POWER 0
1305#define DEFAULT_RF_TX_POWER 5
1306
1307#define MAX_INI_BUFFER_SIZE 4096
1308#define MAX_PARAM_BUFFER_SIZE (2048) // enough for ACL (18*64)
1309 //18 : the length of Mac address acceptable format "01:02:03:04:05:06;")
1310 //64 : MAX_NUM_OF_ACL_LIST
1311// definition of pAd->OpMode
1312#define OPMODE_STA 0
1313#define OPMODE_AP 1
1314//#define OPMODE_L3_BRG 2 // as AP and STA at the same time
1315
1316#ifdef RT_BIG_ENDIAN
1317#define DIR_READ 0
1318#define DIR_WRITE 1
1319#define TYPE_TXD 0
1320#define TYPE_RXD 1
1321#define TYPE_TXINFO 0
1322#define TYPE_RXINFO 1
1323#define TYPE_TXWI 0
1324#define TYPE_RXWI 1
1325#endif
1326
1327// ========================= AP rtmp_def.h ===========================
1328// value domain for pAd->EventTab.Log[].Event
1329#define EVENT_RESET_ACCESS_POINT 0 // Log = "hh:mm:ss Restart Access Point"
1330#define EVENT_ASSOCIATED 1 // Log = "hh:mm:ss STA 00:01:02:03:04:05 associated"
1331#define EVENT_DISASSOCIATED 2 // Log = "hh:mm:ss STA 00:01:02:03:04:05 left this BSS"
1332#define EVENT_AGED_OUT 3 // Log = "hh:mm:ss STA 00:01:02:03:04:05 was aged-out and removed from this BSS"
1333#define EVENT_COUNTER_M 4
1334#define EVENT_INVALID_PSK 5
1335#define EVENT_MAX_EVENT_TYPE 6
1336// ==== end of AP rtmp_def.h ============
1337
1338// definition RSSI Number
1339#define RSSI_0 0
1340#define RSSI_1 1
1341#define RSSI_2 2
1342
1343// definition of radar detection
1344#define RD_NORMAL_MODE 0 // Not found radar signal
1345#define RD_SWITCHING_MODE 1 // Found radar signal, and doing channel switch
1346#define RD_SILENCE_MODE 2 // After channel switch, need to be silence a while to ensure radar not found
1347
1348//Driver defined cid for mapping status and command.
1349#define SLEEPCID 0x11
1350#define WAKECID 0x22
1351#define QUERYPOWERCID 0x33
1352#define OWNERMCU 0x1
1353#define OWNERCPU 0x0
1354
1355// MBSSID definition
1356#define ENTRY_NOT_FOUND 0xFF
1357
1358
1359/* After Linux 2.6.9,
1360 * VLAN module use Private (from user) interface flags (netdevice->priv_flags).
1361 * #define IFF_802_1Q_VLAN 0x1 -- 802.1Q VLAN device. in if.h
1362 * ref to ip_sabotage_out() [ out->priv_flags & IFF_802_1Q_VLAN ] in br_netfilter.c
1363 *
1364 * For this reason, we MUST use EVEN value in priv_flags
1365 */
1366#define INT_MAIN 0x0100
1367#define INT_MBSSID 0x0200
1368#define INT_WDS 0x0300
1369#define INT_APCLI 0x0400
1370#define INT_MESH 0x0500
1371
1372// Use bitmap to allow coexist of ATE_TXFRAME and ATE_RXFRAME(i.e.,to support LoopBack mode)
1373#ifdef RALINK_ATE
1374#define ATE_START 0x00 // Start ATE
1375#define ATE_STOP 0x80 // Stop ATE
1376#define ATE_TXCONT 0x05 // Continuous Transmit
1377#define ATE_TXCARR 0x09 // Transmit Carrier
1378#define ATE_TXCARRSUPP 0x11 // Transmit Carrier Suppression
1379#define ATE_TXFRAME 0x01 // Transmit Frames
1380#define ATE_RXFRAME 0x02 // Receive Frames
1381#ifdef RALINK_28xx_QA
1382#define ATE_TXSTOP 0xe2 // Stop Transmition(i.e., TXCONT, TXCARR, TXCARRSUPP, and TXFRAME)
1383#define ATE_RXSTOP 0xfd // Stop receiving Frames
1384#define BBP22_TXFRAME 0x00 // Transmit Frames
1385#define BBP22_TXCONT_OR_CARRSUPP 0x80 // Continuous Transmit or Carrier Suppression
1386#define BBP22_TXCARR 0xc1 // Transmit Carrier
1387#define BBP24_TXCONT 0x00 // Continuous Transmit
1388#define BBP24_CARRSUPP 0x01 // Carrier Suppression
1389#endif // RALINK_28xx_QA //
1390#endif // RALINK_ATE //
1391
1392// WEP Key TYPE
1393#define WEP_HEXADECIMAL_TYPE 0
1394#define WEP_ASCII_TYPE 1
1395
1396
1397
1398// WIRELESS EVENTS definition
1399/* Max number of char in custom event, refer to wireless_tools.28/wireless.20.h */
1400#define IW_CUSTOM_MAX_LEN 255 /* In bytes */
1401
1402// For system event - start
1403#define IW_SYS_EVENT_FLAG_START 0x0200
1404#define IW_ASSOC_EVENT_FLAG 0x0200
1405#define IW_DISASSOC_EVENT_FLAG 0x0201
1406#define IW_DEAUTH_EVENT_FLAG 0x0202
1407#define IW_AGEOUT_EVENT_FLAG 0x0203
1408#define IW_COUNTER_MEASURES_EVENT_FLAG 0x0204
1409#define IW_REPLAY_COUNTER_DIFF_EVENT_FLAG 0x0205
1410#define IW_RSNIE_DIFF_EVENT_FLAG 0x0206
1411#define IW_MIC_DIFF_EVENT_FLAG 0x0207
1412#define IW_ICV_ERROR_EVENT_FLAG 0x0208
1413#define IW_MIC_ERROR_EVENT_FLAG 0x0209
1414#define IW_GROUP_HS_TIMEOUT_EVENT_FLAG 0x020A
1415#define IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG 0x020B
1416#define IW_RSNIE_SANITY_FAIL_EVENT_FLAG 0x020C
1417#define IW_SET_KEY_DONE_WPA1_EVENT_FLAG 0x020D
1418#define IW_SET_KEY_DONE_WPA2_EVENT_FLAG 0x020E
1419#define IW_STA_LINKUP_EVENT_FLAG 0x020F
1420#define IW_STA_LINKDOWN_EVENT_FLAG 0x0210
1421#define IW_SCAN_COMPLETED_EVENT_FLAG 0x0211
1422#define IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG 0x0212
1423// if add new system event flag, please upadte the IW_SYS_EVENT_FLAG_END
1424#define IW_SYS_EVENT_FLAG_END 0x0212
1425#define IW_SYS_EVENT_TYPE_NUM (IW_SYS_EVENT_FLAG_END - IW_SYS_EVENT_FLAG_START + 1)
1426// For system event - end
1427
1428// For spoof attack event - start
1429#define IW_SPOOF_EVENT_FLAG_START 0x0300
1430#define IW_CONFLICT_SSID_EVENT_FLAG 0x0300
1431#define IW_SPOOF_ASSOC_RESP_EVENT_FLAG 0x0301
1432#define IW_SPOOF_REASSOC_RESP_EVENT_FLAG 0x0302
1433#define IW_SPOOF_PROBE_RESP_EVENT_FLAG 0x0303
1434#define IW_SPOOF_BEACON_EVENT_FLAG 0x0304
1435#define IW_SPOOF_DISASSOC_EVENT_FLAG 0x0305
1436#define IW_SPOOF_AUTH_EVENT_FLAG 0x0306
1437#define IW_SPOOF_DEAUTH_EVENT_FLAG 0x0307
1438#define IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG 0x0308
1439#define IW_REPLAY_ATTACK_EVENT_FLAG 0x0309
1440// if add new spoof attack event flag, please upadte the IW_SPOOF_EVENT_FLAG_END
1441#define IW_SPOOF_EVENT_FLAG_END 0x0309
1442#define IW_SPOOF_EVENT_TYPE_NUM (IW_SPOOF_EVENT_FLAG_END - IW_SPOOF_EVENT_FLAG_START + 1)
1443// For spoof attack event - end
1444
1445// For flooding attack event - start
1446#define IW_FLOOD_EVENT_FLAG_START 0x0400
1447#define IW_FLOOD_AUTH_EVENT_FLAG 0x0400
1448#define IW_FLOOD_ASSOC_REQ_EVENT_FLAG 0x0401
1449#define IW_FLOOD_REASSOC_REQ_EVENT_FLAG 0x0402
1450#define IW_FLOOD_PROBE_REQ_EVENT_FLAG 0x0403
1451#define IW_FLOOD_DISASSOC_EVENT_FLAG 0x0404
1452#define IW_FLOOD_DEAUTH_EVENT_FLAG 0x0405
1453#define IW_FLOOD_EAP_REQ_EVENT_FLAG 0x0406
1454// if add new flooding attack event flag, please upadte the IW_FLOOD_EVENT_FLAG_END
1455#define IW_FLOOD_EVENT_FLAG_END 0x0406
1456#define IW_FLOOD_EVENT_TYPE_NUM (IW_FLOOD_EVENT_FLAG_END - IW_FLOOD_EVENT_FLAG_START + 1)
1457// For flooding attack - end
1458
1459// End - WIRELESS EVENTS definition
1460
1461#ifdef CONFIG_STA_SUPPORT
1462// definition for DLS, kathy
1463#define MAX_NUM_OF_INIT_DLS_ENTRY 1
1464#define MAX_NUM_OF_DLS_ENTRY MAX_NUMBER_OF_DLS_ENTRY
1465
1466//Block ACK , rt2860, kathy
1467#define MAX_TX_REORDERBUF 64
1468#define MAX_RX_REORDERBUF 64
1469#define DEFAULT_TX_TIMEOUT 30
1470#define DEFAULT_RX_TIMEOUT 30
1471#ifndef CONFIG_AP_SUPPORT
1472#define MAX_BARECI_SESSION 8
1473#endif
1474
1475#ifndef IW_ESSID_MAX_SIZE
1476/* Maximum size of the ESSID and pAd->nickname strings */
1477#define IW_ESSID_MAX_SIZE 32
1478#endif
1479#endif // CONFIG_STA_SUPPORT //
1480
1481#ifdef MCAST_RATE_SPECIFIC
1482#define MCAST_DISABLE 0
1483#define MCAST_CCK 1
1484#define MCAST_OFDM 2
1485#define MCAST_HTMIX 3
1486#endif // MCAST_RATE_SPECIFIC //
1487
1488// For AsicRadioOff/AsicRadioOn function
1489#define DOT11POWERSAVE 0
1490#define GUIRADIO_OFF 1
1491#define RTMP_HALT 2
1492#define GUI_IDLE_POWER_SAVE 3
1493// --
1494
1495
1496// definition for WpaSupport flag
1497#define WPA_SUPPLICANT_DISABLE 0
1498#define WPA_SUPPLICANT_ENABLE 1
1499#define WPA_SUPPLICANT_ENABLE_WITH_WEB_UI 2
1500
1501// Endian byte swapping codes
1502#define SWAP16(x) \
1503 ((UINT16)( \
1504 (((UINT16)(x) & (UINT16) 0x00ffU) << 8) | \
1505 (((UINT16)(x) & (UINT16) 0xff00U) >> 8) ))
1506
1507#define SWAP32(x) \
1508 ((UINT32)( \
1509 (((UINT32)(x) & (UINT32) 0x000000ffUL) << 24) | \
1510 (((UINT32)(x) & (UINT32) 0x0000ff00UL) << 8) | \
1511 (((UINT32)(x) & (UINT32) 0x00ff0000UL) >> 8) | \
1512 (((UINT32)(x) & (UINT32) 0xff000000UL) >> 24) ))
1513
1514#define SWAP64(x) \
1515 ((UINT64)( \
1516 (UINT64)(((UINT64)(x) & (UINT64) 0x00000000000000ffULL) << 56) | \
1517 (UINT64)(((UINT64)(x) & (UINT64) 0x000000000000ff00ULL) << 40) | \
1518 (UINT64)(((UINT64)(x) & (UINT64) 0x0000000000ff0000ULL) << 24) | \
1519 (UINT64)(((UINT64)(x) & (UINT64) 0x00000000ff000000ULL) << 8) | \
1520 (UINT64)(((UINT64)(x) & (UINT64) 0x000000ff00000000ULL) >> 8) | \
1521 (UINT64)(((UINT64)(x) & (UINT64) 0x0000ff0000000000ULL) >> 24) | \
1522 (UINT64)(((UINT64)(x) & (UINT64) 0x00ff000000000000ULL) >> 40) | \
1523 (UINT64)(((UINT64)(x) & (UINT64) 0xff00000000000000ULL) >> 56) ))
1524
1525#ifdef RT_BIG_ENDIAN
1526
1527#define cpu2le64(x) SWAP64((x))
1528#define le2cpu64(x) SWAP64((x))
1529#define cpu2le32(x) SWAP32((x))
1530#define le2cpu32(x) SWAP32((x))
1531#define cpu2le16(x) SWAP16((x))
1532#define le2cpu16(x) SWAP16((x))
1533#define cpu2be64(x) ((UINT64)(x))
1534#define be2cpu64(x) ((UINT64)(x))
1535#define cpu2be32(x) ((UINT32)(x))
1536#define be2cpu32(x) ((UINT32)(x))
1537#define cpu2be16(x) ((UINT16)(x))
1538#define be2cpu16(x) ((UINT16)(x))
1539
1540#else // Little_Endian
1541
1542#define cpu2le64(x) ((UINT64)(x))
1543#define le2cpu64(x) ((UINT64)(x))
1544#define cpu2le32(x) ((UINT32)(x))
1545#define le2cpu32(x) ((UINT32)(x))
1546#define cpu2le16(x) ((UINT16)(x))
1547#define le2cpu16(x) ((UINT16)(x))
1548#define cpu2be64(x) SWAP64((x))
1549#define be2cpu64(x) SWAP64((x))
1550#define cpu2be32(x) SWAP32((x))
1551#define be2cpu32(x) SWAP32((x))
1552#define cpu2be16(x) SWAP16((x))
1553#define be2cpu16(x) SWAP16((x))
1554
1555#endif // RT_BIG_ENDIAN
1556
1557#endif // __RTMP_DEF_H__
1558
1559
diff --git a/drivers/staging/rt3070/rtmp_type.h b/drivers/staging/rt3070/rtmp_type.h
new file mode 100644
index 000000000000..4e4b168b9e92
--- /dev/null
+++ b/drivers/staging/rt3070/rtmp_type.h
@@ -0,0 +1,95 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 rtmp_type.h
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Name Date Modification logs
36 Paul Lin 1-2-2004
37*/
38#ifndef __RTMP_TYPE_H__
39#define __RTMP_TYPE_H__
40
41
42#define PACKED __attribute__ ((packed))
43
44// Put platform dependent declaration here
45// For example, linux type definition
46typedef unsigned char UINT8;
47typedef unsigned short UINT16;
48typedef unsigned int UINT32;
49typedef unsigned long long UINT64;
50typedef int INT32;
51typedef long long INT64;
52
53typedef unsigned char * PUINT8;
54typedef unsigned short * PUINT16;
55typedef unsigned int * PUINT32;
56typedef unsigned long long * PUINT64;
57typedef int * PINT32;
58typedef long long * PINT64;
59
60typedef signed char CHAR;
61typedef signed short SHORT;
62typedef signed int INT;
63typedef signed long LONG;
64typedef signed long long LONGLONG;
65
66
67typedef unsigned char UCHAR;
68typedef unsigned short USHORT;
69typedef unsigned int UINT;
70typedef unsigned long ULONG;
71typedef unsigned long long ULONGLONG;
72
73typedef unsigned char BOOLEAN;
74typedef void VOID;
75
76typedef VOID * PVOID;
77typedef CHAR * PCHAR;
78typedef UCHAR * PUCHAR;
79typedef USHORT * PUSHORT;
80typedef LONG * PLONG;
81typedef ULONG * PULONG;
82typedef UINT * PUINT;
83
84typedef unsigned int NDIS_MEDIA_STATE;
85
86typedef union _LARGE_INTEGER {
87 struct {
88 UINT LowPart;
89 INT32 HighPart;
90 } u;
91 INT64 QuadPart;
92} LARGE_INTEGER;
93
94#endif // __RTMP_TYPE_H__
95
diff --git a/drivers/staging/rt3070/spectrum.h b/drivers/staging/rt3070/spectrum.h
new file mode 100644
index 000000000000..94cfa5b174fc
--- /dev/null
+++ b/drivers/staging/rt3070/spectrum.h
@@ -0,0 +1,322 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26 */
27
28#ifndef __SPECTRUM_H__
29#define __SPECTRUM_H__
30
31#include "rtmp_type.h"
32#include "spectrum_def.h"
33
34typedef struct PACKED _TPC_REPORT_INFO
35{
36 UINT8 TxPwr;
37 UINT8 LinkMargin;
38} TPC_REPORT_INFO, *PTPC_REPORT_INFO;
39
40typedef struct PACKED _CH_SW_ANN_INFO
41{
42 UINT8 ChSwMode;
43 UINT8 Channel;
44 UINT8 ChSwCnt;
45} CH_SW_ANN_INFO, *PCH_SW_ANN_INFO;
46
47typedef union PACKED _MEASURE_REQ_MODE
48{
49#ifdef RT_BIG_ENDIAN
50 struct PACKED
51 {
52 UINT8 Rev1:4;
53 UINT8 Report:1;
54 UINT8 Request:1;
55 UINT8 Enable:1;
56 UINT8 Rev0:1;
57 } field;
58#else
59 struct PACKED
60 {
61 UINT8 Rev0:1;
62 UINT8 Enable:1;
63 UINT8 Request:1;
64 UINT8 Report:1;
65 UINT8 Rev1:4;
66 } field;
67#endif // RT_BIG_ENDIAN //
68 UINT8 word;
69} MEASURE_REQ_MODE, *PMEASURE_REQ_MODE;
70
71typedef struct PACKED _MEASURE_REQ
72{
73 UINT8 ChNum;
74 UINT64 MeasureStartTime;
75 UINT16 MeasureDuration;
76} MEASURE_REQ, *PMEASURE_REQ;
77
78typedef struct PACKED _MEASURE_REQ_INFO
79{
80 UINT8 Token;
81 MEASURE_REQ_MODE ReqMode;
82 UINT8 ReqType;
83 MEASURE_REQ MeasureReq;
84} MEASURE_REQ_INFO, *PMEASURE_REQ_INFO;
85
86typedef union PACKED _MEASURE_BASIC_REPORT_MAP
87{
88#ifdef RT_BIG_ENDIAN
89 struct PACKED
90 {
91 UINT8 Rev:3;
92 UINT8 Unmeasure:1;
93 UINT8 Radar:1;
94 UINT8 UnidentifiedSignal:1;
95 UINT8 OfdmPreamble:1;
96 UINT8 BSS:1;
97 } field;
98#else
99 struct PACKED
100 {
101 UINT8 BSS:1;
102 UINT8 OfdmPreamble:1;
103 UINT8 UnidentifiedSignal:1;
104 UINT8 Radar:1;
105 UINT8 Unmeasure:1;
106 UINT8 Rev:3;
107 } field;
108#endif // RT_BIG_ENDIAN //
109 UINT8 word;
110} MEASURE_BASIC_REPORT_MAP, *PMEASURE_BASIC_REPORT_MAP;
111
112typedef struct PACKED _MEASURE_BASIC_REPORT
113{
114 UINT8 ChNum;
115 UINT64 MeasureStartTime;
116 UINT16 MeasureDuration;
117 MEASURE_BASIC_REPORT_MAP Map;
118} MEASURE_BASIC_REPORT, *PMEASURE_BASIC_REPORT;
119
120typedef struct PACKED _MEASURE_CCA_REPORT
121{
122 UINT8 ChNum;
123 UINT64 MeasureStartTime;
124 UINT16 MeasureDuration;
125 UINT8 CCA_Busy_Fraction;
126} MEASURE_CCA_REPORT, *PMEASURE_CCA_REPORT;
127
128typedef struct PACKED _MEASURE_RPI_REPORT
129{
130 UINT8 ChNum;
131 UINT64 MeasureStartTime;
132 UINT16 MeasureDuration;
133 UINT8 RPI_Density[8];
134} MEASURE_RPI_REPORT, *PMEASURE_RPI_REPORT;
135
136typedef union PACKED _MEASURE_REPORT_MODE
137{
138 struct PACKED
139 {
140#ifdef RT_BIG_ENDIAN
141 UINT8 Rev:5;
142 UINT8 Refused:1;
143 UINT8 Incapable:1;
144 UINT8 Late:1;
145#else
146 UINT8 Late:1;
147 UINT8 Incapable:1;
148 UINT8 Refused:1;
149 UINT8 Rev:5;
150#endif // RT_BIG_ENDIAN //
151 } field;
152 UINT8 word;
153} MEASURE_REPORT_MODE, *PMEASURE_REPORT_MODE;
154
155typedef struct PACKED _MEASURE_REPORT_INFO
156{
157 UINT8 Token;
158 MEASURE_REPORT_MODE ReportMode;
159 UINT8 ReportType;
160 UINT8 Octect[0];
161} MEASURE_REPORT_INFO, *PMEASURE_REPORT_INFO;
162
163typedef struct PACKED _QUIET_INFO
164{
165 UINT8 QuietCnt;
166 UINT8 QuietPeriod;
167 UINT8 QuietDuration;
168 UINT8 QuietOffset;
169} QUIET_INFO, *PQUIET_INFO;
170
171/*
172 ==========================================================================
173 Description:
174 Prepare Measurement request action frame and enqueue it into
175 management queue waiting for transmition.
176
177 Parametrs:
178 1. the destination mac address of the frame.
179
180 Return : None.
181 ==========================================================================
182 */
183VOID EnqueueMeasurementReq(
184 IN PRTMP_ADAPTER pAd,
185 IN PUCHAR pDA,
186 IN UINT8 MeasureToken,
187 IN UINT8 MeasureReqMode,
188 IN UINT8 MeasureReqType,
189 IN UINT8 MeasureCh,
190 IN UINT16 MeasureDuration);
191
192/*
193 ==========================================================================
194 Description:
195 Prepare Measurement report action frame and enqueue it into
196 management queue waiting for transmition.
197
198 Parametrs:
199 1. the destination mac address of the frame.
200
201 Return : None.
202 ==========================================================================
203 */
204VOID EnqueueMeasurementRep(
205 IN PRTMP_ADAPTER pAd,
206 IN PUCHAR pDA,
207 IN UINT8 DialogToken,
208 IN UINT8 MeasureToken,
209 IN UINT8 MeasureReqMode,
210 IN UINT8 MeasureReqType,
211 IN UINT8 ReportInfoLen,
212 IN PUINT8 pReportInfo);
213
214/*
215 ==========================================================================
216 Description:
217 Prepare TPC Request action frame and enqueue it into
218 management queue waiting for transmition.
219
220 Parametrs:
221 1. the destination mac address of the frame.
222
223 Return : None.
224 ==========================================================================
225 */
226VOID EnqueueTPCReq(
227 IN PRTMP_ADAPTER pAd,
228 IN PUCHAR pDA,
229 IN UCHAR DialogToken);
230
231/*
232 ==========================================================================
233 Description:
234 Prepare TPC Report action frame and enqueue it into
235 management queue waiting for transmition.
236
237 Parametrs:
238 1. the destination mac address of the frame.
239
240 Return : None.
241 ==========================================================================
242 */
243VOID EnqueueTPCRep(
244 IN PRTMP_ADAPTER pAd,
245 IN PUCHAR pDA,
246 IN UINT8 DialogToken,
247 IN UINT8 TxPwr,
248 IN UINT8 LinkMargin);
249
250/*
251 ==========================================================================
252 Description:
253 Prepare Channel Switch Announcement action frame and enqueue it into
254 management queue waiting for transmition.
255
256 Parametrs:
257 1. the destination mac address of the frame.
258 2. Channel switch announcement mode.
259 2. a New selected channel.
260
261 Return : None.
262 ==========================================================================
263 */
264VOID EnqueueChSwAnn(
265 IN PRTMP_ADAPTER pAd,
266 IN PUCHAR pDA,
267 IN UINT8 ChSwMode,
268 IN UINT8 NewCh);
269
270/*
271 ==========================================================================
272 Description:
273 Spectrun action frames Handler such as channel switch annoucement,
274 measurement report, measurement request actions frames.
275
276 Parametrs:
277 Elme - MLME message containing the received frame
278
279 Return : None.
280 ==========================================================================
281 */
282VOID PeerSpectrumAction(
283 IN PRTMP_ADAPTER pAd,
284 IN MLME_QUEUE_ELEM *Elem);
285
286/*
287 ==========================================================================
288 Description:
289
290 Parametrs:
291
292 Return : None.
293 ==========================================================================
294 */
295INT Set_MeasureReq_Proc(
296 IN PRTMP_ADAPTER pAd,
297 IN PUCHAR arg);
298
299INT Set_TpcReq_Proc(
300 IN PRTMP_ADAPTER pAd,
301 IN PUCHAR arg);
302
303VOID MeasureReqTabInit(
304 IN PRTMP_ADAPTER pAd);
305
306VOID MeasureReqTabExit(
307 IN PRTMP_ADAPTER pAd);
308
309VOID TpcReqTabInit(
310 IN PRTMP_ADAPTER pAd);
311
312VOID TpcReqTabExit(
313 IN PRTMP_ADAPTER pAd);
314
315VOID NotifyChSwAnnToPeerAPs(
316 IN PRTMP_ADAPTER pAd,
317 IN PUCHAR pRA,
318 IN PUCHAR pTA,
319 IN UINT8 ChSwMode,
320 IN UINT8 Channel);
321#endif // __SPECTRUM_H__ //
322
diff --git a/drivers/staging/rt3070/spectrum_def.h b/drivers/staging/rt3070/spectrum_def.h
new file mode 100644
index 000000000000..4ca4817bba05
--- /dev/null
+++ b/drivers/staging/rt3070/spectrum_def.h
@@ -0,0 +1,95 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 spectrum_def.h
29
30 Abstract:
31 Handle association related requests either from WSTA or from local MLME
32
33 Revision History:
34 Who When What
35 --------- ---------- ----------------------------------------------
36 Fonchi Wu 2008 created for 802.11h
37 */
38
39#ifndef __SPECTRUM_DEF_H__
40#define __SPECTRUM_DEF_H__
41
42#define MAX_MEASURE_REQ_TAB_SIZE 3
43#define MAX_HASH_MEASURE_REQ_TAB_SIZE MAX_MEASURE_REQ_TAB_SIZE
44
45#define MAX_TPC_REQ_TAB_SIZE 3
46#define MAX_HASH_TPC_REQ_TAB_SIZE MAX_TPC_REQ_TAB_SIZE
47
48#define MIN_RCV_PWR 100 /* Negative value ((dBm) */
49
50#define RM_TPC_REQ 0
51#define RM_MEASURE_REQ 1
52
53#define RM_BASIC 0
54#define RM_CCA 1
55#define RM_RPI_HISTOGRAM 2
56
57#define TPC_REQ_AGE_OUT 500 /* ms */
58#define MQ_REQ_AGE_OUT 500 /* ms */
59
60#define TPC_DIALOGTOKEN_HASH_INDEX(_DialogToken) ((_DialogToken) % MAX_HASH_TPC_REQ_TAB_SIZE)
61#define MQ_DIALOGTOKEN_HASH_INDEX(_DialogToken) ((_DialogToken) % MAX_MEASURE_REQ_TAB_SIZE)
62
63typedef struct _MEASURE_REQ_ENTRY
64{
65 struct _MEASURE_REQ_ENTRY *pNext;
66 ULONG lastTime;
67 BOOLEAN Valid;
68 UINT8 DialogToken;
69 UINT8 MeasureDialogToken[3]; // 0:basic measure, 1: CCA measure, 2: RPI_Histogram measure.
70} MEASURE_REQ_ENTRY, *PMEASURE_REQ_ENTRY;
71
72typedef struct _MEASURE_REQ_TAB
73{
74 UCHAR Size;
75 PMEASURE_REQ_ENTRY Hash[MAX_HASH_MEASURE_REQ_TAB_SIZE];
76 MEASURE_REQ_ENTRY Content[MAX_MEASURE_REQ_TAB_SIZE];
77} MEASURE_REQ_TAB, *PMEASURE_REQ_TAB;
78
79typedef struct _TPC_REQ_ENTRY
80{
81 struct _TPC_REQ_ENTRY *pNext;
82 ULONG lastTime;
83 BOOLEAN Valid;
84 UINT8 DialogToken;
85} TPC_REQ_ENTRY, *PTPC_REQ_ENTRY;
86
87typedef struct _TPC_REQ_TAB
88{
89 UCHAR Size;
90 PTPC_REQ_ENTRY Hash[MAX_HASH_TPC_REQ_TAB_SIZE];
91 TPC_REQ_ENTRY Content[MAX_TPC_REQ_TAB_SIZE];
92} TPC_REQ_TAB, *PTPC_REQ_TAB;
93
94#endif // __SPECTRUM_DEF_H__ //
95
diff --git a/drivers/staging/rt3070/sta/aironet.c b/drivers/staging/rt3070/sta/aironet.c
new file mode 100644
index 000000000000..4af4a1906181
--- /dev/null
+++ b/drivers/staging/rt3070/sta/aironet.c
@@ -0,0 +1,1312 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 aironet.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Paul Lin 04-06-15 Initial
36*/
37#include "../rt_config.h"
38
39/*
40 ==========================================================================
41 Description:
42 association state machine init, including state transition and timer init
43 Parameters:
44 S - pointer to the association state machine
45 ==========================================================================
46 */
47VOID AironetStateMachineInit(
48 IN PRTMP_ADAPTER pAd,
49 IN STATE_MACHINE *S,
50 OUT STATE_MACHINE_FUNC Trans[])
51{
52 StateMachineInit(S, Trans, MAX_AIRONET_STATE, MAX_AIRONET_MSG, (STATE_MACHINE_FUNC)Drop, AIRONET_IDLE, AIRONET_MACHINE_BASE);
53 StateMachineSetAction(S, AIRONET_IDLE, MT2_AIRONET_MSG, (STATE_MACHINE_FUNC)AironetMsgAction);
54 StateMachineSetAction(S, AIRONET_IDLE, MT2_AIRONET_SCAN_REQ, (STATE_MACHINE_FUNC)AironetRequestAction);
55 StateMachineSetAction(S, AIRONET_SCANNING, MT2_AIRONET_SCAN_DONE, (STATE_MACHINE_FUNC)AironetReportAction);
56}
57
58/*
59 ==========================================================================
60 Description:
61 This is state machine function.
62 When receiving EAPOL packets which is for 802.1x key management.
63 Use both in WPA, and WPAPSK case.
64 In this function, further dispatch to different functions according to the received packet. 3 categories are :
65 1. normal 4-way pairwisekey and 2-way groupkey handshake
66 2. MIC error (Countermeasures attack) report packet from STA.
67 3. Request for pairwise/group key update from STA
68 Return:
69 ==========================================================================
70*/
71VOID AironetMsgAction(
72 IN PRTMP_ADAPTER pAd,
73 IN MLME_QUEUE_ELEM *Elem)
74{
75 USHORT Length;
76 UCHAR Index, i;
77 PUCHAR pData;
78 PAIRONET_RM_REQUEST_FRAME pRMReq;
79 PRM_REQUEST_ACTION pReqElem;
80
81 DBGPRINT(RT_DEBUG_TRACE, ("-----> AironetMsgAction\n"));
82
83 // 0. Get Aironet IAPP header first
84 pRMReq = (PAIRONET_RM_REQUEST_FRAME) &Elem->Msg[LENGTH_802_11];
85 pData = (PUCHAR) &Elem->Msg[LENGTH_802_11];
86
87 // 1. Change endian format form network to little endian
88 Length = be2cpu16(pRMReq->IAPP.Length);
89
90 // 2.0 Sanity check, this should only happen when CCX 2.0 support is enabled
91 if (pAd->StaCfg.CCXEnable != TRUE)
92 return;
93
94 // 2.1 Radio measurement must be on
95 if (pAd->StaCfg.CCXControl.field.RMEnable != 1)
96 return;
97
98 // 2.2. Debug print all bit information
99 DBGPRINT(RT_DEBUG_TRACE, ("IAPP ID & Length %d\n", Length));
100 DBGPRINT(RT_DEBUG_TRACE, ("IAPP Type %x\n", pRMReq->IAPP.Type));
101 DBGPRINT(RT_DEBUG_TRACE, ("IAPP SubType %x\n", pRMReq->IAPP.SubType));
102 DBGPRINT(RT_DEBUG_TRACE, ("IAPP Dialog Token %x\n", pRMReq->IAPP.Token));
103 DBGPRINT(RT_DEBUG_TRACE, ("IAPP Activation Delay %x\n", pRMReq->Delay));
104 DBGPRINT(RT_DEBUG_TRACE, ("IAPP Measurement Offset %x\n", pRMReq->Offset));
105
106 // 3. Check IAPP frame type, it must be 0x32 for Cisco Aironet extension
107 if (pRMReq->IAPP.Type != AIRONET_IAPP_TYPE)
108 {
109 DBGPRINT(RT_DEBUG_ERROR, ("Wrong IAPP type for Cisco Aironet extension\n"));
110 return;
111 }
112
113 // 4. Check IAPP frame subtype, it must be 0x01 for Cisco Aironet extension request.
114 // Since we are acting as client only, we will disregards reply subtype.
115 if (pRMReq->IAPP.SubType != AIRONET_IAPP_SUBTYPE_REQUEST)
116 {
117 DBGPRINT(RT_DEBUG_ERROR, ("Wrong IAPP subtype for Cisco Aironet extension\n"));
118 return;
119 }
120
121 // 5. Verify Destination MAC and Source MAC, both should be all zeros.
122 if (! MAC_ADDR_EQUAL(pRMReq->IAPP.DA, ZERO_MAC_ADDR))
123 {
124 DBGPRINT(RT_DEBUG_ERROR, ("Wrong IAPP DA for Cisco Aironet extension, it's not Zero\n"));
125 return;
126 }
127
128 if (! MAC_ADDR_EQUAL(pRMReq->IAPP.SA, ZERO_MAC_ADDR))
129 {
130 DBGPRINT(RT_DEBUG_ERROR, ("Wrong IAPP SA for Cisco Aironet extension, it's not Zero\n"));
131 return;
132 }
133
134 // 6. Reinit all report related fields
135 NdisZeroMemory(pAd->StaCfg.FrameReportBuf, 2048);
136 NdisZeroMemory(pAd->StaCfg.BssReportOffset, sizeof(USHORT) * MAX_LEN_OF_BSS_TABLE);
137 NdisZeroMemory(pAd->StaCfg.MeasurementRequest, sizeof(RM_REQUEST_ACTION) * 4);
138
139 // 7. Point to the start of first element report element
140 pAd->StaCfg.FrameReportLen = LENGTH_802_11 + sizeof(AIRONET_IAPP_HEADER);
141 DBGPRINT(RT_DEBUG_TRACE, ("FR len = %d\n", pAd->StaCfg.FrameReportLen));
142 pAd->StaCfg.LastBssIndex = 0xff;
143 pAd->StaCfg.RMReqCnt = 0;
144 pAd->StaCfg.ParallelReq = FALSE;
145 pAd->StaCfg.ParallelDuration = 0;
146 pAd->StaCfg.ParallelChannel = 0;
147 pAd->StaCfg.IAPPToken = pRMReq->IAPP.Token;
148 pAd->StaCfg.CurrentRMReqIdx = 0;
149 pAd->StaCfg.CLBusyBytes = 0;
150 // Reset the statistics
151 for (i = 0; i < 8; i++)
152 pAd->StaCfg.RPIDensity[i] = 0;
153
154 Index = 0;
155
156 // 8. Save dialog token for report
157 pAd->StaCfg.IAPPToken = pRMReq->IAPP.Token;
158
159 // Save Activation delay & measurement offset, Not really needed
160
161 // 9. Point to the first request element
162 pData += sizeof(AIRONET_RM_REQUEST_FRAME);
163 // Length should exclude the CISCO Aironet SNAP header
164 Length -= (sizeof(AIRONET_RM_REQUEST_FRAME) - LENGTH_802_1_H);
165
166 // 10. Start Parsing the Measurement elements.
167 // Be careful about multiple MR elements within one frames.
168 while (Length > 0)
169 {
170 pReqElem = (PRM_REQUEST_ACTION) pData;
171 switch (pReqElem->ReqElem.Eid)
172 {
173 case IE_MEASUREMENT_REQUEST:
174 // From the example, it seems we only need to support one request in one frame
175 // There is no multiple request in one frame.
176 // Besides, looks like we need to take care the measurement request only.
177 // The measurement request is always 4 bytes.
178
179 // Start parsing this type of request.
180 // 0. Eid is IE_MEASUREMENT_REQUEST
181 // 1. Length didn't include Eid and Length field, it always be 8.
182 // 2. Measurement Token, we nned to save it for the corresponding report.
183 // 3. Measurement Mode, Although there are definitions, but we din't see value other than
184 // 0 from test specs examples.
185 // 4. Measurement Type, this is what we need to do.
186 switch (pReqElem->ReqElem.Type)
187 {
188 case MSRN_TYPE_CHANNEL_LOAD_REQ:
189 case MSRN_TYPE_NOISE_HIST_REQ:
190 case MSRN_TYPE_BEACON_REQ:
191 // Check the Enable non-serving channel measurement control
192 if (pAd->StaCfg.CCXControl.field.DCRMEnable == 0)
193 {
194 // Check channel before enqueue the action
195 if (pReqElem->Measurement.Channel != pAd->CommonCfg.Channel)
196 break;
197 }
198 else
199 {
200 // If off channel measurement, check the TU duration limit
201 if (pReqElem->Measurement.Channel != pAd->CommonCfg.Channel)
202 if (pReqElem->Measurement.Duration > pAd->StaCfg.CCXControl.field.TuLimit)
203 break;
204 }
205
206 // Save requests and execute actions later
207 NdisMoveMemory(&pAd->StaCfg.MeasurementRequest[Index], pReqElem, sizeof(RM_REQUEST_ACTION));
208 Index += 1;
209 break;
210
211 case MSRN_TYPE_FRAME_REQ:
212 // Since it's option, we will support later
213 // FrameRequestAction(pAd, pData);
214 break;
215
216 default:
217 break;
218 }
219
220 // Point to next Measurement request
221 pData += sizeof(RM_REQUEST_ACTION);
222 Length -= sizeof(RM_REQUEST_ACTION);
223 break;
224
225 // We accept request only, all others are dropped
226 case IE_MEASUREMENT_REPORT:
227 case IE_AP_TX_POWER:
228 case IE_MEASUREMENT_CAPABILITY:
229 default:
230 return;
231 }
232 }
233
234 // 11. Update some flags and index
235 pAd->StaCfg.RMReqCnt = Index;
236
237 if (Index)
238 {
239 MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_REQ, 0, NULL);
240 RT28XX_MLME_HANDLER(pAd);
241 }
242
243 DBGPRINT(RT_DEBUG_TRACE, ("<----- AironetMsgAction\n"));
244}
245
246/*
247 ========================================================================
248
249 Routine Description:
250
251 Arguments:
252
253 Return Value:
254 None
255
256 Note:
257
258 ========================================================================
259*/
260VOID AironetRequestAction(
261 IN PRTMP_ADAPTER pAd,
262 IN MLME_QUEUE_ELEM *Elem)
263{
264 PRM_REQUEST_ACTION pReq;
265
266 // 1. Point to next request element
267 pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx];
268
269 // 2. Parse measurement type and call appropriate functions
270 if (pReq->ReqElem.Type == MSRN_TYPE_CHANNEL_LOAD_REQ)
271 // Channel Load measurement request
272 ChannelLoadRequestAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
273 else if (pReq->ReqElem.Type == MSRN_TYPE_NOISE_HIST_REQ)
274 // Noise Histogram measurement request
275 NoiseHistRequestAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
276 else if (pReq->ReqElem.Type == MSRN_TYPE_BEACON_REQ)
277 // Beacon measurement request
278 BeaconRequestAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
279 else
280 // Unknown. Do nothing and return, this should never happen
281 return;
282
283 // 3. Peek into the next request, if it's parallel, we will update the scan time to the largest one
284 if ((pAd->StaCfg.CurrentRMReqIdx + 1) < pAd->StaCfg.RMReqCnt)
285 {
286 pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx + 1];
287 // Check for parallel bit
288 if ((pReq->ReqElem.Mode & 0x01) && (pReq->Measurement.Channel == pAd->StaCfg.CCXScanChannel))
289 {
290 // Update parallel mode request information
291 pAd->StaCfg.ParallelReq = TRUE;
292 pAd->StaCfg.CCXScanTime = ((pReq->Measurement.Duration > pAd->StaCfg.CCXScanTime) ?
293 (pReq->Measurement.Duration) : (pAd->StaCfg.CCXScanTime));
294 }
295 }
296
297 // 4. Call RT28XX_MLME_HANDLER to execute the request mlme commands, Scan request is the only one used
298 RT28XX_MLME_HANDLER(pAd);
299
300}
301
302
303/*
304 ========================================================================
305
306 Routine Description:
307 Prepare channel load report action, special scan operation added
308 to support
309
310 Arguments:
311 pAd Pointer to our adapter
312 pData Start from element ID
313
314 Return Value:
315 None
316
317 Note:
318
319 ========================================================================
320*/
321VOID ChannelLoadRequestAction(
322 IN PRTMP_ADAPTER pAd,
323 IN UCHAR Index)
324{
325 PRM_REQUEST_ACTION pReq;
326 MLME_SCAN_REQ_STRUCT ScanReq;
327 UCHAR ZeroSsid[32];
328 NDIS_STATUS NStatus;
329 PUCHAR pOutBuffer = NULL;
330 PHEADER_802_11 pNullFrame;
331
332 DBGPRINT(RT_DEBUG_TRACE, ("ChannelLoadRequestAction ----->\n"));
333
334 pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[Index];
335 NdisZeroMemory(ZeroSsid, 32);
336
337 // Prepare for special scan request
338 // The scan definition is different with our Active, Passive scan definition.
339 // For CCX2, Active means send out probe request with broadcast BSSID.
340 // Passive means no probe request sent, only listen to the beacons.
341 // The channel scanned is fixed as specified, no need to scan all channels.
342 // The scan wait time is specified in the request too.
343 // Passive scan Mode
344
345 // Control state machine is not idle, reject the request
346 if ((pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) && (Index == 0))
347 return;
348
349 // Fill out stuff for scan request
350 ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_CISCO_CHANNEL_LOAD);
351 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
352 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
353
354 // Reset some internal control flags to make sure this scan works.
355 BssTableInit(&pAd->StaCfg.CCXBssTab);
356 pAd->StaCfg.ScanCnt = 0;
357 pAd->StaCfg.CCXScanChannel = pReq->Measurement.Channel;
358 pAd->StaCfg.CCXScanTime = pReq->Measurement.Duration;
359
360 DBGPRINT(RT_DEBUG_TRACE, ("Duration %d, Channel %d!\n", pReq->Measurement.Duration, pReq->Measurement.Channel));
361
362 // If it's non serving channel scan, send out a null frame with PSM bit on.
363 if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
364 {
365 // Use MLME enqueue method
366 NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
367 if (NStatus != NDIS_STATUS_SUCCESS)
368 return;
369
370 pNullFrame = (PHEADER_802_11) pOutBuffer;;
371 // Make the power save Null frame with PSM bit on
372 MgtMacHeaderInit(pAd, pNullFrame, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
373 pNullFrame->Duration = 0;
374 pNullFrame->FC.Type = BTYPE_DATA;
375 pNullFrame->FC.PwrMgmt = PWR_SAVE;
376
377 // Send using priority queue
378 MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
379 MlmeFreeMemory(pAd, pOutBuffer);
380 DBGPRINT(RT_DEBUG_TRACE, ("Send PSM Data frame for off channel RM\n"));
381 RTMPusecDelay(5000);
382 }
383
384 pAd->StaCfg.CCXReqType = MSRN_TYPE_CHANNEL_LOAD_REQ;
385 pAd->StaCfg.CLBusyBytes = 0;
386 // Enable Rx with promiscuous reception
387 RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, 0x1010);
388
389 // Set channel load measurement flag
390 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_MEASUREMENT);
391
392 pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
393
394 DBGPRINT(RT_DEBUG_TRACE, ("ChannelLoadRequestAction <-----\n"));
395}
396
397/*
398 ========================================================================
399
400 Routine Description:
401 Prepare noise histogram report action, special scan operation added
402 to support
403
404 Arguments:
405 pAd Pointer to our adapter
406 pData Start from element ID
407
408 Return Value:
409 None
410
411 Note:
412
413 ========================================================================
414*/
415VOID NoiseHistRequestAction(
416 IN PRTMP_ADAPTER pAd,
417 IN UCHAR Index)
418{
419 PRM_REQUEST_ACTION pReq;
420 MLME_SCAN_REQ_STRUCT ScanReq;
421 UCHAR ZeroSsid[32], i;
422 NDIS_STATUS NStatus;
423 PUCHAR pOutBuffer = NULL;
424 PHEADER_802_11 pNullFrame;
425
426 DBGPRINT(RT_DEBUG_TRACE, ("NoiseHistRequestAction ----->\n"));
427
428 pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[Index];
429 NdisZeroMemory(ZeroSsid, 32);
430
431 // Prepare for special scan request
432 // The scan definition is different with our Active, Passive scan definition.
433 // For CCX2, Active means send out probe request with broadcast BSSID.
434 // Passive means no probe request sent, only listen to the beacons.
435 // The channel scanned is fixed as specified, no need to scan all channels.
436 // The scan wait time is specified in the request too.
437 // Passive scan Mode
438
439 // Control state machine is not idle, reject the request
440 if ((pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) && (Index == 0))
441 return;
442
443 // Fill out stuff for scan request
444 ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_CISCO_NOISE);
445 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
446 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
447
448 // Reset some internal control flags to make sure this scan works.
449 BssTableInit(&pAd->StaCfg.CCXBssTab);
450 pAd->StaCfg.ScanCnt = 0;
451 pAd->StaCfg.CCXScanChannel = pReq->Measurement.Channel;
452 pAd->StaCfg.CCXScanTime = pReq->Measurement.Duration;
453 pAd->StaCfg.CCXReqType = MSRN_TYPE_NOISE_HIST_REQ;
454
455 DBGPRINT(RT_DEBUG_TRACE, ("Duration %d, Channel %d!\n", pReq->Measurement.Duration, pReq->Measurement.Channel));
456
457 // If it's non serving channel scan, send out a null frame with PSM bit on.
458 if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
459 {
460 // Use MLME enqueue method
461 NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
462 if (NStatus != NDIS_STATUS_SUCCESS)
463 return;
464
465 pNullFrame = (PHEADER_802_11) pOutBuffer;
466 // Make the power save Null frame with PSM bit on
467 MgtMacHeaderInit(pAd, pNullFrame, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
468 pNullFrame->Duration = 0;
469 pNullFrame->FC.Type = BTYPE_DATA;
470 pNullFrame->FC.PwrMgmt = PWR_SAVE;
471
472 // Send using priority queue
473 MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
474 MlmeFreeMemory(pAd, pOutBuffer);
475 DBGPRINT(RT_DEBUG_TRACE, ("Send PSM Data frame for off channel RM\n"));
476 RTMPusecDelay(5000);
477 }
478
479 // Reset the statistics
480 for (i = 0; i < 8; i++)
481 pAd->StaCfg.RPIDensity[i] = 0;
482
483 // Enable Rx with promiscuous reception
484 RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, 0x1010);
485
486 // Set channel load measurement flag
487 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_MEASUREMENT);
488
489 pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
490
491 DBGPRINT(RT_DEBUG_TRACE, ("NoiseHistRequestAction <-----\n"));
492}
493
494/*
495 ========================================================================
496
497 Routine Description:
498 Prepare Beacon report action, special scan operation added
499 to support
500
501 Arguments:
502 pAd Pointer to our adapter
503 pData Start from element ID
504
505 Return Value:
506 None
507
508 Note:
509
510 ========================================================================
511*/
512VOID BeaconRequestAction(
513 IN PRTMP_ADAPTER pAd,
514 IN UCHAR Index)
515{
516 PRM_REQUEST_ACTION pReq;
517 NDIS_STATUS NStatus;
518 PUCHAR pOutBuffer = NULL;
519 PHEADER_802_11 pNullFrame;
520 MLME_SCAN_REQ_STRUCT ScanReq;
521 UCHAR ZeroSsid[32];
522
523 DBGPRINT(RT_DEBUG_TRACE, ("BeaconRequestAction ----->\n"));
524
525 pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[Index];
526 NdisZeroMemory(ZeroSsid, 32);
527
528 // Prepare for special scan request
529 // The scan definition is different with our Active, Passive scan definition.
530 // For CCX2, Active means send out probe request with broadcast BSSID.
531 // Passive means no probe request sent, only listen to the beacons.
532 // The channel scanned is fixed as specified, no need to scan all channels.
533 // The scan wait time is specified in the request too.
534 if (pReq->Measurement.ScanMode == MSRN_SCAN_MODE_PASSIVE)
535 {
536 // Passive scan Mode
537 DBGPRINT(RT_DEBUG_TRACE, ("Passive Scan Mode!\n"));
538
539 // Control state machine is not idle, reject the request
540 if ((pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) && (Index == 0))
541 return;
542
543 // Fill out stuff for scan request
544 ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_CISCO_PASSIVE);
545 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
546 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
547
548 // Reset some internal control flags to make sure this scan works.
549 BssTableInit(&pAd->StaCfg.CCXBssTab);
550 pAd->StaCfg.ScanCnt = 0;
551 pAd->StaCfg.CCXScanChannel = pReq->Measurement.Channel;
552 pAd->StaCfg.CCXScanTime = pReq->Measurement.Duration;
553 pAd->StaCfg.CCXReqType = MSRN_TYPE_BEACON_REQ;
554 DBGPRINT(RT_DEBUG_TRACE, ("Duration %d!\n", pReq->Measurement.Duration));
555
556 // If it's non serving channel scan, send out a null frame with PSM bit on.
557 if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
558 {
559 // Use MLME enqueue method
560 NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
561 if (NStatus != NDIS_STATUS_SUCCESS)
562 return;
563
564 pNullFrame = (PHEADER_802_11) pOutBuffer;
565 // Make the power save Null frame with PSM bit on
566 MgtMacHeaderInit(pAd, pNullFrame, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
567 pNullFrame->Duration = 0;
568 pNullFrame->FC.Type = BTYPE_DATA;
569 pNullFrame->FC.PwrMgmt = PWR_SAVE;
570
571 // Send using priority queue
572 MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
573 MlmeFreeMemory(pAd, pOutBuffer);
574 DBGPRINT(RT_DEBUG_TRACE, ("Send PSM Data frame for off channel RM\n"));
575 RTMPusecDelay(5000);
576 }
577
578 pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
579 }
580 else if (pReq->Measurement.ScanMode == MSRN_SCAN_MODE_ACTIVE)
581 {
582 // Active scan Mode
583 DBGPRINT(RT_DEBUG_TRACE, ("Active Scan Mode!\n"));
584
585 // Control state machine is not idle, reject the request
586 if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE)
587 return;
588
589 // Fill out stuff for scan request
590 ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_CISCO_ACTIVE);
591 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
592 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
593
594 // Reset some internal control flags to make sure this scan works.
595 BssTableInit(&pAd->StaCfg.CCXBssTab);
596 pAd->StaCfg.ScanCnt = 0;
597 pAd->StaCfg.CCXScanChannel = pReq->Measurement.Channel;
598 pAd->StaCfg.CCXScanTime = pReq->Measurement.Duration;
599 pAd->StaCfg.CCXReqType = MSRN_TYPE_BEACON_REQ;
600 DBGPRINT(RT_DEBUG_TRACE, ("Duration %d!\n", pReq->Measurement.Duration));
601
602 // If it's non serving channel scan, send out a null frame with PSM bit on.
603 if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
604 {
605 // Use MLME enqueue method
606 NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
607 if (NStatus != NDIS_STATUS_SUCCESS)
608 return;
609
610 pNullFrame = (PHEADER_802_11) pOutBuffer;
611 // Make the power save Null frame with PSM bit on
612 MgtMacHeaderInit(pAd, pNullFrame, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
613 pNullFrame->Duration = 0;
614 pNullFrame->FC.Type = BTYPE_DATA;
615 pNullFrame->FC.PwrMgmt = PWR_SAVE;
616
617 // Send using priority queue
618 MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
619 MlmeFreeMemory(pAd, pOutBuffer);
620 DBGPRINT(RT_DEBUG_TRACE, ("Send PSM Data frame for off channel RM\n"));
621 RTMPusecDelay(5000);
622 }
623
624 pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
625 }
626 else if (pReq->Measurement.ScanMode == MSRN_SCAN_MODE_BEACON_TABLE)
627 {
628 // Beacon report Mode, report all the APS in current bss table
629 DBGPRINT(RT_DEBUG_TRACE, ("Beacon Report Mode!\n"));
630
631 // Copy current BSS table to CCX table, we can omit this step later on.
632 NdisMoveMemory(&pAd->StaCfg.CCXBssTab, &pAd->ScanTab, sizeof(BSS_TABLE));
633
634 // Create beacon report from Bss table
635 AironetCreateBeaconReportFromBssTable(pAd);
636
637 // Set state to scanning
638 pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
639
640 // Enqueue report request
641 // Cisco scan request is finished, prepare beacon report
642 MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL);
643 }
644 else
645 {
646 // Wrong scan Mode
647 DBGPRINT(RT_DEBUG_TRACE, ("Wrong Scan Mode!\n"));
648 }
649
650 DBGPRINT(RT_DEBUG_TRACE, ("BeaconRequestAction <-----\n"));
651}
652
653/*
654 ========================================================================
655
656 Routine Description:
657
658 Arguments:
659
660 Return Value:
661 None
662
663 Note:
664
665 ========================================================================
666*/
667VOID AironetReportAction(
668 IN PRTMP_ADAPTER pAd,
669 IN MLME_QUEUE_ELEM *Elem)
670{
671 PRM_REQUEST_ACTION pReq;
672 ULONG Now32;
673
674 NdisGetSystemUpTime(&Now32);
675 pAd->StaCfg.LastBeaconRxTime = Now32;
676
677 pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx];
678
679 DBGPRINT(RT_DEBUG_TRACE, ("AironetReportAction ----->\n"));
680
681 // 1. Parse measurement type and call appropriate functions
682 if (pReq->ReqElem.Type == MSRN_TYPE_CHANNEL_LOAD_REQ)
683 // Channel Load measurement request
684 ChannelLoadReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
685 else if (pReq->ReqElem.Type == MSRN_TYPE_NOISE_HIST_REQ)
686 // Noise Histogram measurement request
687 NoiseHistReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
688 else if (pReq->ReqElem.Type == MSRN_TYPE_BEACON_REQ)
689 // Beacon measurement request
690 BeaconReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
691 else
692 // Unknown. Do nothing and return
693 ;
694
695 // 2. Point to the correct index of action element, start from 0
696 pAd->StaCfg.CurrentRMReqIdx++;
697
698 // 3. Check for parallel actions
699 if (pAd->StaCfg.ParallelReq == TRUE)
700 {
701 pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx];
702
703 // Process next action right away
704 if (pReq->ReqElem.Type == MSRN_TYPE_CHANNEL_LOAD_REQ)
705 // Channel Load measurement request
706 ChannelLoadReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
707 else if (pReq->ReqElem.Type == MSRN_TYPE_NOISE_HIST_REQ)
708 // Noise Histogram measurement request
709 NoiseHistReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
710
711 pAd->StaCfg.ParallelReq = FALSE;
712 pAd->StaCfg.CurrentRMReqIdx++;
713 }
714
715 if (pAd->StaCfg.CurrentRMReqIdx >= pAd->StaCfg.RMReqCnt)
716 {
717 // 4. There is no more unprocessed measurement request, go for transmit this report
718 AironetFinalReportAction(pAd);
719 pAd->Mlme.AironetMachine.CurrState = AIRONET_IDLE;
720 }
721 else
722 {
723 pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx];
724
725 if (pReq->Measurement.Channel != pAd->CommonCfg.Channel)
726 {
727 RTMPusecDelay(100000);
728 }
729
730 // 5. There are more requests to be measure
731 MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_REQ, 0, NULL);
732 RT28XX_MLME_HANDLER(pAd);
733 }
734
735 DBGPRINT(RT_DEBUG_TRACE, ("AironetReportAction <-----\n"));
736}
737
738/*
739 ========================================================================
740
741 Routine Description:
742
743 Arguments:
744
745 Return Value:
746 None
747
748 Note:
749
750 ========================================================================
751*/
752VOID AironetFinalReportAction(
753 IN PRTMP_ADAPTER pAd)
754{
755 PUCHAR pDest;
756 PAIRONET_IAPP_HEADER pIAPP;
757 PHEADER_802_11 pHeader;
758 UCHAR AckRate = RATE_2;
759 USHORT AckDuration = 0;
760 NDIS_STATUS NStatus;
761 PUCHAR pOutBuffer = NULL;
762 ULONG FrameLen = 0;
763
764 DBGPRINT(RT_DEBUG_TRACE, ("AironetFinalReportAction ----->\n"));
765
766 // 0. Set up the frame pointer, Frame was inited at the end of message action
767 pDest = &pAd->StaCfg.FrameReportBuf[LENGTH_802_11];
768
769 // 1. Update report IAPP fields
770 pIAPP = (PAIRONET_IAPP_HEADER) pDest;
771
772 // 2. Copy Cisco SNAP header
773 NdisMoveMemory(pIAPP->CiscoSnapHeader, SNAP_AIRONET, LENGTH_802_1_H);
774
775 // 3. network order for this 16bit length
776 pIAPP->Length = cpu2be16(pAd->StaCfg.FrameReportLen - LENGTH_802_11 - LENGTH_802_1_H);
777
778 // 3.1 sanity check the report length, ignore it if there is nothing to report
779 if (be2cpu16(pIAPP->Length) <= 18)
780 return;
781
782 // 4. Type must be 0x32
783 pIAPP->Type = AIRONET_IAPP_TYPE;
784
785 // 5. SubType for report must be 0x81
786 pIAPP->SubType = AIRONET_IAPP_SUBTYPE_REPORT;
787
788 // 6. DA is not used and must be zero, although the whole frame was cleared at the start of function
789 // We will do it again here. We can use BSSID instead
790 COPY_MAC_ADDR(pIAPP->DA, pAd->CommonCfg.Bssid);
791
792 // 7. SA is the client reporting which must be our MAC
793 COPY_MAC_ADDR(pIAPP->SA, pAd->CurrentAddress);
794
795 // 8. Copy the saved dialog token
796 pIAPP->Token = pAd->StaCfg.IAPPToken;
797
798 // 9. Make the Report frame 802.11 header
799 // Reuse function in wpa.c
800 pHeader = (PHEADER_802_11) pAd->StaCfg.FrameReportBuf;
801 pAd->Sequence ++;
802 WpaMacHeaderInit(pAd, pHeader, 0, pAd->CommonCfg.Bssid);
803
804 // ACK size is 14 include CRC, and its rate is based on real time information
805 AckRate = pAd->CommonCfg.ExpectedACKRate[pAd->CommonCfg.MlmeRate];
806 AckDuration = RTMPCalcDuration(pAd, AckRate, 14);
807 pHeader->Duration = pAd->CommonCfg.Dsifs + AckDuration;
808
809 // Use MLME enqueue method
810 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
811 if (NStatus != NDIS_STATUS_SUCCESS)
812 return;
813
814 // 10. Prepare report frame with dynamic outbuffer. Just simply copy everything.
815 MakeOutgoingFrame(pOutBuffer, &FrameLen,
816 pAd->StaCfg.FrameReportLen, pAd->StaCfg.FrameReportBuf,
817 END_OF_ARGS);
818
819 // 11. Send using priority queue
820 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
821 MlmeFreeMemory(pAd, pOutBuffer);
822
823 pAd->StaCfg.CCXReqType = MSRN_TYPE_UNUSED;
824
825 DBGPRINT(RT_DEBUG_TRACE, ("AironetFinalReportAction <-----\n"));
826}
827
828/*
829 ========================================================================
830
831 Routine Description:
832
833 Arguments:
834
835 Return Value:
836 None
837
838 Note:
839
840 ========================================================================
841*/
842VOID ChannelLoadReportAction(
843 IN PRTMP_ADAPTER pAd,
844 IN UCHAR Index)
845{
846 PMEASUREMENT_REPORT_ELEMENT pReport;
847 PCHANNEL_LOAD_REPORT pLoad;
848 PUCHAR pDest;
849 UCHAR CCABusyFraction;
850
851 DBGPRINT(RT_DEBUG_TRACE, ("ChannelLoadReportAction ----->\n"));
852
853 // Disable Rx with promiscuous reception, make it back to normal
854 RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL); // Staion not drop control frame will fail WiFi Certification.
855
856 // 0. Setup pointer for processing beacon & probe response
857 pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.FrameReportLen];
858 pReport = (PMEASUREMENT_REPORT_ELEMENT) pDest;
859
860 // 1. Fill Measurement report element field.
861 pReport->Eid = IE_MEASUREMENT_REPORT;
862 // Fixed Length at 9, not include Eid and length fields
863 pReport->Length = 9;
864 pReport->Token = pAd->StaCfg.MeasurementRequest[Index].ReqElem.Token;
865 pReport->Mode = pAd->StaCfg.MeasurementRequest[Index].ReqElem.Mode;
866 pReport->Type = MSRN_TYPE_CHANNEL_LOAD_REQ;
867
868 // 2. Fill channel report measurement data
869 pDest += sizeof(MEASUREMENT_REPORT_ELEMENT);
870 pLoad = (PCHANNEL_LOAD_REPORT) pDest;
871 pLoad->Channel = pAd->StaCfg.MeasurementRequest[Index].Measurement.Channel;
872 pLoad->Spare = 0;
873 pLoad->Duration = pAd->StaCfg.MeasurementRequest[Index].Measurement.Duration;
874
875 // 3. Calculate the CCA Busy Fraction
876 // (Bytes + ACK size) * 8 / Tx speed * 255 / 1000 / measurement duration, use 24 us Tx speed
877 // = (Bytes + ACK) / 12 / duration
878 // 9 is the good value for pAd->StaCfg.CLFactor
879 // CCABusyFraction = (UCHAR) (pAd->StaCfg.CLBusyBytes / 9 / pLoad->Duration);
880 CCABusyFraction = (UCHAR) (pAd->StaCfg.CLBusyBytes / pAd->StaCfg.CLFactor / pLoad->Duration);
881 if (CCABusyFraction < 10)
882 CCABusyFraction = (UCHAR) (pAd->StaCfg.CLBusyBytes / 3 / pLoad->Duration) + 1;
883
884 pLoad->CCABusy = CCABusyFraction;
885 DBGPRINT(RT_DEBUG_TRACE, ("CLBusyByte %ld, Duration %d, Result, %d\n", pAd->StaCfg.CLBusyBytes, pLoad->Duration, CCABusyFraction));
886
887 DBGPRINT(RT_DEBUG_TRACE, ("FrameReportLen %d\n", pAd->StaCfg.FrameReportLen));
888 pAd->StaCfg.FrameReportLen += (sizeof(MEASUREMENT_REPORT_ELEMENT) + sizeof(CHANNEL_LOAD_REPORT));
889 DBGPRINT(RT_DEBUG_TRACE, ("FrameReportLen %d\n", pAd->StaCfg.FrameReportLen));
890
891 // 4. Clear channel load measurement flag
892 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_MEASUREMENT);
893
894 // 5. reset to idle state
895 pAd->Mlme.AironetMachine.CurrState = AIRONET_IDLE;
896
897 DBGPRINT(RT_DEBUG_TRACE, ("ChannelLoadReportAction <-----\n"));
898}
899
900/*
901 ========================================================================
902
903 Routine Description:
904
905 Arguments:
906
907 Return Value:
908 None
909
910 Note:
911
912 ========================================================================
913*/
914VOID NoiseHistReportAction(
915 IN PRTMP_ADAPTER pAd,
916 IN UCHAR Index)
917{
918 PMEASUREMENT_REPORT_ELEMENT pReport;
919 PNOISE_HIST_REPORT pNoise;
920 PUCHAR pDest;
921 UCHAR i,NoiseCnt;
922 USHORT TotalRPICnt, TotalRPISum;
923
924 DBGPRINT(RT_DEBUG_TRACE, ("NoiseHistReportAction ----->\n"));
925
926 // 0. Disable Rx with promiscuous reception, make it back to normal
927 RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL); // Staion not drop control frame will fail WiFi Certification.
928 // 1. Setup pointer for processing beacon & probe response
929 pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.FrameReportLen];
930 pReport = (PMEASUREMENT_REPORT_ELEMENT) pDest;
931
932 // 2. Fill Measurement report element field.
933 pReport->Eid = IE_MEASUREMENT_REPORT;
934 // Fixed Length at 16, not include Eid and length fields
935 pReport->Length = 16;
936 pReport->Token = pAd->StaCfg.MeasurementRequest[Index].ReqElem.Token;
937 pReport->Mode = pAd->StaCfg.MeasurementRequest[Index].ReqElem.Mode;
938 pReport->Type = MSRN_TYPE_NOISE_HIST_REQ;
939
940 // 3. Fill noise histogram report measurement data
941 pDest += sizeof(MEASUREMENT_REPORT_ELEMENT);
942 pNoise = (PNOISE_HIST_REPORT) pDest;
943 pNoise->Channel = pAd->StaCfg.MeasurementRequest[Index].Measurement.Channel;
944 pNoise->Spare = 0;
945 pNoise->Duration = pAd->StaCfg.MeasurementRequest[Index].Measurement.Duration;
946 // 4. Fill Noise histogram, the total RPI counts should be 0.4 * TU
947 // We estimate 4000 normal packets received durning 10 seconds test.
948 // Adjust it if required.
949 // 3 is a good value for pAd->StaCfg.NHFactor
950 // TotalRPICnt = pNoise->Duration * 3 / 10;
951 TotalRPICnt = pNoise->Duration * pAd->StaCfg.NHFactor / 10;
952 TotalRPISum = 0;
953
954 for (i = 0; i < 8; i++)
955 {
956 TotalRPISum += pAd->StaCfg.RPIDensity[i];
957 DBGPRINT(RT_DEBUG_TRACE, ("RPI %d Conuts %d\n", i, pAd->StaCfg.RPIDensity[i]));
958 }
959
960 // Double check if the counter is larger than our expectation.
961 // We will replace it with the total number plus a fraction.
962 if (TotalRPISum > TotalRPICnt)
963 TotalRPICnt = TotalRPISum + pNoise->Duration / 20;
964
965 DBGPRINT(RT_DEBUG_TRACE, ("Total RPI Conuts %d\n", TotalRPICnt));
966
967 // 5. Initialize noise count for the total summation of 0xff
968 NoiseCnt = 0;
969 for (i = 1; i < 8; i++)
970 {
971 pNoise->Density[i] = (UCHAR) (pAd->StaCfg.RPIDensity[i] * 255 / TotalRPICnt);
972 if ((pNoise->Density[i] == 0) && (pAd->StaCfg.RPIDensity[i] != 0))
973 pNoise->Density[i]++;
974 NoiseCnt += pNoise->Density[i];
975 DBGPRINT(RT_DEBUG_TRACE, ("Reported RPI[%d] = 0x%02x\n", i, pNoise->Density[i]));
976 }
977
978 // 6. RPI[0] represents the rest of counts
979 pNoise->Density[0] = 0xff - NoiseCnt;
980 DBGPRINT(RT_DEBUG_TRACE, ("Reported RPI[0] = 0x%02x\n", pNoise->Density[0]));
981
982 pAd->StaCfg.FrameReportLen += (sizeof(MEASUREMENT_REPORT_ELEMENT) + sizeof(NOISE_HIST_REPORT));
983
984 // 7. Clear channel load measurement flag
985 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_MEASUREMENT);
986
987 // 8. reset to idle state
988 pAd->Mlme.AironetMachine.CurrState = AIRONET_IDLE;
989
990 DBGPRINT(RT_DEBUG_TRACE, ("NoiseHistReportAction <-----\n"));
991}
992
993/*
994 ========================================================================
995
996 Routine Description:
997 Prepare Beacon report action,
998
999 Arguments:
1000 pAd Pointer to our adapter
1001
1002 Return Value:
1003 None
1004
1005 Note:
1006
1007 ========================================================================
1008*/
1009VOID BeaconReportAction(
1010 IN PRTMP_ADAPTER pAd,
1011 IN UCHAR Index)
1012{
1013 DBGPRINT(RT_DEBUG_TRACE, ("BeaconReportAction ----->\n"));
1014
1015 // Looks like we don't have anything thing need to do here.
1016 // All measurement report already finished in AddBeaconReport
1017 // The length is in the FrameReportLen
1018
1019 // reset Beacon index for next beacon request
1020 pAd->StaCfg.LastBssIndex = 0xff;
1021
1022 // reset to idle state
1023 pAd->Mlme.AironetMachine.CurrState = AIRONET_IDLE;
1024
1025 DBGPRINT(RT_DEBUG_TRACE, ("BeaconReportAction <-----\n"));
1026}
1027
1028/*
1029 ========================================================================
1030
1031 Routine Description:
1032
1033 Arguments:
1034 Index Current BSSID in CCXBsstab entry index
1035
1036 Return Value:
1037
1038 Note:
1039
1040 ========================================================================
1041*/
1042VOID AironetAddBeaconReport(
1043 IN PRTMP_ADAPTER pAd,
1044 IN ULONG Index,
1045 IN PMLME_QUEUE_ELEM pElem)
1046{
1047 PVOID pMsg;
1048 PUCHAR pSrc, pDest;
1049 UCHAR ReqIdx;
1050 ULONG MsgLen;
1051 USHORT Length;
1052 PFRAME_802_11 pFrame;
1053 PMEASUREMENT_REPORT_ELEMENT pReport;
1054 PEID_STRUCT pEid;
1055 PBEACON_REPORT pBeaconReport;
1056 PBSS_ENTRY pBss;
1057
1058 // 0. Setup pointer for processing beacon & probe response
1059 pMsg = pElem->Msg;
1060 MsgLen = pElem->MsgLen;
1061 pFrame = (PFRAME_802_11) pMsg;
1062 pSrc = pFrame->Octet; // Start from AP TSF
1063 pBss = (PBSS_ENTRY) &pAd->StaCfg.CCXBssTab.BssEntry[Index];
1064 ReqIdx = pAd->StaCfg.CurrentRMReqIdx;
1065
1066 // 1 Check the Index, if we already create this entry, only update the average RSSI
1067 if ((Index <= pAd->StaCfg.LastBssIndex) && (pAd->StaCfg.LastBssIndex != 0xff))
1068 {
1069 pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.BssReportOffset[Index]];
1070 // Point to bss report information
1071 pDest += sizeof(MEASUREMENT_REPORT_ELEMENT);
1072 pBeaconReport = (PBEACON_REPORT) pDest;
1073
1074 // Update Rx power, in dBm
1075 // Get the original RSSI readback from BBP
1076 pBeaconReport->RxPower += pAd->BbpRssiToDbmDelta;
1077 // Average the Rssi reading
1078 pBeaconReport->RxPower = (pBeaconReport->RxPower + pBss->Rssi) / 2;
1079 // Get to dBm format
1080 pBeaconReport->RxPower -= pAd->BbpRssiToDbmDelta;
1081
1082 DBGPRINT(RT_DEBUG_TRACE, ("Bssid %02x:%02x:%02x:%02x:%02x:%02x ",
1083 pBss->Bssid[0], pBss->Bssid[1], pBss->Bssid[2],
1084 pBss->Bssid[3], pBss->Bssid[4], pBss->Bssid[5]));
1085 DBGPRINT(RT_DEBUG_TRACE, ("RxPower[%ld] Rssi %d, Avg Rssi %d\n", Index, (pBss->Rssi - pAd->BbpRssiToDbmDelta), pBeaconReport->RxPower - 256));
1086 DBGPRINT(RT_DEBUG_TRACE, ("FrameReportLen = %d\n", pAd->StaCfg.BssReportOffset[Index]));
1087
1088 // Update other information here
1089
1090 // Done
1091 return;
1092 }
1093
1094 // 2. Update reported Index
1095 pAd->StaCfg.LastBssIndex = Index;
1096
1097 // 3. Setup the buffer address for copying this BSSID into reporting frame
1098 // The offset should start after 802.11 header and report frame header.
1099 pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.FrameReportLen];
1100
1101 // 4. Save the start offset of each Bss in report frame
1102 pAd->StaCfg.BssReportOffset[Index] = pAd->StaCfg.FrameReportLen;
1103
1104 // 5. Fill Measurement report fields
1105 pReport = (PMEASUREMENT_REPORT_ELEMENT) pDest;
1106 pReport->Eid = IE_MEASUREMENT_REPORT;
1107 pReport->Length = 0;
1108 pReport->Token = pAd->StaCfg.MeasurementRequest[ReqIdx].ReqElem.Token;
1109 pReport->Mode = pAd->StaCfg.MeasurementRequest[ReqIdx].ReqElem.Mode;
1110 pReport->Type = MSRN_TYPE_BEACON_REQ;
1111 Length = sizeof(MEASUREMENT_REPORT_ELEMENT);
1112 pDest += sizeof(MEASUREMENT_REPORT_ELEMENT);
1113
1114 // 6. Start thebeacon report format
1115 pBeaconReport = (PBEACON_REPORT) pDest;
1116 pDest += sizeof(BEACON_REPORT);
1117 Length += sizeof(BEACON_REPORT);
1118
1119 // 7. Copy Channel number
1120 pBeaconReport->Channel = pBss->Channel;
1121 pBeaconReport->Spare = 0;
1122 pBeaconReport->Duration = pAd->StaCfg.MeasurementRequest[ReqIdx].Measurement.Duration;
1123 pBeaconReport->PhyType = ((pBss->SupRateLen+pBss->ExtRateLen > 4) ? PHY_ERP : PHY_DSS);
1124 // 8. Rx power, in dBm
1125 pBeaconReport->RxPower = pBss->Rssi - pAd->BbpRssiToDbmDelta;
1126
1127 DBGPRINT(RT_DEBUG_TRACE, ("Bssid %02x:%02x:%02x:%02x:%02x:%02x ",
1128 pBss->Bssid[0], pBss->Bssid[1], pBss->Bssid[2],
1129 pBss->Bssid[3], pBss->Bssid[4], pBss->Bssid[5]));
1130 DBGPRINT(RT_DEBUG_TRACE, ("RxPower[%ld], Rssi %d\n", Index, pBeaconReport->RxPower - 256));
1131 DBGPRINT(RT_DEBUG_TRACE, ("FrameReportLen = %d\n", pAd->StaCfg.FrameReportLen));
1132
1133 pBeaconReport->BeaconInterval = pBss->BeaconPeriod;
1134 COPY_MAC_ADDR(pBeaconReport->BSSID, pFrame->Hdr.Addr3);
1135 NdisMoveMemory(pBeaconReport->ParentTSF, pSrc, 4);
1136 NdisMoveMemory(pBeaconReport->TargetTSF, &pElem->TimeStamp.u.LowPart, 4);
1137 NdisMoveMemory(&pBeaconReport->TargetTSF[4], &pElem->TimeStamp.u.HighPart, 4);
1138
1139 // 9. Skip the beacon frame and offset to start of capabilityinfo since we already processed capabilityinfo
1140 pSrc += (TIMESTAMP_LEN + 2);
1141 pBeaconReport->CapabilityInfo = *(USHORT *)pSrc;
1142
1143 // 10. Point to start of element ID
1144 pSrc += 2;
1145 pEid = (PEID_STRUCT) pSrc;
1146
1147 // 11. Start process all variable Eid oayload and add the appropriate to the frame report
1148 while (((PUCHAR) pEid + pEid->Len + 1) < ((PUCHAR) pFrame + MsgLen))
1149 {
1150 // Only limited EID are required to report for CCX 2. It includes SSID, Supported rate,
1151 // FH paramenter set, DS parameter set, CF parameter set, IBSS parameter set,
1152 // TIM (report first 4 bytes only, radio measurement capability
1153 switch (pEid->Eid)
1154 {
1155 case IE_SSID:
1156 case IE_SUPP_RATES:
1157 case IE_FH_PARM:
1158 case IE_DS_PARM:
1159 case IE_CF_PARM:
1160 case IE_IBSS_PARM:
1161 NdisMoveMemory(pDest, pEid, pEid->Len + 2);
1162 pDest += (pEid->Len + 2);
1163 Length += (pEid->Len + 2);
1164 break;
1165
1166 case IE_MEASUREMENT_CAPABILITY:
1167 // Since this IE is duplicated with WPA security IE, we has to do sanity check before
1168 // recognize it.
1169 // 1. It also has fixed 6 bytes IE length.
1170 if (pEid->Len != 6)
1171 break;
1172 // 2. Check the Cisco Aironet OUI
1173 if (NdisEqualMemory(CISCO_OUI, (pSrc + 2), 3))
1174 {
1175 // Matched, this is what we want
1176 NdisMoveMemory(pDest, pEid, pEid->Len + 2);
1177 pDest += (pEid->Len + 2);
1178 Length += (pEid->Len + 2);
1179 }
1180 break;
1181
1182 case IE_TIM:
1183 if (pEid->Len > 4)
1184 {
1185 // May truncate and report the first 4 bytes only, with the eid & len, total should be 6
1186 NdisMoveMemory(pDest, pEid, 6);
1187 pDest += 6;
1188 Length += 6;
1189 }
1190 else
1191 {
1192 NdisMoveMemory(pDest, pEid, pEid->Len + 2);
1193 pDest += (pEid->Len + 2);
1194 Length += (pEid->Len + 2);
1195 }
1196 break;
1197
1198 default:
1199 break;
1200 }
1201 // 12. Move to next element ID
1202 pSrc += (2 + pEid->Len);
1203 pEid = (PEID_STRUCT) pSrc;
1204 }
1205
1206 // 13. Update the length in the header, not include EID and length
1207 pReport->Length = Length - 4;
1208
1209 // 14. Update the frame report buffer data length
1210 pAd->StaCfg.FrameReportLen += Length;
1211 DBGPRINT(RT_DEBUG_TRACE, ("FR len = %d\n", pAd->StaCfg.FrameReportLen));
1212}
1213
1214/*
1215 ========================================================================
1216
1217 Routine Description:
1218
1219 Arguments:
1220 Index Current BSSID in CCXBsstab entry index
1221
1222 Return Value:
1223
1224 Note:
1225
1226 ========================================================================
1227*/
1228VOID AironetCreateBeaconReportFromBssTable(
1229 IN PRTMP_ADAPTER pAd)
1230{
1231 PMEASUREMENT_REPORT_ELEMENT pReport;
1232 PBEACON_REPORT pBeaconReport;
1233 UCHAR Index, ReqIdx;
1234 USHORT Length;
1235 PUCHAR pDest;
1236 PBSS_ENTRY pBss;
1237
1238 // 0. setup base pointer
1239 ReqIdx = pAd->StaCfg.CurrentRMReqIdx;
1240
1241 for (Index = 0; Index < pAd->StaCfg.CCXBssTab.BssNr; Index++)
1242 {
1243 // 1. Setup the buffer address for copying this BSSID into reporting frame
1244 // The offset should start after 802.11 header and report frame header.
1245 pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.FrameReportLen];
1246 pBss = (PBSS_ENTRY) &pAd->StaCfg.CCXBssTab.BssEntry[Index];
1247 Length = 0;
1248
1249 // 2. Fill Measurement report fields
1250 pReport = (PMEASUREMENT_REPORT_ELEMENT) pDest;
1251 pReport->Eid = IE_MEASUREMENT_REPORT;
1252 pReport->Length = 0;
1253 pReport->Token = pAd->StaCfg.MeasurementRequest[ReqIdx].ReqElem.Token;
1254 pReport->Mode = pAd->StaCfg.MeasurementRequest[ReqIdx].ReqElem.Mode;
1255 pReport->Type = MSRN_TYPE_BEACON_REQ;
1256 Length = sizeof(MEASUREMENT_REPORT_ELEMENT);
1257 pDest += sizeof(MEASUREMENT_REPORT_ELEMENT);
1258
1259 // 3. Start the beacon report format
1260 pBeaconReport = (PBEACON_REPORT) pDest;
1261 pDest += sizeof(BEACON_REPORT);
1262 Length += sizeof(BEACON_REPORT);
1263
1264 // 4. Copy Channel number
1265 pBeaconReport->Channel = pBss->Channel;
1266 pBeaconReport->Spare = 0;
1267 pBeaconReport->Duration = pAd->StaCfg.MeasurementRequest[ReqIdx].Measurement.Duration;
1268 pBeaconReport->PhyType = ((pBss->SupRateLen+pBss->ExtRateLen > 4) ? PHY_ERP : PHY_DSS);
1269 pBeaconReport->RxPower = pBss->Rssi - pAd->BbpRssiToDbmDelta;
1270 pBeaconReport->BeaconInterval = pBss->BeaconPeriod;
1271 pBeaconReport->CapabilityInfo = pBss->CapabilityInfo;
1272 COPY_MAC_ADDR(pBeaconReport->BSSID, pBss->Bssid);
1273 NdisMoveMemory(pBeaconReport->ParentTSF, pBss->PTSF, 4);
1274 NdisMoveMemory(pBeaconReport->TargetTSF, pBss->TTSF, 8);
1275
1276 // 5. Create SSID
1277 *pDest++ = 0x00;
1278 *pDest++ = pBss->SsidLen;
1279 NdisMoveMemory(pDest, pBss->Ssid, pBss->SsidLen);
1280 pDest += pBss->SsidLen;
1281 Length += (2 + pBss->SsidLen);
1282
1283 // 6. Create SupportRates
1284 *pDest++ = 0x01;
1285 *pDest++ = pBss->SupRateLen;
1286 NdisMoveMemory(pDest, pBss->SupRate, pBss->SupRateLen);
1287 pDest += pBss->SupRateLen;
1288 Length += (2 + pBss->SupRateLen);
1289
1290 // 7. DS Parameter
1291 *pDest++ = 0x03;
1292 *pDest++ = 1;
1293 *pDest++ = pBss->Channel;
1294 Length += 3;
1295
1296 // 8. IBSS parameter if presents
1297 if (pBss->BssType == BSS_ADHOC)
1298 {
1299 *pDest++ = 0x06;
1300 *pDest++ = 2;
1301 *(PUSHORT) pDest = pBss->AtimWin;
1302 pDest += 2;
1303 Length += 4;
1304 }
1305
1306 // 9. Update length field, not include EID and length
1307 pReport->Length = Length - 4;
1308
1309 // 10. Update total frame size
1310 pAd->StaCfg.FrameReportLen += Length;
1311 }
1312}
diff --git a/drivers/staging/rt3070/sta/assoc.c b/drivers/staging/rt3070/sta/assoc.c
new file mode 100644
index 000000000000..5c33a895bf7f
--- /dev/null
+++ b/drivers/staging/rt3070/sta/assoc.c
@@ -0,0 +1,2060 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 assoc.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 John 2004-9-3 porting from RT2500
36*/
37#include "../rt_config.h"
38
39UCHAR CipherWpaTemplate[] = {
40 0xdd, // WPA IE
41 0x16, // Length
42 0x00, 0x50, 0xf2, 0x01, // oui
43 0x01, 0x00, // Version
44 0x00, 0x50, 0xf2, 0x02, // Multicast
45 0x01, 0x00, // Number of unicast
46 0x00, 0x50, 0xf2, 0x02, // unicast
47 0x01, 0x00, // number of authentication method
48 0x00, 0x50, 0xf2, 0x01 // authentication
49 };
50
51UCHAR CipherWpa2Template[] = {
52 0x30, // RSN IE
53 0x14, // Length
54 0x01, 0x00, // Version
55 0x00, 0x0f, 0xac, 0x02, // group cipher, TKIP
56 0x01, 0x00, // number of pairwise
57 0x00, 0x0f, 0xac, 0x02, // unicast
58 0x01, 0x00, // number of authentication method
59 0x00, 0x0f, 0xac, 0x02, // authentication
60 0x00, 0x00, // RSN capability
61 };
62
63UCHAR Ccx2IeInfo[] = { 0x00, 0x40, 0x96, 0x03, 0x02};
64
65/*
66 ==========================================================================
67 Description:
68 association state machine init, including state transition and timer init
69 Parameters:
70 S - pointer to the association state machine
71
72 IRQL = PASSIVE_LEVEL
73
74 ==========================================================================
75 */
76VOID AssocStateMachineInit(
77 IN PRTMP_ADAPTER pAd,
78 IN STATE_MACHINE *S,
79 OUT STATE_MACHINE_FUNC Trans[])
80{
81 StateMachineInit(S, Trans, MAX_ASSOC_STATE, MAX_ASSOC_MSG, (STATE_MACHINE_FUNC)Drop, ASSOC_IDLE, ASSOC_MACHINE_BASE);
82
83 // first column
84 StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)MlmeAssocReqAction);
85 StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)MlmeReassocReqAction);
86 StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)MlmeDisassocReqAction);
87 StateMachineSetAction(S, ASSOC_IDLE, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
88
89 // second column
90 StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAssoc);
91 StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenReassoc);
92 StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenDisassociate);
93 StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
94 StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_ASSOC_RSP, (STATE_MACHINE_FUNC)PeerAssocRspAction);
95 //
96 // Patch 3Com AP MOde:3CRWE454G72
97 // We send Assoc request frame to this AP, it always send Reassoc Rsp not Associate Rsp.
98 //
99 StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_REASSOC_RSP, (STATE_MACHINE_FUNC)PeerAssocRspAction);
100 StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_ASSOC_TIMEOUT, (STATE_MACHINE_FUNC)AssocTimeoutAction);
101
102 // third column
103 StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAssoc);
104 StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenReassoc);
105 StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenDisassociate);
106 StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
107 StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_REASSOC_RSP, (STATE_MACHINE_FUNC)PeerReassocRspAction);
108 //
109 // Patch, AP doesn't send Reassociate Rsp frame to Station.
110 //
111 StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_ASSOC_RSP, (STATE_MACHINE_FUNC)PeerReassocRspAction);
112 StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_REASSOC_TIMEOUT, (STATE_MACHINE_FUNC)ReassocTimeoutAction);
113
114 // fourth column
115 StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAssoc);
116 StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenReassoc);
117 StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenDisassociate);
118 StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
119 StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_DISASSOC_TIMEOUT, (STATE_MACHINE_FUNC)DisassocTimeoutAction);
120
121 // initialize the timer
122 RTMPInitTimer(pAd, &pAd->MlmeAux.AssocTimer, GET_TIMER_FUNCTION(AssocTimeout), pAd, FALSE);
123 RTMPInitTimer(pAd, &pAd->MlmeAux.ReassocTimer, GET_TIMER_FUNCTION(ReassocTimeout), pAd, FALSE);
124 RTMPInitTimer(pAd, &pAd->MlmeAux.DisassocTimer, GET_TIMER_FUNCTION(DisassocTimeout), pAd, FALSE);
125}
126
127/*
128 ==========================================================================
129 Description:
130 Association timeout procedure. After association timeout, this function
131 will be called and it will put a message into the MLME queue
132 Parameters:
133 Standard timer parameters
134
135 IRQL = DISPATCH_LEVEL
136
137 ==========================================================================
138 */
139VOID AssocTimeout(IN PVOID SystemSpecific1,
140 IN PVOID FunctionContext,
141 IN PVOID SystemSpecific2,
142 IN PVOID SystemSpecific3)
143{
144 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
145
146 // Do nothing if the driver is starting halt state.
147 // This might happen when timer already been fired before cancel timer with mlmehalt
148 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
149 return;
150
151 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_ASSOC_TIMEOUT, 0, NULL);
152 RT28XX_MLME_HANDLER(pAd);
153}
154
155/*
156 ==========================================================================
157 Description:
158 Reassociation timeout procedure. After reassociation timeout, this
159 function will be called and put a message into the MLME queue
160 Parameters:
161 Standard timer parameters
162
163 IRQL = DISPATCH_LEVEL
164
165 ==========================================================================
166 */
167VOID ReassocTimeout(IN PVOID SystemSpecific1,
168 IN PVOID FunctionContext,
169 IN PVOID SystemSpecific2,
170 IN PVOID SystemSpecific3)
171{
172 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
173
174 // Do nothing if the driver is starting halt state.
175 // This might happen when timer already been fired before cancel timer with mlmehalt
176 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
177 return;
178
179 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_REASSOC_TIMEOUT, 0, NULL);
180 RT28XX_MLME_HANDLER(pAd);
181}
182
183/*
184 ==========================================================================
185 Description:
186 Disassociation timeout procedure. After disassociation timeout, this
187 function will be called and put a message into the MLME queue
188 Parameters:
189 Standard timer parameters
190
191 IRQL = DISPATCH_LEVEL
192
193 ==========================================================================
194 */
195VOID DisassocTimeout(IN PVOID SystemSpecific1,
196 IN PVOID FunctionContext,
197 IN PVOID SystemSpecific2,
198 IN PVOID SystemSpecific3)
199{
200 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
201
202 // Do nothing if the driver is starting halt state.
203 // This might happen when timer already been fired before cancel timer with mlmehalt
204 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
205 return;
206
207 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_DISASSOC_TIMEOUT, 0, NULL);
208 RT28XX_MLME_HANDLER(pAd);
209}
210
211/*
212 ==========================================================================
213 Description:
214 mlme assoc req handling procedure
215 Parameters:
216 Adapter - Adapter pointer
217 Elem - MLME Queue Element
218 Pre:
219 the station has been authenticated and the following information is stored in the config
220 -# SSID
221 -# supported rates and their length
222 -# listen interval (Adapter->StaCfg.default_listen_count)
223 -# Transmit power (Adapter->StaCfg.tx_power)
224 Post :
225 -# An association request frame is generated and sent to the air
226 -# Association timer starts
227 -# Association state -> ASSOC_WAIT_RSP
228
229 IRQL = DISPATCH_LEVEL
230
231 ==========================================================================
232 */
233VOID MlmeAssocReqAction(
234 IN PRTMP_ADAPTER pAd,
235 IN MLME_QUEUE_ELEM *Elem)
236{
237 UCHAR ApAddr[6];
238 HEADER_802_11 AssocHdr;
239 UCHAR Ccx2Len = 5;
240 UCHAR WmeIe[9] = {IE_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
241 USHORT ListenIntv;
242 ULONG Timeout;
243 USHORT CapabilityInfo;
244 BOOLEAN TimerCancelled;
245 PUCHAR pOutBuffer = NULL;
246 NDIS_STATUS NStatus;
247 ULONG FrameLen = 0;
248 ULONG tmp;
249 USHORT VarIesOffset;
250 UCHAR CkipFlag;
251 UCHAR CkipNegotiationBuffer[CKIP_NEGOTIATION_LENGTH];
252 UCHAR AironetCkipIe = IE_AIRONET_CKIP;
253 UCHAR AironetCkipLen = CKIP_NEGOTIATION_LENGTH;
254 UCHAR AironetIPAddressIE = IE_AIRONET_IPADDRESS;
255 UCHAR AironetIPAddressLen = AIRONET_IPADDRESS_LENGTH;
256 UCHAR AironetIPAddressBuffer[AIRONET_IPADDRESS_LENGTH] = {0x00, 0x40, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
257 USHORT Status;
258
259 // Block all authentication request durning WPA block period
260 if (pAd->StaCfg.bBlockAssoc == TRUE)
261 {
262 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Block Assoc request durning WPA block period!\n"));
263 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
264 Status = MLME_STATE_MACHINE_REJECT;
265 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
266 }
267 // check sanity first
268 else if (MlmeAssocReqSanity(pAd, Elem->Msg, Elem->MsgLen, ApAddr, &CapabilityInfo, &Timeout, &ListenIntv))
269 {
270 RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &TimerCancelled);
271 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, ApAddr);
272
273 // Get an unused nonpaged memory
274 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
275 if (NStatus != NDIS_STATUS_SUCCESS)
276 {
277 DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeAssocReqAction() allocate memory failed \n"));
278 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
279 Status = MLME_FAIL_NO_RESOURCE;
280 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
281 return;
282 }
283
284 // Add by James 03/06/27
285 pAd->StaCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
286 // Association don't need to report MAC address
287 pAd->StaCfg.AssocInfo.AvailableRequestFixedIEs =
288 NDIS_802_11_AI_REQFI_CAPABILITIES | NDIS_802_11_AI_REQFI_LISTENINTERVAL;
289 pAd->StaCfg.AssocInfo.RequestFixedIEs.Capabilities = CapabilityInfo;
290 pAd->StaCfg.AssocInfo.RequestFixedIEs.ListenInterval = ListenIntv;
291 // Only reassociate need this
292 //COPY_MAC_ADDR(pAd->StaCfg.AssocInfo.RequestFixedIEs.CurrentAPAddress, ApAddr);
293 pAd->StaCfg.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
294
295 NdisZeroMemory(pAd->StaCfg.ReqVarIEs, MAX_VIE_LEN);
296 // First add SSID
297 VarIesOffset = 0;
298 NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &SsidIe, 1);
299 VarIesOffset += 1;
300 NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &pAd->MlmeAux.SsidLen, 1);
301 VarIesOffset += 1;
302 NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
303 VarIesOffset += pAd->MlmeAux.SsidLen;
304
305 // Second add Supported rates
306 NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &SupRateIe, 1);
307 VarIesOffset += 1;
308 NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &pAd->MlmeAux.SupRateLen, 1);
309 VarIesOffset += 1;
310 NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, pAd->MlmeAux.SupRate, pAd->MlmeAux.SupRateLen);
311 VarIesOffset += pAd->MlmeAux.SupRateLen;
312 // End Add by James
313
314 if ((pAd->CommonCfg.Channel > 14) &&
315 (pAd->CommonCfg.bIEEE80211H == TRUE))
316 CapabilityInfo |= 0x0100;
317
318 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Send ASSOC request...\n"));
319 MgtMacHeaderInit(pAd, &AssocHdr, SUBTYPE_ASSOC_REQ, 0, ApAddr, ApAddr);
320
321 // Build basic frame first
322 MakeOutgoingFrame(pOutBuffer, &FrameLen,
323 sizeof(HEADER_802_11), &AssocHdr,
324 2, &CapabilityInfo,
325 2, &ListenIntv,
326 1, &SsidIe,
327 1, &pAd->MlmeAux.SsidLen,
328 pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid,
329 1, &SupRateIe,
330 1, &pAd->MlmeAux.SupRateLen,
331 pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate,
332 END_OF_ARGS);
333
334 if (pAd->MlmeAux.ExtRateLen != 0)
335 {
336 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
337 1, &ExtRateIe,
338 1, &pAd->MlmeAux.ExtRateLen,
339 pAd->MlmeAux.ExtRateLen, pAd->MlmeAux.ExtRate,
340 END_OF_ARGS);
341 FrameLen += tmp;
342 }
343
344#ifdef DOT11_N_SUPPORT
345 // HT
346 if ((pAd->MlmeAux.HtCapabilityLen > 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
347 {
348 ULONG TmpLen;
349 UCHAR HtLen;
350 UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
351 if (pAd->StaActive.SupportedPhyInfo.bPreNHt == TRUE)
352 {
353 HtLen = SIZE_HT_CAP_IE + 4;
354 MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
355 1, &WpaIe,
356 1, &HtLen,
357 4, &BROADCOM[0],
358 pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability,
359 END_OF_ARGS);
360 }
361 else
362 {
363#ifdef RT_BIG_ENDIAN
364 HT_CAPABILITY_IE HtCapabilityTmp;
365#endif
366
367#ifndef RT_BIG_ENDIAN
368 MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
369 1, &HtCapIe,
370 1, &pAd->MlmeAux.HtCapabilityLen,
371 pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability,
372 END_OF_ARGS);
373#else
374 NdisZeroMemory(&HtCapabilityTmp, sizeof(HT_CAPABILITY_IE));
375 NdisMoveMemory(&HtCapabilityTmp, &pAd->MlmeAux.HtCapability, pAd->MlmeAux.HtCapabilityLen);
376 *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
377 *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
378
379 MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
380 1, &HtCapIe,
381 1, &pAd->MlmeAux.HtCapabilityLen,
382 pAd->MlmeAux.HtCapabilityLen,&HtCapabilityTmp,
383 END_OF_ARGS);
384#endif
385 }
386 FrameLen += TmpLen;
387 }
388#endif // DOT11_N_SUPPORT //
389
390 // add Ralink proprietary IE to inform AP this STA is going to use AGGREGATION or PIGGY-BACK+AGGREGATION
391 // Case I: (Aggregation + Piggy-Back)
392 // 1. user enable aggregation, AND
393 // 2. Mac support piggy-back
394 // 3. AP annouces it's PIGGY-BACK+AGGREGATION-capable in BEACON
395 // Case II: (Aggregation)
396 // 1. user enable aggregation, AND
397 // 2. AP annouces it's AGGREGATION-capable in BEACON
398 if (pAd->CommonCfg.bAggregationCapable)
399 {
400 if ((pAd->CommonCfg.bPiggyBackCapable) && ((pAd->MlmeAux.APRalinkIe & 0x00000003) == 3))
401 {
402 ULONG TmpLen;
403 UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x03, 0x00, 0x00, 0x00};
404 MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
405 9, RalinkIe,
406 END_OF_ARGS);
407 FrameLen += TmpLen;
408 }
409 else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
410 {
411 ULONG TmpLen;
412 UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x01, 0x00, 0x00, 0x00};
413 MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
414 9, RalinkIe,
415 END_OF_ARGS);
416 FrameLen += TmpLen;
417 }
418 }
419 else
420 {
421 ULONG TmpLen;
422 UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x06, 0x00, 0x00, 0x00};
423 MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
424 9, RalinkIe,
425 END_OF_ARGS);
426 FrameLen += TmpLen;
427 }
428
429 if (pAd->MlmeAux.APEdcaParm.bValid)
430 {
431 if (pAd->CommonCfg.bAPSDCapable && pAd->MlmeAux.APEdcaParm.bAPSDCapable)
432 {
433 QBSS_STA_INFO_PARM QosInfo;
434
435 NdisZeroMemory(&QosInfo, sizeof(QBSS_STA_INFO_PARM));
436 QosInfo.UAPSD_AC_BE = pAd->CommonCfg.bAPSDAC_BE;
437 QosInfo.UAPSD_AC_BK = pAd->CommonCfg.bAPSDAC_BK;
438 QosInfo.UAPSD_AC_VI = pAd->CommonCfg.bAPSDAC_VI;
439 QosInfo.UAPSD_AC_VO = pAd->CommonCfg.bAPSDAC_VO;
440 QosInfo.MaxSPLength = pAd->CommonCfg.MaxSPLength;
441 WmeIe[8] |= *(PUCHAR)&QosInfo;
442 }
443 else
444 {
445 // The Parameter Set Count is set to ¡§0¡¨ in the association request frames
446 // WmeIe[8] |= (pAd->MlmeAux.APEdcaParm.EdcaUpdateCount & 0x0f);
447 }
448
449 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
450 9, &WmeIe[0],
451 END_OF_ARGS);
452 FrameLen += tmp;
453 }
454
455 //
456 // Let WPA(#221) Element ID on the end of this association frame.
457 // Otherwise some AP will fail on parsing Element ID and set status fail on Assoc Rsp.
458 // For example: Put Vendor Specific IE on the front of WPA IE.
459 // This happens on AP (Model No:Linksys WRK54G)
460 //
461 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
462 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
463 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
464 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)
465 )
466 )
467 {
468 UCHAR RSNIe = IE_WPA;
469
470 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
471 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2))
472 {
473 RSNIe = IE_WPA2;
474 }
475
476#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
477#ifdef SIOCSIWGENIE
478 if (pAd->StaCfg.WpaSupplicantUP != 1)
479#endif // SIOCSIWGENIE //
480#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
481 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
482
483 // Check for WPA PMK cache list
484 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)
485 {
486 INT idx;
487 BOOLEAN FoundPMK = FALSE;
488 // Search chched PMKID, append it if existed
489 for (idx = 0; idx < PMKID_NO; idx++)
490 {
491 if (NdisEqualMemory(ApAddr, &pAd->StaCfg.SavedPMK[idx].BSSID, 6))
492 {
493 FoundPMK = TRUE;
494 break;
495 }
496 }
497
498 if (FoundPMK)
499 {
500 // Set PMK number
501 *(PUSHORT) &pAd->StaCfg.RSN_IE[pAd->StaCfg.RSNIE_Len] = 1;
502 NdisMoveMemory(&pAd->StaCfg.RSN_IE[pAd->StaCfg.RSNIE_Len + 2], &pAd->StaCfg.SavedPMK[idx].PMKID, 16);
503 pAd->StaCfg.RSNIE_Len += 18;
504 }
505 }
506
507#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
508#ifdef SIOCSIWGENIE
509 if (pAd->StaCfg.WpaSupplicantUP == 1)
510 {
511 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
512 pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
513 END_OF_ARGS);
514 }
515 else
516#endif
517#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
518 {
519 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
520 1, &RSNIe,
521 1, &pAd->StaCfg.RSNIE_Len,
522 pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
523 END_OF_ARGS);
524 }
525
526 FrameLen += tmp;
527
528#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
529#ifdef SIOCSIWGENIE
530 if (pAd->StaCfg.WpaSupplicantUP != 1)
531#endif
532#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
533 {
534 // Append Variable IE
535 NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &RSNIe, 1);
536 VarIesOffset += 1;
537 NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &pAd->StaCfg.RSNIE_Len, 1);
538 VarIesOffset += 1;
539 }
540 NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, pAd->StaCfg.RSN_IE, pAd->StaCfg.RSNIE_Len);
541 VarIesOffset += pAd->StaCfg.RSNIE_Len;
542
543 // Set Variable IEs Length
544 pAd->StaCfg.ReqVarIELen = VarIesOffset;
545 }
546
547 // We have update that at PeerBeaconAtJoinRequest()
548 CkipFlag = pAd->StaCfg.CkipFlag;
549 if (CkipFlag != 0)
550 {
551 NdisZeroMemory(CkipNegotiationBuffer, CKIP_NEGOTIATION_LENGTH);
552 CkipNegotiationBuffer[2] = 0x66;
553 // Make it try KP & MIC, since we have to follow the result from AssocRsp
554 CkipNegotiationBuffer[8] = 0x18;
555 CkipNegotiationBuffer[CKIP_NEGOTIATION_LENGTH - 1] = 0x22;
556 CkipFlag = 0x18;
557
558 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
559 1, &AironetCkipIe,
560 1, &AironetCkipLen,
561 AironetCkipLen, CkipNegotiationBuffer,
562 END_OF_ARGS);
563 FrameLen += tmp;
564 }
565
566 // Add CCX v2 request if CCX2 admin state is on
567 if (pAd->StaCfg.CCXControl.field.Enable == 1)
568 {
569
570 //
571 // Add AironetIPAddressIE for Cisco CCX 2.X
572 // Add CCX Version
573 //
574 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
575 1, &AironetIPAddressIE,
576 1, &AironetIPAddressLen,
577 AironetIPAddressLen, AironetIPAddressBuffer,
578 1, &Ccx2Ie,
579 1, &Ccx2Len,
580 Ccx2Len, Ccx2IeInfo,
581 END_OF_ARGS);
582 FrameLen += tmp;
583
584 //
585 // Add CipherSuite CCKM or LeapTkip if setting.
586 //
587#ifdef LEAP_SUPPORT
588 if (LEAP_CCKM_ON(pAd))
589 {
590 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
591 CipherSuiteCiscoCCKMLen, CipherSuiteCiscoCCKM,
592 END_OF_ARGS);
593 FrameLen += tmp;
594
595 // Third add RSN
596 NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, CipherSuiteCiscoCCKM, CipherSuiteCiscoCCKMLen); //Save CipherSuite
597 VarIesOffset += CipherSuiteCiscoCCKMLen;
598 }
599 else if ((pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP) && (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled))
600 {
601 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
602 CipherSuiteCCXTkipLen, CipherSuiteCCXTkip,
603 END_OF_ARGS);
604 FrameLen += tmp;
605
606 // Third add RSN
607 NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, CipherSuiteCCXTkip, CipherSuiteCCXTkipLen);
608 VarIesOffset += CipherSuiteCCXTkipLen;
609 }
610#endif // LEAP_SUPPORT //
611
612 // Add by James 03/06/27
613 // Set Variable IEs Length
614 pAd->StaCfg.ReqVarIELen = VarIesOffset;
615 pAd->StaCfg.AssocInfo.RequestIELength = VarIesOffset;
616
617 // OffsetResponseIEs follow ReqVarIE
618 pAd->StaCfg.AssocInfo.OffsetResponseIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION) + pAd->StaCfg.ReqVarIELen;
619 // End Add by James
620 }
621
622
623 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
624 MlmeFreeMemory(pAd, pOutBuffer);
625
626 RTMPSetTimer(&pAd->MlmeAux.AssocTimer, Timeout);
627 pAd->Mlme.AssocMachine.CurrState = ASSOC_WAIT_RSP;
628 }
629 else
630 {
631 DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeAssocReqAction() sanity check failed. BUG!!!!!! \n"));
632 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
633 Status = MLME_INVALID_FORMAT;
634 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
635 }
636
637}
638
639/*
640 ==========================================================================
641 Description:
642 mlme reassoc req handling procedure
643 Parameters:
644 Elem -
645 Pre:
646 -# SSID (Adapter->StaCfg.ssid[])
647 -# BSSID (AP address, Adapter->StaCfg.bssid)
648 -# Supported rates (Adapter->StaCfg.supported_rates[])
649 -# Supported rates length (Adapter->StaCfg.supported_rates_len)
650 -# Tx power (Adapter->StaCfg.tx_power)
651
652 IRQL = DISPATCH_LEVEL
653
654 ==========================================================================
655 */
656VOID MlmeReassocReqAction(
657 IN PRTMP_ADAPTER pAd,
658 IN MLME_QUEUE_ELEM *Elem)
659{
660 UCHAR ApAddr[6];
661 HEADER_802_11 ReassocHdr;
662 UCHAR Ccx2Len = 5;
663 UCHAR WmeIe[9] = {IE_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
664 USHORT CapabilityInfo, ListenIntv;
665 ULONG Timeout;
666 ULONG FrameLen = 0;
667 BOOLEAN TimerCancelled;
668 NDIS_STATUS NStatus;
669 ULONG tmp;
670 PUCHAR pOutBuffer = NULL;
671//CCX 2.X
672#ifdef LEAP_SUPPORT
673 UCHAR CkipFlag;
674 UCHAR CkipNegotiationBuffer[CKIP_NEGOTIATION_LENGTH];
675 UCHAR AironetCkipIe = IE_AIRONET_CKIP;
676 UCHAR AironetCkipLen = CKIP_NEGOTIATION_LENGTH;
677 UCHAR AironetIPAddressIE = IE_AIRONET_IPADDRESS;
678 UCHAR AironetIPAddressLen = AIRONET_IPADDRESS_LENGTH;
679 UCHAR AironetIPAddressBuffer[AIRONET_IPADDRESS_LENGTH] = {0x00, 0x40, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
680 UCHAR AironetCCKMReassocIE = IE_AIRONET_CCKMREASSOC;
681 UCHAR AironetCCKMReassocLen = AIRONET_CCKMREASSOC_LENGTH;
682 UCHAR AironetCCKMReassocBuffer[AIRONET_CCKMREASSOC_LENGTH];
683 UCHAR AironetOUI[] = {0x00, 0x40, 0x96, 0x00};
684 UCHAR MICMN[16];
685 UCHAR CalcMicBuffer[80];
686 ULONG CalcMicBufferLen = 0;
687#endif // LEAP_SUPPORT //
688 USHORT Status;
689
690 // Block all authentication request durning WPA block period
691 if (pAd->StaCfg.bBlockAssoc == TRUE)
692 {
693 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Block ReAssoc request durning WPA block period!\n"));
694 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
695 Status = MLME_STATE_MACHINE_REJECT;
696 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
697 }
698 // the parameters are the same as the association
699 else if(MlmeAssocReqSanity(pAd, Elem->Msg, Elem->MsgLen, ApAddr, &CapabilityInfo, &Timeout, &ListenIntv))
700 {
701 RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &TimerCancelled);
702
703 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
704 if(NStatus != NDIS_STATUS_SUCCESS)
705 {
706 DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeReassocReqAction() allocate memory failed \n"));
707 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
708 Status = MLME_FAIL_NO_RESOURCE;
709 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
710 return;
711 }
712
713 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, ApAddr);
714
715 // make frame, use bssid as the AP address??
716 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Send RE-ASSOC request...\n"));
717 MgtMacHeaderInit(pAd, &ReassocHdr, SUBTYPE_REASSOC_REQ, 0, ApAddr, ApAddr);
718 MakeOutgoingFrame(pOutBuffer, &FrameLen,
719 sizeof(HEADER_802_11), &ReassocHdr,
720 2, &CapabilityInfo,
721 2, &ListenIntv,
722 MAC_ADDR_LEN, ApAddr,
723 1, &SsidIe,
724 1, &pAd->MlmeAux.SsidLen,
725 pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid,
726 1, &SupRateIe,
727 1, &pAd->MlmeAux.SupRateLen,
728 pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate,
729 END_OF_ARGS);
730
731 if (pAd->MlmeAux.ExtRateLen != 0)
732 {
733 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
734 1, &ExtRateIe,
735 1, &pAd->MlmeAux.ExtRateLen,
736 pAd->MlmeAux.ExtRateLen, pAd->MlmeAux.ExtRate,
737 END_OF_ARGS);
738 FrameLen += tmp;
739 }
740
741 if (pAd->MlmeAux.APEdcaParm.bValid)
742 {
743 if (pAd->CommonCfg.bAPSDCapable && pAd->MlmeAux.APEdcaParm.bAPSDCapable)
744 {
745 QBSS_STA_INFO_PARM QosInfo;
746
747 NdisZeroMemory(&QosInfo, sizeof(QBSS_STA_INFO_PARM));
748 QosInfo.UAPSD_AC_BE = pAd->CommonCfg.bAPSDAC_BE;
749 QosInfo.UAPSD_AC_BK = pAd->CommonCfg.bAPSDAC_BK;
750 QosInfo.UAPSD_AC_VI = pAd->CommonCfg.bAPSDAC_VI;
751 QosInfo.UAPSD_AC_VO = pAd->CommonCfg.bAPSDAC_VO;
752 QosInfo.MaxSPLength = pAd->CommonCfg.MaxSPLength;
753 WmeIe[8] |= *(PUCHAR)&QosInfo;
754 }
755
756 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
757 9, &WmeIe[0],
758 END_OF_ARGS);
759 FrameLen += tmp;
760 }
761
762#ifdef DOT11_N_SUPPORT
763 // HT
764 if ((pAd->MlmeAux.HtCapabilityLen > 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
765 {
766 ULONG TmpLen;
767 UCHAR HtLen;
768 UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
769 if (pAd->StaActive.SupportedPhyInfo.bPreNHt == TRUE)
770 {
771 HtLen = SIZE_HT_CAP_IE + 4;
772 MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
773 1, &WpaIe,
774 1, &HtLen,
775 4, &BROADCOM[0],
776 pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability,
777 END_OF_ARGS);
778 }
779 else
780 {
781 MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
782 1, &HtCapIe,
783 1, &pAd->MlmeAux.HtCapabilityLen,
784 pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability,
785 END_OF_ARGS);
786 }
787 FrameLen += TmpLen;
788 }
789#endif // DOT11_N_SUPPORT //
790
791 // add Ralink proprietary IE to inform AP this STA is going to use AGGREGATION or PIGGY-BACK+AGGREGATION
792 // Case I: (Aggregation + Piggy-Back)
793 // 1. user enable aggregation, AND
794 // 2. Mac support piggy-back
795 // 3. AP annouces it's PIGGY-BACK+AGGREGATION-capable in BEACON
796 // Case II: (Aggregation)
797 // 1. user enable aggregation, AND
798 // 2. AP annouces it's AGGREGATION-capable in BEACON
799 if (pAd->CommonCfg.bAggregationCapable)
800 {
801 if ((pAd->CommonCfg.bPiggyBackCapable) && ((pAd->MlmeAux.APRalinkIe & 0x00000003) == 3))
802 {
803 ULONG TmpLen;
804 UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x03, 0x00, 0x00, 0x00};
805 MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
806 9, RalinkIe,
807 END_OF_ARGS);
808 FrameLen += TmpLen;
809 }
810 else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
811 {
812 ULONG TmpLen;
813 UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x01, 0x00, 0x00, 0x00};
814 MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
815 9, RalinkIe,
816 END_OF_ARGS);
817 FrameLen += TmpLen;
818 }
819 }
820 else
821 {
822 ULONG TmpLen;
823 UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x04, 0x00, 0x00, 0x00};
824 MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
825 9, RalinkIe,
826 END_OF_ARGS);
827 FrameLen += TmpLen;
828 }
829#ifdef LEAP_SUPPORT
830 if (LEAP_CCKM_ON(pAd) && (pAd->StaCfg.CCKMLinkUpFlag == TRUE))
831 {
832 CkipFlag = pAd->StaCfg.CkipFlag; // We have update that at PeerBeaconAtJoinRequest()
833 if (CkipFlag != 0)
834 {
835 NdisZeroMemory(CkipNegotiationBuffer, CKIP_NEGOTIATION_LENGTH);
836 CkipNegotiationBuffer[2] = 0x66;
837 // Make it try KP & MIC, since we have to follow the result from AssocRsp
838 CkipNegotiationBuffer[8] = 0x18;
839 CkipNegotiationBuffer[CKIP_NEGOTIATION_LENGTH - 1] = 0x22;
840
841 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
842 1, &AironetCkipIe,
843 1, &AironetCkipLen,
844 AironetCkipLen, CkipNegotiationBuffer,
845 END_OF_ARGS);
846 FrameLen += tmp;
847 }
848
849 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
850 1, &AironetIPAddressIE,
851 1, &AironetIPAddressLen,
852 AironetIPAddressLen, AironetIPAddressBuffer,
853 END_OF_ARGS);
854 FrameLen += tmp;
855
856 //
857 // The RN is incremented before each reassociation request.
858 //
859 pAd->StaCfg.CCKMRN++;
860 //
861 // Calculate MIC = hmac-md5(krk, STA-ID|BSSID|RSNIE|TSF|RN);
862 //
863 COPY_MAC_ADDR(CalcMicBuffer, pAd->CurrentAddress);
864 CalcMicBufferLen = MAC_ADDR_LEN;
865 COPY_MAC_ADDR(CalcMicBuffer + CalcMicBufferLen, pAd->MlmeAux.Bssid);
866 CalcMicBufferLen += MAC_ADDR_LEN;
867 NdisMoveMemory(CalcMicBuffer + CalcMicBufferLen, CipherSuiteCiscoCCKM, CipherSuiteCiscoCCKMLen);
868 CalcMicBufferLen += CipherSuiteCiscoCCKMLen;
869 NdisMoveMemory(CalcMicBuffer + CalcMicBufferLen, (PUCHAR) &pAd->StaCfg.CCKMBeaconAtJoinTimeStamp, sizeof(pAd->StaCfg.CCKMBeaconAtJoinTimeStamp));
870 CalcMicBufferLen += sizeof(pAd->StaCfg.CCKMBeaconAtJoinTimeStamp);
871 NdisMoveMemory(CalcMicBuffer + CalcMicBufferLen, (PUCHAR)&pAd->StaCfg.CCKMRN, sizeof(pAd->StaCfg.CCKMRN));
872 CalcMicBufferLen += sizeof(pAd->StaCfg.CCKMRN);
873 hmac_md5(pAd->StaCfg.KRK, LEN_EAP_MICK, CalcMicBuffer, CalcMicBufferLen, MICMN);
874
875 //
876 // fill up CCKM reassociation request element
877 //
878 NdisMoveMemory(AironetCCKMReassocBuffer, AironetOUI, 4);
879 NdisMoveMemory(AironetCCKMReassocBuffer + 4, (PUCHAR)&pAd->StaCfg.CCKMBeaconAtJoinTimeStamp, 8);
880 NdisMoveMemory(AironetCCKMReassocBuffer + 12, (PUCHAR) &pAd->StaCfg.CCKMRN, 4);
881 NdisMoveMemory(AironetCCKMReassocBuffer +16, MICMN, 8);
882
883 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
884 1, &AironetCCKMReassocIE,
885 1, &AironetCCKMReassocLen,
886 AironetCCKMReassocLen, AironetCCKMReassocBuffer,
887 END_OF_ARGS);
888 FrameLen += tmp;
889
890 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
891 CipherSuiteCiscoCCKMLen,CipherSuiteCiscoCCKM,
892 END_OF_ARGS);
893 FrameLen += tmp;
894 }
895#endif // LEAP_SUPPORT //
896
897 // Add CCX v2 request if CCX2 admin state is on
898 if (pAd->StaCfg.CCXControl.field.Enable == 1)
899 {
900 //
901 // Add CCX Version
902 //
903 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
904 1, &Ccx2Ie,
905 1, &Ccx2Len,
906 Ccx2Len, Ccx2IeInfo,
907 END_OF_ARGS);
908 FrameLen += tmp;
909 }
910
911 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
912 MlmeFreeMemory(pAd, pOutBuffer);
913
914 RTMPSetTimer(&pAd->MlmeAux.ReassocTimer, Timeout); /* in mSec */
915 pAd->Mlme.AssocMachine.CurrState = REASSOC_WAIT_RSP;
916 }
917 else
918 {
919 DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeReassocReqAction() sanity check failed. BUG!!!! \n"));
920 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
921 Status = MLME_INVALID_FORMAT;
922 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
923 }
924}
925
926/*
927 ==========================================================================
928 Description:
929 Upper layer issues disassoc request
930 Parameters:
931 Elem -
932
933 IRQL = PASSIVE_LEVEL
934
935 ==========================================================================
936 */
937VOID MlmeDisassocReqAction(
938 IN PRTMP_ADAPTER pAd,
939 IN MLME_QUEUE_ELEM *Elem)
940{
941 PMLME_DISASSOC_REQ_STRUCT pDisassocReq;
942 HEADER_802_11 DisassocHdr;
943 PHEADER_802_11 pDisassocHdr;
944 PUCHAR pOutBuffer = NULL;
945 ULONG FrameLen = 0;
946 NDIS_STATUS NStatus;
947 BOOLEAN TimerCancelled;
948 ULONG Timeout = 0;
949 USHORT Status;
950
951#ifdef QOS_DLS_SUPPORT
952 // send DLS-TEAR_DOWN message,
953 if (pAd->CommonCfg.bDLSCapable)
954 {
955 UCHAR i;
956
957 // tear down local dls table entry
958 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
959 {
960 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
961 {
962 RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
963 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
964 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
965 }
966 }
967
968 // tear down peer dls table entry
969 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
970 {
971 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
972 {
973 RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
974 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
975 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
976 }
977 }
978 }
979#endif // QOS_DLS_SUPPORT //
980
981 // skip sanity check
982 pDisassocReq = (PMLME_DISASSOC_REQ_STRUCT)(Elem->Msg);
983
984 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
985 if (NStatus != NDIS_STATUS_SUCCESS)
986 {
987 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - MlmeDisassocReqAction() allocate memory failed\n"));
988 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
989 Status = MLME_FAIL_NO_RESOURCE;
990 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, &Status);
991 return;
992 }
993
994
995
996 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &TimerCancelled);
997
998 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Send DISASSOC request[BSSID::%02x:%02x:%02x:%02x:%02x:%02x (Reason=%d)\n",
999 pDisassocReq->Addr[0], pDisassocReq->Addr[1], pDisassocReq->Addr[2],
1000 pDisassocReq->Addr[3], pDisassocReq->Addr[4], pDisassocReq->Addr[5], pDisassocReq->Reason));
1001 MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pDisassocReq->Addr, pDisassocReq->Addr); // patch peap ttls switching issue
1002 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1003 sizeof(HEADER_802_11),&DisassocHdr,
1004 2, &pDisassocReq->Reason,
1005 END_OF_ARGS);
1006 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1007
1008 // To patch Instance and Buffalo(N) AP
1009 // Driver has to send deauth to Instance AP, but Buffalo(N) needs to send disassoc to reset Authenticator's state machine
1010 // Therefore, we send both of them.
1011 pDisassocHdr = (PHEADER_802_11)pOutBuffer;
1012 pDisassocHdr->FC.SubType = SUBTYPE_DEAUTH;
1013 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1014
1015 MlmeFreeMemory(pAd, pOutBuffer);
1016
1017 pAd->StaCfg.DisassocReason = REASON_DISASSOC_STA_LEAVING;
1018 COPY_MAC_ADDR(pAd->StaCfg.DisassocSta, pDisassocReq->Addr);
1019
1020 RTMPSetTimer(&pAd->MlmeAux.DisassocTimer, Timeout); /* in mSec */
1021 pAd->Mlme.AssocMachine.CurrState = DISASSOC_WAIT_RSP;
1022
1023#ifdef WPA_SUPPLICANT_SUPPORT
1024#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
1025 if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
1026 {
1027 union iwreq_data wrqu;
1028 //send disassociate event to wpa_supplicant
1029 memset(&wrqu, 0, sizeof(wrqu));
1030 wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
1031 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
1032 }
1033#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1034#endif // WPA_SUPPLICANT_SUPPORT //
1035
1036#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
1037 {
1038 union iwreq_data wrqu;
1039 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
1040 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
1041 }
1042#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1043
1044}
1045
1046/*
1047 ==========================================================================
1048 Description:
1049 peer sends assoc rsp back
1050 Parameters:
1051 Elme - MLME message containing the received frame
1052
1053 IRQL = DISPATCH_LEVEL
1054
1055 ==========================================================================
1056 */
1057VOID PeerAssocRspAction(
1058 IN PRTMP_ADAPTER pAd,
1059 IN MLME_QUEUE_ELEM *Elem)
1060{
1061 USHORT CapabilityInfo, Status, Aid;
1062 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], SupRateLen;
1063 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRateLen;
1064 UCHAR Addr2[MAC_ADDR_LEN];
1065 BOOLEAN TimerCancelled;
1066 UCHAR CkipFlag;
1067 EDCA_PARM EdcaParm;
1068 HT_CAPABILITY_IE HtCapability;
1069 ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
1070 UCHAR HtCapabilityLen;
1071 UCHAR AddHtInfoLen;
1072 UCHAR NewExtChannelOffset = 0xff;
1073
1074 if (PeerAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &CapabilityInfo, &Status, &Aid, SupRate, &SupRateLen, ExtRate, &ExtRateLen,
1075 &HtCapability,&AddHtInfo, &HtCapabilityLen,&AddHtInfoLen,&NewExtChannelOffset, &EdcaParm, &CkipFlag))
1076 {
1077 // The frame is for me ?
1078 if(MAC_ADDR_EQUAL(Addr2, pAd->MlmeAux.Bssid))
1079 {
1080 DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspAction():ASSOC - receive ASSOC_RSP to me (status=%d)\n", Status));
1081#ifdef DOT11_N_SUPPORT
1082 DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspAction():MacTable [%d].AMsduSize = %d. ClientStatusFlags = 0x%lx \n",Elem->Wcid, pAd->MacTab.Content[BSSID_WCID].AMsduSize, pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1083#endif // DOT11_N_SUPPORT //
1084 RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &TimerCancelled);
1085 if(Status == MLME_SUCCESS)
1086 {
1087 UCHAR MaxSupportedRateIn500Kbps = 0;
1088 UCHAR idx;
1089
1090 // supported rates array may not be sorted. sort it and find the maximum rate
1091 for (idx=0; idx<SupRateLen; idx++)
1092 {
1093 if (MaxSupportedRateIn500Kbps < (SupRate[idx] & 0x7f))
1094 MaxSupportedRateIn500Kbps = SupRate[idx] & 0x7f;
1095 }
1096
1097 for (idx=0; idx<ExtRateLen; idx++)
1098 {
1099 if (MaxSupportedRateIn500Kbps < (ExtRate[idx] & 0x7f))
1100 MaxSupportedRateIn500Kbps = ExtRate[idx] & 0x7f;
1101 }
1102 // go to procedure listed on page 376
1103 AssocPostProc(pAd, Addr2, CapabilityInfo, Aid, SupRate, SupRateLen, ExtRate, ExtRateLen,
1104 &EdcaParm, &HtCapability, HtCapabilityLen, &AddHtInfo);
1105
1106 StaAddMacTableEntry(pAd, &pAd->MacTab.Content[BSSID_WCID], MaxSupportedRateIn500Kbps, &HtCapability, HtCapabilityLen, CapabilityInfo);
1107
1108 pAd->StaCfg.CkipFlag = CkipFlag;
1109 if (CkipFlag & 0x18)
1110 {
1111 NdisZeroMemory(pAd->StaCfg.TxSEQ, 4);
1112 NdisZeroMemory(pAd->StaCfg.RxSEQ, 4);
1113 NdisZeroMemory(pAd->StaCfg.CKIPMIC, 4);
1114 pAd->StaCfg.GIV[0] = RandomByte(pAd);
1115 pAd->StaCfg.GIV[1] = RandomByte(pAd);
1116 pAd->StaCfg.GIV[2] = RandomByte(pAd);
1117 pAd->StaCfg.bCkipOn = TRUE;
1118 DBGPRINT(RT_DEBUG_TRACE, ("<CCX> pAd->StaCfg.CkipFlag = 0x%02x\n", pAd->StaCfg.CkipFlag));
1119 }
1120 }
1121 else
1122 {
1123 // Faile on Association, we need to check the status code
1124 // Is that a Rogue AP?
1125#ifdef LEAP_SUPPORT
1126 if ((pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP) && (Status == MLME_ALG_NOT_SUPPORT))
1127 { //Possibly Rogue AP
1128 RogueApTableSetEntry(pAd, &pAd->StaCfg.RogueApTab, pAd->MlmeAux.Bssid, LEAP_REASON_INVALID_AUTH);
1129 }
1130#endif // LEAP_SUPPORT //
1131 }
1132 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1133 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
1134 }
1135 }
1136 else
1137 {
1138 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerAssocRspAction() sanity check fail\n"));
1139 }
1140}
1141
1142/*
1143 ==========================================================================
1144 Description:
1145 peer sends reassoc rsp
1146 Parametrs:
1147 Elem - MLME message cntaining the received frame
1148
1149 IRQL = DISPATCH_LEVEL
1150
1151 ==========================================================================
1152 */
1153VOID PeerReassocRspAction(
1154 IN PRTMP_ADAPTER pAd,
1155 IN MLME_QUEUE_ELEM *Elem)
1156{
1157 USHORT CapabilityInfo;
1158 USHORT Status;
1159 USHORT Aid;
1160 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], SupRateLen;
1161 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRateLen;
1162 UCHAR Addr2[MAC_ADDR_LEN];
1163 UCHAR CkipFlag;
1164 BOOLEAN TimerCancelled;
1165 EDCA_PARM EdcaParm;
1166 HT_CAPABILITY_IE HtCapability;
1167 ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
1168 UCHAR HtCapabilityLen;
1169 UCHAR AddHtInfoLen;
1170 UCHAR NewExtChannelOffset = 0xff;
1171
1172 if(PeerAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &CapabilityInfo, &Status, &Aid, SupRate, &SupRateLen, ExtRate, &ExtRateLen,
1173 &HtCapability, &AddHtInfo, &HtCapabilityLen, &AddHtInfoLen,&NewExtChannelOffset, &EdcaParm, &CkipFlag))
1174 {
1175 if(MAC_ADDR_EQUAL(Addr2, pAd->MlmeAux.Bssid)) // The frame is for me ?
1176 {
1177 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - receive REASSOC_RSP to me (status=%d)\n", Status));
1178 RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &TimerCancelled);
1179
1180 if(Status == MLME_SUCCESS)
1181 {
1182 // go to procedure listed on page 376
1183 AssocPostProc(pAd, Addr2, CapabilityInfo, Aid, SupRate, SupRateLen, ExtRate, ExtRateLen,
1184 &EdcaParm, &HtCapability, HtCapabilityLen, &AddHtInfo);
1185
1186#ifdef WPA_SUPPLICANT_SUPPORT
1187#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
1188 if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
1189 {
1190 union iwreq_data wrqu;
1191
1192 SendAssocIEsToWpaSupplicant(pAd);
1193 memset(&wrqu, 0, sizeof(wrqu));
1194 wrqu.data.flags = RT_ASSOC_EVENT_FLAG;
1195 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
1196 }
1197#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1198#endif // WPA_SUPPLICANT_SUPPORT //
1199
1200#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
1201 {
1202 union iwreq_data wrqu;
1203 wext_notify_event_assoc(pAd);
1204
1205 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
1206 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
1207 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
1208
1209 }
1210#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1211
1212 }
1213
1214 //
1215 // Cisco Leap CCKM supported Re-association.
1216 //
1217#ifdef LEAP_SUPPORT
1218 if (LEAP_CCKM_ON(pAd) && (pAd->StaCfg.CCKMLinkUpFlag == TRUE))
1219 {
1220 if (CCKMAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen) == TRUE)
1221 {
1222 pAd->StaCfg.CkipFlag = CkipFlag;
1223 if (CkipFlag & 0x18)
1224 {
1225 NdisZeroMemory(pAd->StaCfg.TxSEQ, 4);
1226 NdisZeroMemory(pAd->StaCfg.RxSEQ, 4);
1227 NdisZeroMemory(pAd->StaCfg.CKIPMIC, 4);
1228 pAd->StaCfg.GIV[0] = RandomByte(pAd);
1229 pAd->StaCfg.GIV[1] = RandomByte(pAd);
1230 pAd->StaCfg.GIV[2] = RandomByte(pAd);
1231 pAd->StaCfg.bCkipOn = TRUE;
1232 DBGPRINT(RT_DEBUG_TRACE, ("<CCX> pAd->StaCfg.CkipFlag = 0x%02x\n", pAd->StaCfg.CkipFlag));
1233 }
1234
1235 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1236 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
1237 }
1238 else
1239 {
1240 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - CCKMAssocRspSanity() sanity check fail\n"));
1241 }
1242 }
1243 else
1244#endif // LEAP_SUPPORT //
1245 {
1246 // CkipFlag is no use for reassociate
1247 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1248 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
1249 }
1250 }
1251 }
1252 else
1253 {
1254 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerReassocRspAction() sanity check fail\n"));
1255 }
1256
1257}
1258
1259/*
1260 ==========================================================================
1261 Description:
1262 procedures on IEEE 802.11/1999 p.376
1263 Parametrs:
1264
1265 IRQL = DISPATCH_LEVEL
1266
1267 ==========================================================================
1268 */
1269VOID AssocPostProc(
1270 IN PRTMP_ADAPTER pAd,
1271 IN PUCHAR pAddr2,
1272 IN USHORT CapabilityInfo,
1273 IN USHORT Aid,
1274 IN UCHAR SupRate[],
1275 IN UCHAR SupRateLen,
1276 IN UCHAR ExtRate[],
1277 IN UCHAR ExtRateLen,
1278 IN PEDCA_PARM pEdcaParm,
1279 IN HT_CAPABILITY_IE *pHtCapability,
1280 IN UCHAR HtCapabilityLen,
1281 IN ADD_HT_INFO_IE *pAddHtInfo) // AP might use this additional ht info IE
1282{
1283 ULONG Idx;
1284
1285 pAd->MlmeAux.BssType = BSS_INFRA;
1286 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pAddr2);
1287 pAd->MlmeAux.Aid = Aid;
1288 pAd->MlmeAux.CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO;
1289#ifdef DOT11_N_SUPPORT
1290 // Some HT AP might lost WMM IE. We add WMM ourselves. beacuase HT requires QoS on.
1291 if ((HtCapabilityLen > 0) && (pEdcaParm->bValid == FALSE))
1292 {
1293 pEdcaParm->bValid = TRUE;
1294 pEdcaParm->Aifsn[0] = 3;
1295 pEdcaParm->Aifsn[1] = 7;
1296 pEdcaParm->Aifsn[2] = 2;
1297 pEdcaParm->Aifsn[3] = 2;
1298
1299 pEdcaParm->Cwmin[0] = 4;
1300 pEdcaParm->Cwmin[1] = 4;
1301 pEdcaParm->Cwmin[2] = 3;
1302 pEdcaParm->Cwmin[3] = 2;
1303
1304 pEdcaParm->Cwmax[0] = 10;
1305 pEdcaParm->Cwmax[1] = 10;
1306 pEdcaParm->Cwmax[2] = 4;
1307 pEdcaParm->Cwmax[3] = 3;
1308
1309 pEdcaParm->Txop[0] = 0;
1310 pEdcaParm->Txop[1] = 0;
1311 pEdcaParm->Txop[2] = 96;
1312 pEdcaParm->Txop[3] = 48;
1313
1314 }
1315#endif // DOT11_N_SUPPORT //
1316
1317 NdisMoveMemory(&pAd->MlmeAux.APEdcaParm, pEdcaParm, sizeof(EDCA_PARM));
1318
1319 // filter out un-supported rates
1320 pAd->MlmeAux.SupRateLen = SupRateLen;
1321 NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate, SupRateLen);
1322 RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen);
1323
1324 // filter out un-supported rates
1325 pAd->MlmeAux.ExtRateLen = ExtRateLen;
1326 NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate, ExtRateLen);
1327 RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen);
1328
1329#ifdef DOT11_N_SUPPORT
1330 if (HtCapabilityLen > 0)
1331 {
1332 RTMPCheckHt(pAd, BSSID_WCID, pHtCapability, pAddHtInfo);
1333 }
1334 DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> AP.AMsduSize = %d. ClientStatusFlags = 0x%lx \n", pAd->MacTab.Content[BSSID_WCID].AMsduSize, pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1335
1336 DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> (Mmps=%d, AmsduSize=%d, )\n",
1337 pAd->MacTab.Content[BSSID_WCID].MmpsMode, pAd->MacTab.Content[BSSID_WCID].AMsduSize));
1338#endif // DOT11_N_SUPPORT //
1339
1340 // Set New WPA information
1341 Idx = BssTableSearch(&pAd->ScanTab, pAddr2, pAd->MlmeAux.Channel);
1342 if (Idx == BSS_NOT_FOUND)
1343 {
1344 DBGPRINT_ERR(("ASSOC - Can't find BSS after receiving Assoc response\n"));
1345 }
1346 else
1347 {
1348 // Init variable
1349 pAd->MacTab.Content[BSSID_WCID].RSNIE_Len = 0;
1350 NdisZeroMemory(pAd->MacTab.Content[BSSID_WCID].RSN_IE, MAX_LEN_OF_RSNIE);
1351
1352 // Store appropriate RSN_IE for WPA SM negotiation later
1353 if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) && (pAd->ScanTab.BssEntry[Idx].VarIELen != 0))
1354 {
1355 PUCHAR pVIE;
1356 USHORT len;
1357 PEID_STRUCT pEid;
1358
1359 pVIE = pAd->ScanTab.BssEntry[Idx].VarIEs;
1360 len = pAd->ScanTab.BssEntry[Idx].VarIELen;
1361
1362 while (len > 0)
1363 {
1364 pEid = (PEID_STRUCT) pVIE;
1365 // For WPA/WPAPSK
1366 if ((pEid->Eid == IE_WPA) && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
1367 && (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
1368 {
1369 NdisMoveMemory(pAd->MacTab.Content[BSSID_WCID].RSN_IE, pVIE, (pEid->Len + 2));
1370 pAd->MacTab.Content[BSSID_WCID].RSNIE_Len = (pEid->Len + 2);
1371 DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> Store RSN_IE for WPA SM negotiation \n"));
1372 }
1373 // For WPA2/WPA2PSK
1374 else if ((pEid->Eid == IE_RSN) && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))
1375 && (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2 || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
1376 {
1377 NdisMoveMemory(pAd->MacTab.Content[BSSID_WCID].RSN_IE, pVIE, (pEid->Len + 2));
1378 pAd->MacTab.Content[BSSID_WCID].RSNIE_Len = (pEid->Len + 2);
1379 DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> Store RSN_IE for WPA2 SM negotiation \n"));
1380 }
1381
1382 pVIE += (pEid->Len + 2);
1383 len -= (pEid->Len + 2);
1384 }
1385 }
1386
1387 if (pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == 0)
1388 {
1389 DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> no RSN_IE \n"));
1390 }
1391 else
1392 {
1393 hex_dump("RSN_IE", pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len);
1394 }
1395 }
1396}
1397
1398/*
1399 ==========================================================================
1400 Description:
1401 left part of IEEE 802.11/1999 p.374
1402 Parameters:
1403 Elem - MLME message containing the received frame
1404
1405 IRQL = DISPATCH_LEVEL
1406
1407 ==========================================================================
1408 */
1409VOID PeerDisassocAction(
1410 IN PRTMP_ADAPTER pAd,
1411 IN MLME_QUEUE_ELEM *Elem)
1412{
1413 UCHAR Addr2[MAC_ADDR_LEN];
1414 USHORT Reason;
1415
1416 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerDisassocAction()\n"));
1417 if(PeerDisassocSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Reason))
1418 {
1419 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerDisassocAction() Reason = %d\n", Reason));
1420 if (INFRA_ON(pAd) && MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, Addr2))
1421 {
1422
1423 if (pAd->CommonCfg.bWirelessEvent)
1424 {
1425 RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1426 }
1427
1428
1429#ifdef LEAP_SUPPORT
1430 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
1431 {
1432 // Cisco_LEAP has start a timer
1433 // We should cancel it if using LEAP
1434 RTMPCancelTimer(&pAd->StaCfg.LeapAuthTimer, &TimerCancelled);
1435 //Check is it mach the LEAP Authentication failed as possible a Rogue AP
1436 //on it's PortSecured not equal to WPA_802_1X_PORT_SECURED while process the Association.
1437 if ((pAd->Mlme.LeapMachine.CurrState != LEAP_IDLE) && (pAd->StaCfg.PortSecured != WPA_802_1X_PORT_SECURED))
1438 {
1439 RogueApTableSetEntry(pAd, &pAd->StaCfg.RogueApTab, Addr2, LEAP_REASON_AUTH_TIMEOUT);
1440 }
1441 }
1442#endif // LEAP_SUPPORT //
1443 //
1444 // Get Current System time and Turn on AdjacentAPReport
1445 //
1446 NdisGetSystemUpTime(&pAd->StaCfg.CCXAdjacentAPLinkDownTime);
1447 pAd->StaCfg.CCXAdjacentAPReportFlag = TRUE;
1448 LinkDown(pAd, TRUE);
1449 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1450
1451#ifdef WPA_SUPPLICANT_SUPPORT
1452#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
1453 if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
1454 {
1455 union iwreq_data wrqu;
1456 //send disassociate event to wpa_supplicant
1457 memset(&wrqu, 0, sizeof(wrqu));
1458 wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
1459 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
1460 }
1461#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1462#endif // WPA_SUPPLICANT_SUPPORT //
1463
1464#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
1465 {
1466 union iwreq_data wrqu;
1467 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
1468 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
1469 }
1470#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1471 }
1472 }
1473 else
1474 {
1475 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerDisassocAction() sanity check fail\n"));
1476 }
1477
1478}
1479
1480/*
1481 ==========================================================================
1482 Description:
1483 what the state machine will do after assoc timeout
1484 Parameters:
1485 Elme -
1486
1487 IRQL = DISPATCH_LEVEL
1488
1489 ==========================================================================
1490 */
1491VOID AssocTimeoutAction(
1492 IN PRTMP_ADAPTER pAd,
1493 IN MLME_QUEUE_ELEM *Elem)
1494{
1495 USHORT Status;
1496 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - AssocTimeoutAction\n"));
1497 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1498 Status = MLME_REJ_TIMEOUT;
1499 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
1500}
1501
1502/*
1503 ==========================================================================
1504 Description:
1505 what the state machine will do after reassoc timeout
1506
1507 IRQL = DISPATCH_LEVEL
1508
1509 ==========================================================================
1510 */
1511VOID ReassocTimeoutAction(
1512 IN PRTMP_ADAPTER pAd,
1513 IN MLME_QUEUE_ELEM *Elem)
1514{
1515 USHORT Status;
1516 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - ReassocTimeoutAction\n"));
1517 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1518 Status = MLME_REJ_TIMEOUT;
1519 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
1520}
1521
1522/*
1523 ==========================================================================
1524 Description:
1525 what the state machine will do after disassoc timeout
1526
1527 IRQL = DISPATCH_LEVEL
1528
1529 ==========================================================================
1530 */
1531VOID DisassocTimeoutAction(
1532 IN PRTMP_ADAPTER pAd,
1533 IN MLME_QUEUE_ELEM *Elem)
1534{
1535 USHORT Status;
1536 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - DisassocTimeoutAction\n"));
1537 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1538 Status = MLME_SUCCESS;
1539 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, &Status);
1540}
1541
1542VOID InvalidStateWhenAssoc(
1543 IN PRTMP_ADAPTER pAd,
1544 IN MLME_QUEUE_ELEM *Elem)
1545{
1546 USHORT Status;
1547 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - InvalidStateWhenAssoc(state=%ld), reset ASSOC state machine\n",
1548 pAd->Mlme.AssocMachine.CurrState));
1549 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1550 Status = MLME_STATE_MACHINE_REJECT;
1551 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
1552}
1553
1554VOID InvalidStateWhenReassoc(
1555 IN PRTMP_ADAPTER pAd,
1556 IN MLME_QUEUE_ELEM *Elem)
1557{
1558 USHORT Status;
1559 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - InvalidStateWhenReassoc(state=%ld), reset ASSOC state machine\n",
1560 pAd->Mlme.AssocMachine.CurrState));
1561 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1562 Status = MLME_STATE_MACHINE_REJECT;
1563 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
1564}
1565
1566VOID InvalidStateWhenDisassociate(
1567 IN PRTMP_ADAPTER pAd,
1568 IN MLME_QUEUE_ELEM *Elem)
1569{
1570 USHORT Status;
1571 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - InvalidStateWhenDisassoc(state=%ld), reset ASSOC state machine\n",
1572 pAd->Mlme.AssocMachine.CurrState));
1573 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1574 Status = MLME_STATE_MACHINE_REJECT;
1575 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, &Status);
1576}
1577
1578/*
1579 ==========================================================================
1580 Description:
1581 right part of IEEE 802.11/1999 page 374
1582 Note:
1583 This event should never cause ASSOC state machine perform state
1584 transition, and has no relationship with CNTL machine. So we separate
1585 this routine as a service outside of ASSOC state transition table.
1586
1587 IRQL = DISPATCH_LEVEL
1588
1589 ==========================================================================
1590 */
1591VOID Cls3errAction(
1592 IN PRTMP_ADAPTER pAd,
1593 IN PUCHAR pAddr)
1594{
1595 HEADER_802_11 DisassocHdr;
1596 PHEADER_802_11 pDisassocHdr;
1597 PUCHAR pOutBuffer = NULL;
1598 ULONG FrameLen = 0;
1599 NDIS_STATUS NStatus;
1600 USHORT Reason = REASON_CLS3ERR;
1601
1602 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1603 if (NStatus != NDIS_STATUS_SUCCESS)
1604 return;
1605
1606 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Class 3 Error, Send DISASSOC frame\n"));
1607 MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pAddr, pAd->CommonCfg.Bssid); // patch peap ttls switching issue
1608 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1609 sizeof(HEADER_802_11),&DisassocHdr,
1610 2, &Reason,
1611 END_OF_ARGS);
1612 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1613
1614 // To patch Instance and Buffalo(N) AP
1615 // Driver has to send deauth to Instance AP, but Buffalo(N) needs to send disassoc to reset Authenticator's state machine
1616 // Therefore, we send both of them.
1617 pDisassocHdr = (PHEADER_802_11)pOutBuffer;
1618 pDisassocHdr->FC.SubType = SUBTYPE_DEAUTH;
1619 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1620
1621 MlmeFreeMemory(pAd, pOutBuffer);
1622
1623 pAd->StaCfg.DisassocReason = REASON_CLS3ERR;
1624 COPY_MAC_ADDR(pAd->StaCfg.DisassocSta, pAddr);
1625}
1626
1627 /*
1628 ==========================================================================
1629 Description:
1630 Switch between WEP and CKIP upon new association up.
1631 Parameters:
1632
1633 IRQL = DISPATCH_LEVEL
1634
1635 ==========================================================================
1636 */
1637VOID SwitchBetweenWepAndCkip(
1638 IN PRTMP_ADAPTER pAd)
1639{
1640 int i;
1641 SHAREDKEY_MODE_STRUC csr1;
1642
1643 // if KP is required. change the CipherAlg in hardware shard key table from WEP
1644 // to CKIP. else remain as WEP
1645 if (pAd->StaCfg.bCkipOn && (pAd->StaCfg.CkipFlag & 0x10))
1646 {
1647 // modify hardware key table so that MAC use correct algorithm to decrypt RX
1648 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE, &csr1.word);
1649 if (csr1.field.Bss0Key0CipherAlg == CIPHER_WEP64)
1650 csr1.field.Bss0Key0CipherAlg = CIPHER_CKIP64;
1651 else if (csr1.field.Bss0Key0CipherAlg == CIPHER_WEP128)
1652 csr1.field.Bss0Key0CipherAlg = CIPHER_CKIP128;
1653
1654 if (csr1.field.Bss0Key1CipherAlg == CIPHER_WEP64)
1655 csr1.field.Bss0Key1CipherAlg = CIPHER_CKIP64;
1656 else if (csr1.field.Bss0Key1CipherAlg == CIPHER_WEP128)
1657 csr1.field.Bss0Key1CipherAlg = CIPHER_CKIP128;
1658
1659 if (csr1.field.Bss0Key2CipherAlg == CIPHER_WEP64)
1660 csr1.field.Bss0Key2CipherAlg = CIPHER_CKIP64;
1661 else if (csr1.field.Bss0Key2CipherAlg == CIPHER_WEP128)
1662 csr1.field.Bss0Key2CipherAlg = CIPHER_CKIP128;
1663
1664 if (csr1.field.Bss0Key3CipherAlg == CIPHER_WEP64)
1665 csr1.field.Bss0Key3CipherAlg = CIPHER_CKIP64;
1666 else if (csr1.field.Bss0Key3CipherAlg == CIPHER_WEP128)
1667 csr1.field.Bss0Key3CipherAlg = CIPHER_CKIP128;
1668 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE, csr1.word);
1669 DBGPRINT(RT_DEBUG_TRACE, ("SwitchBetweenWepAndCkip: modify BSS0 cipher to %s\n", CipherName[csr1.field.Bss0Key0CipherAlg]));
1670
1671 // modify software key table so that driver can specify correct algorithm in TXD upon TX
1672 for (i=0; i<SHARE_KEY_NUM; i++)
1673 {
1674 if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_WEP64)
1675 pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_CKIP64;
1676 else if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_WEP128)
1677 pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_CKIP128;
1678 }
1679 }
1680
1681 // else if KP NOT inused. change the CipherAlg in hardware shard key table from CKIP
1682 // to WEP.
1683 else
1684 {
1685 // modify hardware key table so that MAC use correct algorithm to decrypt RX
1686 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE, &csr1.word);
1687 if (csr1.field.Bss0Key0CipherAlg == CIPHER_CKIP64)
1688 csr1.field.Bss0Key0CipherAlg = CIPHER_WEP64;
1689 else if (csr1.field.Bss0Key0CipherAlg == CIPHER_CKIP128)
1690 csr1.field.Bss0Key0CipherAlg = CIPHER_WEP128;
1691
1692 if (csr1.field.Bss0Key1CipherAlg == CIPHER_CKIP64)
1693 csr1.field.Bss0Key1CipherAlg = CIPHER_WEP64;
1694 else if (csr1.field.Bss0Key1CipherAlg == CIPHER_CKIP128)
1695 csr1.field.Bss0Key1CipherAlg = CIPHER_WEP128;
1696
1697 if (csr1.field.Bss0Key2CipherAlg == CIPHER_CKIP64)
1698 csr1.field.Bss0Key2CipherAlg = CIPHER_WEP64;
1699 else if (csr1.field.Bss0Key2CipherAlg == CIPHER_CKIP128)
1700 csr1.field.Bss0Key2CipherAlg = CIPHER_WEP128;
1701
1702 if (csr1.field.Bss0Key3CipherAlg == CIPHER_CKIP64)
1703 csr1.field.Bss0Key3CipherAlg = CIPHER_WEP64;
1704 else if (csr1.field.Bss0Key3CipherAlg == CIPHER_CKIP128)
1705 csr1.field.Bss0Key3CipherAlg = CIPHER_WEP128;
1706
1707 // modify software key table so that driver can specify correct algorithm in TXD upon TX
1708 for (i=0; i<SHARE_KEY_NUM; i++)
1709 {
1710 if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_CKIP64)
1711 pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_WEP64;
1712 else if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_CKIP128)
1713 pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_WEP128;
1714 }
1715
1716 //
1717 // On WPA-NONE, must update CipherAlg.
1718 // Because the OID_802_11_WEP_STATUS was been set after OID_802_11_ADD_KEY
1719 // and CipherAlg will be CIPHER_NONE by Windows ZeroConfig.
1720 // So we need to update CipherAlg after connect.
1721 //
1722 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1723 {
1724 for (i = 0; i < SHARE_KEY_NUM; i++)
1725 {
1726 if (pAd->SharedKey[BSS0][i].KeyLen != 0)
1727 {
1728 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
1729 {
1730 pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_TKIP;
1731 }
1732 else if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1733 {
1734 pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_AES;
1735 }
1736 }
1737 else
1738 {
1739 pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_NONE;
1740 }
1741 }
1742
1743 csr1.field.Bss0Key0CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
1744 csr1.field.Bss0Key1CipherAlg = pAd->SharedKey[BSS0][1].CipherAlg;
1745 csr1.field.Bss0Key2CipherAlg = pAd->SharedKey[BSS0][2].CipherAlg;
1746 csr1.field.Bss0Key3CipherAlg = pAd->SharedKey[BSS0][3].CipherAlg;
1747 }
1748 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE, csr1.word);
1749 DBGPRINT(RT_DEBUG_TRACE, ("SwitchBetweenWepAndCkip: modify BSS0 cipher to %s\n", CipherName[csr1.field.Bss0Key0CipherAlg]));
1750 }
1751}
1752
1753#ifdef WPA_SUPPLICANT_SUPPORT
1754#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
1755VOID SendAssocIEsToWpaSupplicant(
1756 IN PRTMP_ADAPTER pAd)
1757{
1758 union iwreq_data wrqu;
1759 unsigned char custom[IW_CUSTOM_MAX] = {0};
1760
1761 if ((pAd->StaCfg.ReqVarIELen + 17) <= IW_CUSTOM_MAX)
1762 {
1763 sprintf(custom, "ASSOCINFO_ReqIEs=");
1764 NdisMoveMemory(custom+17, pAd->StaCfg.ReqVarIEs, pAd->StaCfg.ReqVarIELen);
1765 memset(&wrqu, 0, sizeof(wrqu));
1766 wrqu.data.length = pAd->StaCfg.ReqVarIELen + 17;
1767 wrqu.data.flags = RT_REQIE_EVENT_FLAG;
1768 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, custom);
1769
1770 memset(&wrqu, 0, sizeof(wrqu));
1771 wrqu.data.flags = RT_ASSOCINFO_EVENT_FLAG;
1772 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
1773 }
1774 else
1775 DBGPRINT(RT_DEBUG_TRACE, ("pAd->StaCfg.ReqVarIELen + 17 > MAX_CUSTOM_LEN\n"));
1776
1777 return;
1778}
1779#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1780#endif // WPA_SUPPLICANT_SUPPORT //
1781
1782#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
1783int wext_notify_event_assoc(
1784 IN RTMP_ADAPTER *pAd)
1785{
1786 union iwreq_data wrqu;
1787 char custom[IW_CUSTOM_MAX] = {0};
1788
1789#if WIRELESS_EXT > 17
1790 if (pAd->StaCfg.ReqVarIELen <= IW_CUSTOM_MAX)
1791 {
1792 wrqu.data.length = pAd->StaCfg.ReqVarIELen;
1793 memcpy(custom, pAd->StaCfg.ReqVarIEs, pAd->StaCfg.ReqVarIELen);
1794 wireless_send_event(pAd->net_dev, IWEVASSOCREQIE, &wrqu, custom);
1795 }
1796 else
1797 DBGPRINT(RT_DEBUG_TRACE, ("pAd->StaCfg.ReqVarIELen > MAX_CUSTOM_LEN\n"));
1798#else
1799 if (((pAd->StaCfg.ReqVarIELen*2) + 17) <= IW_CUSTOM_MAX)
1800 {
1801 UCHAR idx;
1802 wrqu.data.length = (pAd->StaCfg.ReqVarIELen*2) + 17;
1803 sprintf(custom, "ASSOCINFO(ReqIEs=");
1804 for (idx=0; idx<pAd->StaCfg.ReqVarIELen; idx++)
1805 sprintf(custom, "%s%02x", custom, pAd->StaCfg.ReqVarIEs[idx]);
1806 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, custom);
1807 }
1808 else
1809 DBGPRINT(RT_DEBUG_TRACE, ("(pAd->StaCfg.ReqVarIELen*2) + 17 > MAX_CUSTOM_LEN\n"));
1810#endif
1811
1812 return 0;
1813
1814}
1815#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1816
1817
1818BOOLEAN StaAddMacTableEntry(
1819 IN PRTMP_ADAPTER pAd,
1820 IN PMAC_TABLE_ENTRY pEntry,
1821 IN UCHAR MaxSupportedRateIn500Kbps,
1822 IN HT_CAPABILITY_IE *pHtCapability,
1823 IN UCHAR HtCapabilityLen,
1824 IN USHORT CapabilityInfo)
1825{
1826 UCHAR MaxSupportedRate = RATE_11;
1827
1828 if (ADHOC_ON(pAd))
1829 CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
1830
1831 switch (MaxSupportedRateIn500Kbps)
1832 {
1833 case 108: MaxSupportedRate = RATE_54; break;
1834 case 96: MaxSupportedRate = RATE_48; break;
1835 case 72: MaxSupportedRate = RATE_36; break;
1836 case 48: MaxSupportedRate = RATE_24; break;
1837 case 36: MaxSupportedRate = RATE_18; break;
1838 case 24: MaxSupportedRate = RATE_12; break;
1839 case 18: MaxSupportedRate = RATE_9; break;
1840 case 12: MaxSupportedRate = RATE_6; break;
1841 case 22: MaxSupportedRate = RATE_11; break;
1842 case 11: MaxSupportedRate = RATE_5_5; break;
1843 case 4: MaxSupportedRate = RATE_2; break;
1844 case 2: MaxSupportedRate = RATE_1; break;
1845 default: MaxSupportedRate = RATE_11; break;
1846 }
1847
1848 if ((pAd->CommonCfg.PhyMode == PHY_11G) && (MaxSupportedRate < RATE_FIRST_OFDM_RATE))
1849 return FALSE;
1850
1851#ifdef DOT11_N_SUPPORT
1852 // 11n only
1853 if (((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G))&& (HtCapabilityLen == 0))
1854 return FALSE;
1855#endif // DOT11_N_SUPPORT //
1856
1857 if (!pEntry)
1858 return FALSE;
1859
1860 NdisAcquireSpinLock(&pAd->MacTabLock);
1861 if (pEntry)
1862 {
1863 pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
1864 if ((MaxSupportedRate < RATE_FIRST_OFDM_RATE) ||
1865 (pAd->CommonCfg.PhyMode == PHY_11B))
1866 {
1867 pEntry->RateLen = 4;
1868 if (MaxSupportedRate >= RATE_FIRST_OFDM_RATE)
1869 MaxSupportedRate = RATE_11;
1870 }
1871 else
1872 pEntry->RateLen = 12;
1873
1874 pEntry->MaxHTPhyMode.word = 0;
1875 pEntry->MinHTPhyMode.word = 0;
1876 pEntry->HTPhyMode.word = 0;
1877 pEntry->MaxSupportedRate = MaxSupportedRate;
1878 if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
1879 {
1880 pEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
1881 pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
1882 pEntry->MinHTPhyMode.field.MODE = MODE_CCK;
1883 pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
1884 pEntry->HTPhyMode.field.MODE = MODE_CCK;
1885 pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate;
1886 }
1887 else
1888 {
1889 pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
1890 pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
1891 pEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
1892 pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
1893 pEntry->HTPhyMode.field.MODE = MODE_OFDM;
1894 pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
1895 }
1896 pEntry->CapabilityInfo = CapabilityInfo;
1897 CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE);
1898 CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE);
1899 }
1900
1901#ifdef DOT11_N_SUPPORT
1902 // If this Entry supports 802.11n, upgrade to HT rate.
1903 if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
1904 {
1905 UCHAR j, bitmask; //k,bitmask;
1906 CHAR i;
1907
1908 if (ADHOC_ON(pAd))
1909 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
1910 if ((pHtCapability->HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
1911 {
1912 pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
1913 }
1914 else
1915 {
1916 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
1917 pAd->MacTab.fAnyStationNonGF = TRUE;
1918 pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
1919 }
1920
1921 if ((pHtCapability->HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
1922 {
1923 pEntry->MaxHTPhyMode.field.BW= BW_40;
1924 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(pHtCapability->HtCapInfo.ShortGIfor40));
1925 }
1926 else
1927 {
1928 pEntry->MaxHTPhyMode.field.BW = BW_20;
1929 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(pHtCapability->HtCapInfo.ShortGIfor20));
1930 pAd->MacTab.fAnyStation20Only = TRUE;
1931 }
1932
1933 // 3*3
1934 if (pAd->MACVersion >= RALINK_2883_VERSION && pAd->MACVersion < RALINK_3070_VERSION)
1935 pEntry->MaxHTPhyMode.field.TxBF = pAd->CommonCfg.RegTransmitSetting.field.TxBF;
1936
1937 // find max fixed rate
1938 for (i=23; i>=0; i--) // 3*3
1939 {
1940 j = i/8;
1941 bitmask = (1<<(i-(j*8)));
1942 if ((pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j] & bitmask) && (pHtCapability->MCSSet[j] & bitmask))
1943 {
1944 pEntry->MaxHTPhyMode.field.MCS = i;
1945 break;
1946 }
1947 if (i==0)
1948 break;
1949 }
1950
1951
1952 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
1953 {
1954 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
1955 {
1956 // Fix MCS as HT Duplicated Mode
1957 pEntry->MaxHTPhyMode.field.BW = 1;
1958 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
1959 pEntry->MaxHTPhyMode.field.STBC = 0;
1960 pEntry->MaxHTPhyMode.field.ShortGI = 0;
1961 pEntry->MaxHTPhyMode.field.MCS = 32;
1962 }
1963 else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
1964 {
1965 // STA supports fixed MCS
1966 pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
1967 }
1968 }
1969
1970 pEntry->MaxHTPhyMode.field.STBC = (pHtCapability->HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
1971 pEntry->MpduDensity = pHtCapability->HtCapParm.MpduDensity;
1972 pEntry->MaxRAmpduFactor = pHtCapability->HtCapParm.MaxRAmpduFactor;
1973 pEntry->MmpsMode = (UCHAR)pHtCapability->HtCapInfo.MimoPs;
1974 pEntry->AMsduSize = (UCHAR)pHtCapability->HtCapInfo.AMsduSize;
1975 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
1976
1977 if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable && (pAd->CommonCfg.REGBACapability.field.AutoBA == FALSE))
1978 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_AMSDU_INUSED);
1979 if (pHtCapability->HtCapInfo.ShortGIfor20)
1980 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
1981 if (pHtCapability->HtCapInfo.ShortGIfor40)
1982 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
1983 if (pHtCapability->HtCapInfo.TxSTBC)
1984 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
1985 if (pHtCapability->HtCapInfo.RxSTBC)
1986 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
1987 if (pHtCapability->ExtHtCapInfo.PlusHTC)
1988 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
1989 if (pAd->CommonCfg.bRdg && pHtCapability->ExtHtCapInfo.RDGSupport)
1990 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
1991 if (pHtCapability->ExtHtCapInfo.MCSFeedback == 0x03)
1992 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
1993 }
1994 else
1995 {
1996 pAd->MacTab.fAnyStationIsLegacy = TRUE;
1997 }
1998
1999 NdisMoveMemory(&pEntry->HTCapability, pHtCapability, sizeof(HT_CAPABILITY_IE));
2000#endif // DOT11_N_SUPPORT //
2001
2002 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
2003 pEntry->CurrTxRate = pEntry->MaxSupportedRate;
2004
2005 // Set asic auto fall back
2006 if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
2007 {
2008 PUCHAR pTable;
2009 UCHAR TableSize = 0;
2010
2011 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
2012 pEntry->bAutoTxRateSwitch = TRUE;
2013 }
2014 else
2015 {
2016 pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
2017 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
2018 pEntry->bAutoTxRateSwitch = FALSE;
2019
2020 // If the legacy mode is set, overwrite the transmit setting of this entry.
2021 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
2022 }
2023
2024 pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
2025 pEntry->Sst = SST_ASSOC;
2026 pEntry->AuthState = AS_AUTH_OPEN;
2027 pEntry->AuthMode = pAd->StaCfg.AuthMode;
2028 pEntry->WepStatus = pAd->StaCfg.WepStatus;
2029
2030 NdisReleaseSpinLock(&pAd->MacTabLock);
2031
2032#ifdef WPA_SUPPLICANT_SUPPORT
2033#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
2034 if (pAd->StaCfg.WpaSupplicantUP)
2035 {
2036 union iwreq_data wrqu;
2037
2038 SendAssocIEsToWpaSupplicant(pAd);
2039 memset(&wrqu, 0, sizeof(wrqu));
2040 wrqu.data.flags = RT_ASSOC_EVENT_FLAG;
2041 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
2042 }
2043#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2044#endif // WPA_SUPPLICANT_SUPPORT //
2045
2046#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
2047 {
2048 union iwreq_data wrqu;
2049 wext_notify_event_assoc(pAd);
2050
2051 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
2052 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
2053 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
2054
2055 }
2056#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2057 return TRUE;
2058}
2059
2060
diff --git a/drivers/staging/rt3070/sta/auth.c b/drivers/staging/rt3070/sta/auth.c
new file mode 100644
index 000000000000..032b5df058bc
--- /dev/null
+++ b/drivers/staging/rt3070/sta/auth.c
@@ -0,0 +1,475 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 auth.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 John 2004-9-3 porting from RT2500
36*/
37#include "../rt_config.h"
38
39/*
40 ==========================================================================
41 Description:
42 authenticate state machine init, including state transition and timer init
43 Parameters:
44 Sm - pointer to the auth state machine
45 Note:
46 The state machine looks like this
47
48 AUTH_REQ_IDLE AUTH_WAIT_SEQ2 AUTH_WAIT_SEQ4
49 MT2_MLME_AUTH_REQ mlme_auth_req_action invalid_state_when_auth invalid_state_when_auth
50 MT2_PEER_AUTH_EVEN drop peer_auth_even_at_seq2_action peer_auth_even_at_seq4_action
51 MT2_AUTH_TIMEOUT Drop auth_timeout_action auth_timeout_action
52
53 IRQL = PASSIVE_LEVEL
54
55 ==========================================================================
56 */
57
58void AuthStateMachineInit(
59 IN PRTMP_ADAPTER pAd,
60 IN STATE_MACHINE *Sm,
61 OUT STATE_MACHINE_FUNC Trans[])
62{
63 StateMachineInit(Sm, Trans, MAX_AUTH_STATE, MAX_AUTH_MSG, (STATE_MACHINE_FUNC)Drop, AUTH_REQ_IDLE, AUTH_MACHINE_BASE);
64
65 // the first column
66 StateMachineSetAction(Sm, AUTH_REQ_IDLE, MT2_MLME_AUTH_REQ, (STATE_MACHINE_FUNC)MlmeAuthReqAction);
67
68 // the second column
69 StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_MLME_AUTH_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAuth);
70 StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_PEER_AUTH_EVEN, (STATE_MACHINE_FUNC)PeerAuthRspAtSeq2Action);
71 StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_AUTH_TIMEOUT, (STATE_MACHINE_FUNC)AuthTimeoutAction);
72
73 // the third column
74 StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_MLME_AUTH_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAuth);
75 StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_PEER_AUTH_EVEN, (STATE_MACHINE_FUNC)PeerAuthRspAtSeq4Action);
76 StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_AUTH_TIMEOUT, (STATE_MACHINE_FUNC)AuthTimeoutAction);
77
78 RTMPInitTimer(pAd, &pAd->MlmeAux.AuthTimer, GET_TIMER_FUNCTION(AuthTimeout), pAd, FALSE);
79}
80
81/*
82 ==========================================================================
83 Description:
84 function to be executed at timer thread when auth timer expires
85
86 IRQL = DISPATCH_LEVEL
87
88 ==========================================================================
89 */
90VOID AuthTimeout(
91 IN PVOID SystemSpecific1,
92 IN PVOID FunctionContext,
93 IN PVOID SystemSpecific2,
94 IN PVOID SystemSpecific3)
95{
96 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
97
98 DBGPRINT(RT_DEBUG_TRACE,("AUTH - AuthTimeout\n"));
99
100 // Do nothing if the driver is starting halt state.
101 // This might happen when timer already been fired before cancel timer with mlmehalt
102 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
103 return;
104
105 // send a de-auth to reset AP's state machine (Patch AP-Dir635)
106 if (pAd->Mlme.AuthMachine.CurrState == AUTH_WAIT_SEQ2)
107 Cls2errAction(pAd, pAd->MlmeAux.Bssid);
108
109
110 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_AUTH_TIMEOUT, 0, NULL);
111 RT28XX_MLME_HANDLER(pAd);
112}
113
114
115/*
116 ==========================================================================
117 Description:
118
119 IRQL = DISPATCH_LEVEL
120
121 ==========================================================================
122 */
123VOID MlmeAuthReqAction(
124 IN PRTMP_ADAPTER pAd,
125 IN MLME_QUEUE_ELEM *Elem)
126{
127 UCHAR Addr[6];
128 USHORT Alg, Seq, Status;
129 ULONG Timeout;
130 HEADER_802_11 AuthHdr;
131 BOOLEAN TimerCancelled;
132 NDIS_STATUS NStatus;
133 PUCHAR pOutBuffer = NULL;
134 ULONG FrameLen = 0;
135
136 // Block all authentication request durning WPA block period
137 if (pAd->StaCfg.bBlockAssoc == TRUE)
138 {
139 DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Block Auth request durning WPA block period!\n"));
140 pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
141 Status = MLME_STATE_MACHINE_REJECT;
142 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
143 }
144 else if(MlmeAuthReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr, &Timeout, &Alg))
145 {
146 // reset timer
147 RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &TimerCancelled);
148 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, Addr);
149 pAd->MlmeAux.Alg = Alg;
150 Seq = 1;
151 Status = MLME_SUCCESS;
152
153 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
154 if(NStatus != NDIS_STATUS_SUCCESS)
155 {
156 DBGPRINT(RT_DEBUG_TRACE, ("AUTH - MlmeAuthReqAction(Alg:%d) allocate memory failed\n", Alg));
157 pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
158 Status = MLME_FAIL_NO_RESOURCE;
159 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
160 return;
161 }
162
163 DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Send AUTH request seq#1 (Alg=%d)...\n", Alg));
164 MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, Addr, pAd->MlmeAux.Bssid);
165 MakeOutgoingFrame(pOutBuffer, &FrameLen,
166 sizeof(HEADER_802_11),&AuthHdr,
167 2, &Alg,
168 2, &Seq,
169 2, &Status,
170 END_OF_ARGS);
171 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
172 MlmeFreeMemory(pAd, pOutBuffer);
173
174 RTMPSetTimer(&pAd->MlmeAux.AuthTimer, Timeout);
175 pAd->Mlme.AuthMachine.CurrState = AUTH_WAIT_SEQ2;
176 }
177 else
178 {
179 DBGPRINT_ERR(("AUTH - MlmeAuthReqAction() sanity check failed\n"));
180 pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
181 Status = MLME_INVALID_FORMAT;
182 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
183 }
184}
185
186/*
187 ==========================================================================
188 Description:
189
190 IRQL = DISPATCH_LEVEL
191
192 ==========================================================================
193 */
194VOID PeerAuthRspAtSeq2Action(
195 IN PRTMP_ADAPTER pAd,
196 IN MLME_QUEUE_ELEM *Elem)
197{
198 UCHAR Addr2[MAC_ADDR_LEN];
199 USHORT Seq, Status, RemoteStatus, Alg;
200 UCHAR ChlgText[CIPHER_TEXT_LEN];
201 UCHAR CyperChlgText[CIPHER_TEXT_LEN + 8 + 8];
202 UCHAR Element[2];
203 HEADER_802_11 AuthHdr;
204 BOOLEAN TimerCancelled;
205 PUCHAR pOutBuffer = NULL;
206 NDIS_STATUS NStatus;
207 ULONG FrameLen = 0;
208 USHORT Status2;
209
210 if (PeerAuthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Alg, &Seq, &Status, ChlgText))
211 {
212 if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Addr2) && Seq == 2)
213 {
214 DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Receive AUTH_RSP seq#2 to me (Alg=%d, Status=%d)\n", Alg, Status));
215 RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &TimerCancelled);
216
217 if (Status == MLME_SUCCESS)
218 {
219 // Authentication Mode "LEAP" has allow for CCX 1.X
220 if ((pAd->MlmeAux.Alg == Ndis802_11AuthModeOpen)
221#ifdef LEAP_SUPPORT
222 || (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
223#endif // LEAP_SUPPORT //
224 )
225 {
226 pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
227#ifdef LEAP_SUPPORT
228 pAd->Mlme.LeapMachine.CurrState = LEAP_IDLE;
229#endif // LEAP_SUPPORT //
230 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
231 }
232 else
233 {
234 // 2. shared key, need to be challenged
235 Seq++;
236 RemoteStatus = MLME_SUCCESS;
237
238 // Get an unused nonpaged memory
239 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
240 if(NStatus != NDIS_STATUS_SUCCESS)
241 {
242 DBGPRINT(RT_DEBUG_TRACE, ("AUTH - PeerAuthRspAtSeq2Action() allocate memory fail\n"));
243 pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
244 Status2 = MLME_FAIL_NO_RESOURCE;
245 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status2);
246 return;
247 }
248
249 DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Send AUTH request seq#3...\n"));
250 MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, Addr2, pAd->MlmeAux.Bssid);
251 AuthHdr.FC.Wep = 1;
252 // Encrypt challenge text & auth information
253 RTMPInitWepEngine(
254 pAd,
255 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
256 pAd->StaCfg.DefaultKeyId,
257 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen,
258 CyperChlgText);
259
260 Alg = cpu2le16(*(USHORT *)&Alg);
261 Seq = cpu2le16(*(USHORT *)&Seq);
262 RemoteStatus= cpu2le16(*(USHORT *)&RemoteStatus);
263
264 RTMPEncryptData(pAd, (PUCHAR) &Alg, CyperChlgText + 4, 2);
265 RTMPEncryptData(pAd, (PUCHAR) &Seq, CyperChlgText + 6, 2);
266 RTMPEncryptData(pAd, (PUCHAR) &RemoteStatus, CyperChlgText + 8, 2);
267 Element[0] = 16;
268 Element[1] = 128;
269 RTMPEncryptData(pAd, Element, CyperChlgText + 10, 2);
270 RTMPEncryptData(pAd, ChlgText, CyperChlgText + 12, 128);
271 RTMPSetICV(pAd, CyperChlgText + 140);
272 MakeOutgoingFrame(pOutBuffer, &FrameLen,
273 sizeof(HEADER_802_11), &AuthHdr,
274 CIPHER_TEXT_LEN + 16, CyperChlgText,
275 END_OF_ARGS);
276 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
277 MlmeFreeMemory(pAd, pOutBuffer);
278
279 RTMPSetTimer(&pAd->MlmeAux.AuthTimer, AUTH_TIMEOUT);
280 pAd->Mlme.AuthMachine.CurrState = AUTH_WAIT_SEQ4;
281 }
282 }
283 else
284 {
285#ifdef LEAP_SUPPORT
286 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
287 {
288 //Invalid Authentication possible rogue AP
289 //Add this Ap to Rogue AP.
290 RogueApTableSetEntry(pAd, &pAd->StaCfg.RogueApTab, Addr2, LEAP_REASON_INVALID_AUTH);
291 }
292#endif // LEAP_SUPPORT //
293 pAd->StaCfg.AuthFailReason = Status;
294 COPY_MAC_ADDR(pAd->StaCfg.AuthFailSta, Addr2);
295 pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
296 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
297 }
298 }
299 }
300 else
301 {
302 DBGPRINT(RT_DEBUG_TRACE, ("AUTH - PeerAuthSanity() sanity check fail\n"));
303 }
304}
305
306/*
307 ==========================================================================
308 Description:
309
310 IRQL = DISPATCH_LEVEL
311
312 ==========================================================================
313 */
314VOID PeerAuthRspAtSeq4Action(
315 IN PRTMP_ADAPTER pAd,
316 IN MLME_QUEUE_ELEM *Elem)
317{
318 UCHAR Addr2[MAC_ADDR_LEN];
319 USHORT Alg, Seq, Status;
320 CHAR ChlgText[CIPHER_TEXT_LEN];
321 BOOLEAN TimerCancelled;
322
323 if(PeerAuthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Alg, &Seq, &Status, ChlgText))
324 {
325 if(MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Addr2) && Seq == 4)
326 {
327 DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Receive AUTH_RSP seq#4 to me\n"));
328 RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &TimerCancelled);
329
330 if (Status != MLME_SUCCESS)
331 {
332 pAd->StaCfg.AuthFailReason = Status;
333 COPY_MAC_ADDR(pAd->StaCfg.AuthFailSta, Addr2);
334 }
335
336 pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
337 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
338 }
339 }
340 else
341 {
342 DBGPRINT(RT_DEBUG_TRACE, ("AUTH - PeerAuthRspAtSeq4Action() sanity check fail\n"));
343 }
344}
345
346/*
347 ==========================================================================
348 Description:
349
350 IRQL = DISPATCH_LEVEL
351
352 ==========================================================================
353 */
354VOID MlmeDeauthReqAction(
355 IN PRTMP_ADAPTER pAd,
356 IN MLME_QUEUE_ELEM *Elem)
357{
358 MLME_DEAUTH_REQ_STRUCT *pInfo;
359 HEADER_802_11 DeauthHdr;
360 PUCHAR pOutBuffer = NULL;
361 NDIS_STATUS NStatus;
362 ULONG FrameLen = 0;
363 USHORT Status;
364
365 pInfo = (MLME_DEAUTH_REQ_STRUCT *)Elem->Msg;
366
367 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
368 if (NStatus != NDIS_STATUS_SUCCESS)
369 {
370 DBGPRINT(RT_DEBUG_TRACE, ("AUTH - MlmeDeauthReqAction() allocate memory fail\n"));
371 pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
372 Status = MLME_FAIL_NO_RESOURCE;
373 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DEAUTH_CONF, 2, &Status);
374 return;
375 }
376
377
378 DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Send DE-AUTH request (Reason=%d)...\n", pInfo->Reason));
379 MgtMacHeaderInit(pAd, &DeauthHdr, SUBTYPE_DEAUTH, 0, pInfo->Addr, pAd->MlmeAux.Bssid);
380 MakeOutgoingFrame(pOutBuffer, &FrameLen,
381 sizeof(HEADER_802_11),&DeauthHdr,
382 2, &pInfo->Reason,
383 END_OF_ARGS);
384 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
385 MlmeFreeMemory(pAd, pOutBuffer);
386
387 pAd->StaCfg.DeauthReason = pInfo->Reason;
388 COPY_MAC_ADDR(pAd->StaCfg.DeauthSta, pInfo->Addr);
389 pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
390 Status = MLME_SUCCESS;
391 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DEAUTH_CONF, 2, &Status);
392
393 // send wireless event - for deauthentication
394 if (pAd->CommonCfg.bWirelessEvent)
395 RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
396}
397
398/*
399 ==========================================================================
400 Description:
401
402 IRQL = DISPATCH_LEVEL
403
404 ==========================================================================
405 */
406VOID AuthTimeoutAction(
407 IN PRTMP_ADAPTER pAd,
408 IN MLME_QUEUE_ELEM *Elem)
409{
410 USHORT Status;
411 DBGPRINT(RT_DEBUG_TRACE, ("AUTH - AuthTimeoutAction\n"));
412 pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
413 Status = MLME_REJ_TIMEOUT;
414 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
415}
416
417/*
418 ==========================================================================
419 Description:
420
421 IRQL = DISPATCH_LEVEL
422
423 ==========================================================================
424 */
425VOID InvalidStateWhenAuth(
426 IN PRTMP_ADAPTER pAd,
427 IN MLME_QUEUE_ELEM *Elem)
428{
429 USHORT Status;
430 DBGPRINT(RT_DEBUG_TRACE, ("AUTH - InvalidStateWhenAuth (state=%ld), reset AUTH state machine\n", pAd->Mlme.AuthMachine.CurrState));
431 pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
432 Status = MLME_STATE_MACHINE_REJECT;
433 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
434}
435
436/*
437 ==========================================================================
438 Description:
439 Some STA/AP
440 Note:
441 This action should never trigger AUTH state transition, therefore we
442 separate it from AUTH state machine, and make it as a standalone service
443
444 IRQL = DISPATCH_LEVEL
445
446 ==========================================================================
447 */
448VOID Cls2errAction(
449 IN PRTMP_ADAPTER pAd,
450 IN PUCHAR pAddr)
451{
452 HEADER_802_11 DeauthHdr;
453 PUCHAR pOutBuffer = NULL;
454 NDIS_STATUS NStatus;
455 ULONG FrameLen = 0;
456 USHORT Reason = REASON_CLS2ERR;
457
458 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
459 if (NStatus != NDIS_STATUS_SUCCESS)
460 return;
461
462 DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Class 2 error, Send DEAUTH frame...\n"));
463 MgtMacHeaderInit(pAd, &DeauthHdr, SUBTYPE_DEAUTH, 0, pAddr, pAd->MlmeAux.Bssid);
464 MakeOutgoingFrame(pOutBuffer, &FrameLen,
465 sizeof(HEADER_802_11),&DeauthHdr,
466 2, &Reason,
467 END_OF_ARGS);
468 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
469 MlmeFreeMemory(pAd, pOutBuffer);
470
471 pAd->StaCfg.DeauthReason = Reason;
472 COPY_MAC_ADDR(pAd->StaCfg.DeauthSta, pAddr);
473}
474
475
diff --git a/drivers/staging/rt3070/sta/auth_rsp.c b/drivers/staging/rt3070/sta/auth_rsp.c
new file mode 100644
index 000000000000..f7aa4b99cf56
--- /dev/null
+++ b/drivers/staging/rt3070/sta/auth_rsp.c
@@ -0,0 +1,167 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 auth_rsp.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 John 2004-10-1 copy from RT2560
36*/
37#include "../rt_config.h"
38
39/*
40 ==========================================================================
41 Description:
42 authentication state machine init procedure
43 Parameters:
44 Sm - the state machine
45
46 IRQL = PASSIVE_LEVEL
47
48 ==========================================================================
49 */
50VOID AuthRspStateMachineInit(
51 IN PRTMP_ADAPTER pAd,
52 IN PSTATE_MACHINE Sm,
53 IN STATE_MACHINE_FUNC Trans[])
54{
55 StateMachineInit(Sm, Trans, MAX_AUTH_RSP_STATE, MAX_AUTH_RSP_MSG, (STATE_MACHINE_FUNC)Drop, AUTH_RSP_IDLE, AUTH_RSP_MACHINE_BASE);
56
57 // column 1
58 StateMachineSetAction(Sm, AUTH_RSP_IDLE, MT2_PEER_DEAUTH, (STATE_MACHINE_FUNC)PeerDeauthAction);
59
60 // column 2
61 StateMachineSetAction(Sm, AUTH_RSP_WAIT_CHAL, MT2_PEER_DEAUTH, (STATE_MACHINE_FUNC)PeerDeauthAction);
62
63}
64
65/*
66 ==========================================================================
67 Description:
68
69 IRQL = DISPATCH_LEVEL
70
71 ==========================================================================
72*/
73VOID PeerAuthSimpleRspGenAndSend(
74 IN PRTMP_ADAPTER pAd,
75 IN PHEADER_802_11 pHdr80211,
76 IN USHORT Alg,
77 IN USHORT Seq,
78 IN USHORT Reason,
79 IN USHORT Status)
80{
81 HEADER_802_11 AuthHdr;
82 ULONG FrameLen = 0;
83 PUCHAR pOutBuffer = NULL;
84 NDIS_STATUS NStatus;
85
86 if (Reason != MLME_SUCCESS)
87 {
88 DBGPRINT(RT_DEBUG_TRACE, ("Peer AUTH fail...\n"));
89 return;
90 }
91
92 //Get an unused nonpaged memory
93 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
94 if (NStatus != NDIS_STATUS_SUCCESS)
95 return;
96
97 DBGPRINT(RT_DEBUG_TRACE, ("Send AUTH response (seq#2)...\n"));
98 MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, pHdr80211->Addr2, pAd->MlmeAux.Bssid);
99 MakeOutgoingFrame(pOutBuffer, &FrameLen,
100 sizeof(HEADER_802_11), &AuthHdr,
101 2, &Alg,
102 2, &Seq,
103 2, &Reason,
104 END_OF_ARGS);
105 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
106 MlmeFreeMemory(pAd, pOutBuffer);
107}
108
109/*
110 ==========================================================================
111 Description:
112
113 IRQL = DISPATCH_LEVEL
114
115 ==========================================================================
116*/
117VOID PeerDeauthAction(
118 IN PRTMP_ADAPTER pAd,
119 IN PMLME_QUEUE_ELEM Elem)
120{
121 UCHAR Addr2[MAC_ADDR_LEN];
122 USHORT Reason;
123
124 if (PeerDeauthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Reason))
125 {
126 if (INFRA_ON(pAd) && MAC_ADDR_EQUAL(Addr2, pAd->CommonCfg.Bssid))
127 {
128 DBGPRINT(RT_DEBUG_TRACE,("AUTH_RSP - receive DE-AUTH from our AP (Reason=%d)\n", Reason));
129
130
131#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
132 {
133 union iwreq_data wrqu;
134 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
135 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
136 }
137#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
138
139
140 // send wireless event - for deauthentication
141 if (pAd->CommonCfg.bWirelessEvent)
142 RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
143
144 LinkDown(pAd, TRUE);
145
146 // Authentication Mode Cisco_LEAP has start a timer
147 // We should cancel it if using LEAP
148#ifdef LEAP_SUPPORT
149 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
150 {
151 RTMPCancelTimer(&pAd->StaCfg.LeapAuthTimer, &TimerCancelled);
152 //Check is it mach the LEAP Authentication failed as possible a Rogue AP
153 //on it's PortSecured not equal to WPA_802_1X_PORT_SECURED while process the Authenticaton.
154 if ((pAd->StaCfg.PortSecured != WPA_802_1X_PORT_SECURED) && (pAd->Mlme.LeapMachine.CurrState != LEAP_IDLE))
155 {
156 RogueApTableSetEntry(pAd, &pAd->StaCfg.RogueApTab, Addr2, LEAP_REASON_AUTH_TIMEOUT);
157 }
158 }
159#endif // LEAP_SUPPORT //
160 }
161 }
162 else
163 {
164 DBGPRINT(RT_DEBUG_TRACE,("AUTH_RSP - PeerDeauthAction() sanity check fail\n"));
165 }
166}
167
diff --git a/drivers/staging/rt3070/sta/connect.c b/drivers/staging/rt3070/sta/connect.c
new file mode 100644
index 000000000000..152c0bd0f822
--- /dev/null
+++ b/drivers/staging/rt3070/sta/connect.c
@@ -0,0 +1,2857 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 connect.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 John 2004-08-08 Major modification from RT2560
36*/
37#include "../rt_config.h"
38
39UCHAR CipherSuiteWpaNoneTkip[] = {
40 0x00, 0x50, 0xf2, 0x01, // oui
41 0x01, 0x00, // Version
42 0x00, 0x50, 0xf2, 0x02, // Multicast
43 0x01, 0x00, // Number of unicast
44 0x00, 0x50, 0xf2, 0x02, // unicast
45 0x01, 0x00, // number of authentication method
46 0x00, 0x50, 0xf2, 0x00 // authentication
47 };
48UCHAR CipherSuiteWpaNoneTkipLen = (sizeof(CipherSuiteWpaNoneTkip) / sizeof(UCHAR));
49
50UCHAR CipherSuiteWpaNoneAes[] = {
51 0x00, 0x50, 0xf2, 0x01, // oui
52 0x01, 0x00, // Version
53 0x00, 0x50, 0xf2, 0x04, // Multicast
54 0x01, 0x00, // Number of unicast
55 0x00, 0x50, 0xf2, 0x04, // unicast
56 0x01, 0x00, // number of authentication method
57 0x00, 0x50, 0xf2, 0x00 // authentication
58 };
59UCHAR CipherSuiteWpaNoneAesLen = (sizeof(CipherSuiteWpaNoneAes) / sizeof(UCHAR));
60
61// The following MACRO is called after 1. starting an new IBSS, 2. succesfully JOIN an IBSS,
62// or 3. succesfully ASSOCIATE to a BSS, 4. successfully RE_ASSOCIATE to a BSS
63// All settings successfuly negotiated furing MLME state machines become final settings
64// and are copied to pAd->StaActive
65#define COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd) \
66{ \
67 (_pAd)->CommonCfg.SsidLen = (_pAd)->MlmeAux.SsidLen; \
68 NdisMoveMemory((_pAd)->CommonCfg.Ssid, (_pAd)->MlmeAux.Ssid, (_pAd)->MlmeAux.SsidLen); \
69 COPY_MAC_ADDR((_pAd)->CommonCfg.Bssid, (_pAd)->MlmeAux.Bssid); \
70 (_pAd)->CommonCfg.Channel = (_pAd)->MlmeAux.Channel; \
71 (_pAd)->CommonCfg.CentralChannel = (_pAd)->MlmeAux.CentralChannel; \
72 (_pAd)->StaActive.Aid = (_pAd)->MlmeAux.Aid; \
73 (_pAd)->StaActive.AtimWin = (_pAd)->MlmeAux.AtimWin; \
74 (_pAd)->StaActive.CapabilityInfo = (_pAd)->MlmeAux.CapabilityInfo; \
75 (_pAd)->CommonCfg.BeaconPeriod = (_pAd)->MlmeAux.BeaconPeriod; \
76 (_pAd)->StaActive.CfpMaxDuration = (_pAd)->MlmeAux.CfpMaxDuration; \
77 (_pAd)->StaActive.CfpPeriod = (_pAd)->MlmeAux.CfpPeriod; \
78 (_pAd)->StaActive.SupRateLen = (_pAd)->MlmeAux.SupRateLen; \
79 NdisMoveMemory((_pAd)->StaActive.SupRate, (_pAd)->MlmeAux.SupRate, (_pAd)->MlmeAux.SupRateLen);\
80 (_pAd)->StaActive.ExtRateLen = (_pAd)->MlmeAux.ExtRateLen; \
81 NdisMoveMemory((_pAd)->StaActive.ExtRate, (_pAd)->MlmeAux.ExtRate, (_pAd)->MlmeAux.ExtRateLen);\
82 NdisMoveMemory(&(_pAd)->CommonCfg.APEdcaParm, &(_pAd)->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));\
83 NdisMoveMemory(&(_pAd)->CommonCfg.APQosCapability, &(_pAd)->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));\
84 NdisMoveMemory(&(_pAd)->CommonCfg.APQbssLoad, &(_pAd)->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));\
85 COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].Addr, (_pAd)->MlmeAux.Bssid); \
86 (_pAd)->MacTab.Content[BSSID_WCID].Aid = (_pAd)->MlmeAux.Aid; \
87 (_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = (_pAd)->StaCfg.PairCipher;\
88 COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.BssId, (_pAd)->MlmeAux.Bssid);\
89 (_pAd)->MacTab.Content[BSSID_WCID].RateLen = (_pAd)->StaActive.SupRateLen + (_pAd)->StaActive.ExtRateLen;\
90}
91
92/*
93 ==========================================================================
94 Description:
95
96 IRQL = PASSIVE_LEVEL
97
98 ==========================================================================
99*/
100VOID MlmeCntlInit(
101 IN PRTMP_ADAPTER pAd,
102 IN STATE_MACHINE *S,
103 OUT STATE_MACHINE_FUNC Trans[])
104{
105 // Control state machine differs from other state machines, the interface
106 // follows the standard interface
107 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
108}
109
110/*
111 ==========================================================================
112 Description:
113
114 IRQL = DISPATCH_LEVEL
115
116 ==========================================================================
117*/
118VOID MlmeCntlMachinePerformAction(
119 IN PRTMP_ADAPTER pAd,
120 IN STATE_MACHINE *S,
121 IN MLME_QUEUE_ELEM *Elem)
122{
123 switch(pAd->Mlme.CntlMachine.CurrState)
124 {
125 case CNTL_IDLE:
126 {
127 CntlIdleProc(pAd, Elem);
128 }
129 break;
130 case CNTL_WAIT_DISASSOC:
131 CntlWaitDisassocProc(pAd, Elem);
132 break;
133 case CNTL_WAIT_JOIN:
134 CntlWaitJoinProc(pAd, Elem);
135 break;
136
137 // CNTL_WAIT_REASSOC is the only state in CNTL machine that does
138 // not triggered directly or indirectly by "RTMPSetInformation(OID_xxx)".
139 // Therefore not protected by NDIS's "only one outstanding OID request"
140 // rule. Which means NDIS may SET OID in the middle of ROAMing attempts.
141 // Current approach is to block new SET request at RTMPSetInformation()
142 // when CntlMachine.CurrState is not CNTL_IDLE
143 case CNTL_WAIT_REASSOC:
144 CntlWaitReassocProc(pAd, Elem);
145 break;
146
147 case CNTL_WAIT_START:
148 CntlWaitStartProc(pAd, Elem);
149 break;
150 case CNTL_WAIT_AUTH:
151 CntlWaitAuthProc(pAd, Elem);
152 break;
153 case CNTL_WAIT_AUTH2:
154 CntlWaitAuthProc2(pAd, Elem);
155 break;
156 case CNTL_WAIT_ASSOC:
157 CntlWaitAssocProc(pAd, Elem);
158 break;
159
160 case CNTL_WAIT_OID_LIST_SCAN:
161 if(Elem->MsgType == MT2_SCAN_CONF)
162 {
163 // Resume TxRing after SCANING complete. We hope the out-of-service time
164 // won't be too long to let upper layer time-out the waiting frames
165 RTMPResumeMsduTransmission(pAd);
166 if (pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED)
167 {
168 // Cisco scan request is finished, prepare beacon report
169 MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL);
170 }
171 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
172
173 //
174 // Set LED status to previous status.
175 //
176 if (pAd->bLedOnScanning)
177 {
178 pAd->bLedOnScanning = FALSE;
179 RTMPSetLED(pAd, pAd->LedStatus);
180 }
181#ifdef DOT11N_DRAFT3
182 // AP sent a 2040Coexistence mgmt frame, then station perform a scan, and then send back the respone.
183 if (pAd->CommonCfg.BSSCoexist2040.field.InfoReq == 1)
184 {
185 Update2040CoexistFrameAndNotify(pAd, BSSID_WCID, TRUE);
186 }
187#endif // DOT11N_DRAFT3 //
188 }
189 break;
190
191 case CNTL_WAIT_OID_DISASSOC:
192 if (Elem->MsgType == MT2_DISASSOC_CONF)
193 {
194 LinkDown(pAd, FALSE);
195 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
196 }
197 break;
198#ifdef RT2870
199 //
200 // This state is for that we want to connect to an AP but
201 // it didn't find on BSS List table. So we need to scan the air first,
202 // after that we can try to connect to the desired AP if available.
203 //
204 case CNTL_WAIT_SCAN_FOR_CONNECT:
205 if(Elem->MsgType == MT2_SCAN_CONF)
206 {
207 // Resume TxRing after SCANING complete. We hope the out-of-service time
208 // won't be too long to let upper layer time-out the waiting frames
209 RTMPResumeMsduTransmission(pAd);
210#ifdef CCX_SUPPORT
211 if (pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED)
212 {
213 // Cisco scan request is finished, prepare beacon report
214 MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL);
215 }
216#endif // CCX_SUPPORT //
217 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
218
219 //
220 // Check if we can connect to.
221 //
222 BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
223 if (pAd->MlmeAux.SsidBssTab.BssNr > 0)
224 {
225 MlmeAutoReconnectLastSSID(pAd);
226 }
227 }
228 break;
229#endif // RT2870 //
230 default:
231 DBGPRINT_ERR(("!ERROR! CNTL - Illegal message type(=%ld)", Elem->MsgType));
232 break;
233 }
234}
235
236
237/*
238 ==========================================================================
239 Description:
240
241 IRQL = DISPATCH_LEVEL
242
243 ==========================================================================
244*/
245VOID CntlIdleProc(
246 IN PRTMP_ADAPTER pAd,
247 IN MLME_QUEUE_ELEM *Elem)
248{
249 MLME_DISASSOC_REQ_STRUCT DisassocReq;
250
251 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
252 return;
253
254 switch(Elem->MsgType)
255 {
256 case OID_802_11_SSID:
257 CntlOidSsidProc(pAd, Elem);
258 break;
259
260 case OID_802_11_BSSID:
261 CntlOidRTBssidProc(pAd,Elem);
262 break;
263
264 case OID_802_11_BSSID_LIST_SCAN:
265 CntlOidScanProc(pAd,Elem);
266 break;
267
268 case OID_802_11_DISASSOCIATE:
269#ifdef RALINK_ATE
270 if(ATE_ON(pAd))
271 {
272 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
273 break;
274 }
275#endif // RALINK_ATE //
276 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
277 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
278 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
279#ifdef WPA_SUPPLICANT_SUPPORT
280 if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_ENABLE_WITH_WEB_UI)
281#endif // WPA_SUPPLICANT_SUPPORT //
282 {
283 // Set the AutoReconnectSsid to prevent it reconnect to old SSID
284 // Since calling this indicate user don't want to connect to that SSID anymore.
285 pAd->MlmeAux.AutoReconnectSsidLen= 32;
286 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
287 }
288 break;
289
290 case MT2_MLME_ROAMING_REQ:
291 CntlMlmeRoamingProc(pAd, Elem);
292 break;
293
294 case OID_802_11_MIC_FAILURE_REPORT_FRAME:
295 WpaMicFailureReportFrame(pAd, Elem);
296 break;
297
298#ifdef QOS_DLS_SUPPORT
299 case RT_OID_802_11_SET_DLS_PARAM:
300 CntlOidDLSSetupProc(pAd, Elem);
301 break;
302#endif // QOS_DLS_SUPPORT //
303
304 default:
305 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Illegal message in CntlIdleProc(MsgType=%ld)\n",Elem->MsgType));
306 break;
307 }
308}
309
310VOID CntlOidScanProc(
311 IN PRTMP_ADAPTER pAd,
312 IN MLME_QUEUE_ELEM *Elem)
313{
314 MLME_SCAN_REQ_STRUCT ScanReq;
315 ULONG BssIdx = BSS_NOT_FOUND;
316 BSS_ENTRY CurrBss;
317
318#ifdef RALINK_ATE
319/* Disable scanning when ATE is running. */
320 if (ATE_ON(pAd))
321 return;
322#endif // RALINK_ATE //
323
324
325 // record current BSS if network is connected.
326 // 2003-2-13 do not include current IBSS if this is the only STA in this IBSS.
327 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
328 {
329 BssIdx = BssSsidTableSearch(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->CommonCfg.Channel);
330 if (BssIdx != BSS_NOT_FOUND)
331 {
332 NdisMoveMemory(&CurrBss, &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
333 }
334 }
335
336 // clean up previous SCAN result, add current BSS back to table if any
337 BssTableInit(&pAd->ScanTab);
338 if (BssIdx != BSS_NOT_FOUND)
339 {
340 // DDK Note: If the NIC is associated with a particular BSSID and SSID
341 // that are not contained in the list of BSSIDs generated by this scan, the
342 // BSSID description of the currently associated BSSID and SSID should be
343 // appended to the list of BSSIDs in the NIC's database.
344 // To ensure this, we append this BSS as the first entry in SCAN result
345 NdisMoveMemory(&pAd->ScanTab.BssEntry[0], &CurrBss, sizeof(BSS_ENTRY));
346 pAd->ScanTab.BssNr = 1;
347 }
348
349 ScanParmFill(pAd, &ScanReq, "", 0, BSS_ANY, SCAN_ACTIVE);
350 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
351 sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
352 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
353}
354
355/*
356 ==========================================================================
357 Description:
358 Before calling this routine, user desired SSID should already been
359 recorded in CommonCfg.Ssid[]
360 IRQL = DISPATCH_LEVEL
361
362 ==========================================================================
363*/
364VOID CntlOidSsidProc(
365 IN PRTMP_ADAPTER pAd,
366 IN MLME_QUEUE_ELEM * Elem)
367{
368 PNDIS_802_11_SSID pOidSsid = (NDIS_802_11_SSID *)Elem->Msg;
369 MLME_DISASSOC_REQ_STRUCT DisassocReq;
370 ULONG Now;
371
372 // Step 1. record the desired user settings to MlmeAux
373 NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
374 NdisMoveMemory(pAd->MlmeAux.Ssid, pOidSsid->Ssid, pOidSsid->SsidLength);
375 pAd->MlmeAux.SsidLen = (UCHAR)pOidSsid->SsidLength;
376 NdisZeroMemory(pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
377 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
378
379
380 //
381 // Update Reconnect Ssid, that user desired to connect.
382 //
383 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
384 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
385 pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
386
387 // step 2. find all matching BSS in the lastest SCAN result (inBssTab)
388 // & log them into MlmeAux.SsidBssTab for later-on iteration. Sort by RSSI order
389 BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
390
391 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - %d BSS of %d BSS match the desire (%d)SSID - %s\n",
392 pAd->MlmeAux.SsidBssTab.BssNr, pAd->ScanTab.BssNr, pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid));
393 NdisGetSystemUpTime(&Now);
394
395 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
396 (pAd->CommonCfg.SsidLen == pAd->MlmeAux.SsidBssTab.BssEntry[0].SsidLen) &&
397 NdisEqualMemory(pAd->CommonCfg.Ssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Ssid, pAd->CommonCfg.SsidLen) &&
398 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Bssid))
399 {
400 // Case 1. already connected with an AP who has the desired SSID
401 // with highest RSSI
402
403 // Add checking Mode "LEAP" for CCX 1.0
404 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
405 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
406 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
407 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
408#ifdef LEAP_SUPPORT
409 || (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
410#endif // LEAP_SUPPORT //
411 ) &&
412 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
413 {
414 // case 1.1 For WPA, WPA-PSK, if the 1x port is not secured, we have to redo
415 // connection process
416 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
417 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
418 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
419 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
420 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
421 }
422 else if (pAd->bConfigChanged == TRUE)
423 {
424 // case 1.2 Important Config has changed, we have to reconnect to the same AP
425 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP Because config changed...\n"));
426 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
427 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
428 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
429 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
430 }
431 else
432 {
433 // case 1.3. already connected to the SSID with highest RSSI.
434 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - already with this BSSID. ignore this SET_SSID request\n"));
435 //
436 // (HCT 12.1) 1c_wlan_mediaevents required
437 // media connect events are indicated when associating with the same AP
438 //
439 if (INFRA_ON(pAd))
440 {
441 //
442 // Since MediaState already is NdisMediaStateConnected
443 // We just indicate the connect event again to meet the WHQL required.
444 //
445 pAd->IndicateMediaState = NdisMediaStateConnected;
446 RTMP_IndicateMediaState(pAd);
447 pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
448 }
449
450 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
451#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
452 {
453 union iwreq_data wrqu;
454
455 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
456 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
457 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
458
459 }
460#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
461 }
462 }
463 else if (INFRA_ON(pAd))
464 {
465 //
466 // For RT61
467 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
468 // RT61 may lost SSID, and not connect to NDTEST_WEP_AP2 and will connect to NDTEST_WEP_AP2 by Autoreconnect
469 // But media status is connected, so the SSID not report correctly.
470 //
471 if (!SSID_EQUAL(pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen))
472 {
473 //
474 // Different SSID means not Roaming case, so we let LinkDown() to Indicate a disconnect event.
475 //
476 pAd->MlmeAux.CurrReqIsFromNdis = TRUE;
477 }
478 // case 2. active INFRA association existent
479 // roaming is done within miniport driver, nothing to do with configuration
480 // utility. so upon a new SET(OID_802_11_SSID) is received, we just
481 // disassociate with the current associated AP,
482 // then perform a new association with this new SSID, no matter the
483 // new/old SSID are the same or not.
484 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
485 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
486 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
487 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
488 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
489 }
490 else
491 {
492 if (ADHOC_ON(pAd))
493 {
494 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - drop current ADHOC\n"));
495 LinkDown(pAd, FALSE);
496 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
497 pAd->IndicateMediaState = NdisMediaStateDisconnected;
498 RTMP_IndicateMediaState(pAd);
499 pAd->ExtraInfo = GENERAL_LINK_DOWN;
500 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
501 }
502
503 if ((pAd->MlmeAux.SsidBssTab.BssNr == 0) &&
504 (pAd->StaCfg.bAutoReconnect == TRUE) &&
505 (pAd->MlmeAux.BssType == BSS_INFRA) &&
506 (MlmeValidateSSID(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen) == TRUE)
507 )
508 {
509 MLME_SCAN_REQ_STRUCT ScanReq;
510
511 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - No matching BSS, start a new scan\n"));
512 ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE);
513 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
514 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
515 // Reset Missed scan number
516 pAd->StaCfg.LastScanTime = Now;
517 }
518 else
519 {
520 pAd->MlmeAux.BssIdx = 0;
521 IterateOnBssTab(pAd);
522 }
523 }
524}
525
526
527/*
528 ==========================================================================
529 Description:
530
531 IRQL = DISPATCH_LEVEL
532
533 ==========================================================================
534*/
535VOID CntlOidRTBssidProc(
536 IN PRTMP_ADAPTER pAd,
537 IN MLME_QUEUE_ELEM * Elem)
538{
539 ULONG BssIdx;
540 PUCHAR pOidBssid = (PUCHAR)Elem->Msg;
541 MLME_DISASSOC_REQ_STRUCT DisassocReq;
542 MLME_JOIN_REQ_STRUCT JoinReq;
543
544#ifdef RALINK_ATE
545/* No need to perform this routine when ATE is running. */
546 if (ATE_ON(pAd))
547 return;
548#endif // RALINK_ATE //
549
550 // record user desired settings
551 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pOidBssid);
552 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
553
554 //
555 // Update Reconnect Ssid, that user desired to connect.
556 //
557 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
558 pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
559 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
560
561 // find the desired BSS in the latest SCAN result table
562 BssIdx = BssTableSearch(&pAd->ScanTab, pOidBssid, pAd->MlmeAux.Channel);
563 if (BssIdx == BSS_NOT_FOUND)
564 {
565 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n"));
566 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
567 return;
568 }
569
570 // copy the matched BSS entry from ScanTab to MlmeAux.SsidBssTab. Why?
571 // Because we need this entry to become the JOIN target in later on SYNC state machine
572 pAd->MlmeAux.BssIdx = 0;
573 pAd->MlmeAux.SsidBssTab.BssNr = 1;
574 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab.BssEntry[0], &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
575
576 //pAd->MlmeAux.AutoReconnectSsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen;
577 //NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->ScanTab.BssEntry[BssIdx].Ssid, pAd->ScanTab.BssEntry[BssIdx].SsidLen);
578
579 // Add SSID into MlmeAux for site surey joining hidden SSID
580 //pAd->MlmeAux.SsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen;
581 //NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->ScanTab.BssEntry[BssIdx].Ssid, pAd->MlmeAux.SsidLen);
582
583 // 2002-11-26 skip the following checking. i.e. if user wants to re-connect to same AP
584 // we just follow normal procedure. The reason of user doing this may because he/she changed
585 // AP to another channel, but we still received BEACON from it thus don't claim Link Down.
586 // Since user knows he's changed AP channel, he'll re-connect again. By skipping the following
587 // checking, we'll disassociate then re-do normal association with this AP at the new channel.
588 // 2003-1-6 Re-enable this feature based on microsoft requirement which prefer not to re-do
589 // connection when setting the same BSSID.
590 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
591 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pOidBssid))
592 {
593 // already connected to the same BSSID, go back to idle state directly
594 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - already in this BSSID. ignore this SET_BSSID request\n"));
595 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
596#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
597 {
598 union iwreq_data wrqu;
599
600 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
601 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
602 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
603
604 }
605#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
606 }
607 else
608 {
609 if (INFRA_ON(pAd))
610 {
611 // disassoc from current AP first
612 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - disassociate with current AP ...\n"));
613 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
614 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
615 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
616
617 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
618 }
619 else
620 {
621 if (ADHOC_ON(pAd))
622 {
623 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - drop current ADHOC\n"));
624 LinkDown(pAd, FALSE);
625 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
626 pAd->IndicateMediaState = NdisMediaStateDisconnected;
627 RTMP_IndicateMediaState(pAd);
628 pAd->ExtraInfo = GENERAL_LINK_DOWN;
629 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
630 }
631
632 // Change the wepstatus to original wepstatus
633 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
634 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
635 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
636
637 // Check cipher suite, AP must have more secured cipher than station setting
638 // Set the Pairwise and Group cipher to match the intended AP setting
639 // We can only connect to AP with less secured cipher setting
640 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
641 {
642 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.GroupCipher;
643
644 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher)
645 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher;
646 else if (pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
647 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux;
648 else // There is no PairCipher Aux, downgrade our capability to TKIP
649 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
650 }
651 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
652 {
653 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.GroupCipher;
654
655 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher)
656 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher;
657 else if (pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
658 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux;
659 else // There is no PairCipher Aux, downgrade our capability to TKIP
660 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
661
662 // RSN capability
663 pAd->StaCfg.RsnCapability = pAd->ScanTab.BssEntry[BssIdx].WPA2.RsnCapability;
664 }
665
666 // Set Mix cipher flag
667 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
668 if (pAd->StaCfg.bMixCipher == TRUE)
669 {
670 // If mix cipher, re-build RSNIE
671 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
672 }
673 // No active association, join the BSS immediately
674 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - joining %02x:%02x:%02x:%02x:%02x:%02x ...\n",
675 pOidBssid[0],pOidBssid[1],pOidBssid[2],pOidBssid[3],pOidBssid[4],pOidBssid[5]));
676
677 JoinParmFill(pAd, &JoinReq, pAd->MlmeAux.BssIdx);
678 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT), &JoinReq);
679
680 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
681 }
682 }
683}
684
685// Roaming is the only external request triggering CNTL state machine
686// despite of other "SET OID" operation. All "SET OID" related oerations
687// happen in sequence, because no other SET OID will be sent to this device
688// until the the previous SET operation is complete (successful o failed).
689// So, how do we quarantee this ROAMING request won't corrupt other "SET OID"?
690// or been corrupted by other "SET OID"?
691//
692// IRQL = DISPATCH_LEVEL
693VOID CntlMlmeRoamingProc(
694 IN PRTMP_ADAPTER pAd,
695 IN MLME_QUEUE_ELEM *Elem)
696{
697 // TODO:
698 // AP in different channel may show lower RSSI than actual value??
699 // should we add a weighting factor to compensate it?
700 DBGPRINT(RT_DEBUG_TRACE,("CNTL - Roaming in MlmeAux.RoamTab...\n"));
701
702 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab, sizeof(pAd->MlmeAux.RoamTab));
703 pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr;
704
705 BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab);
706 pAd->MlmeAux.BssIdx = 0;
707 IterateOnBssTab(pAd);
708}
709
710#ifdef QOS_DLS_SUPPORT
711/*
712 ==========================================================================
713 Description:
714
715 IRQL = DISPATCH_LEVEL
716
717 ==========================================================================
718*/
719VOID CntlOidDLSSetupProc(
720 IN PRTMP_ADAPTER pAd,
721 IN MLME_QUEUE_ELEM *Elem)
722{
723 PRT_802_11_DLS pDLS = (PRT_802_11_DLS)Elem->Msg;
724 MLME_DLS_REQ_STRUCT MlmeDlsReq;
725 INT i;
726 USHORT reason = REASON_UNSPECIFY;
727
728 DBGPRINT(RT_DEBUG_TRACE,("CNTL - (OID set %02x:%02x:%02x:%02x:%02x:%02x with Valid=%d, Status=%d, TimeOut=%d, CountDownTimer=%d)\n",
729 pDLS->MacAddr[0], pDLS->MacAddr[1], pDLS->MacAddr[2], pDLS->MacAddr[3], pDLS->MacAddr[4], pDLS->MacAddr[5],
730 pDLS->Valid, pDLS->Status, pDLS->TimeOut, pDLS->CountDownTimer));
731
732 if (!pAd->CommonCfg.bDLSCapable)
733 return;
734
735 // DLS will not be supported when Adhoc mode
736 if (INFRA_ON(pAd))
737 {
738 for (i = 0; i < MAX_NUM_OF_DLS_ENTRY; i++)
739 {
740 if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
741 (pDLS->TimeOut == pAd->StaCfg.DLSEntry[i].TimeOut) && MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
742 {
743 // 1. Same setting, just drop it
744 DBGPRINT(RT_DEBUG_TRACE,("CNTL - setting unchanged\n"));
745 break;
746 }
747 else if (!pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
748 MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
749 {
750 // 2. Disable DLS link case, just tear down DLS link
751 reason = REASON_QOS_UNWANTED_MECHANISM;
752 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
753 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
754 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
755 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
756 DBGPRINT(RT_DEBUG_TRACE,("CNTL - start tear down procedure\n"));
757 break;
758 }
759 else if ((i < MAX_NUM_OF_DLS_ENTRY) && pDLS->Valid && !pAd->StaCfg.DLSEntry[i].Valid)
760 {
761 // 3. Enable case, start DLS setup procedure
762 NdisMoveMemory(&pAd->StaCfg.DLSEntry[i], pDLS, sizeof(RT_802_11_DLS_UI));
763
764 //Update countdown timer
765 pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
766 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
767 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
768 DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS setup case\n"));
769 break;
770 }
771 else if ((i < MAX_NUM_OF_DLS_ENTRY) && pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
772 (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) && !MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
773 {
774 // 4. update mac case, tear down old DLS and setup new DLS
775 reason = REASON_QOS_UNWANTED_MECHANISM;
776 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
777 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
778 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
779 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
780 NdisMoveMemory(&pAd->StaCfg.DLSEntry[i], pDLS, sizeof(RT_802_11_DLS_UI));
781 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
782 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
783 DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS tear down and restart case\n"));
784 break;
785 }
786 else if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
787 MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr) && (pAd->StaCfg.DLSEntry[i].TimeOut != pDLS->TimeOut))
788 {
789 // 5. update timeout case, start DLS setup procedure (no tear down)
790 pAd->StaCfg.DLSEntry[i].TimeOut = pDLS->TimeOut;
791 //Update countdown timer
792 pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
793 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
794 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
795 DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS update timeout case\n"));
796 break;
797 }
798 else if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
799 (pAd->StaCfg.DLSEntry[i].Status != DLS_FINISH) && MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
800 {
801 // 6. re-setup case, start DLS setup procedure (no tear down)
802 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
803 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
804 DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS retry setup procedure\n"));
805 break;
806 }
807 else
808 {
809 DBGPRINT(RT_DEBUG_WARN,("CNTL - DLS not changed in entry - %d - Valid=%d, Status=%d, TimeOut=%d\n",
810 i, pAd->StaCfg.DLSEntry[i].Valid, pAd->StaCfg.DLSEntry[i].Status, pAd->StaCfg.DLSEntry[i].TimeOut));
811 }
812 }
813 }
814}
815#endif // QOS_DLS_SUPPORT //
816
817/*
818 ==========================================================================
819 Description:
820
821 IRQL = DISPATCH_LEVEL
822
823 ==========================================================================
824*/
825VOID CntlWaitDisassocProc(
826 IN PRTMP_ADAPTER pAd,
827 IN MLME_QUEUE_ELEM *Elem)
828{
829 MLME_START_REQ_STRUCT StartReq;
830
831 if (Elem->MsgType == MT2_DISASSOC_CONF)
832 {
833 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Dis-associate successful\n"));
834
835 if (pAd->CommonCfg.bWirelessEvent)
836 {
837 RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
838 }
839
840 LinkDown(pAd, FALSE);
841
842 // case 1. no matching BSS, and user wants ADHOC, so we just start a new one
843 if ((pAd->MlmeAux.SsidBssTab.BssNr==0) && (pAd->StaCfg.BssType == BSS_ADHOC))
844 {
845 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
846 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
847 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
848 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
849 }
850 // case 2. try each matched BSS
851 else
852 {
853 pAd->MlmeAux.BssIdx = 0;
854
855 IterateOnBssTab(pAd);
856 }
857 }
858}
859
860/*
861 ==========================================================================
862 Description:
863
864 IRQL = DISPATCH_LEVEL
865
866 ==========================================================================
867*/
868VOID CntlWaitJoinProc(
869 IN PRTMP_ADAPTER pAd,
870 IN MLME_QUEUE_ELEM *Elem)
871{
872 USHORT Reason;
873 MLME_AUTH_REQ_STRUCT AuthReq;
874
875 if (Elem->MsgType == MT2_JOIN_CONF)
876 {
877 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
878 if (Reason == MLME_SUCCESS)
879 {
880 // 1. joined an IBSS, we are pretty much done here
881 if (pAd->MlmeAux.BssType == BSS_ADHOC)
882 {
883 //
884 // 5G bands rules of Japan:
885 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
886 //
887 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
888 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
889 )
890 {
891 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
892 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Join adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
893 return;
894 }
895
896 LinkUp(pAd, BSS_ADHOC);
897 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
898 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - join the IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
899 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
900 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
901
902 pAd->IndicateMediaState = NdisMediaStateConnected;
903 pAd->ExtraInfo = GENERAL_LINK_UP;
904 }
905 // 2. joined a new INFRA network, start from authentication
906 else
907 {
908#ifdef LEAP_SUPPORT
909 // Add AuthMode "LEAP" for CCX 1.X
910 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
911 {
912 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, CISCO_AuthModeLEAP);
913 }
914 else
915#endif // LEAP_SUPPORT //
916 {
917 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
918 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
919 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
920 {
921 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
922 }
923 else
924 {
925 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
926 }
927 }
928 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
929 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
930
931 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH;
932 }
933 }
934 else
935 {
936 // 3. failed, try next BSS
937 pAd->MlmeAux.BssIdx++;
938 IterateOnBssTab(pAd);
939 }
940 }
941}
942
943
944/*
945 ==========================================================================
946 Description:
947
948 IRQL = DISPATCH_LEVEL
949
950 ==========================================================================
951*/
952VOID CntlWaitStartProc(
953 IN PRTMP_ADAPTER pAd,
954 IN MLME_QUEUE_ELEM *Elem)
955{
956 USHORT Result;
957
958 if (Elem->MsgType == MT2_START_CONF)
959 {
960 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
961 if (Result == MLME_SUCCESS)
962 {
963 //
964 // 5G bands rules of Japan:
965 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
966 //
967 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
968 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
969 )
970 {
971 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
972 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Start adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
973 return;
974 }
975#ifdef DOT11_N_SUPPORT
976 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
977 {
978 N_ChannelCheck(pAd);
979 SetCommonHT(pAd);
980 NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, &pAd->CommonCfg.AddHTInfo, sizeof(ADD_HT_INFO_IE));
981 RTMPCheckHt(pAd, BSSID_WCID, &pAd->CommonCfg.HtCapability, &pAd->CommonCfg.AddHTInfo);
982 pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
983 NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16);
984 NdisMoveMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], &pAd->CommonCfg.HtCapability.MCSSet[0], 16);
985 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
986
987 if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
988 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
989 {
990 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel + 2;
991 }
992 else if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
993 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW))
994 {
995 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel - 2;
996 }
997 }
998 else
999#endif // DOT11_N_SUPPORT //
1000 {
1001 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
1002 }
1003 LinkUp(pAd, BSS_ADHOC);
1004 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1005 // Before send beacon, driver need do radar detection
1006 if ((pAd->CommonCfg.Channel > 14 )
1007 && (pAd->CommonCfg.bIEEE80211H == 1)
1008 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
1009 {
1010 pAd->CommonCfg.RadarDetect.RDMode = RD_SILENCE_MODE;
1011 pAd->CommonCfg.RadarDetect.RDCount = 0;
1012#ifdef DFS_SUPPORT
1013 BbpRadarDetectionStart(pAd);
1014#endif // DFS_SUPPORT //
1015 }
1016
1017 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - start a new IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
1018 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
1019 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
1020 }
1021 else
1022 {
1023 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Start IBSS fail. BUG!!!!!\n"));
1024 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1025 }
1026 }
1027}
1028
1029/*
1030 ==========================================================================
1031 Description:
1032
1033 IRQL = DISPATCH_LEVEL
1034
1035 ==========================================================================
1036*/
1037VOID CntlWaitAuthProc(
1038 IN PRTMP_ADAPTER pAd,
1039 IN MLME_QUEUE_ELEM *Elem)
1040{
1041 USHORT Reason;
1042 MLME_ASSOC_REQ_STRUCT AssocReq;
1043 MLME_AUTH_REQ_STRUCT AuthReq;
1044
1045 if (Elem->MsgType == MT2_AUTH_CONF)
1046 {
1047 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
1048 if (Reason == MLME_SUCCESS)
1049 {
1050 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
1051 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
1052 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
1053
1054#ifdef LEAP_SUPPORT
1055 //
1056 // Cisco Leap CCKM supported Re-association.
1057 //
1058 if (LEAP_CCKM_ON(pAd) && (pAd->StaCfg.CCKMLinkUpFlag == TRUE))
1059 {
1060 //if CCKM is turn on , that's mean Fast Reauthentication
1061 //Use CCKM Reassociation instead of normal association for Fast Roaming.
1062 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
1063 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
1064
1065 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
1066 }
1067 else
1068#endif // LEAP_SUPPORT //
1069 {
1070 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
1071 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
1072
1073 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
1074 }
1075 }
1076 else
1077 {
1078 // This fail may because of the AP already keep us in its MAC table without
1079 // ageing-out. The previous authentication attempt must have let it remove us.
1080 // so try Authentication again may help. For D-Link DWL-900AP+ compatibility.
1081 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try again...\n"));
1082#ifdef LEAP_SUPPORT
1083 //Add AuthMode "LEAP" for CCX 1.X
1084 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
1085 {
1086 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, CISCO_AuthModeLEAP);
1087 }
1088 else
1089#endif // LEAP_SUPPORT //
1090 {
1091 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
1092 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
1093 {
1094 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
1095 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
1096 }
1097 else
1098 {
1099 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
1100 }
1101 }
1102 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
1103 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
1104
1105 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
1106 }
1107 }
1108}
1109
1110/*
1111 ==========================================================================
1112 Description:
1113
1114 IRQL = DISPATCH_LEVEL
1115
1116 ==========================================================================
1117*/
1118VOID CntlWaitAuthProc2(
1119 IN PRTMP_ADAPTER pAd,
1120 IN MLME_QUEUE_ELEM *Elem)
1121{
1122 USHORT Reason;
1123 MLME_ASSOC_REQ_STRUCT AssocReq;
1124 MLME_AUTH_REQ_STRUCT AuthReq;
1125
1126 if (Elem->MsgType == MT2_AUTH_CONF)
1127 {
1128 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
1129 if (Reason == MLME_SUCCESS)
1130 {
1131 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
1132 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
1133 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
1134 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
1135 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
1136
1137 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
1138 }
1139 else
1140 {
1141#ifdef LEAP_SUPPORT
1142 // Process LEAP first, since it use different control variable
1143 // We don't want to affect other poven operation
1144 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
1145 {
1146 // LEAP Auth not success, try next BSS
1147 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - *LEAP* AUTH FAIL, give up; try next BSS\n"));
1148 DBGPRINT(RT_DEBUG_TRACE, ("Total match BSSID [=%d]\n", pAd->MlmeAux.SsidBssTab.BssNr));
1149 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1150 pAd->MlmeAux.BssIdx++;
1151 IterateOnBssTab(pAd);
1152 }
1153 else
1154#endif // LEAP_SUPPORT //
1155 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch) &&
1156 (pAd->MlmeAux.Alg == Ndis802_11AuthModeShared))
1157 {
1158 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try OPEN system...\n"));
1159 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
1160 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
1161 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
1162
1163 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
1164 }
1165 else
1166 {
1167 // not success, try next BSS
1168 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, give up; try next BSS\n"));
1169 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; //???????
1170 pAd->MlmeAux.BssIdx++;
1171 IterateOnBssTab(pAd);
1172 }
1173 }
1174 }
1175}
1176
1177/*
1178 ==========================================================================
1179 Description:
1180
1181 IRQL = DISPATCH_LEVEL
1182
1183 ==========================================================================
1184*/
1185VOID CntlWaitAssocProc(
1186 IN PRTMP_ADAPTER pAd,
1187 IN MLME_QUEUE_ELEM *Elem)
1188{
1189 USHORT Reason;
1190
1191 if (Elem->MsgType == MT2_ASSOC_CONF)
1192 {
1193 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
1194 if (Reason == MLME_SUCCESS)
1195 {
1196 LinkUp(pAd, BSS_INFRA);
1197 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1198 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association successful on BSS #%ld\n",pAd->MlmeAux.BssIdx));
1199
1200 if (pAd->CommonCfg.bWirelessEvent)
1201 {
1202 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1203 }
1204 }
1205 else
1206 {
1207 // not success, try next BSS
1208 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association fails on BSS #%ld\n",pAd->MlmeAux.BssIdx));
1209 pAd->MlmeAux.BssIdx++;
1210 IterateOnBssTab(pAd);
1211 }
1212 }
1213}
1214
1215/*
1216 ==========================================================================
1217 Description:
1218
1219 IRQL = DISPATCH_LEVEL
1220
1221 ==========================================================================
1222*/
1223VOID CntlWaitReassocProc(
1224 IN PRTMP_ADAPTER pAd,
1225 IN MLME_QUEUE_ELEM *Elem)
1226{
1227 USHORT Result;
1228
1229 if (Elem->MsgType == MT2_REASSOC_CONF)
1230 {
1231 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
1232 if (Result == MLME_SUCCESS)
1233 {
1234 //
1235 // NDIS requires a new Link UP indication but no Link Down for RE-ASSOC
1236 //
1237 LinkUp(pAd, BSS_INFRA);
1238
1239 // send wireless event - for association
1240 if (pAd->CommonCfg.bWirelessEvent)
1241 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1242
1243
1244#ifdef LEAP_SUPPORT
1245 if (LEAP_CCKM_ON(pAd))
1246 {
1247 STA_PORT_SECURED(pAd);
1248 pAd->StaCfg.WpaState = SS_FINISH;
1249 }
1250#endif // LEAP_SUPPORT //
1251 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1252 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition successful on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1253 }
1254 else
1255 {
1256 // reassoc failed, try to pick next BSS in the BSS Table
1257 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition fails on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1258 pAd->MlmeAux.RoamIdx++;
1259 IterateOnBssTab2(pAd);
1260 }
1261 }
1262}
1263
1264
1265VOID AdhocTurnOnQos(
1266 IN PRTMP_ADAPTER pAd)
1267{
1268#define AC0_DEF_TXOP 0
1269#define AC1_DEF_TXOP 0
1270#define AC2_DEF_TXOP 94
1271#define AC3_DEF_TXOP 47
1272
1273 // Turn on QOs if use HT rate.
1274 if (pAd->CommonCfg.APEdcaParm.bValid == FALSE)
1275 {
1276 pAd->CommonCfg.APEdcaParm.bValid = TRUE;
1277 pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
1278 pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
1279 pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
1280 pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
1281
1282 pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
1283 pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
1284 pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
1285 pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
1286
1287 pAd->CommonCfg.APEdcaParm.Cwmax[0] = 10;
1288 pAd->CommonCfg.APEdcaParm.Cwmax[1] = 6;
1289 pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
1290 pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
1291
1292 pAd->CommonCfg.APEdcaParm.Txop[0] = 0;
1293 pAd->CommonCfg.APEdcaParm.Txop[1] = 0;
1294 pAd->CommonCfg.APEdcaParm.Txop[2] = AC2_DEF_TXOP;
1295 pAd->CommonCfg.APEdcaParm.Txop[3] = AC3_DEF_TXOP;
1296 }
1297 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1298}
1299
1300/*
1301 ==========================================================================
1302 Description:
1303
1304 IRQL = DISPATCH_LEVEL
1305
1306 ==========================================================================
1307*/
1308VOID LinkUp(
1309 IN PRTMP_ADAPTER pAd,
1310 IN UCHAR BssType)
1311{
1312 ULONG Now;
1313 UINT32 Data;
1314 BOOLEAN Cancelled;
1315 UCHAR Value = 0, idx;
1316 MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
1317
1318 pEntry = &pAd->MacTab.Content[BSSID_WCID];
1319
1320 //
1321 // ASSOC - DisassocTimeoutAction
1322 // CNTL - Dis-associate successful
1323 // !!! LINK DOWN !!!
1324 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
1325 //
1326 // To prevent DisassocTimeoutAction to call Link down after we link up,
1327 // cancel the DisassocTimer no matter what it start or not.
1328 //
1329 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
1330
1331 COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1332
1333#ifdef DOT11_N_SUPPORT
1334 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1335#endif // DOT11_N_SUPPORT //
1336 // It's quite difficult to tell if a newly added KEY is WEP or CKIP until a new BSS
1337 // is formed (either ASSOC/RE-ASSOC done or IBSS started. LinkUP should be a safe place
1338 // to examine if cipher algorithm switching is required.
1339 //rt2860b. Don't know why need this
1340 SwitchBetweenWepAndCkip(pAd);
1341
1342
1343 if (BssType == BSS_ADHOC)
1344 {
1345 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1346 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1347
1348#ifdef DOT11_N_SUPPORT
1349 if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
1350 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
1351 {
1352 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2;
1353 }
1354 else if ((pAd->CommonCfg.Channel > 2) &&
1355 (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
1356 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW))
1357 {
1358 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2;
1359 }
1360#endif // DOT11_N_SUPPORT //
1361
1362#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
1363 // No carrier detection when adhoc
1364 // CarrierDetectionStop(pAd);
1365 pAd->CommonCfg.CarrierDetect.CD_State = CD_NORMAL;
1366#endif // CARRIER_DETECTION_SUPPORT //
1367
1368#ifdef DOT11_N_SUPPORT
1369 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
1370 AdhocTurnOnQos(pAd);
1371#endif // DOT11_N_SUPPORT //
1372
1373 DBGPRINT(RT_DEBUG_TRACE, ("!!!Adhoc LINK UP !!! \n" ));
1374 }
1375 else
1376 {
1377 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_INFRA_ON);
1378 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1379
1380 DBGPRINT(RT_DEBUG_TRACE, ("!!!Infra LINK UP !!! \n" ));
1381 }
1382
1383 // 3*3
1384 // reset Tx beamforming bit
1385 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1386 Value &= (~0x01);
1387 Value |= pAd->CommonCfg.RegTransmitSetting.field.TxBF;
1388 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1389
1390#ifdef DOT11_N_SUPPORT
1391 // Change to AP channel
1392 if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1393 {
1394 // Must using 40MHz.
1395 pAd->CommonCfg.BBPCurrentBW = BW_40;
1396 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1397 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1398
1399 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1400 Value &= (~0x18);
1401 Value |= 0x10;
1402 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1403
1404 // RX : control channel at lower
1405 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1406 Value &= (~0x20);
1407 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1408
1409 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1410 Data &= 0xfffffffe;
1411 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1412
1413 if (pAd->MACVersion == 0x28600100)
1414 {
1415 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1416 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1417 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1418 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1419 }
1420
1421 DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
1422 }
1423 else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1424 {
1425 // Must using 40MHz.
1426 pAd->CommonCfg.BBPCurrentBW = BW_40;
1427 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1428 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1429
1430 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1431 Value &= (~0x18);
1432 Value |= 0x10;
1433 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1434
1435 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1436 Data |= 0x1;
1437 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1438
1439 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1440 Value |= (0x20);
1441 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1442
1443 if (pAd->MACVersion == 0x28600100)
1444 {
1445 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1446 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1447 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1448 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1449 }
1450
1451 DBGPRINT(RT_DEBUG_TRACE, ("!!! 40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
1452 }
1453 else
1454#endif // DOT11_N_SUPPORT //
1455 {
1456 pAd->CommonCfg.BBPCurrentBW = BW_20;
1457 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
1458 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1459 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1460
1461 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1462 Value &= (~0x18);
1463 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1464
1465 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1466 Data &= 0xfffffffe;
1467 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1468
1469 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1470 Value &= (~0x20);
1471 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1472
1473 if (pAd->MACVersion == 0x28600100)
1474 {
1475 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
1476 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
1477 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
1478 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1479 }
1480
1481 DBGPRINT(RT_DEBUG_TRACE, ("!!! 20MHz LINK UP !!! \n" ));
1482 }
1483
1484 RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
1485 //
1486 // Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission
1487 //
1488 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
1489
1490 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (BssType=%d, AID=%d, ssid=%s, Channel=%d, CentralChannel = %d)\n",
1491 BssType, pAd->StaActive.Aid, pAd->CommonCfg.Ssid, pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
1492
1493#ifdef DOT11_N_SUPPORT
1494 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (Density =%d, )\n", pAd->MacTab.Content[BSSID_WCID].MpduDensity));
1495#endif // DOT11_N_SUPPORT //
1496
1497 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1498
1499 AsicSetSlotTime(pAd, TRUE);
1500 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1501
1502 // Call this for RTS protectionfor legacy rate, we will always enable RTS threshold, but normally it will not hit
1503 AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE, FALSE);
1504
1505#ifdef DOT11_N_SUPPORT
1506 if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE))
1507 {
1508 // Update HT protectionfor based on AP's operating mode.
1509 if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
1510 {
1511 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE);
1512 }
1513 else
1514 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
1515 }
1516#endif // DOT11_N_SUPPORT //
1517
1518 NdisZeroMemory(&pAd->DrsCounters, sizeof(COUNTER_DRS));
1519
1520 NdisGetSystemUpTime(&Now);
1521 pAd->StaCfg.LastBeaconRxTime = Now; // last RX timestamp
1522
1523 if ((pAd->CommonCfg.TxPreamble != Rt802_11PreambleLong) &&
1524 CAP_IS_SHORT_PREAMBLE_ON(pAd->StaActive.CapabilityInfo))
1525 {
1526 MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
1527 }
1528
1529 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1530
1531 if (pAd->CommonCfg.RadarDetect.RDMode == RD_SILENCE_MODE)
1532 {
1533#ifdef DFS_SUPPORT
1534 RadarDetectionStop(pAd);
1535#endif // DFS_SUPPORT //
1536 }
1537 pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
1538
1539 if (BssType == BSS_ADHOC)
1540 {
1541 MakeIbssBeacon(pAd);
1542 if ((pAd->CommonCfg.Channel > 14)
1543 && (pAd->CommonCfg.bIEEE80211H == 1)
1544 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
1545 {
1546 ; //Do nothing
1547 }
1548 else
1549 {
1550 AsicEnableIbssSync(pAd);
1551 }
1552
1553 // In ad hoc mode, use MAC table from index 1.
1554 // p.s ASIC use all 0xff as termination of WCID table search.To prevent it's 0xff-ff-ff-ff-ff-ff, Write 0 here.
1555 RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00);
1556 RTMP_IO_WRITE32(pAd, 0x1808, 0x00);
1557
1558 // If WEP is enabled, add key material and cipherAlg into Asic
1559 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1560
1561 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
1562 {
1563 PUCHAR Key;
1564 UCHAR CipherAlg;
1565
1566 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1567 {
1568 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1569 Key = pAd->SharedKey[BSS0][idx].Key;
1570
1571 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1572 {
1573 // Set key material and cipherAlg to Asic
1574 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1575
1576 if (idx == pAd->StaCfg.DefaultKeyId)
1577 {
1578 // Update WCID attribute table and IVEIV table for this group key table
1579 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1580 }
1581 }
1582
1583
1584 }
1585 }
1586 // If WPANone is enabled, add key material and cipherAlg into Asic
1587 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1588 else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1589 {
1590 pAd->StaCfg.DefaultKeyId = 0; // always be zero
1591
1592 NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
1593 pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
1594 NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pAd->StaCfg.PMK, LEN_TKIP_EK);
1595
1596 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1597 {
1598 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_RXMICK);
1599 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_TXMICK);
1600 }
1601
1602 // Decide its ChiperAlg
1603 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1604 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
1605 else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
1606 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1607 else
1608 {
1609 DBGPRINT(RT_DEBUG_TRACE, ("Unknow Cipher (=%d), set Cipher to AES\n", pAd->StaCfg.PairCipher));
1610 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1611 }
1612
1613 // Set key material and cipherAlg to Asic
1614 AsicAddSharedKeyEntry(pAd,
1615 BSS0,
1616 0,
1617 pAd->SharedKey[BSS0][0].CipherAlg,
1618 pAd->SharedKey[BSS0][0].Key,
1619 pAd->SharedKey[BSS0][0].TxMic,
1620 pAd->SharedKey[BSS0][0].RxMic);
1621
1622 // Update WCID attribute table and IVEIV table for this group key table
1623 RTMPAddWcidAttributeEntry(pAd, BSS0, 0, pAd->SharedKey[BSS0][0].CipherAlg, NULL);
1624
1625 }
1626
1627 }
1628 else // BSS_INFRA
1629 {
1630 // Check the new SSID with last SSID
1631 while (Cancelled == TRUE)
1632 {
1633 if (pAd->CommonCfg.LastSsidLen == pAd->CommonCfg.SsidLen)
1634 {
1635 if (RTMPCompareMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen) == 0)
1636 {
1637 // Link to the old one no linkdown is required.
1638 break;
1639 }
1640 }
1641 // Send link down event before set to link up
1642 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1643 RTMP_IndicateMediaState(pAd);
1644 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1645 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event AA!\n"));
1646 break;
1647 }
1648
1649 //
1650 // On WPA mode, Remove All Keys if not connect to the last BSSID
1651 // Key will be set after 4-way handshake.
1652 //
1653 if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1654 {
1655 ULONG IV;
1656
1657 // Remove all WPA keys
1658 RTMPWPARemoveAllKeys(pAd);
1659 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1660 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1661
1662 // Fixed connection failed with Range Maximizer - 515 AP (Marvell Chip) when security is WPAPSK/TKIP
1663 // If IV related values are too large in GroupMsg2, AP would ignore this message.
1664 IV = 0;
1665 IV |= (pAd->StaCfg.DefaultKeyId << 30);
1666 AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0);
1667 }
1668 // NOTE:
1669 // the decision of using "short slot time" or not may change dynamically due to
1670 // new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1671
1672 // NOTE:
1673 // the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically
1674 // due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1675
1676 ComposePsPoll(pAd);
1677 ComposeNullFrame(pAd);
1678
1679 AsicEnableBssSync(pAd);
1680
1681 // Add BSSID to WCID search table
1682 AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->CommonCfg.Bssid);
1683
1684 NdisAcquireSpinLock(&pAd->MacTabLock);
1685 // add this BSSID entry into HASH table
1686 {
1687 UCHAR HashIdx;
1688
1689 //pEntry = &pAd->MacTab.Content[BSSID_WCID];
1690 HashIdx = MAC_ADDR_HASH_INDEX(pAd->CommonCfg.Bssid);
1691 if (pAd->MacTab.Hash[HashIdx] == NULL)
1692 {
1693 pAd->MacTab.Hash[HashIdx] = pEntry;
1694 }
1695 else
1696 {
1697 pCurrEntry = pAd->MacTab.Hash[HashIdx];
1698 while (pCurrEntry->pNext != NULL)
1699 pCurrEntry = pCurrEntry->pNext;
1700 pCurrEntry->pNext = pEntry;
1701 }
1702 }
1703 NdisReleaseSpinLock(&pAd->MacTabLock);
1704
1705
1706 // If WEP is enabled, add paiewise and shared key
1707#ifdef WPA_SUPPLICANT_SUPPORT
1708 if (((pAd->StaCfg.WpaSupplicantUP)&&
1709 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)&&
1710 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) ||
1711 ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)&&
1712 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)))
1713#else
1714 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
1715#endif // WPA_SUPPLICANT_SUPPORT //
1716 {
1717 PUCHAR Key;
1718 UCHAR CipherAlg;
1719
1720 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1721 {
1722 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1723 Key = pAd->SharedKey[BSS0][idx].Key;
1724
1725 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1726 {
1727 // Set key material and cipherAlg to Asic
1728 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1729
1730 if (idx == pAd->StaCfg.DefaultKeyId)
1731 {
1732 // Assign group key info
1733 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1734
1735 // Assign pairwise key info
1736 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, pEntry);
1737 }
1738 }
1739 }
1740 }
1741
1742 // only INFRASTRUCTURE mode need to indicate connectivity immediately; ADHOC mode
1743 // should wait until at least 2 active nodes in this BSSID.
1744 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1745
1746 // For GUI ++
1747 if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
1748 {
1749 pAd->IndicateMediaState = NdisMediaStateConnected;
1750 pAd->ExtraInfo = GENERAL_LINK_UP;
1751 RTMP_IndicateMediaState(pAd);
1752 }
1753 // --
1754
1755 // Add BSSID in my MAC Table.
1756 NdisAcquireSpinLock(&pAd->MacTabLock);
1757 RTMPMoveMemory(pAd->MacTab.Content[BSSID_WCID].Addr, pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1758 pAd->MacTab.Content[BSSID_WCID].Aid = BSSID_WCID;
1759 pAd->MacTab.Content[BSSID_WCID].pAd = pAd;
1760 pAd->MacTab.Content[BSSID_WCID].ValidAsCLI = TRUE; //Although this is bssid..still set ValidAsCl
1761 pAd->MacTab.Size = 1; // infra mode always set MACtab size =1.
1762 pAd->MacTab.Content[BSSID_WCID].Sst = SST_ASSOC;
1763 pAd->MacTab.Content[BSSID_WCID].AuthState = SST_ASSOC;
1764 pAd->MacTab.Content[BSSID_WCID].AuthMode = pAd->StaCfg.AuthMode;
1765 pAd->MacTab.Content[BSSID_WCID].WepStatus = pAd->StaCfg.WepStatus;
1766 NdisReleaseSpinLock(&pAd->MacTabLock);
1767
1768 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! ClientStatusFlags=%lx)\n",
1769 pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1770
1771 MlmeUpdateTxRates(pAd, TRUE, BSS0);
1772#ifdef DOT11_N_SUPPORT
1773 MlmeUpdateHtTxRates(pAd, BSS0);
1774 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !! (StaActive.bHtEnable =%d, )\n", pAd->StaActive.SupportedPhyInfo.bHtEnable));
1775#endif // DOT11_N_SUPPORT //
1776
1777 //
1778 // Report Adjacent AP report.
1779 //
1780#ifdef LEAP_SUPPORT
1781 CCXAdjacentAPReport(pAd);
1782#endif // LEAP_SUPPORT //
1783
1784 if (pAd->CommonCfg.bAggregationCapable)
1785 {
1786 if ((pAd->CommonCfg.bPiggyBackCapable) && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3)
1787 {
1788
1789 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
1790 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1791 RTMPSetPiggyBack(pAd, TRUE);
1792 DBGPRINT(RT_DEBUG_TRACE, ("Turn on Piggy-Back\n"));
1793 }
1794 else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
1795 {
1796 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1797 }
1798 }
1799
1800 if (pAd->MlmeAux.APRalinkIe != 0x0)
1801 {
1802#ifdef DOT11_N_SUPPORT
1803 if (CLIENT_STATUS_TEST_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RDG_CAPABLE))
1804 {
1805 AsicEnableRDG(pAd);
1806 }
1807#endif // DOT11_N_SUPPORT //
1808 OPSTATUS_SET_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1809 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1810 }
1811 else
1812 {
1813 OPSTATUS_CLEAR_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1814 CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1815 }
1816 }
1817
1818#ifdef DOT11_N_SUPPORT
1819 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_CONNECT Event B!.BACapability = %x. ClientStatusFlags = %lx\n", pAd->CommonCfg.BACapability.word, pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1820#endif // DOT11_N_SUPPORT //
1821
1822 // Set LED
1823 RTMPSetLED(pAd, LED_LINK_UP);
1824
1825 pAd->Mlme.PeriodicRound = 0;
1826 pAd->Mlme.OneSecPeriodicRound = 0;
1827 pAd->bConfigChanged = FALSE; // Reset config flag
1828 pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
1829
1830 // Set asic auto fall back
1831 {
1832 PUCHAR pTable;
1833 UCHAR TableSize = 0;
1834
1835 MlmeSelectTxRateTable(pAd, &pAd->MacTab.Content[BSSID_WCID], &pTable, &TableSize, &pAd->CommonCfg.TxRateIndex);
1836 AsicUpdateAutoFallBackTable(pAd, pTable);
1837 }
1838
1839 NdisAcquireSpinLock(&pAd->MacTabLock);
1840 pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1841 pEntry->MaxHTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1842 if (pAd->StaCfg.bAutoTxRateSwitch == FALSE)
1843 {
1844 pEntry->bAutoTxRateSwitch = FALSE;
1845#ifdef DOT11_N_SUPPORT
1846 if (pEntry->HTPhyMode.field.MCS == 32)
1847 pEntry->HTPhyMode.field.ShortGI = GI_800;
1848
1849 if ((pEntry->HTPhyMode.field.MCS > MCS_7) || (pEntry->HTPhyMode.field.MCS == 32))
1850 pEntry->HTPhyMode.field.STBC = STBC_NONE;
1851#endif // DOT11_N_SUPPORT //
1852 // If the legacy mode is set, overwrite the transmit setting of this entry.
1853 if (pEntry->HTPhyMode.field.MODE <= MODE_OFDM)
1854 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
1855 }
1856 else
1857 pEntry->bAutoTxRateSwitch = TRUE;
1858 NdisReleaseSpinLock(&pAd->MacTabLock);
1859
1860 // Let Link Status Page display first initial rate.
1861 pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
1862 // Select DAC according to HT or Legacy
1863 if (pAd->StaActive.SupportedPhyInfo.MCSSet[0] != 0x00)
1864 {
1865 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1866 Value &= (~0x18);
1867 if (pAd->Antenna.field.TxPath == 2)
1868 {
1869 Value |= 0x10;
1870 }
1871 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1872 }
1873 else
1874 {
1875 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1876 Value &= (~0x18);
1877 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1878 }
1879
1880#ifdef DOT11_N_SUPPORT
1881 if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
1882 {
1883 }
1884 else if (pEntry->MaxRAmpduFactor == 0)
1885 {
1886 // If HT AP doesn't support MaxRAmpduFactor = 1, we need to set max PSDU to 0.
1887 // Because our Init value is 1 at MACRegTable.
1888 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x0fff);
1889 }
1890#endif // DOT11_N_SUPPORT //
1891
1892 // Patch for Marvel AP to gain high throughput
1893 // Need to set as following,
1894 // 1. Set txop in register-EDCA_AC0_CFG as 0x60
1895 // 2. Set EnTXWriteBackDDONE in register-WPDMA_GLO_CFG as zero
1896 // 3. PBF_MAX_PCNT as 0x1F3FBF9F
1897 // 4. kick per two packets when dequeue
1898 //
1899 // Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable
1900 //
1901 // if 1. Legacy AP WMM on, or 2. 11n AP, AMPDU disable. Force turn off burst no matter what bEnableTxBurst is.
1902#ifdef DOT11_N_SUPPORT
1903// if ((!IS_RT30xx(pAd)) &&
1904 if (!((pAd->CommonCfg.RxStream == 1)&&(pAd->CommonCfg.TxStream == 1)) &&
1905 (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))
1906 || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE))))
1907 {
1908 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1909 Data &= 0xFFFFFF00;
1910 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1911
1912 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1913 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 1\n"));
1914 }
1915 else
1916#endif // DOT11_N_SUPPORT //
1917 if (pAd->CommonCfg.bEnableTxBurst)
1918 {
1919 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1920 Data &= 0xFFFFFF00;
1921 Data |= 0x60;
1922 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1923 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = TRUE;
1924
1925 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3FBF9F);
1926 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 2\n"));
1927 }
1928 else
1929 {
1930 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1931 Data &= 0xFFFFFF00;
1932 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1933
1934 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1935 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 3\n"));
1936 }
1937
1938#ifdef DOT11_N_SUPPORT
1939 // Re-check to turn on TX burst or not.
1940 if ((pAd->CommonCfg.IOTestParm.bLastAtheros == TRUE) && ((STA_WEP_ON(pAd))||(STA_TKIP_ON(pAd))))
1941 {
1942 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = TRUE;
1943 if (pAd->CommonCfg.bEnableTxBurst)
1944 {
1945 UINT32 MACValue = 0;
1946 // Force disable TXOP value in this case. The same action in MLMEUpdateProtect too.
1947 // I didn't change PBF_MAX_PCNT setting.
1948 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &MACValue);
1949 MACValue &= 0xFFFFFF00;
1950 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, MACValue);
1951 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
1952 }
1953 }
1954 else
1955 {
1956 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = FALSE;
1957 }
1958#endif // DOT11_N_SUPPORT //
1959
1960 pAd->CommonCfg.IOTestParm.bLastAtheros = FALSE;
1961 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1962 DBGPRINT(RT_DEBUG_TRACE, ("!!!pAd->bNextDisableRxBA= %d \n", pAd->CommonCfg.IOTestParm.bNextDisableRxBA));
1963 // BSSID add in one MAC entry too. Because in Tx, ASIC need to check Cipher and IV/EIV, BAbitmap
1964 // Pther information in MACTab.Content[BSSID_WCID] is not necessary for driver.
1965 // Note: As STA, The MACTab.Content[BSSID_WCID]. PairwiseKey and Shared Key for BSS0 are the same.
1966
1967 if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled)
1968 {
1969 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1970 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1971 }
1972
1973 NdisAcquireSpinLock(&pAd->MacTabLock);
1974 pEntry->PortSecured = pAd->StaCfg.PortSecured;
1975 NdisReleaseSpinLock(&pAd->MacTabLock);
1976
1977 //
1978 // Patch Atheros AP TX will breakdown issue.
1979 // AP Model: DLink DWL-8200AP
1980 //
1981 if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && STA_TKIP_ON(pAd))
1982 {
1983 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x01);
1984 }
1985 else
1986 {
1987 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x00);
1988 }
1989
1990 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1991
1992#ifdef DOT11_N_SUPPORT
1993#ifdef DOT11N_DRAFT3
1994 if ((pAd->CommonCfg.BACapability.field.b2040CoexistScanSup) && (pAd->CommonCfg.Channel <= 11))
1995 {
1996 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SCAN_2040);
1997 BuildEffectedChannelList(pAd);
1998 }
1999#endif // DOT11N_DRAFT3 //
2000#endif // DOT11_N_SUPPORT //
2001}
2002
2003/*
2004 ==========================================================================
2005
2006 Routine Description:
2007 Disconnect current BSSID
2008
2009 Arguments:
2010 pAd - Pointer to our adapter
2011 IsReqFromAP - Request from AP
2012
2013 Return Value:
2014 None
2015
2016 IRQL = DISPATCH_LEVEL
2017
2018 Note:
2019 We need more information to know it's this requst from AP.
2020 If yes! we need to do extra handling, for example, remove the WPA key.
2021 Otherwise on 4-way handshaking will faied, since the WPA key didn't be
2022 remove while auto reconnect.
2023 Disconnect request from AP, it means we will start afresh 4-way handshaking
2024 on WPA mode.
2025
2026 ==========================================================================
2027*/
2028VOID LinkDown(
2029 IN PRTMP_ADAPTER pAd,
2030 IN BOOLEAN IsReqFromAP)
2031{
2032 UCHAR i, ByteValue = 0;
2033
2034 // Do nothing if monitor mode is on
2035 if (MONITOR_ON(pAd))
2036 return;
2037
2038#ifdef RALINK_ATE
2039 // Nothing to do in ATE mode.
2040 if (ATE_ON(pAd))
2041 return;
2042#endif // RALINK_ATE //
2043
2044 if (pAd->CommonCfg.bWirelessEvent)
2045 {
2046 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
2047 }
2048
2049 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN !!!\n"));
2050 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
2051
2052 if (ADHOC_ON(pAd)) // Adhoc mode link down
2053 {
2054 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 1!!!\n"));
2055
2056 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
2057 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
2058 pAd->IndicateMediaState = NdisMediaStateDisconnected;
2059 RTMP_IndicateMediaState(pAd);
2060 pAd->ExtraInfo = GENERAL_LINK_DOWN;
2061 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
2062 DBGPRINT(RT_DEBUG_TRACE, ("!!! MacTab.Size=%d !!!\n", pAd->MacTab.Size));
2063 }
2064 else // Infra structure mode
2065 {
2066 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 2!!!\n"));
2067
2068#ifdef QOS_DLS_SUPPORT
2069 // DLS tear down frame must be sent before link down
2070 // send DLS-TEAR_DOWN message
2071 if (pAd->CommonCfg.bDLSCapable)
2072 {
2073 // tear down local dls table entry
2074 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
2075 {
2076 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
2077 {
2078 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
2079 RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
2080 }
2081 }
2082
2083 // tear down peer dls table entry
2084 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
2085 {
2086 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
2087 {
2088 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
2089 RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
2090 }
2091 }
2092 }
2093#endif // QOS_DLS_SUPPORT //
2094
2095 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
2096 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
2097
2098 // Saved last SSID for linkup comparison
2099 pAd->CommonCfg.LastSsidLen = pAd->CommonCfg.SsidLen;
2100 NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen);
2101 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
2102 if (pAd->MlmeAux.CurrReqIsFromNdis == TRUE)
2103 {
2104 pAd->IndicateMediaState = NdisMediaStateDisconnected;
2105 RTMP_IndicateMediaState(pAd);
2106 pAd->ExtraInfo = GENERAL_LINK_DOWN;
2107 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event A!\n"));
2108 pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
2109 }
2110 else
2111 {
2112 //
2113 // If disassociation request is from NDIS, then we don't need to delete BSSID from entry.
2114 // Otherwise lost beacon or receive De-Authentication from AP,
2115 // then we should delete BSSID from BssTable.
2116 // If we don't delete from entry, roaming will fail.
2117 //
2118 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
2119 }
2120
2121 // restore back to -
2122 // 1. long slot (20 us) or short slot (9 us) time
2123 // 2. turn on/off RTS/CTS and/or CTS-to-self protection
2124 // 3. short preamble
2125 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
2126
2127 if (pAd->StaCfg.CCXAdjacentAPReportFlag == TRUE)
2128 {
2129 //
2130 // Record current AP's information.
2131 // for later used reporting Adjacent AP report.
2132 //
2133 pAd->StaCfg.CCXAdjacentAPChannel = pAd->CommonCfg.Channel;
2134 pAd->StaCfg.CCXAdjacentAPSsidLen = pAd->CommonCfg.SsidLen;
2135 NdisMoveMemory(pAd->StaCfg.CCXAdjacentAPSsid, pAd->CommonCfg.Ssid, pAd->StaCfg.CCXAdjacentAPSsidLen);
2136 COPY_MAC_ADDR(pAd->StaCfg.CCXAdjacentAPBssid, pAd->CommonCfg.Bssid);
2137 }
2138
2139#ifdef EXT_BUILD_CHANNEL_LIST
2140 // Country IE of the AP will be evaluated and will be used.
2141 if (pAd->StaCfg.IEEE80211dClientMode != Rt802_11_D_None)
2142 {
2143 NdisMoveMemory(&pAd->CommonCfg.CountryCode[0], &pAd->StaCfg.StaOriCountryCode[0], 2);
2144 pAd->CommonCfg.Geography = pAd->StaCfg.StaOriGeography;
2145 BuildChannelListEx(pAd);
2146 }
2147#endif // EXT_BUILD_CHANNEL_LIST //
2148
2149 }
2150
2151 for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
2152 {
2153 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
2154 MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid, pAd->MacTab.Content[i].Addr);
2155 }
2156
2157 pAd->StaCfg.CCXQosECWMin = 4;
2158 pAd->StaCfg.CCXQosECWMax = 10;
2159
2160 AsicSetSlotTime(pAd, TRUE); //FALSE);
2161 AsicSetEdcaParm(pAd, NULL);
2162
2163 // Set LED
2164 RTMPSetLED(pAd, LED_LINK_DOWN);
2165 pAd->LedIndicatorStregth = 0xF0;
2166 RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, firmware is not done it.
2167
2168 AsicDisableSync(pAd);
2169
2170 pAd->Mlme.PeriodicRound = 0;
2171 pAd->Mlme.OneSecPeriodicRound = 0;
2172
2173 if (pAd->StaCfg.BssType == BSS_INFRA)
2174 {
2175 // Remove StaCfg Information after link down
2176 NdisZeroMemory(pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
2177 NdisZeroMemory(pAd->CommonCfg.Ssid, MAX_LEN_OF_SSID);
2178 pAd->CommonCfg.SsidLen = 0;
2179 }
2180#ifdef DOT11_N_SUPPORT
2181 NdisZeroMemory(&pAd->MlmeAux.HtCapability, sizeof(HT_CAPABILITY_IE));
2182 NdisZeroMemory(&pAd->MlmeAux.AddHtInfo, sizeof(ADD_HT_INFO_IE));
2183 pAd->MlmeAux.HtCapabilityLen = 0;
2184 pAd->MlmeAux.NewExtChannelOffset = 0xff;
2185#endif // DOT11_N_SUPPORT //
2186
2187 // Reset WPA-PSK state. Only reset when supplicant enabled
2188 if (pAd->StaCfg.WpaState != SS_NOTUSE)
2189 {
2190 pAd->StaCfg.WpaState = SS_START;
2191 // Clear Replay counter
2192 NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
2193
2194#ifdef QOS_DLS_SUPPORT
2195 if (pAd->CommonCfg.bDLSCapable)
2196 NdisZeroMemory(pAd->StaCfg.DlsReplayCounter, 8);
2197#endif // QOS_DLS_SUPPORT //
2198 }
2199
2200
2201 //
2202 // if link down come from AP, we need to remove all WPA keys on WPA mode.
2203 // otherwise will cause 4-way handshaking failed, since the WPA key not empty.
2204 //
2205 if ((IsReqFromAP) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
2206 {
2207 // Remove all WPA keys
2208 RTMPWPARemoveAllKeys(pAd);
2209 }
2210
2211 // 802.1x port control
2212#ifdef WPA_SUPPLICANT_SUPPORT
2213 // Prevent clear PortSecured here with static WEP
2214 // NetworkManger set security policy first then set SSID to connect AP.
2215 if (pAd->StaCfg.WpaSupplicantUP &&
2216 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
2217 (pAd->StaCfg.IEEE8021X == FALSE))
2218 {
2219 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2220 }
2221 else
2222#endif // WPA_SUPPLICANT_SUPPORT //
2223 {
2224 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
2225 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
2226 }
2227
2228 NdisAcquireSpinLock(&pAd->MacTabLock);
2229 pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured;
2230 NdisReleaseSpinLock(&pAd->MacTabLock);
2231
2232 pAd->StaCfg.MicErrCnt = 0;
2233
2234 // Turn off Ckip control flag
2235 pAd->StaCfg.bCkipOn = FALSE;
2236 pAd->StaCfg.CCXEnable = FALSE;
2237
2238 pAd->IndicateMediaState = NdisMediaStateDisconnected;
2239 // Update extra information to link is up
2240 pAd->ExtraInfo = GENERAL_LINK_DOWN;
2241
2242 //pAd->StaCfg.AdhocBOnlyJoined = FALSE;
2243 //pAd->StaCfg.AdhocBGJoined = FALSE;
2244 //pAd->StaCfg.Adhoc20NJoined = FALSE;
2245 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
2246
2247 // Reset the Current AP's IP address
2248 NdisZeroMemory(pAd->StaCfg.AironetIPAddress, 4);
2249#ifdef RT2870
2250 pAd->bUsbTxBulkAggre = FALSE;
2251#endif // RT2870 //
2252
2253 // Clean association information
2254 NdisZeroMemory(&pAd->StaCfg.AssocInfo, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION));
2255 pAd->StaCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
2256 pAd->StaCfg.ReqVarIELen = 0;
2257 pAd->StaCfg.ResVarIELen = 0;
2258
2259 //
2260 // Reset RSSI value after link down
2261 //
2262 pAd->StaCfg.RssiSample.AvgRssi0 = 0;
2263 pAd->StaCfg.RssiSample.AvgRssi0X8 = 0;
2264 pAd->StaCfg.RssiSample.AvgRssi1 = 0;
2265 pAd->StaCfg.RssiSample.AvgRssi1X8 = 0;
2266 pAd->StaCfg.RssiSample.AvgRssi2 = 0;
2267 pAd->StaCfg.RssiSample.AvgRssi2X8 = 0;
2268
2269 // Restore MlmeRate
2270 pAd->CommonCfg.MlmeRate = pAd->CommonCfg.BasicMlmeRate;
2271 pAd->CommonCfg.RtsRate = pAd->CommonCfg.BasicMlmeRate;
2272
2273#ifdef DOT11_N_SUPPORT
2274 //
2275 // After Link down, reset piggy-back setting in ASIC. Disable RDG.
2276 //
2277 if (pAd->CommonCfg.BBPCurrentBW == BW_40)
2278 {
2279 pAd->CommonCfg.BBPCurrentBW = BW_20;
2280 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &ByteValue);
2281 ByteValue &= (~0x18);
2282 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, ByteValue);
2283 }
2284#endif // DOT11_N_SUPPORT //
2285 // Reset DAC
2286 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &ByteValue);
2287 ByteValue &= (~0x18);
2288 if (pAd->Antenna.field.TxPath == 2)
2289 {
2290 ByteValue |= 0x10;
2291 }
2292 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, ByteValue);
2293
2294 RTMPSetPiggyBack(pAd,FALSE);
2295 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
2296
2297#ifdef DOT11_N_SUPPORT
2298 pAd->CommonCfg.BACapability.word = pAd->CommonCfg.REGBACapability.word;
2299#endif // DOT11_N_SUPPORT //
2300
2301 // Restore all settings in the following.
2302 AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT|CCKSETPROTECT|OFDMSETPROTECT), TRUE, FALSE);
2303 AsicDisableRDG(pAd);
2304 pAd->CommonCfg.IOTestParm.bCurrentAtheros = FALSE;
2305 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
2306
2307#ifdef DOT11_N_SUPPORT
2308#ifdef DOT11N_DRAFT3
2309 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SCAN_2040);
2310 pAd->CommonCfg.BSSCoexist2040.word = 0;
2311 TriEventInit(pAd);
2312 for (i = 0; i < (pAd->ChannelListNum - 1); i++)
2313 {
2314 pAd->ChannelList[i].bEffectedChannel = FALSE;
2315 }
2316#endif // DOT11N_DRAFT3 //
2317#endif // DOT11_N_SUPPORT //
2318
2319 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff);
2320 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
2321
2322#ifdef WPA_SUPPLICANT_SUPPORT
2323#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
2324 if (pAd->StaCfg.WpaSupplicantUP) {
2325 union iwreq_data wrqu;
2326 //send disassociate event to wpa_supplicant
2327 memset(&wrqu, 0, sizeof(wrqu));
2328 wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
2329 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
2330 }
2331#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2332#endif // WPA_SUPPLICANT_SUPPORT //
2333
2334#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
2335 {
2336 union iwreq_data wrqu;
2337 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
2338 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
2339 }
2340#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2341
2342#ifdef RT30xx
2343 if (IS_RT3090(pAd))
2344 {
2345 UINT32 macdata;
2346 // disable MMPS BBP control register
2347 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &ByteValue);
2348 ByteValue &= ~(0x04); //bit 2
2349 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, ByteValue);
2350
2351 // disable MMPS MAC control register
2352 RTMP_IO_READ32(pAd, 0x1210, &macdata);
2353 macdata &= ~(0x09); //bit 0, 3
2354 RTMP_IO_WRITE32(pAd, 0x1210, macdata);
2355 }
2356#endif // RT30xx //
2357
2358}
2359
2360/*
2361 ==========================================================================
2362 Description:
2363
2364 IRQL = DISPATCH_LEVEL
2365
2366 ==========================================================================
2367*/
2368VOID IterateOnBssTab(
2369 IN PRTMP_ADAPTER pAd)
2370{
2371 MLME_START_REQ_STRUCT StartReq;
2372 MLME_JOIN_REQ_STRUCT JoinReq;
2373 ULONG BssIdx;
2374
2375 // Change the wepstatus to original wepstatus
2376 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
2377 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
2378 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
2379
2380 BssIdx = pAd->MlmeAux.BssIdx;
2381 if (BssIdx < pAd->MlmeAux.SsidBssTab.BssNr)
2382 {
2383 // Check cipher suite, AP must have more secured cipher than station setting
2384 // Set the Pairwise and Group cipher to match the intended AP setting
2385 // We can only connect to AP with less secured cipher setting
2386 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
2387 {
2388 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.GroupCipher;
2389
2390 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher)
2391 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher;
2392 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
2393 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux;
2394 else // There is no PairCipher Aux, downgrade our capability to TKIP
2395 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2396 }
2397 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
2398 {
2399 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.GroupCipher;
2400
2401 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher)
2402 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher;
2403 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
2404 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux;
2405 else // There is no PairCipher Aux, downgrade our capability to TKIP
2406 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2407
2408 // RSN capability
2409 pAd->StaCfg.RsnCapability = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.RsnCapability;
2410 }
2411
2412 // Set Mix cipher flag
2413 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
2414 if (pAd->StaCfg.bMixCipher == TRUE)
2415 {
2416 // If mix cipher, re-build RSNIE
2417 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
2418 }
2419
2420 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.SsidBssTab.BssNr));
2421 JoinParmFill(pAd, &JoinReq, BssIdx);
2422 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT),
2423 &JoinReq);
2424 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
2425 }
2426 else if (pAd->StaCfg.BssType == BSS_ADHOC)
2427 {
2428 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
2429 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
2430 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
2431 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
2432 }
2433 else // no more BSS
2434 {
2435 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All roaming failed, stay @ ch #%d\n", pAd->CommonCfg.Channel));
2436 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2437 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2438 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2439 }
2440}
2441
2442// for re-association only
2443// IRQL = DISPATCH_LEVEL
2444VOID IterateOnBssTab2(
2445 IN PRTMP_ADAPTER pAd)
2446{
2447 MLME_REASSOC_REQ_STRUCT ReassocReq;
2448 ULONG BssIdx;
2449 BSS_ENTRY *pBss;
2450
2451 BssIdx = pAd->MlmeAux.RoamIdx;
2452 pBss = &pAd->MlmeAux.RoamTab.BssEntry[BssIdx];
2453
2454 if (BssIdx < pAd->MlmeAux.RoamTab.BssNr)
2455 {
2456 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.RoamTab.BssNr));
2457
2458 AsicSwitchChannel(pAd, pBss->Channel, FALSE);
2459 AsicLockChannel(pAd, pBss->Channel);
2460
2461 // reassociate message has the same structure as associate message
2462 AssocParmFill(pAd, &ReassocReq, pBss->Bssid, pBss->CapabilityInfo,
2463 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
2464 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
2465 sizeof(MLME_REASSOC_REQ_STRUCT), &ReassocReq);
2466
2467 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
2468 }
2469 else // no more BSS
2470 {
2471 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All fast roaming failed, back to ch #%d\n",pAd->CommonCfg.Channel));
2472 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2473 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2474 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2475 }
2476}
2477
2478/*
2479 ==========================================================================
2480 Description:
2481
2482 IRQL = DISPATCH_LEVEL
2483
2484 ==========================================================================
2485*/
2486VOID JoinParmFill(
2487 IN PRTMP_ADAPTER pAd,
2488 IN OUT MLME_JOIN_REQ_STRUCT *JoinReq,
2489 IN ULONG BssIdx)
2490{
2491 JoinReq->BssIdx = BssIdx;
2492}
2493
2494/*
2495 ==========================================================================
2496 Description:
2497
2498 IRQL = DISPATCH_LEVEL
2499
2500 ==========================================================================
2501*/
2502VOID ScanParmFill(
2503 IN PRTMP_ADAPTER pAd,
2504 IN OUT MLME_SCAN_REQ_STRUCT *ScanReq,
2505 IN CHAR Ssid[],
2506 IN UCHAR SsidLen,
2507 IN UCHAR BssType,
2508 IN UCHAR ScanType)
2509{
2510 NdisZeroMemory(ScanReq->Ssid, MAX_LEN_OF_SSID);
2511 ScanReq->SsidLen = SsidLen;
2512 NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen);
2513 ScanReq->BssType = BssType;
2514 ScanReq->ScanType = ScanType;
2515}
2516
2517#ifdef QOS_DLS_SUPPORT
2518/*
2519 ==========================================================================
2520 Description:
2521
2522 IRQL = DISPATCH_LEVEL
2523
2524 ==========================================================================
2525*/
2526VOID DlsParmFill(
2527 IN PRTMP_ADAPTER pAd,
2528 IN OUT MLME_DLS_REQ_STRUCT *pDlsReq,
2529 IN PRT_802_11_DLS pDls,
2530 IN USHORT reason)
2531{
2532 pDlsReq->pDLS = pDls;
2533 pDlsReq->Reason = reason;
2534}
2535#endif // QOS_DLS_SUPPORT //
2536
2537/*
2538 ==========================================================================
2539 Description:
2540
2541 IRQL = DISPATCH_LEVEL
2542
2543 ==========================================================================
2544*/
2545VOID StartParmFill(
2546 IN PRTMP_ADAPTER pAd,
2547 IN OUT MLME_START_REQ_STRUCT *StartReq,
2548 IN CHAR Ssid[],
2549 IN UCHAR SsidLen)
2550{
2551 ASSERT(SsidLen <= MAX_LEN_OF_SSID);
2552 NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen);
2553 StartReq->SsidLen = SsidLen;
2554}
2555
2556/*
2557 ==========================================================================
2558 Description:
2559
2560 IRQL = DISPATCH_LEVEL
2561
2562 ==========================================================================
2563*/
2564VOID AuthParmFill(
2565 IN PRTMP_ADAPTER pAd,
2566 IN OUT MLME_AUTH_REQ_STRUCT *AuthReq,
2567 IN PUCHAR pAddr,
2568 IN USHORT Alg)
2569{
2570 COPY_MAC_ADDR(AuthReq->Addr, pAddr);
2571 AuthReq->Alg = Alg;
2572 AuthReq->Timeout = AUTH_TIMEOUT;
2573}
2574
2575/*
2576 ==========================================================================
2577 Description:
2578
2579 IRQL = DISPATCH_LEVEL
2580
2581 ==========================================================================
2582 */
2583
2584
2585#ifdef RT2870
2586
2587VOID MlmeCntlConfirm(
2588 IN PRTMP_ADAPTER pAd,
2589 IN ULONG MsgType,
2590 IN USHORT Msg)
2591{
2592 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MsgType, sizeof(USHORT), &Msg);
2593}
2594
2595VOID ComposePsPoll(
2596 IN PRTMP_ADAPTER pAd)
2597{
2598 PTXINFO_STRUC pTxInfo;
2599 PTXWI_STRUC pTxWI;
2600
2601 DBGPRINT(RT_DEBUG_TRACE, ("ComposePsPoll\n"));
2602 NdisZeroMemory(&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
2603
2604 pAd->PsPollFrame.FC.PwrMgmt = 0;
2605 pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
2606 pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
2607 pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
2608 COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
2609 COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
2610
2611 RTMPZeroMemory(&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[0], 100);
2612 pTxInfo = (PTXINFO_STRUC)&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[0];
2613 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(PSPOLL_FRAME)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
2614 pTxWI = (PTXWI_STRUC)&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
2615 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(PSPOLL_FRAME)),
2616 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
2617 RTMPMoveMemory(&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[TXWI_SIZE+TXINFO_SIZE], &pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
2618 // Append 4 extra zero bytes.
2619 pAd->PsPollContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(PSPOLL_FRAME) + 4;
2620}
2621
2622// IRQL = DISPATCH_LEVEL
2623VOID ComposeNullFrame(
2624 IN PRTMP_ADAPTER pAd)
2625{
2626 PTXINFO_STRUC pTxInfo;
2627 PTXWI_STRUC pTxWI;
2628
2629 NdisZeroMemory(&pAd->NullFrame, sizeof(HEADER_802_11));
2630 pAd->NullFrame.FC.Type = BTYPE_DATA;
2631 pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
2632 pAd->NullFrame.FC.ToDs = 1;
2633 COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
2634 COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
2635 COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
2636 RTMPZeroMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[0], 100);
2637 pTxInfo = (PTXINFO_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[0];
2638 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(HEADER_802_11)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
2639 pTxWI = (PTXWI_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
2640 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(HEADER_802_11)),
2641 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
2642 RTMPMoveMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXWI_SIZE+TXINFO_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11));
2643 pAd->NullContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;
2644}
2645#endif // RT2870 //
2646
2647
2648/*
2649 ==========================================================================
2650 Description:
2651 Pre-build a BEACON frame in the shared memory
2652
2653 IRQL = PASSIVE_LEVEL
2654 IRQL = DISPATCH_LEVEL
2655
2656 ==========================================================================
2657*/
2658ULONG MakeIbssBeacon(
2659 IN PRTMP_ADAPTER pAd)
2660{
2661 UCHAR DsLen = 1, IbssLen = 2;
2662 UCHAR LocalErpIe[3] = {IE_ERP, 1, 0x04};
2663 HEADER_802_11 BcnHdr;
2664 USHORT CapabilityInfo;
2665 LARGE_INTEGER FakeTimestamp;
2666 ULONG FrameLen = 0;
2667 PTXWI_STRUC pTxWI = &pAd->BeaconTxWI;
2668 CHAR *pBeaconFrame = pAd->BeaconBuf;
2669 BOOLEAN Privacy;
2670 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
2671 UCHAR SupRateLen = 0;
2672 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
2673 UCHAR ExtRateLen = 0;
2674 UCHAR RSNIe = IE_WPA;
2675
2676 if ((pAd->CommonCfg.PhyMode == PHY_11B) && (pAd->CommonCfg.Channel <= 14))
2677 {
2678 SupRate[0] = 0x82; // 1 mbps
2679 SupRate[1] = 0x84; // 2 mbps
2680 SupRate[2] = 0x8b; // 5.5 mbps
2681 SupRate[3] = 0x96; // 11 mbps
2682 SupRateLen = 4;
2683 ExtRateLen = 0;
2684 }
2685 else if (pAd->CommonCfg.Channel > 14)
2686 {
2687 SupRate[0] = 0x8C; // 6 mbps, in units of 0.5 Mbps, basic rate
2688 SupRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2689 SupRate[2] = 0x98; // 12 mbps, in units of 0.5 Mbps, basic rate
2690 SupRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2691 SupRate[4] = 0xb0; // 24 mbps, in units of 0.5 Mbps, basic rate
2692 SupRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2693 SupRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2694 SupRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2695 SupRateLen = 8;
2696 ExtRateLen = 0;
2697
2698 //
2699 // Also Update MlmeRate & RtsRate for G only & A only
2700 //
2701 pAd->CommonCfg.MlmeRate = RATE_6;
2702 pAd->CommonCfg.RtsRate = RATE_6;
2703 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
2704 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2705 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
2706 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2707 }
2708 else
2709 {
2710 SupRate[0] = 0x82; // 1 mbps
2711 SupRate[1] = 0x84; // 2 mbps
2712 SupRate[2] = 0x8b; // 5.5 mbps
2713 SupRate[3] = 0x96; // 11 mbps
2714 SupRateLen = 4;
2715
2716 ExtRate[0] = 0x0C; // 6 mbps, in units of 0.5 Mbps,
2717 ExtRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2718 ExtRate[2] = 0x18; // 12 mbps, in units of 0.5 Mbps,
2719 ExtRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2720 ExtRate[4] = 0x30; // 24 mbps, in units of 0.5 Mbps,
2721 ExtRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2722 ExtRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2723 ExtRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2724 ExtRateLen = 8;
2725 }
2726
2727 pAd->StaActive.SupRateLen = SupRateLen;
2728 NdisMoveMemory(pAd->StaActive.SupRate, SupRate, SupRateLen);
2729 pAd->StaActive.ExtRateLen = ExtRateLen;
2730 NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, ExtRateLen);
2731
2732 // compose IBSS beacon frame
2733 MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, pAd->CommonCfg.Bssid);
2734 Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
2735 (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
2736 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
2737 CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
2738
2739 MakeOutgoingFrame(pBeaconFrame, &FrameLen,
2740 sizeof(HEADER_802_11), &BcnHdr,
2741 TIMESTAMP_LEN, &FakeTimestamp,
2742 2, &pAd->CommonCfg.BeaconPeriod,
2743 2, &CapabilityInfo,
2744 1, &SsidIe,
2745 1, &pAd->CommonCfg.SsidLen,
2746 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
2747 1, &SupRateIe,
2748 1, &SupRateLen,
2749 SupRateLen, SupRate,
2750 1, &DsIe,
2751 1, &DsLen,
2752 1, &pAd->CommonCfg.Channel,
2753 1, &IbssIe,
2754 1, &IbssLen,
2755 2, &pAd->StaActive.AtimWin,
2756 END_OF_ARGS);
2757
2758 // add ERP_IE and EXT_RAE IE of in 802.11g
2759 if (ExtRateLen)
2760 {
2761 ULONG tmp;
2762
2763 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2764 3, LocalErpIe,
2765 1, &ExtRateIe,
2766 1, &ExtRateLen,
2767 ExtRateLen, ExtRate,
2768 END_OF_ARGS);
2769 FrameLen += tmp;
2770 }
2771
2772 // If adhoc secruity is set for WPA-None, append the cipher suite IE
2773 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
2774 {
2775 ULONG tmp;
2776 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
2777
2778 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2779 1, &RSNIe,
2780 1, &pAd->StaCfg.RSNIE_Len,
2781 pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
2782 END_OF_ARGS);
2783 FrameLen += tmp;
2784 }
2785
2786#ifdef DOT11_N_SUPPORT
2787 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
2788 {
2789 ULONG TmpLen;
2790 UCHAR HtLen, HtLen1;
2791
2792#ifdef RT_BIG_ENDIAN
2793 HT_CAPABILITY_IE HtCapabilityTmp;
2794 ADD_HT_INFO_IE addHTInfoTmp;
2795 USHORT b2lTmp, b2lTmp2;
2796#endif
2797
2798 // add HT Capability IE
2799 HtLen = sizeof(pAd->CommonCfg.HtCapability);
2800 HtLen1 = sizeof(pAd->CommonCfg.AddHTInfo);
2801#ifndef RT_BIG_ENDIAN
2802 MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
2803 1, &HtCapIe,
2804 1, &HtLen,
2805 HtLen, &pAd->CommonCfg.HtCapability,
2806 1, &AddHtInfoIe,
2807 1, &HtLen1,
2808 HtLen1, &pAd->CommonCfg.AddHTInfo,
2809 END_OF_ARGS);
2810#else
2811 NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
2812 *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
2813 *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
2814
2815 NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, HtLen1);
2816 *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2));
2817 *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3));
2818
2819 MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
2820 1, &HtCapIe,
2821 1, &HtLen,
2822 HtLen, &HtCapabilityTmp,
2823 1, &AddHtInfoIe,
2824 1, &HtLen1,
2825 HtLen1, &addHTInfoTmp,
2826 END_OF_ARGS);
2827#endif
2828 FrameLen += TmpLen;
2829 }
2830#endif // DOT11_N_SUPPORT //
2831
2832 //beacon use reserved WCID 0xff
2833 if (pAd->CommonCfg.Channel > 14)
2834 {
2835 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2836 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
2837 }
2838 else
2839 {
2840 // Set to use 1Mbps for Adhoc beacon.
2841 HTTRANSMIT_SETTING Transmit;
2842 Transmit.word = 0;
2843 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2844 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &Transmit);
2845 }
2846
2847#ifdef RT_BIG_ENDIAN
2848 RTMPFrameEndianChange(pAd, pBeaconFrame, DIR_WRITE, FALSE);
2849 RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
2850#endif
2851
2852 DBGPRINT(RT_DEBUG_TRACE, ("MakeIbssBeacon (len=%ld), SupRateLen=%d, ExtRateLen=%d, Channel=%d, PhyMode=%d\n",
2853 FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel, pAd->CommonCfg.PhyMode));
2854 return FrameLen;
2855}
2856
2857
diff --git a/drivers/staging/rt3070/sta/dls.c b/drivers/staging/rt3070/sta/dls.c
new file mode 100644
index 000000000000..8bcd41329343
--- /dev/null
+++ b/drivers/staging/rt3070/sta/dls.c
@@ -0,0 +1,2170 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 dls.c
29
30 Abstract:
31 Handle WMM-DLS state machine
32
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36 Rory Chen 02-14-2006
37 Arvin Tai 06-03-2008 Modified for RT28xx
38 */
39
40#include "../rt_config.h"
41
42/*
43 ==========================================================================
44 Description:
45 dls state machine init, including state transition and timer init
46 Parameters:
47 Sm - pointer to the dls state machine
48 Note:
49 The state machine looks like this
50
51 DLS_IDLE
52 MT2_MLME_DLS_REQUEST MlmeDlsReqAction
53 MT2_PEER_DLS_REQUEST PeerDlsReqAction
54 MT2_PEER_DLS_RESPONSE PeerDlsRspAction
55 MT2_MLME_DLS_TEARDOWN MlmeTearDownAction
56 MT2_PEER_DLS_TEARDOWN PeerTearDownAction
57
58 IRQL = PASSIVE_LEVEL
59
60 ==========================================================================
61 */
62void DlsStateMachineInit(
63 IN PRTMP_ADAPTER pAd,
64 IN STATE_MACHINE *Sm,
65 OUT STATE_MACHINE_FUNC Trans[])
66{
67 UCHAR i;
68
69 StateMachineInit(Sm, (STATE_MACHINE_FUNC*)Trans, MAX_DLS_STATE, MAX_DLS_MSG, (STATE_MACHINE_FUNC)Drop, DLS_IDLE, DLS_MACHINE_BASE);
70
71 // the first column
72 StateMachineSetAction(Sm, DLS_IDLE, MT2_MLME_DLS_REQ, (STATE_MACHINE_FUNC)MlmeDlsReqAction);
73 StateMachineSetAction(Sm, DLS_IDLE, MT2_PEER_DLS_REQ, (STATE_MACHINE_FUNC)PeerDlsReqAction);
74 StateMachineSetAction(Sm, DLS_IDLE, MT2_PEER_DLS_RSP, (STATE_MACHINE_FUNC)PeerDlsRspAction);
75 StateMachineSetAction(Sm, DLS_IDLE, MT2_MLME_DLS_TEAR_DOWN, (STATE_MACHINE_FUNC)MlmeDlsTearDownAction);
76 StateMachineSetAction(Sm, DLS_IDLE, MT2_PEER_DLS_TEAR_DOWN, (STATE_MACHINE_FUNC)PeerDlsTearDownAction);
77
78 for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
79 {
80 pAd->StaCfg.DLSEntry[i].pAd = pAd;
81 RTMPInitTimer(pAd, &pAd->StaCfg.DLSEntry[i].Timer, GET_TIMER_FUNCTION(DlsTimeoutAction), pAd, FALSE);
82 }
83}
84
85/*
86 ==========================================================================
87 Description:
88
89 IRQL = DISPATCH_LEVEL
90
91 ==========================================================================
92 */
93VOID MlmeDlsReqAction(
94 IN PRTMP_ADAPTER pAd,
95 IN MLME_QUEUE_ELEM *Elem)
96{
97 PUCHAR pOutBuffer = NULL;
98 NDIS_STATUS NStatus;
99 ULONG FrameLen = 0;
100 HEADER_802_11 DlsReqHdr;
101 PRT_802_11_DLS pDLS = NULL;
102 UCHAR Category = CATEGORY_DLS;
103 UCHAR Action = ACTION_DLS_REQUEST;
104 ULONG tmp;
105 USHORT reason;
106 ULONG Timeout;
107 BOOLEAN TimerCancelled;
108
109 if(!MlmeDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, &pDLS, &reason))
110 return;
111
112 DBGPRINT(RT_DEBUG_TRACE,("DLS - MlmeDlsReqAction() \n"));
113
114 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
115 if (NStatus != NDIS_STATUS_SUCCESS)
116 {
117 DBGPRINT(RT_DEBUG_ERROR,("DLS - MlmeDlsReqAction() allocate memory failed \n"));
118 return;
119 }
120
121 ActHeaderInit(pAd, &DlsReqHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
122
123 // Build basic frame first
124 MakeOutgoingFrame(pOutBuffer, &FrameLen,
125 sizeof(HEADER_802_11), &DlsReqHdr,
126 1, &Category,
127 1, &Action,
128 6, &pDLS->MacAddr,
129 6, pAd->CurrentAddress,
130 2, &pAd->StaActive.CapabilityInfo,
131 2, &pDLS->TimeOut,
132 1, &SupRateIe,
133 1, &pAd->MlmeAux.SupRateLen,
134 pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate,
135 END_OF_ARGS);
136
137 if (pAd->MlmeAux.ExtRateLen != 0)
138 {
139 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
140 1, &ExtRateIe,
141 1, &pAd->MlmeAux.ExtRateLen,
142 pAd->MlmeAux.ExtRateLen, pAd->MlmeAux.ExtRate,
143 END_OF_ARGS);
144 FrameLen += tmp;
145 }
146
147#ifdef DOT11_N_SUPPORT
148 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
149 {
150 UCHAR HtLen;
151
152#ifdef RT_BIG_ENDIAN
153 HT_CAPABILITY_IE HtCapabilityTmp;
154#endif
155
156 // add HT Capability IE
157 HtLen = sizeof(HT_CAPABILITY_IE);
158#ifndef RT_BIG_ENDIAN
159 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
160 1, &HtCapIe,
161 1, &HtLen,
162 HtLen, &pAd->CommonCfg.HtCapability,
163 END_OF_ARGS);
164#else
165 NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
166 *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
167 *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
168
169 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
170 1, &HtCapIe,
171 1, &HtLen,
172 HtLen, &HtCapabilityTmp,
173 END_OF_ARGS);
174#endif
175 FrameLen = FrameLen + tmp;
176 }
177#endif // DOT11_N_SUPPORT //
178
179 RTMPCancelTimer(&pDLS->Timer, &TimerCancelled);
180 Timeout = DLS_TIMEOUT;
181 RTMPSetTimer(&pDLS->Timer, Timeout);
182
183 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
184 MlmeFreeMemory(pAd, pOutBuffer);
185}
186
187/*
188 ==========================================================================
189 Description:
190
191 IRQL = DISPATCH_LEVEL
192
193 ==========================================================================
194 */
195VOID PeerDlsReqAction(
196 IN PRTMP_ADAPTER pAd,
197 IN MLME_QUEUE_ELEM *Elem)
198{
199 PUCHAR pOutBuffer = NULL;
200 NDIS_STATUS NStatus;
201 ULONG FrameLen = 0;
202 USHORT StatusCode = MLME_SUCCESS;
203 HEADER_802_11 DlsRspHdr;
204 UCHAR Category = CATEGORY_DLS;
205 UCHAR Action = ACTION_DLS_RESPONSE;
206 ULONG tmp;
207 USHORT CapabilityInfo;
208 UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN];
209 USHORT DLSTimeOut;
210 SHORT i;
211 ULONG Timeout;
212 BOOLEAN TimerCancelled;
213 PRT_802_11_DLS pDLS = NULL;
214 UCHAR MaxSupportedRateIn500Kbps = 0;
215 UCHAR SupportedRatesLen;
216 UCHAR SupportedRates[MAX_LEN_OF_SUPPORTED_RATES];
217 UCHAR HtCapabilityLen;
218 HT_CAPABILITY_IE HtCapability;
219
220 if (!PeerDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, DA, SA, &CapabilityInfo, &DLSTimeOut,
221 &SupportedRatesLen, &SupportedRates[0], &HtCapabilityLen, &HtCapability))
222 return;
223
224 // supported rates array may not be sorted. sort it and find the maximum rate
225 for (i = 0; i < SupportedRatesLen; i++)
226 {
227 if (MaxSupportedRateIn500Kbps < (SupportedRates[i] & 0x7f))
228 MaxSupportedRateIn500Kbps = SupportedRates[i] & 0x7f;
229 }
230
231 DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsReqAction() from %02x:%02x:%02x:%02x:%02x:%02x\n", SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
232
233 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
234 if (NStatus != NDIS_STATUS_SUCCESS)
235 {
236 DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsReqAction() allocate memory failed \n"));
237 return;
238 }
239
240 if (!INFRA_ON(pAd))
241 {
242 StatusCode = MLME_REQUEST_DECLINED;
243 }
244 else if (!pAd->CommonCfg.bWmmCapable)
245 {
246 StatusCode = MLME_DEST_STA_IS_NOT_A_QSTA;
247 }
248 else if (!pAd->CommonCfg.bDLSCapable)
249 {
250 StatusCode = MLME_REQUEST_DECLINED;
251 }
252 else
253 {
254 // find table to update parameters
255 for (i = (MAX_NUM_OF_DLS_ENTRY-1); i >= 0; i--)
256 {
257 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
258 {
259 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
260 pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
261 else
262 {
263 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
264 pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
265 }
266
267 pAd->StaCfg.DLSEntry[i].Sequence = 0;
268 pAd->StaCfg.DLSEntry[i].TimeOut = DLSTimeOut;
269 pAd->StaCfg.DLSEntry[i].CountDownTimer = DLSTimeOut;
270 if (HtCapabilityLen != 0)
271 pAd->StaCfg.DLSEntry[i].bHTCap = TRUE;
272 else
273 pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
274 pDLS = &pAd->StaCfg.DLSEntry[i];
275 break;
276 }
277 }
278
279 // can not find in table, create a new one
280 if (i < 0)
281 {
282 DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsReqAction() can not find same entry \n"));
283 for (i=(MAX_NUM_OF_DLS_ENTRY - 1); i >= MAX_NUM_OF_INIT_DLS_ENTRY; i--)
284 {
285 if (!pAd->StaCfg.DLSEntry[i].Valid)
286 {
287 MAC_TABLE_ENTRY *pEntry;
288 UCHAR MaxSupportedRate = RATE_11;
289
290 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
291 {
292 pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
293 }
294 else
295 {
296 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
297 pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
298 }
299
300 pAd->StaCfg.DLSEntry[i].Sequence = 0;
301 pAd->StaCfg.DLSEntry[i].Valid = TRUE;
302 pAd->StaCfg.DLSEntry[i].TimeOut = DLSTimeOut;
303 pAd->StaCfg.DLSEntry[i].CountDownTimer = DLSTimeOut;
304 NdisMoveMemory(pAd->StaCfg.DLSEntry[i].MacAddr, SA, MAC_ADDR_LEN);
305 if (HtCapabilityLen != 0)
306 pAd->StaCfg.DLSEntry[i].bHTCap = TRUE;
307 else
308 pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
309 pDLS = &pAd->StaCfg.DLSEntry[i];
310 pEntry = MacTableInsertDlsEntry(pAd, SA, i);
311
312 switch (MaxSupportedRateIn500Kbps)
313 {
314 case 108: MaxSupportedRate = RATE_54; break;
315 case 96: MaxSupportedRate = RATE_48; break;
316 case 72: MaxSupportedRate = RATE_36; break;
317 case 48: MaxSupportedRate = RATE_24; break;
318 case 36: MaxSupportedRate = RATE_18; break;
319 case 24: MaxSupportedRate = RATE_12; break;
320 case 18: MaxSupportedRate = RATE_9; break;
321 case 12: MaxSupportedRate = RATE_6; break;
322 case 22: MaxSupportedRate = RATE_11; break;
323 case 11: MaxSupportedRate = RATE_5_5; break;
324 case 4: MaxSupportedRate = RATE_2; break;
325 case 2: MaxSupportedRate = RATE_1; break;
326 default: MaxSupportedRate = RATE_11; break;
327 }
328
329 pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate);
330
331 if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
332 {
333 pEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
334 pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
335 pEntry->MinHTPhyMode.field.MODE = MODE_CCK;
336 pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
337 pEntry->HTPhyMode.field.MODE = MODE_CCK;
338 pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate;
339 }
340 else
341 {
342 pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
343 pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
344 pEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
345 pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
346 pEntry->HTPhyMode.field.MODE = MODE_OFDM;
347 pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
348 }
349
350 pEntry->MaxHTPhyMode.field.BW = BW_20;
351 pEntry->MinHTPhyMode.field.BW = BW_20;
352
353#ifdef DOT11_N_SUPPORT
354 pEntry->HTCapability.MCSSet[0] = 0;
355 pEntry->HTCapability.MCSSet[1] = 0;
356
357 // If this Entry supports 802.11n, upgrade to HT rate.
358 if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
359 {
360 UCHAR j, bitmask; //k,bitmask;
361 CHAR ii;
362
363 if ((HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
364 {
365 pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
366 }
367 else
368 {
369 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
370 pAd->MacTab.fAnyStationNonGF = TRUE;
371 pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
372 }
373
374 if ((HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
375 {
376 pEntry->MaxHTPhyMode.field.BW= BW_40;
377 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(HtCapability.HtCapInfo.ShortGIfor40));
378 }
379 else
380 {
381 pEntry->MaxHTPhyMode.field.BW = BW_20;
382 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(HtCapability.HtCapInfo.ShortGIfor20));
383 pAd->MacTab.fAnyStation20Only = TRUE;
384 }
385
386 // find max fixed rate
387 for (ii=15; ii>=0; ii--)
388 {
389 j = ii/8;
390 bitmask = (1<<(ii-(j*8)));
391 if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask))
392 {
393 pEntry->MaxHTPhyMode.field.MCS = ii;
394 break;
395 }
396 if (ii==0)
397 break;
398 }
399
400
401 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
402 {
403
404 printk("@@@ pAd->CommonCfg.RegTransmitSetting.field.MCS = %d\n",
405 pAd->StaCfg.DesiredTransmitSetting.field.MCS);
406 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
407 {
408 // Fix MCS as HT Duplicated Mode
409 pEntry->MaxHTPhyMode.field.BW = 1;
410 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
411 pEntry->MaxHTPhyMode.field.STBC = 0;
412 pEntry->MaxHTPhyMode.field.ShortGI = 0;
413 pEntry->MaxHTPhyMode.field.MCS = 32;
414 }
415 else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
416 {
417 // STA supports fixed MCS
418 pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
419 }
420 }
421
422 pEntry->MaxHTPhyMode.field.STBC = (HtCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
423 pEntry->MpduDensity = HtCapability.HtCapParm.MpduDensity;
424 pEntry->MaxRAmpduFactor = HtCapability.HtCapParm.MaxRAmpduFactor;
425 pEntry->MmpsMode = (UCHAR)HtCapability.HtCapInfo.MimoPs;
426 pEntry->AMsduSize = (UCHAR)HtCapability.HtCapInfo.AMsduSize;
427 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
428
429 if (HtCapability.HtCapInfo.ShortGIfor20)
430 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
431 if (HtCapability.HtCapInfo.ShortGIfor40)
432 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
433 if (HtCapability.HtCapInfo.TxSTBC)
434 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
435 if (HtCapability.HtCapInfo.RxSTBC)
436 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
437 if (HtCapability.ExtHtCapInfo.PlusHTC)
438 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
439 if (pAd->CommonCfg.bRdg && HtCapability.ExtHtCapInfo.RDGSupport)
440 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
441 if (HtCapability.ExtHtCapInfo.MCSFeedback == 0x03)
442 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
443
444 NdisMoveMemory(&pEntry->HTCapability, &HtCapability, sizeof(HT_CAPABILITY_IE));
445 }
446#endif // DOT11_N_SUPPORT //
447
448 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
449 pEntry->CurrTxRate = pEntry->MaxSupportedRate;
450 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
451
452 if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
453 {
454 PUCHAR pTable;
455 UCHAR TableSize = 0;
456
457 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
458 pEntry->bAutoTxRateSwitch = TRUE;
459 }
460 else
461 {
462 pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
463 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
464 pEntry->bAutoTxRateSwitch = FALSE;
465
466 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
467 }
468 pEntry->RateLen = SupportedRatesLen;
469
470 break;
471 }
472 }
473 }
474 StatusCode = MLME_SUCCESS;
475
476 // can not find in table, create a new one
477 if (i < 0)
478 {
479 StatusCode = MLME_QOS_UNSPECIFY;
480 DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsReqAction() DLSEntry table full(only can support %d DLS session) \n", MAX_NUM_OF_DLS_ENTRY - MAX_NUM_OF_INIT_DLS_ENTRY));
481 }
482 else
483 {
484 DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsReqAction() use entry(%d) %02x:%02x:%02x:%02x:%02x:%02x\n",
485 i, SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
486 }
487 }
488
489 ActHeaderInit(pAd, &DlsRspHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
490
491 // Build basic frame first
492 if (StatusCode == MLME_SUCCESS)
493 {
494 MakeOutgoingFrame(pOutBuffer, &FrameLen,
495 sizeof(HEADER_802_11), &DlsRspHdr,
496 1, &Category,
497 1, &Action,
498 2, &StatusCode,
499 6, SA,
500 6, pAd->CurrentAddress,
501 2, &pAd->StaActive.CapabilityInfo,
502 1, &SupRateIe,
503 1, &pAd->MlmeAux.SupRateLen,
504 pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate,
505 END_OF_ARGS);
506
507 if (pAd->MlmeAux.ExtRateLen != 0)
508 {
509 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
510 1, &ExtRateIe,
511 1, &pAd->MlmeAux.ExtRateLen,
512 pAd->MlmeAux.ExtRateLen, pAd->MlmeAux.ExtRate,
513 END_OF_ARGS);
514 FrameLen += tmp;
515 }
516
517#ifdef DOT11_N_SUPPORT
518 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
519 {
520 UCHAR HtLen;
521
522#ifdef RT_BIG_ENDIAN
523 HT_CAPABILITY_IE HtCapabilityTmp;
524#endif
525
526 // add HT Capability IE
527 HtLen = sizeof(HT_CAPABILITY_IE);
528#ifndef RT_BIG_ENDIAN
529 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
530 1, &HtCapIe,
531 1, &HtLen,
532 HtLen, &pAd->CommonCfg.HtCapability,
533 END_OF_ARGS);
534#else
535 NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
536 *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
537 *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
538
539 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
540 1, &HtCapIe,
541 1, &HtLen,
542 HtLen, &HtCapabilityTmp,
543 END_OF_ARGS);
544#endif
545 FrameLen = FrameLen + tmp;
546 }
547#endif // DOT11_N_SUPPORT //
548
549 if (pDLS && (pDLS->Status != DLS_FINISH))
550 {
551 RTMPCancelTimer(&pDLS->Timer, &TimerCancelled);
552 Timeout = DLS_TIMEOUT;
553 RTMPSetTimer(&pDLS->Timer, Timeout);
554 }
555 }
556 else
557 {
558 MakeOutgoingFrame(pOutBuffer, &FrameLen,
559 sizeof(HEADER_802_11), &DlsRspHdr,
560 1, &Category,
561 1, &Action,
562 2, &StatusCode,
563 6, SA,
564 6, pAd->CurrentAddress,
565 END_OF_ARGS);
566 }
567
568 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
569 MlmeFreeMemory(pAd, pOutBuffer);
570}
571
572/*
573 ==========================================================================
574 Description:
575
576 IRQL = DISPATCH_LEVEL
577
578 ==========================================================================
579 */
580VOID PeerDlsRspAction(
581 IN PRTMP_ADAPTER pAd,
582 IN MLME_QUEUE_ELEM *Elem)
583{
584 USHORT CapabilityInfo;
585 UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN];
586 USHORT StatusCode;
587 SHORT i;
588 BOOLEAN TimerCancelled;
589 UCHAR MaxSupportedRateIn500Kbps = 0;
590 UCHAR SupportedRatesLen;
591 UCHAR SupportedRates[MAX_LEN_OF_SUPPORTED_RATES];
592 UCHAR HtCapabilityLen;
593 HT_CAPABILITY_IE HtCapability;
594
595 if (!pAd->CommonCfg.bDLSCapable)
596 return;
597
598 if (!INFRA_ON(pAd))
599 return;
600
601 if (!PeerDlsRspSanity(pAd, Elem->Msg, Elem->MsgLen, DA, SA, &CapabilityInfo, &StatusCode,
602 &SupportedRatesLen, &SupportedRates[0], &HtCapabilityLen, &HtCapability))
603 return;
604
605 // supported rates array may not be sorted. sort it and find the maximum rate
606 for (i=0; i<SupportedRatesLen; i++)
607 {
608 if (MaxSupportedRateIn500Kbps < (SupportedRates[i] & 0x7f))
609 MaxSupportedRateIn500Kbps = SupportedRates[i] & 0x7f;
610 }
611
612 DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsRspAction() from %02x:%02x:%02x:%02x:%02x:%02x with StatusCode=%d, CapabilityInfo=0x%x\n",
613 SA[0], SA[1], SA[2], SA[3], SA[4], SA[5], StatusCode, CapabilityInfo));
614
615 for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
616 {
617 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
618 {
619 if (StatusCode == MLME_SUCCESS)
620 {
621 MAC_TABLE_ENTRY *pEntry;
622 UCHAR MaxSupportedRate = RATE_11;
623
624 pEntry = MacTableInsertDlsEntry(pAd, SA, i);
625
626 switch (MaxSupportedRateIn500Kbps)
627 {
628 case 108: MaxSupportedRate = RATE_54; break;
629 case 96: MaxSupportedRate = RATE_48; break;
630 case 72: MaxSupportedRate = RATE_36; break;
631 case 48: MaxSupportedRate = RATE_24; break;
632 case 36: MaxSupportedRate = RATE_18; break;
633 case 24: MaxSupportedRate = RATE_12; break;
634 case 18: MaxSupportedRate = RATE_9; break;
635 case 12: MaxSupportedRate = RATE_6; break;
636 case 22: MaxSupportedRate = RATE_11; break;
637 case 11: MaxSupportedRate = RATE_5_5; break;
638 case 4: MaxSupportedRate = RATE_2; break;
639 case 2: MaxSupportedRate = RATE_1; break;
640 default: MaxSupportedRate = RATE_11; break;
641 }
642
643 pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate);
644
645 if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
646 {
647 pEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
648 pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
649 pEntry->MinHTPhyMode.field.MODE = MODE_CCK;
650 pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
651 pEntry->HTPhyMode.field.MODE = MODE_CCK;
652 pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate;
653 }
654 else
655 {
656 pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
657 pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
658 pEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
659 pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
660 pEntry->HTPhyMode.field.MODE = MODE_OFDM;
661 pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
662 }
663
664 pEntry->MaxHTPhyMode.field.BW = BW_20;
665 pEntry->MinHTPhyMode.field.BW = BW_20;
666
667#ifdef DOT11_N_SUPPORT
668 pEntry->HTCapability.MCSSet[0] = 0;
669 pEntry->HTCapability.MCSSet[1] = 0;
670
671 // If this Entry supports 802.11n, upgrade to HT rate.
672 if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
673 {
674 UCHAR j, bitmask; //k,bitmask;
675 CHAR ii;
676
677 if ((HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
678 {
679 pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
680 }
681 else
682 {
683 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
684 pAd->MacTab.fAnyStationNonGF = TRUE;
685 pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
686 }
687
688 if ((HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
689 {
690 pEntry->MaxHTPhyMode.field.BW= BW_40;
691 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(HtCapability.HtCapInfo.ShortGIfor40));
692 }
693 else
694 {
695 pEntry->MaxHTPhyMode.field.BW = BW_20;
696 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(HtCapability.HtCapInfo.ShortGIfor20));
697 pAd->MacTab.fAnyStation20Only = TRUE;
698 }
699
700 // find max fixed rate
701 for (ii=15; ii>=0; ii--)
702 {
703 j = ii/8;
704 bitmask = (1<<(ii-(j*8)));
705 if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask))
706 {
707 pEntry->MaxHTPhyMode.field.MCS = ii;
708 break;
709 }
710 if (ii==0)
711 break;
712 }
713
714 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
715 {
716 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
717 {
718 // Fix MCS as HT Duplicated Mode
719 pEntry->MaxHTPhyMode.field.BW = 1;
720 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
721 pEntry->MaxHTPhyMode.field.STBC = 0;
722 pEntry->MaxHTPhyMode.field.ShortGI = 0;
723 pEntry->MaxHTPhyMode.field.MCS = 32;
724 }
725 else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
726 {
727 // STA supports fixed MCS
728 pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
729 }
730 }
731
732 pEntry->MaxHTPhyMode.field.STBC = (HtCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
733 pEntry->MpduDensity = HtCapability.HtCapParm.MpduDensity;
734 pEntry->MaxRAmpduFactor = HtCapability.HtCapParm.MaxRAmpduFactor;
735 pEntry->MmpsMode = (UCHAR)HtCapability.HtCapInfo.MimoPs;
736 pEntry->AMsduSize = (UCHAR)HtCapability.HtCapInfo.AMsduSize;
737 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
738
739 if (HtCapability.HtCapInfo.ShortGIfor20)
740 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
741 if (HtCapability.HtCapInfo.ShortGIfor40)
742 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
743 if (HtCapability.HtCapInfo.TxSTBC)
744 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
745 if (HtCapability.HtCapInfo.RxSTBC)
746 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
747 if (HtCapability.ExtHtCapInfo.PlusHTC)
748 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
749 if (pAd->CommonCfg.bRdg && HtCapability.ExtHtCapInfo.RDGSupport)
750 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
751 if (HtCapability.ExtHtCapInfo.MCSFeedback == 0x03)
752 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
753
754 NdisMoveMemory(&pEntry->HTCapability, &HtCapability, sizeof(HT_CAPABILITY_IE));
755 }
756#endif // DOT11_N_SUPPORT //
757 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
758 pEntry->CurrTxRate = pEntry->MaxSupportedRate;
759 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
760
761 if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
762 {
763 PUCHAR pTable;
764 UCHAR TableSize = 0;
765
766 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
767 pEntry->bAutoTxRateSwitch = TRUE;
768 }
769 else
770 {
771 pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
772 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
773 pEntry->bAutoTxRateSwitch = FALSE;
774
775 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
776 }
777 pEntry->RateLen = SupportedRatesLen;
778
779 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
780 {
781 // If support WPA or WPA2, start STAKey hand shake,
782 // If failed hand shake, just tear down peer DLS
783 if (RTMPSendSTAKeyRequest(pAd, pAd->StaCfg.DLSEntry[i].MacAddr) != NDIS_STATUS_SUCCESS)
784 {
785 MLME_DLS_REQ_STRUCT MlmeDlsReq;
786 USHORT reason = REASON_QOS_CIPHER_NOT_SUPPORT;
787
788 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
789 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
790 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
791 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
792 DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed when call RTMPSendSTAKeyRequest \n"));
793 }
794 else
795 {
796 pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
797 DBGPRINT(RT_DEBUG_TRACE,("DLS - waiting for STAKey handshake procedure\n"));
798 }
799 }
800 else
801 {
802 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
803 pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
804 DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsRspAction() from %02x:%02x:%02x:%02x:%02x:%02x Succeed with WEP or no security\n", SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
805 }
806
807 //initialize seq no for DLS frames.
808 pAd->StaCfg.DLSEntry[i].Sequence = 0;
809 if (HtCapabilityLen != 0)
810 pAd->StaCfg.DLSEntry[i].bHTCap = TRUE;
811 else
812 pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
813 }
814 else
815 {
816 // DLS setup procedure failed.
817 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
818 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
819 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
820 DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed with StatusCode=%d \n", StatusCode));
821 }
822 }
823 }
824
825 if (i >= MAX_NUM_OF_INIT_DLS_ENTRY)
826 {
827 DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsRspAction() update timeout value \n"));
828 for (i=(MAX_NUM_OF_DLS_ENTRY-1); i>=MAX_NUM_OF_INIT_DLS_ENTRY; i--)
829 {
830 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
831 {
832 if (StatusCode == MLME_SUCCESS)
833 {
834 MAC_TABLE_ENTRY *pEntry;
835 UCHAR MaxSupportedRate = RATE_11;
836
837 pEntry = MacTableInsertDlsEntry(pAd, SA, i);
838
839 switch (MaxSupportedRateIn500Kbps)
840 {
841 case 108: MaxSupportedRate = RATE_54; break;
842 case 96: MaxSupportedRate = RATE_48; break;
843 case 72: MaxSupportedRate = RATE_36; break;
844 case 48: MaxSupportedRate = RATE_24; break;
845 case 36: MaxSupportedRate = RATE_18; break;
846 case 24: MaxSupportedRate = RATE_12; break;
847 case 18: MaxSupportedRate = RATE_9; break;
848 case 12: MaxSupportedRate = RATE_6; break;
849 case 22: MaxSupportedRate = RATE_11; break;
850 case 11: MaxSupportedRate = RATE_5_5; break;
851 case 4: MaxSupportedRate = RATE_2; break;
852 case 2: MaxSupportedRate = RATE_1; break;
853 default: MaxSupportedRate = RATE_11; break;
854 }
855
856 pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate);
857
858 if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
859 {
860 pEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
861 pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
862 pEntry->MinHTPhyMode.field.MODE = MODE_CCK;
863 pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
864 pEntry->HTPhyMode.field.MODE = MODE_CCK;
865 pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate;
866 }
867 else
868 {
869 pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
870 pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
871 pEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
872 pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
873 pEntry->HTPhyMode.field.MODE = MODE_OFDM;
874 pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
875 }
876
877 pEntry->MaxHTPhyMode.field.BW = BW_20;
878 pEntry->MinHTPhyMode.field.BW = BW_20;
879
880#ifdef DOT11_N_SUPPORT
881 pEntry->HTCapability.MCSSet[0] = 0;
882 pEntry->HTCapability.MCSSet[1] = 0;
883
884 // If this Entry supports 802.11n, upgrade to HT rate.
885 if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
886 {
887 UCHAR j, bitmask; //k,bitmask;
888 CHAR ii;
889
890 if ((HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
891 {
892 pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
893 }
894 else
895 {
896 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
897 pAd->MacTab.fAnyStationNonGF = TRUE;
898 pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
899 }
900
901 if ((HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
902 {
903 pEntry->MaxHTPhyMode.field.BW= BW_40;
904 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(HtCapability.HtCapInfo.ShortGIfor40));
905 }
906 else
907 {
908 pEntry->MaxHTPhyMode.field.BW = BW_20;
909 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(HtCapability.HtCapInfo.ShortGIfor20));
910 pAd->MacTab.fAnyStation20Only = TRUE;
911 }
912
913 // find max fixed rate
914 for (ii=15; ii>=0; ii--)
915 {
916 j = ii/8;
917 bitmask = (1<<(ii-(j*8)));
918 if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask))
919 {
920 pEntry->MaxHTPhyMode.field.MCS = ii;
921 break;
922 }
923 if (ii==0)
924 break;
925 }
926
927 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
928 {
929 printk("@@@ pAd->CommonCfg.RegTransmitSetting.field.MCS = %d\n",
930 pAd->StaCfg.DesiredTransmitSetting.field.MCS);
931 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
932 {
933 // Fix MCS as HT Duplicated Mode
934 pEntry->MaxHTPhyMode.field.BW = 1;
935 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
936 pEntry->MaxHTPhyMode.field.STBC = 0;
937 pEntry->MaxHTPhyMode.field.ShortGI = 0;
938 pEntry->MaxHTPhyMode.field.MCS = 32;
939 }
940 else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
941 {
942 // STA supports fixed MCS
943 pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
944 }
945 }
946
947 pEntry->MaxHTPhyMode.field.STBC = (HtCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
948 pEntry->MpduDensity = HtCapability.HtCapParm.MpduDensity;
949 pEntry->MaxRAmpduFactor = HtCapability.HtCapParm.MaxRAmpduFactor;
950 pEntry->MmpsMode = (UCHAR)HtCapability.HtCapInfo.MimoPs;
951 pEntry->AMsduSize = (UCHAR)HtCapability.HtCapInfo.AMsduSize;
952 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
953
954 if (HtCapability.HtCapInfo.ShortGIfor20)
955 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
956 if (HtCapability.HtCapInfo.ShortGIfor40)
957 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
958 if (HtCapability.HtCapInfo.TxSTBC)
959 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
960 if (HtCapability.HtCapInfo.RxSTBC)
961 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
962 if (HtCapability.ExtHtCapInfo.PlusHTC)
963 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
964 if (pAd->CommonCfg.bRdg && HtCapability.ExtHtCapInfo.RDGSupport)
965 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
966 if (HtCapability.ExtHtCapInfo.MCSFeedback == 0x03)
967 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
968
969 NdisMoveMemory(&pEntry->HTCapability, &HtCapability, sizeof(HT_CAPABILITY_IE));
970 }
971#endif // DOT11_N_SUPPORT //
972
973 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
974 pEntry->CurrTxRate = pEntry->MaxSupportedRate;
975 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
976
977 if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
978 {
979 PUCHAR pTable;
980 UCHAR TableSize = 0;
981
982 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
983 pEntry->bAutoTxRateSwitch = TRUE;
984 }
985 else
986 {
987 pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
988 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
989 pEntry->bAutoTxRateSwitch = FALSE;
990
991 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
992 }
993 pEntry->RateLen = SupportedRatesLen;
994
995 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
996 {
997 // If support WPA or WPA2, start STAKey hand shake,
998 // If failed hand shake, just tear down peer DLS
999 if (RTMPSendSTAKeyRequest(pAd, pAd->StaCfg.DLSEntry[i].MacAddr) != NDIS_STATUS_SUCCESS)
1000 {
1001 MLME_DLS_REQ_STRUCT MlmeDlsReq;
1002 USHORT reason = REASON_QOS_CIPHER_NOT_SUPPORT;
1003
1004 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
1005 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
1006 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1007 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1008 DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed when call RTMPSendSTAKeyRequest \n"));
1009 }
1010 else
1011 {
1012 pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
1013 DBGPRINT(RT_DEBUG_TRACE,("DLS - waiting for STAKey handshake procedure\n"));
1014 }
1015 }
1016 else
1017 {
1018 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1019 pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
1020 DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsRspAction() from %02x:%02x:%02x:%02x:%02x:%02x Succeed with WEP or no security\n", SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
1021 }
1022 pAd->StaCfg.DLSEntry[i].Sequence = 0;
1023 if (HtCapabilityLen != 0)
1024 pAd->StaCfg.DLSEntry[i].bHTCap = TRUE;
1025 else
1026 pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
1027 }
1028 else
1029 {
1030 // DLS setup procedure failed.
1031 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1032 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1033 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1034 DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed with StatusCode=%d \n", StatusCode));
1035 }
1036 }
1037 }
1038 }
1039}
1040
1041/*
1042 ==========================================================================
1043 Description:
1044
1045 IRQL = DISPATCH_LEVEL
1046
1047 ==========================================================================
1048 */
1049VOID MlmeDlsTearDownAction(
1050 IN PRTMP_ADAPTER pAd,
1051 IN MLME_QUEUE_ELEM *Elem)
1052{
1053 PUCHAR pOutBuffer = NULL;
1054 NDIS_STATUS NStatus;
1055 ULONG FrameLen = 0;
1056 UCHAR Category = CATEGORY_DLS;
1057 UCHAR Action = ACTION_DLS_TEARDOWN;
1058 USHORT ReasonCode = REASON_QOS_UNSPECIFY;
1059 HEADER_802_11 DlsTearDownHdr;
1060 PRT_802_11_DLS pDLS;
1061 BOOLEAN TimerCancelled;
1062 UCHAR i;
1063
1064 if(!MlmeDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, &pDLS, &ReasonCode))
1065 return;
1066
1067 DBGPRINT(RT_DEBUG_TRACE,("DLS - MlmeDlsTearDownAction() with ReasonCode=%d \n", ReasonCode));
1068
1069 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1070 if (NStatus != NDIS_STATUS_SUCCESS)
1071 {
1072 DBGPRINT(RT_DEBUG_ERROR,("DLS - MlmeDlsTearDownAction() allocate memory failed \n"));
1073 return;
1074 }
1075
1076 ActHeaderInit(pAd, &DlsTearDownHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
1077
1078 // Build basic frame first
1079 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1080 sizeof(HEADER_802_11), &DlsTearDownHdr,
1081 1, &Category,
1082 1, &Action,
1083 6, &pDLS->MacAddr,
1084 6, pAd->CurrentAddress,
1085 2, &ReasonCode,
1086 END_OF_ARGS);
1087
1088 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
1089 MlmeFreeMemory(pAd, pOutBuffer);
1090 RTMPCancelTimer(&pDLS->Timer, &TimerCancelled);
1091
1092 // Remove key in local dls table entry
1093 for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1094 {
1095 if (MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
1096 {
1097 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1098 }
1099 }
1100
1101 // clear peer dls table entry
1102 for (i = MAX_NUM_OF_INIT_DLS_ENTRY; i < MAX_NUM_OF_DLS_ENTRY; i++)
1103 {
1104 if (MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
1105 {
1106 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1107 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1108 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1109 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1110 }
1111 }
1112}
1113
1114/*
1115 ==========================================================================
1116 Description:
1117
1118 IRQL = DISPATCH_LEVEL
1119
1120 ==========================================================================
1121 */
1122VOID PeerDlsTearDownAction(
1123 IN PRTMP_ADAPTER pAd,
1124 IN MLME_QUEUE_ELEM *Elem)
1125{
1126 UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN];
1127 USHORT ReasonCode;
1128 UINT i;
1129 BOOLEAN TimerCancelled;
1130
1131 if (!pAd->CommonCfg.bDLSCapable)
1132 return;
1133
1134 if (!INFRA_ON(pAd))
1135 return;
1136
1137 if (!PeerDlsTearDownSanity(pAd, Elem->Msg, Elem->MsgLen, DA, SA, &ReasonCode))
1138 return;
1139
1140 DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsTearDownAction() from %02x:%02x:%02x:%02x:%02x:%02x with ReasonCode=%d\n", SA[0], SA[1], SA[2], SA[3], SA[4], SA[5], ReasonCode));
1141
1142 // clear local dls table entry
1143 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1144 {
1145 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
1146 {
1147 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1148 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1149 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1150 //AsicDelWcidTab(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
1151 //AsicRemovePairwiseKeyEntry(pAd, BSS0, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
1152 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1153 }
1154 }
1155
1156 // clear peer dls table entry
1157 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1158 {
1159 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
1160 {
1161 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1162 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1163 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1164 //AsicDelWcidTab(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
1165 //AsicRemovePairwiseKeyEntry(pAd, BSS0, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
1166 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1167 }
1168 }
1169}
1170
1171/*
1172 ==========================================================================
1173 Description:
1174
1175 IRQL = DISPATCH_LEVEL
1176
1177 ==========================================================================
1178 */
1179VOID RTMPCheckDLSTimeOut(
1180 IN PRTMP_ADAPTER pAd)
1181{
1182 ULONG i;
1183 MLME_DLS_REQ_STRUCT MlmeDlsReq;
1184 USHORT reason = REASON_QOS_UNSPECIFY;
1185
1186 if (! pAd->CommonCfg.bDLSCapable)
1187 return;
1188
1189 if (! INFRA_ON(pAd))
1190 return;
1191
1192 // If timeout value is equaled to zero, it means always not be timeout.
1193
1194 // update local dls table entry
1195 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1196 {
1197 if ((pAd->StaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1198 && (pAd->StaCfg.DLSEntry[i].TimeOut != 0))
1199 {
1200 pAd->StaCfg.DLSEntry[i].CountDownTimer --;
1201
1202 if (pAd->StaCfg.DLSEntry[i].CountDownTimer == 0)
1203 {
1204 reason = REASON_QOS_REQUEST_TIMEOUT;
1205 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1206 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1207 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
1208 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
1209 }
1210 }
1211 }
1212
1213 // update peer dls table entry
1214 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1215 {
1216 if ((pAd->StaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1217 && (pAd->StaCfg.DLSEntry[i].TimeOut != 0))
1218 {
1219 pAd->StaCfg.DLSEntry[i].CountDownTimer --;
1220
1221 if (pAd->StaCfg.DLSEntry[i].CountDownTimer == 0)
1222 {
1223 reason = REASON_QOS_REQUEST_TIMEOUT;
1224 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1225 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1226 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
1227 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
1228 }
1229 }
1230 }
1231}
1232
1233/*
1234 ==========================================================================
1235 Description:
1236
1237 IRQL = DISPATCH_LEVEL
1238
1239 ==========================================================================
1240 */
1241BOOLEAN RTMPRcvFrameDLSCheck(
1242 IN PRTMP_ADAPTER pAd,
1243 IN PHEADER_802_11 pHeader,
1244 IN ULONG Len,
1245 IN PRT28XX_RXD_STRUC pRxD)
1246{
1247 ULONG i;
1248 BOOLEAN bFindEntry = FALSE;
1249 BOOLEAN bSTAKeyFrame = FALSE;
1250 PEAPOL_PACKET pEap;
1251 PUCHAR pProto, pAddr = NULL;
1252 PUCHAR pSTAKey = NULL;
1253 UCHAR ZeroReplay[LEN_KEY_DESC_REPLAY];
1254 UCHAR Mic[16], OldMic[16];
1255 UCHAR digest[80];
1256 UCHAR DlsPTK[80];
1257 UCHAR temp[64];
1258 BOOLEAN TimerCancelled;
1259 CIPHER_KEY PairwiseKey;
1260
1261
1262 if (! pAd->CommonCfg.bDLSCapable)
1263 return bSTAKeyFrame;
1264
1265 if (! INFRA_ON(pAd))
1266 return bSTAKeyFrame;
1267
1268 if (! (pHeader->FC.SubType & 0x08))
1269 return bSTAKeyFrame;
1270
1271 if (Len < LENGTH_802_11 + 6 + 2 + 2)
1272 return bSTAKeyFrame;
1273
1274 pProto = (PUCHAR)pHeader + LENGTH_802_11 + 2 + 6; // QOS Control field , 0xAA 0xAA 0xAA 0x00 0x00 0x00
1275 pAddr = pHeader->Addr2;
1276
1277 // L2PAD bit on will pad 2 bytes at LLC
1278 if (pRxD->L2PAD)
1279 {
1280 pProto += 2;
1281 }
1282
1283 if (RTMPEqualMemory(EAPOL, pProto, 2) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1284 {
1285 pEap = (PEAPOL_PACKET) (pProto + 2);
1286
1287 DBGPRINT(RT_DEBUG_TRACE,("DLS - Sniff Len=%ld, DataLen=%d, KeyMic=%d, Install=%d, KeyAck=%d, Secure=%d, EKD_DL=%d, Error=%d, Request=%d\n", Len,
1288 (LENGTH_802_11 + 6 + 2 + 2 + sizeof(EAPOL_PACKET) - MAX_LEN_OF_RSNIE + 16),
1289 pEap->KeyDesc.KeyInfo.KeyMic,
1290 pEap->KeyDesc.KeyInfo.Install,
1291 pEap->KeyDesc.KeyInfo.KeyAck,
1292 pEap->KeyDesc.KeyInfo.Secure,
1293 pEap->KeyDesc.KeyInfo.EKD_DL,
1294 pEap->KeyDesc.KeyInfo.Error,
1295 pEap->KeyDesc.KeyInfo.Request));
1296
1297 if ((Len >= (LENGTH_802_11 + 6 + 2 + 2 + sizeof(EAPOL_PACKET) - MAX_LEN_OF_RSNIE + 16)) && pEap->KeyDesc.KeyInfo.KeyMic
1298 && pEap->KeyDesc.KeyInfo.Install && pEap->KeyDesc.KeyInfo.KeyAck && pEap->KeyDesc.KeyInfo.Secure
1299 && pEap->KeyDesc.KeyInfo.EKD_DL && !pEap->KeyDesc.KeyInfo.Error && !pEap->KeyDesc.KeyInfo.Request)
1300 {
1301 // First validate replay counter, only accept message with larger replay counter
1302 // Let equal pass, some AP start with all zero replay counter
1303 NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY);
1304 if ((RTMPCompareMemory(pEap->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1) &&
1305 (RTMPCompareMemory(pEap->KeyDesc.ReplayCounter, ZeroReplay, LEN_KEY_DESC_REPLAY) != 0))
1306 return bSTAKeyFrame;
1307
1308 //RTMPMoveMemory(pAd->StaCfg.ReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1309 RTMPMoveMemory(pAd->StaCfg.DlsReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1310 DBGPRINT(RT_DEBUG_TRACE,("DLS - Sniff replay counter (%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x) Len=%ld, KeyDataLen=%d\n",
1311 pAd->StaCfg.ReplayCounter[0], pAd->StaCfg.ReplayCounter[1], pAd->StaCfg.ReplayCounter[2],
1312 pAd->StaCfg.ReplayCounter[3], pAd->StaCfg.ReplayCounter[4], pAd->StaCfg.ReplayCounter[5],
1313 pAd->StaCfg.ReplayCounter[6], pAd->StaCfg.ReplayCounter[7], Len, pEap->KeyDesc.KeyData[1]));
1314
1315 // put these code segment to get the replay counter
1316 if (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED)
1317 return bSTAKeyFrame;
1318
1319 // Check MIC value
1320 // Save the MIC and replace with zero
1321 // use proprietary PTK
1322 NdisZeroMemory(temp, 64);
1323 NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
1324 WpaCountPTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK);
1325
1326 NdisMoveMemory(OldMic, pEap->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
1327 NdisZeroMemory(pEap->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
1328 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1329 {
1330 // AES
1331 HMAC_SHA1((PUCHAR) pEap, pEap->Body_Len[1] + 4, DlsPTK, LEN_EAP_MICK, digest);
1332 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
1333 }
1334 else
1335 {
1336 hmac_md5(DlsPTK, LEN_EAP_MICK, (PUCHAR) pEap, pEap->Body_Len[1] + 4, Mic);
1337 }
1338
1339 if (!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
1340 {
1341 DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in Msg1 of STAKey handshake! \n"));
1342 return bSTAKeyFrame;
1343 }
1344 else
1345 DBGPRINT(RT_DEBUG_TRACE, ("MIC VALID in Msg1 of STAKey handshake! \n"));
1346#if 1
1347 if ((pEap->KeyDesc.KeyData[0] == 0xDD) && (pEap->KeyDesc.KeyData[2] == 0x00) && (pEap->KeyDesc.KeyData[3] == 0x0C)
1348 && (pEap->KeyDesc.KeyData[4] == 0x43) && (pEap->KeyDesc.KeyData[5] == 0x02))
1349 {
1350 pAddr = pEap->KeyDesc.KeyData + 8; // Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2)
1351 pSTAKey = pEap->KeyDesc.KeyData + 14; // Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2), STAKey_Mac_Addr(6)
1352
1353 DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 from %02x:%02x:%02x:%02x:%02x:%02x Len=%ld, KeyDataLen=%d\n",
1354 pAddr[0], pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5], Len, pEap->KeyDesc.KeyData[1]));
1355
1356 bSTAKeyFrame = TRUE;
1357 }
1358#else
1359 if ((pEap->KeyDesc.KeyData[0] == 0xDD) && (pEap->KeyDesc.KeyData[2] == 0x00) && (pEap->KeyDesc.KeyData[3] == 0x0F)
1360 && (pEap->KeyDesc.KeyData[4] == 0xAC) && (pEap->KeyDesc.KeyData[5] == 0x02))
1361 {
1362 pAddr = pEap->KeyDesc.KeyData + 8; // Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2)
1363 pSTAKey = pEap->KeyDesc.KeyData + 14; // Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2), STAKey_Mac_Addr(6)
1364
1365 DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 from %02x:%02x:%02x:%02x:%02x:%02x Len=%d, KeyDataLen=%d\n",
1366 pAddr[0], pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5], Len, pEap->KeyDesc.KeyData[1]));
1367
1368 bSTAKeyFrame = TRUE;
1369 }
1370#endif
1371
1372 }
1373 else if (Len >= (LENGTH_802_11 + 6 + 2 + 2 + sizeof(EAPOL_PACKET) - MAX_LEN_OF_RSNIE))
1374 {
1375 RTMPMoveMemory(pAd->StaCfg.DlsReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1376 DBGPRINT(RT_DEBUG_TRACE,("DLS - Sniff replay counter 2(%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x) Len=%ld, KeyDataLen=%d\n",
1377 pAd->StaCfg.ReplayCounter[0], pAd->StaCfg.ReplayCounter[1], pAd->StaCfg.ReplayCounter[2],
1378 pAd->StaCfg.ReplayCounter[3], pAd->StaCfg.ReplayCounter[4], pAd->StaCfg.ReplayCounter[5],
1379 pAd->StaCfg.ReplayCounter[6], pAd->StaCfg.ReplayCounter[7], Len, pEap->KeyDesc.KeyData[1]));
1380
1381 }
1382 }
1383
1384 // If timeout value is equaled to zero, it means always not be timeout.
1385 // update local dls table entry
1386 for (i= 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1387 {
1388 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(pAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
1389 {
1390 if (bSTAKeyFrame)
1391 {
1392 PMAC_TABLE_ENTRY pEntry;
1393
1394 // STAKey frame, add pairwise key table
1395 pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
1396 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1397
1398 PairwiseKey.KeyLen = LEN_TKIP_EK;
1399 NdisMoveMemory(PairwiseKey.Key, &pSTAKey[0], LEN_TKIP_EK);
1400 NdisMoveMemory(PairwiseKey.TxMic, &pSTAKey[16], LEN_TKIP_RXMICK);
1401 NdisMoveMemory(PairwiseKey.RxMic, &pSTAKey[24], LEN_TKIP_TXMICK);
1402
1403 PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg;
1404
1405 pEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
1406 //AsicAddKeyEntry(pAd, (USHORT)(i + 2), BSS0, 0, &PairwiseKey, TRUE, TRUE); // reserve 0 for multicast, 1 for unicast
1407 //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
1408 // Add Pair-wise key to Asic
1409#ifdef RT2870
1410//Benson modified for USB interface, avoid in interrupt when write key, 20080724 -->
1411 {
1412 RT_ADD_PAIRWISE_KEY_ENTRY KeyInfo;
1413 COPY_MAC_ADDR(KeyInfo.MacAddr,pAd->StaCfg.DLSEntry[i].MacAddr);
1414 KeyInfo.MacTabMatchWCID=pAd->StaCfg.DLSEntry[i].MacTabMatchWCID;
1415 NdisMoveMemory(&KeyInfo.CipherKey, &PairwiseKey,sizeof(CIPHER_KEY));
1416 RTUSBEnqueueInternalCmd(pAd, RT_CMD_SET_KEY_TABLE, &KeyInfo, sizeof(RT_ADD_PAIRWISE_KEY_ENTRY));
1417 }
1418 {
1419 PMAC_TABLE_ENTRY pDLSEntry;
1420 pDLSEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
1421 pDLSEntry->PairwiseKey.CipherAlg=PairwiseKey.CipherAlg;
1422 RTUSBEnqueueInternalCmd(pAd, RT_CMD_SET_RX_WCID_TABLE, pDLSEntry, sizeof(MAC_TABLE_ENTRY));
1423 }
1424//Benson modified for USB interface, avoid in interrupt when write key, 20080724 <--
1425#endif // RT2870 //
1426 NdisMoveMemory(&pEntry->PairwiseKey, &PairwiseKey, sizeof(CIPHER_KEY));
1427 DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 (Peer STA MAC Address STAKey) \n"));
1428
1429 RTMPSendSTAKeyHandShake(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
1430
1431 DBGPRINT(RT_DEBUG_TRACE,("DLS - Finish STAKey handshake procedure (Initiator side)\n"));
1432 }
1433 else
1434 {
1435 // Data frame, update timeout value
1436 if (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1437 {
1438 pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
1439 //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
1440 }
1441 }
1442
1443 bFindEntry = TRUE;
1444 }
1445 }
1446
1447 // update peer dls table entry
1448 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1449 {
1450 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(pAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
1451 {
1452 if (bSTAKeyFrame)
1453 {
1454 PMAC_TABLE_ENTRY pEntry = NULL;
1455
1456 // STAKey frame, add pairwise key table, and send STAkey Msg-2
1457 pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
1458 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1459
1460 PairwiseKey.KeyLen = LEN_TKIP_EK;
1461 NdisMoveMemory(PairwiseKey.Key, &pSTAKey[0], LEN_TKIP_EK);
1462 NdisMoveMemory(PairwiseKey.TxMic, &pSTAKey[16], LEN_TKIP_RXMICK);
1463 NdisMoveMemory(PairwiseKey.RxMic, &pSTAKey[24], LEN_TKIP_TXMICK);
1464
1465 PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg;
1466
1467 pEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
1468 //AsicAddKeyEntry(pAd, (USHORT)(i + 2), BSS0, 0, &PairwiseKey, TRUE, TRUE); // reserve 0 for multicast, 1 for unicast
1469 //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
1470 // Add Pair-wise key to Asic
1471#ifdef RT2870
1472//Benson modified for USB interface, avoid in interrupt when write key, 20080724 -->
1473 {
1474 RT_ADD_PAIRWISE_KEY_ENTRY KeyInfo;
1475 COPY_MAC_ADDR(KeyInfo.MacAddr,pAd->StaCfg.DLSEntry[i].MacAddr);
1476 KeyInfo.MacTabMatchWCID=pAd->StaCfg.DLSEntry[i].MacTabMatchWCID;
1477 NdisMoveMemory(&KeyInfo.CipherKey, &PairwiseKey,sizeof(CIPHER_KEY));
1478 RTUSBEnqueueInternalCmd(pAd, RT_CMD_SET_KEY_TABLE, &KeyInfo, sizeof(RT_ADD_PAIRWISE_KEY_ENTRY));
1479 }
1480 {
1481 PMAC_TABLE_ENTRY pDLSEntry;
1482 pDLSEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
1483 pDLSEntry->PairwiseKey.CipherAlg=PairwiseKey.CipherAlg;
1484 RTUSBEnqueueInternalCmd(pAd, RT_CMD_SET_RX_WCID_TABLE, pDLSEntry, sizeof(MAC_TABLE_ENTRY));
1485 }
1486//Benson modified for USB interface, avoid in interrupt when write key, 20080724 <--
1487#endif // RT2870 //
1488 NdisMoveMemory(&pEntry->PairwiseKey, &PairwiseKey, sizeof(CIPHER_KEY));
1489 DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 (Initiator STA MAC Address STAKey)\n"));
1490
1491 // If support WPA or WPA2, start STAKey hand shake,
1492 // If failed hand shake, just tear down peer DLS
1493 if (RTMPSendSTAKeyHandShake(pAd, pAddr) != NDIS_STATUS_SUCCESS)
1494 {
1495 MLME_DLS_REQ_STRUCT MlmeDlsReq;
1496 USHORT reason = REASON_QOS_CIPHER_NOT_SUPPORT;
1497
1498 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1499 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1500 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
1501 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
1502 }
1503 else
1504 {
1505 DBGPRINT(RT_DEBUG_TRACE,("DLS - Finish STAKey handshake procedure (Peer side)\n"));
1506 }
1507 }
1508 else
1509 {
1510 // Data frame, update timeout value
1511 if (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1512 {
1513 pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
1514 }
1515 }
1516
1517 bFindEntry = TRUE;
1518 }
1519 }
1520
1521
1522 return bSTAKeyFrame;
1523}
1524
1525/*
1526 ========================================================================
1527
1528 Routine Description:
1529 Check if the frame can be sent through DLS direct link interface
1530
1531 Arguments:
1532 pAd Pointer to adapter
1533
1534 Return Value:
1535 DLS entry index
1536
1537 Note:
1538
1539 ========================================================================
1540*/
1541INT RTMPCheckDLSFrame(
1542 IN PRTMP_ADAPTER pAd,
1543 IN PUCHAR pDA)
1544{
1545 INT rval = -1;
1546 INT i;
1547
1548 if (!pAd->CommonCfg.bDLSCapable)
1549 return rval;
1550
1551 if (!INFRA_ON(pAd))
1552 return rval;
1553
1554 do{
1555 // check local dls table entry
1556 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1557 {
1558 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
1559 MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1560 {
1561 rval = i;
1562 break;
1563 }
1564 }
1565
1566 // check peer dls table entry
1567 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1568 {
1569 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
1570 MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1571 {
1572 rval = i;
1573 break;
1574 }
1575 }
1576 } while (FALSE);
1577
1578 return rval;
1579}
1580
1581/*
1582 ==========================================================================
1583 Description:
1584
1585 IRQL = DISPATCH_LEVEL
1586
1587 ==========================================================================
1588 */
1589VOID RTMPSendDLSTearDownFrame(
1590 IN PRTMP_ADAPTER pAd,
1591 IN PUCHAR pDA)
1592{
1593 PUCHAR pOutBuffer = NULL;
1594 NDIS_STATUS NStatus;
1595 HEADER_802_11 DlsTearDownHdr;
1596 ULONG FrameLen = 0;
1597 USHORT Reason = REASON_QOS_QSTA_LEAVING_QBSS;
1598 UCHAR Category = CATEGORY_DLS;
1599 UCHAR Action = ACTION_DLS_TEARDOWN;
1600 UCHAR i = 0;
1601
1602 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
1603 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
1604 return;
1605
1606 DBGPRINT(RT_DEBUG_TRACE, ("Send DLS TearDown Frame \n"));
1607
1608 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1609 if (NStatus != NDIS_STATUS_SUCCESS)
1610 {
1611 DBGPRINT(RT_DEBUG_ERROR,("ASSOC - RTMPSendDLSTearDownFrame() allocate memory failed \n"));
1612 return;
1613 }
1614
1615 ActHeaderInit(pAd, &DlsTearDownHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
1616 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1617 sizeof(HEADER_802_11), &DlsTearDownHdr,
1618 1, &Category,
1619 1, &Action,
1620 6, pDA,
1621 6, pAd->CurrentAddress,
1622 2, &Reason,
1623 END_OF_ARGS);
1624
1625 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1626 MlmeFreeMemory(pAd, pOutBuffer);
1627
1628 // Remove key in local dls table entry
1629 for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1630 {
1631 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1632 && MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1633 {
1634 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1635 }
1636 }
1637
1638 // Remove key in peer dls table entry
1639 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1640 {
1641 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1642 && MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1643 {
1644 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1645 }
1646 }
1647
1648 DBGPRINT(RT_DEBUG_TRACE, ("Send DLS TearDown Frame and remove key in (i=%d) \n", i));
1649}
1650
1651/*
1652 ==========================================================================
1653 Description:
1654
1655 IRQL = DISPATCH_LEVEL
1656
1657 ==========================================================================
1658 */
1659NDIS_STATUS RTMPSendSTAKeyRequest(
1660 IN PRTMP_ADAPTER pAd,
1661 IN PUCHAR pDA)
1662{
1663 UCHAR Header802_3[14];
1664 NDIS_STATUS NStatus;
1665 ULONG FrameLen = 0;
1666 EAPOL_PACKET Packet;
1667 UCHAR Mic[16];
1668 UCHAR digest[80];
1669 PUCHAR pOutBuffer = NULL;
1670 PNDIS_PACKET pNdisPacket;
1671 UCHAR temp[64];
1672 UCHAR DlsPTK[80];
1673
1674 DBGPRINT(RT_DEBUG_TRACE,("DLS - RTMPSendSTAKeyRequest() to %02x:%02x:%02x:%02x:%02x:%02x\n", pDA[0], pDA[1], pDA[2], pDA[3], pDA[4], pDA[5]));
1675
1676 pAd->Sequence ++;
1677 MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
1678
1679 // Zero message body
1680 NdisZeroMemory(&Packet, sizeof(Packet));
1681 Packet.ProVer = EAPOL_VER;
1682 Packet.ProType = EAPOLKey;
1683 Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + 6 + MAC_ADDR_LEN; // data field contain KDE andPeer MAC address
1684
1685 // STAKey Message is as EAPOL-Key(1,1,0,0,G/0,0,0, MIC, 0,Peer MAC KDE)
1686 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
1687 {
1688 Packet.KeyDesc.Type = WPA1_KEY_DESC;
1689 }
1690 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
1691 {
1692 Packet.KeyDesc.Type = WPA2_KEY_DESC;
1693 }
1694
1695 // Key descriptor version
1696 Packet.KeyDesc.KeyInfo.KeyDescVer =
1697 (((pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) || (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
1698
1699 Packet.KeyDesc.KeyInfo.KeyMic = 1;
1700 Packet.KeyDesc.KeyInfo.Secure = 1;
1701 Packet.KeyDesc.KeyInfo.Request = 1;
1702
1703 Packet.KeyDesc.KeyDataLen[1] = 12;
1704
1705 // use our own OUI to distinguish proprietary with standard.
1706 Packet.KeyDesc.KeyData[0] = 0xDD;
1707 Packet.KeyDesc.KeyData[1] = 0x0A;
1708 Packet.KeyDesc.KeyData[2] = 0x00;
1709 Packet.KeyDesc.KeyData[3] = 0x0C;
1710 Packet.KeyDesc.KeyData[4] = 0x43;
1711 Packet.KeyDesc.KeyData[5] = 0x03;
1712 NdisMoveMemory(&Packet.KeyDesc.KeyData[6], pDA, MAC_ADDR_LEN);
1713
1714 NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.DlsReplayCounter, LEN_KEY_DESC_REPLAY);
1715
1716 // Allocate buffer for transmitting message
1717 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
1718 if (NStatus != NDIS_STATUS_SUCCESS)
1719 return NStatus;
1720
1721 // Prepare EAPOL frame for MIC calculation
1722 // Be careful, only EAPOL frame is counted for MIC calculation
1723 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1724 Packet.Body_Len[1] + 4, &Packet,
1725 END_OF_ARGS);
1726
1727 // use proprietary PTK
1728 NdisZeroMemory(temp, 64);
1729 NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
1730 WpaCountPTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK);
1731
1732 // calculate MIC
1733 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1734 {
1735 // AES
1736 NdisZeroMemory(digest, sizeof(digest));
1737 HMAC_SHA1(pOutBuffer, FrameLen, DlsPTK, LEN_EAP_MICK, digest);
1738 NdisMoveMemory(Packet.KeyDesc.KeyMic, digest, LEN_KEY_DESC_MIC);
1739 }
1740 else
1741 {
1742 NdisZeroMemory(Mic, sizeof(Mic));
1743 hmac_md5(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
1744 NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
1745 }
1746
1747 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1748 sizeof(Header802_3), Header802_3,
1749 Packet.Body_Len[1] + 4, &Packet,
1750 END_OF_ARGS);
1751
1752 NStatus = RTMPAllocateNdisPacket(pAd, &pNdisPacket, NULL, 0, pOutBuffer, FrameLen);
1753 if (NStatus == NDIS_STATUS_SUCCESS)
1754 {
1755 RTMP_SET_PACKET_WCID(pNdisPacket, BSSID_WCID);
1756 STASendPacket(pAd, pNdisPacket);
1757 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1758 }
1759
1760 MlmeFreeMemory(pAd, pOutBuffer);
1761
1762 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSendSTAKeyRequest- Send STAKey request (NStatus=%x, FrameLen=%ld)\n", NStatus, FrameLen));
1763
1764 return NStatus;
1765}
1766
1767/*
1768 ==========================================================================
1769 Description:
1770
1771 IRQL = DISPATCH_LEVEL
1772
1773 ==========================================================================
1774 */
1775NDIS_STATUS RTMPSendSTAKeyHandShake(
1776 IN PRTMP_ADAPTER pAd,
1777 IN PUCHAR pDA)
1778{
1779 UCHAR Header802_3[14];
1780 NDIS_STATUS NStatus;
1781 ULONG FrameLen = 0;
1782 EAPOL_PACKET Packet;
1783 UCHAR Mic[16];
1784 UCHAR digest[80];
1785 PUCHAR pOutBuffer = NULL;
1786 PNDIS_PACKET pNdisPacket;
1787 UCHAR temp[64];
1788 UCHAR DlsPTK[80]; // Due to dirver can not get PTK, use proprietary PTK
1789
1790 DBGPRINT(RT_DEBUG_TRACE,("DLS - RTMPSendSTAKeyHandShake() to %02x:%02x:%02x:%02x:%02x:%02x\n", pDA[0], pDA[1], pDA[2], pDA[3], pDA[4], pDA[5]));
1791
1792 pAd->Sequence ++;
1793 MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
1794
1795 // Zero message body
1796 NdisZeroMemory(&Packet, sizeof(Packet));
1797 Packet.ProVer = EAPOL_VER;
1798 Packet.ProType = EAPOLKey;
1799 Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + 6 + MAC_ADDR_LEN; // data field contain KDE and Peer MAC address
1800
1801 // STAKey Message is as EAPOL-Key(1,1,0,0,G/0,0,0, MIC, 0,Peer MAC KDE)
1802 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
1803 {
1804 Packet.KeyDesc.Type = WPA1_KEY_DESC;
1805 }
1806 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
1807 {
1808 Packet.KeyDesc.Type = WPA2_KEY_DESC;
1809 }
1810
1811 // Key descriptor version
1812 Packet.KeyDesc.KeyInfo.KeyDescVer =
1813 (((pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) || (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
1814
1815 Packet.KeyDesc.KeyInfo.KeyMic = 1;
1816 Packet.KeyDesc.KeyInfo.Secure = 1;
1817
1818 Packet.KeyDesc.KeyDataLen[1] = 12;
1819
1820 // use our own OUI to distinguish proprietary with standard.
1821 Packet.KeyDesc.KeyData[0] = 0xDD;
1822 Packet.KeyDesc.KeyData[1] = 0x0A;
1823 Packet.KeyDesc.KeyData[2] = 0x00;
1824 Packet.KeyDesc.KeyData[3] = 0x0C;
1825 Packet.KeyDesc.KeyData[4] = 0x43;
1826 Packet.KeyDesc.KeyData[5] = 0x03;
1827 NdisMoveMemory(&Packet.KeyDesc.KeyData[6], pDA, MAC_ADDR_LEN);
1828
1829 NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.DlsReplayCounter, LEN_KEY_DESC_REPLAY);
1830
1831 // Allocate buffer for transmitting message
1832 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
1833 if (NStatus != NDIS_STATUS_SUCCESS)
1834 return NStatus;
1835
1836 // Prepare EAPOL frame for MIC calculation
1837 // Be careful, only EAPOL frame is counted for MIC calculation
1838 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1839 Packet.Body_Len[1] + 4, &Packet,
1840 END_OF_ARGS);
1841
1842 // use proprietary PTK
1843 NdisZeroMemory(temp, 64);
1844 NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
1845 WpaCountPTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK);
1846
1847 // calculate MIC
1848 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1849 {
1850 // AES
1851 NdisZeroMemory(digest, sizeof(digest));
1852 HMAC_SHA1(pOutBuffer, FrameLen, DlsPTK, LEN_EAP_MICK, digest);
1853 NdisMoveMemory(Packet.KeyDesc.KeyMic, digest, LEN_KEY_DESC_MIC);
1854 }
1855 else
1856 {
1857 NdisZeroMemory(Mic, sizeof(Mic));
1858 hmac_md5(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
1859 NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
1860 }
1861
1862 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1863 sizeof(Header802_3), Header802_3,
1864 Packet.Body_Len[1] + 4, &Packet,
1865 END_OF_ARGS);
1866
1867 NStatus = RTMPAllocateNdisPacket(pAd, &pNdisPacket, NULL, 0, pOutBuffer, FrameLen);
1868 if (NStatus == NDIS_STATUS_SUCCESS)
1869 {
1870 RTMP_SET_PACKET_WCID(pNdisPacket, BSSID_WCID);
1871 STASendPacket(pAd, pNdisPacket);
1872 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1873 }
1874
1875 MlmeFreeMemory(pAd, pOutBuffer);
1876
1877 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSendSTAKeyHandShake- Send STAKey Message-2 (NStatus=%x, FrameLen=%ld)\n", NStatus, FrameLen));
1878
1879 return NStatus;
1880}
1881
1882VOID DlsTimeoutAction(
1883 IN PVOID SystemSpecific1,
1884 IN PVOID FunctionContext,
1885 IN PVOID SystemSpecific2,
1886 IN PVOID SystemSpecific3)
1887{
1888 MLME_DLS_REQ_STRUCT MlmeDlsReq;
1889 USHORT reason;
1890 PRT_802_11_DLS pDLS = (PRT_802_11_DLS)FunctionContext;
1891 PRTMP_ADAPTER pAd = pDLS->pAd;
1892
1893 DBGPRINT(RT_DEBUG_TRACE, ("DlsTimeout - Tear down DLS links (%02x:%02x:%02x:%02x:%02x:%02x)\n",
1894 pDLS->MacAddr[0], pDLS->MacAddr[1], pDLS->MacAddr[2], pDLS->MacAddr[3], pDLS->MacAddr[4], pDLS->MacAddr[5]));
1895
1896 if ((pDLS) && (pDLS->Valid))
1897 {
1898 reason = REASON_QOS_REQUEST_TIMEOUT;
1899 pDLS->Valid = FALSE;
1900 pDLS->Status = DLS_NONE;
1901 DlsParmFill(pAd, &MlmeDlsReq, pDLS, reason);
1902 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
1903 RT28XX_MLME_HANDLER(pAd);
1904 }
1905}
1906
1907/*
1908================================================================
1909Description : because DLS and CLI share the same WCID table in ASIC.
1910Mesh entry also insert to pAd->MacTab.content[]. Such is marked as ValidAsDls = TRUE.
1911Also fills the pairwise key.
1912Because front MAX_AID_BA entries have direct mapping to BAEntry, which is only used as CLI. So we insert Dls
1913from index MAX_AID_BA.
1914================================================================
1915*/
1916MAC_TABLE_ENTRY *MacTableInsertDlsEntry(
1917 IN PRTMP_ADAPTER pAd,
1918 IN PUCHAR pAddr,
1919 IN UINT DlsEntryIdx)
1920{
1921 PMAC_TABLE_ENTRY pEntry = NULL;
1922
1923 DBGPRINT(RT_DEBUG_TRACE, ("====> MacTableInsertDlsEntry\n"));
1924 // if FULL, return
1925 if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
1926 return NULL;
1927
1928 do
1929 {
1930 if((pEntry = DlsEntryTableLookup(pAd, pAddr, TRUE)) != NULL)
1931 break;
1932
1933 // allocate one MAC entry
1934 pEntry = MacTableInsertEntry(pAd, pAddr, DlsEntryIdx + MIN_NET_DEVICE_FOR_DLS, TRUE);
1935 if (pEntry)
1936 {
1937 pAd->StaCfg.DLSEntry[DlsEntryIdx].MacTabMatchWCID = pEntry->Aid;
1938 pEntry->MatchDlsEntryIdx = DlsEntryIdx;
1939 pEntry->AuthMode = pAd->StaCfg.AuthMode;
1940 pEntry->WepStatus = pAd->StaCfg.WepStatus;
1941
1942 DBGPRINT(RT_DEBUG_TRACE, ("MacTableInsertDlsEntry - allocate entry #%d, Total= %d\n",pEntry->Aid, pAd->MacTab.Size));
1943
1944 // If legacy WEP is used, set pair-wise cipherAlg into WCID attribute table for this entry
1945 if ((pEntry->ValidAsDls) && (pEntry->WepStatus == Ndis802_11WEPEnabled))
1946 {
1947 UCHAR KeyIdx = 0;
1948 UCHAR CipherAlg = 0;
1949
1950 KeyIdx = pAd->StaCfg.DefaultKeyId;
1951
1952 CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
1953
1954 RTMPAddWcidAttributeEntry(pAd,
1955 BSS0,
1956 pAd->StaCfg.DefaultKeyId,
1957 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
1958 pEntry);
1959 }
1960
1961 break;
1962 }
1963 } while(FALSE);
1964
1965 DBGPRINT(RT_DEBUG_TRACE, ("<==== MacTableInsertDlsEntry\n"));
1966
1967 return pEntry;
1968}
1969
1970
1971/*
1972 ==========================================================================
1973 Description:
1974 Delete all Mesh Entry in pAd->MacTab
1975 ==========================================================================
1976 */
1977BOOLEAN MacTableDeleteDlsEntry(
1978 IN PRTMP_ADAPTER pAd,
1979 IN USHORT wcid,
1980 IN PUCHAR pAddr)
1981{
1982 DBGPRINT(RT_DEBUG_TRACE, ("====> MacTableDeleteDlsEntry\n"));
1983
1984 if (!VALID_WCID(wcid))
1985 return FALSE;
1986
1987 MacTableDeleteEntry(pAd, wcid, pAddr);
1988
1989 DBGPRINT(RT_DEBUG_TRACE, ("<==== MacTableDeleteDlsEntry\n"));
1990
1991 return TRUE;
1992}
1993
1994MAC_TABLE_ENTRY *DlsEntryTableLookup(
1995 IN PRTMP_ADAPTER pAd,
1996 IN PUCHAR pAddr,
1997 IN BOOLEAN bResetIdelCount)
1998{
1999 ULONG HashIdx;
2000 MAC_TABLE_ENTRY *pEntry = NULL;
2001
2002 RTMP_SEM_LOCK(&pAd->MacTabLock);
2003 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
2004 pEntry = pAd->MacTab.Hash[HashIdx];
2005
2006 while (pEntry)
2007 {
2008 if ((pEntry->ValidAsDls == TRUE)
2009 && MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
2010 {
2011 if(bResetIdelCount)
2012 pEntry->NoDataIdleCount = 0;
2013 break;
2014 }
2015 else
2016 pEntry = pEntry->pNext;
2017 }
2018
2019 RTMP_SEM_UNLOCK(&pAd->MacTabLock);
2020 return pEntry;
2021}
2022
2023MAC_TABLE_ENTRY *DlsEntryTableLookupByWcid(
2024 IN PRTMP_ADAPTER pAd,
2025 IN UCHAR wcid,
2026 IN PUCHAR pAddr,
2027 IN BOOLEAN bResetIdelCount)
2028{
2029 ULONG DLsIndex;
2030 PMAC_TABLE_ENTRY pCurEntry = NULL;
2031 PMAC_TABLE_ENTRY pEntry = NULL;
2032
2033 if (!VALID_WCID(wcid))
2034 return NULL;
2035
2036 RTMP_SEM_LOCK(&pAd->MacTabLock);
2037
2038 do
2039 {
2040 pCurEntry = &pAd->MacTab.Content[wcid];
2041
2042 DLsIndex = 0xff;
2043 if ((pCurEntry) && (pCurEntry->ValidAsDls== TRUE))
2044 {
2045 DLsIndex = pCurEntry->MatchDlsEntryIdx;
2046 }
2047
2048 if (DLsIndex == 0xff)
2049 break;
2050
2051 if (MAC_ADDR_EQUAL(pCurEntry->Addr, pAddr))
2052 {
2053 if(bResetIdelCount)
2054 pCurEntry->NoDataIdleCount = 0;
2055 pEntry = pCurEntry;
2056 break;
2057 }
2058 } while(FALSE);
2059
2060 RTMP_SEM_UNLOCK(&pAd->MacTabLock);
2061
2062 return pEntry;
2063}
2064
2065INT Set_DlsEntryInfo_Display_Proc(
2066 IN PRTMP_ADAPTER pAd,
2067 IN PUCHAR arg)
2068{
2069 INT i;
2070
2071 printk("\n%-19s%-8s\n", "MAC", "TIMEOUT\n");
2072 for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
2073 {
2074 if ((pAd->StaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
2075 {
2076 printk("%02x:%02x:%02x:%02x:%02x:%02x ",
2077 pAd->StaCfg.DLSEntry[i].MacAddr[0], pAd->StaCfg.DLSEntry[i].MacAddr[1], pAd->StaCfg.DLSEntry[i].MacAddr[2],
2078 pAd->StaCfg.DLSEntry[i].MacAddr[3], pAd->StaCfg.DLSEntry[i].MacAddr[4], pAd->StaCfg.DLSEntry[i].MacAddr[5]);
2079 printk("%-8d\n", pAd->StaCfg.DLSEntry[i].TimeOut);
2080 }
2081 }
2082
2083 return TRUE;
2084}
2085
2086INT Set_DlsAddEntry_Proc(
2087 IN PRTMP_ADAPTER pAd,
2088 IN PUCHAR arg)
2089{
2090 UCHAR mac[MAC_ADDR_LEN];
2091 USHORT Timeout;
2092 char *token, sepValue[] = ":", DASH = '-';
2093 INT i;
2094 RT_802_11_DLS Dls;
2095
2096 if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and timeout value in decimal format.
2097 return FALSE;
2098
2099 token = strchr(arg, DASH);
2100 if ((token != NULL) && (strlen(token)>1))
2101 {
2102 Timeout = simple_strtol((token+1), 0, 10);
2103
2104 *token = '\0';
2105 for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
2106 {
2107 if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
2108 return FALSE;
2109 AtoH(token, (PUCHAR)(&mac[i]), 1);
2110 }
2111 if(i != 6)
2112 return FALSE;
2113
2114 printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%d", mac[0], mac[1],
2115 mac[2], mac[3], mac[4], mac[5], (int)Timeout);
2116
2117 NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
2118 Dls.TimeOut = Timeout;
2119 COPY_MAC_ADDR(Dls.MacAddr, mac);
2120 Dls.Valid = 1;
2121
2122 MlmeEnqueue(pAd,
2123 MLME_CNTL_STATE_MACHINE,
2124 RT_OID_802_11_SET_DLS_PARAM,
2125 sizeof(RT_802_11_DLS),
2126 &Dls);
2127
2128 return TRUE;
2129 }
2130
2131 return FALSE;
2132
2133}
2134
2135INT Set_DlsTearDownEntry_Proc(
2136 IN PRTMP_ADAPTER pAd,
2137 IN PUCHAR arg)
2138{
2139 UCHAR macAddr[MAC_ADDR_LEN];
2140 CHAR *value;
2141 INT i;
2142 RT_802_11_DLS Dls;
2143
2144 if(strlen(arg) != 17) //Mac address acceptable format 01:02:03:04:05:06 length 17
2145 return FALSE;
2146
2147 for (i=0, value = rstrtok(arg,":"); value; value = rstrtok(NULL,":"))
2148 {
2149 if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
2150 return FALSE; //Invalid
2151
2152 AtoH(value, &macAddr[i++], 2);
2153 }
2154
2155 printk("\n%02x:%02x:%02x:%02x:%02x:%02x", macAddr[0], macAddr[1],
2156 macAddr[2], macAddr[3], macAddr[4], macAddr[5]);
2157
2158 NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
2159 COPY_MAC_ADDR(Dls.MacAddr, macAddr);
2160 Dls.Valid = 0;
2161
2162 MlmeEnqueue(pAd,
2163 MLME_CNTL_STATE_MACHINE,
2164 RT_OID_802_11_SET_DLS_PARAM,
2165 sizeof(RT_802_11_DLS),
2166 &Dls);
2167
2168 return TRUE;
2169}
2170
diff --git a/drivers/staging/rt3070/sta/rtmp_data.c b/drivers/staging/rt3070/sta/rtmp_data.c
new file mode 100644
index 000000000000..b0f259b35c74
--- /dev/null
+++ b/drivers/staging/rt3070/sta/rtmp_data.c
@@ -0,0 +1,2637 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 rtmp_data.c
29
30 Abstract:
31 Data path subroutines
32
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36 John Aug/17/04 major modification for RT2561/2661
37 Jan Lee Mar/17/06 major modification for RT2860 New Ring Design
38*/
39#include "../rt_config.h"
40
41
42
43VOID STARxEAPOLFrameIndicate(
44 IN PRTMP_ADAPTER pAd,
45 IN MAC_TABLE_ENTRY *pEntry,
46 IN RX_BLK *pRxBlk,
47 IN UCHAR FromWhichBSSID)
48{
49 PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
50 PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
51 UCHAR *pTmpBuf;
52
53
54#ifdef WPA_SUPPLICANT_SUPPORT
55 if (pAd->StaCfg.WpaSupplicantUP)
56 {
57 // All EAPoL frames have to pass to upper layer (ex. WPA_SUPPLICANT daemon)
58 // TBD : process fragmented EAPol frames
59 {
60 // In 802.1x mode, if the received frame is EAP-SUCCESS packet, turn on the PortSecured variable
61 if ( pAd->StaCfg.IEEE8021X == TRUE &&
62 (EAP_CODE_SUCCESS == WpaCheckEapCode(pAd, pRxBlk->pData, pRxBlk->DataSize, LENGTH_802_1_H)))
63 {
64 PUCHAR Key;
65 UCHAR CipherAlg;
66 int idx = 0;
67
68 DBGPRINT_RAW(RT_DEBUG_TRACE, ("Receive EAP-SUCCESS Packet\n"));
69 //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
70 STA_PORT_SECURED(pAd);
71
72 if (pAd->StaCfg.IEEE8021x_required_keys == FALSE)
73 {
74 idx = pAd->StaCfg.DesireSharedKeyId;
75 CipherAlg = pAd->StaCfg.DesireSharedKey[idx].CipherAlg;
76 Key = pAd->StaCfg.DesireSharedKey[idx].Key;
77
78 if (pAd->StaCfg.DesireSharedKey[idx].KeyLen > 0)
79 {
80#ifdef RT2870
81 union
82 {
83 char buf[sizeof(NDIS_802_11_WEP)+MAX_LEN_OF_KEY- 1];
84 NDIS_802_11_WEP keyinfo;
85 } WepKey;
86 int len;
87
88
89 NdisZeroMemory(&WepKey, sizeof(WepKey));
90 len =pAd->StaCfg.DesireSharedKey[idx].KeyLen;
91
92 NdisMoveMemory(WepKey.keyinfo.KeyMaterial,
93 pAd->StaCfg.DesireSharedKey[idx].Key,
94 pAd->StaCfg.DesireSharedKey[idx].KeyLen);
95
96 WepKey.keyinfo.KeyIndex = 0x80000000 + idx;
97 WepKey.keyinfo.KeyLength = len;
98 pAd->SharedKey[BSS0][idx].KeyLen =(UCHAR) (len <= 5 ? 5 : 13);
99
100 pAd->IndicateMediaState = NdisMediaStateConnected;
101 pAd->ExtraInfo = GENERAL_LINK_UP;
102 // need to enqueue cmd to thread
103 RTUSBEnqueueCmdFromNdis(pAd, OID_802_11_ADD_WEP, TRUE, &WepKey, sizeof(WepKey.keyinfo) + len - 1);
104#endif // RT2870 //
105 // For Preventing ShardKey Table is cleared by remove key procedure.
106 pAd->SharedKey[BSS0][idx].CipherAlg = CipherAlg;
107 pAd->SharedKey[BSS0][idx].KeyLen = pAd->StaCfg.DesireSharedKey[idx].KeyLen;
108 NdisMoveMemory(pAd->SharedKey[BSS0][idx].Key,
109 pAd->StaCfg.DesireSharedKey[idx].Key,
110 pAd->StaCfg.DesireSharedKey[idx].KeyLen);
111 }
112 }
113 }
114
115 Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
116 return;
117 }
118 }
119 else
120#endif // WPA_SUPPLICANT_SUPPORT //
121 {
122 // Special DATA frame that has to pass to MLME
123 // 1. Cisco Aironet frames for CCX2. We need pass it to MLME for special process
124 // 2. EAPOL handshaking frames when driver supplicant enabled, pass to MLME for special process
125 {
126 pTmpBuf = pRxBlk->pData - LENGTH_802_11;
127 NdisMoveMemory(pTmpBuf, pRxBlk->pHeader, LENGTH_802_11);
128 REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->WirelessCliID, pTmpBuf, pRxBlk->DataSize + LENGTH_802_11, pRxWI->RSSI0, pRxWI->RSSI1, pRxWI->RSSI2, pRxD->PlcpSignal);
129 DBGPRINT_RAW(RT_DEBUG_TRACE, ("!!! report EAPOL/AIRONET DATA to MLME (len=%d) !!!\n", pRxBlk->DataSize));
130 }
131 }
132
133 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
134 return;
135
136}
137
138VOID STARxDataFrameAnnounce(
139 IN PRTMP_ADAPTER pAd,
140 IN MAC_TABLE_ENTRY *pEntry,
141 IN RX_BLK *pRxBlk,
142 IN UCHAR FromWhichBSSID)
143{
144
145 // non-EAP frame
146 if (!RTMPCheckWPAframe(pAd, pEntry, pRxBlk->pData, pRxBlk->DataSize, FromWhichBSSID))
147 {
148
149 {
150 // drop all non-EAP DATA frame before
151 // this client's Port-Access-Control is secured
152 if (pRxBlk->pHeader->FC.Wep)
153 {
154 // unsupported cipher suite
155 if (pAd->StaCfg.WepStatus == Ndis802_11EncryptionDisabled)
156 {
157 // release packet
158 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
159 return;
160 }
161 }
162 else
163 {
164 // encryption in-use but receive a non-EAPOL clear text frame, drop it
165 if ((pAd->StaCfg.WepStatus != Ndis802_11EncryptionDisabled) &&
166 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
167 {
168 // release packet
169 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
170 return;
171 }
172 }
173 }
174 RX_BLK_CLEAR_FLAG(pRxBlk, fRX_EAP);
175 if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_ARALINK))
176 {
177 // Normal legacy, AMPDU or AMSDU
178 CmmRxnonRalinkFrameIndicate(pAd, pRxBlk, FromWhichBSSID);
179
180 }
181 else
182 {
183 // ARALINK
184 CmmRxRalinkFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
185 }
186#ifdef QOS_DLS_SUPPORT
187 RX_BLK_CLEAR_FLAG(pRxBlk, fRX_DLS);
188#endif // QOS_DLS_SUPPORT //
189 }
190 else
191 {
192 RX_BLK_SET_FLAG(pRxBlk, fRX_EAP);
193#ifdef DOT11_N_SUPPORT
194 if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU) && (pAd->CommonCfg.bDisableReordering == 0))
195 {
196 Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID);
197 }
198 else
199#endif // DOT11_N_SUPPORT //
200 {
201 // Determin the destination of the EAP frame
202 // to WPA state machine or upper layer
203 STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
204 }
205 }
206}
207
208
209// For TKIP frame, calculate the MIC value
210BOOLEAN STACheckTkipMICValue(
211 IN PRTMP_ADAPTER pAd,
212 IN MAC_TABLE_ENTRY *pEntry,
213 IN RX_BLK *pRxBlk)
214{
215 PHEADER_802_11 pHeader = pRxBlk->pHeader;
216 UCHAR *pData = pRxBlk->pData;
217 USHORT DataSize = pRxBlk->DataSize;
218 UCHAR UserPriority = pRxBlk->UserPriority;
219 PCIPHER_KEY pWpaKey;
220 UCHAR *pDA, *pSA;
221
222 pWpaKey = &pAd->SharedKey[BSS0][pRxBlk->pRxWI->KeyIndex];
223
224 pDA = pHeader->Addr1;
225 if (RX_BLK_TEST_FLAG(pRxBlk, fRX_INFRA))
226 {
227 pSA = pHeader->Addr3;
228 }
229 else
230 {
231 pSA = pHeader->Addr2;
232 }
233
234 if (RTMPTkipCompareMICValue(pAd,
235 pData,
236 pDA,
237 pSA,
238 pWpaKey->RxMic,
239 UserPriority,
240 DataSize) == FALSE)
241 {
242 DBGPRINT_RAW(RT_DEBUG_ERROR,("Rx MIC Value error 2\n"));
243
244#ifdef WPA_SUPPLICANT_SUPPORT
245 if (pAd->StaCfg.WpaSupplicantUP)
246 {
247 WpaSendMicFailureToWpaSupplicant(pAd, (pWpaKey->Type == PAIRWISEKEY) ? TRUE : FALSE);
248 }
249 else
250#endif // WPA_SUPPLICANT_SUPPORT //
251 {
252 RTMPReportMicError(pAd, pWpaKey);
253 }
254
255 // release packet
256 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
257 return FALSE;
258 }
259
260 return TRUE;
261}
262
263
264//
265// All Rx routines use RX_BLK structure to hande rx events
266// It is very important to build pRxBlk attributes
267// 1. pHeader pointer to 802.11 Header
268// 2. pData pointer to payload including LLC (just skip Header)
269// 3. set payload size including LLC to DataSize
270// 4. set some flags with RX_BLK_SET_FLAG()
271//
272VOID STAHandleRxDataFrame(
273 IN PRTMP_ADAPTER pAd,
274 IN RX_BLK *pRxBlk)
275{
276 PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
277 PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
278 PHEADER_802_11 pHeader = pRxBlk->pHeader;
279 PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
280 BOOLEAN bFragment = FALSE;
281 MAC_TABLE_ENTRY *pEntry = NULL;
282 UCHAR FromWhichBSSID = BSS0;
283 UCHAR UserPriority = 0;
284
285 {
286 // before LINK UP, all DATA frames are rejected
287 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
288 {
289 // release packet
290 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
291 return;
292 }
293
294#ifdef QOS_DLS_SUPPORT
295 //if ((pHeader->FC.FrDs == 0) && (pHeader->FC.ToDs == 0))
296 if (RTMPRcvFrameDLSCheck(pAd, pHeader, pRxWI->MPDUtotalByteCount, pRxD))
297 {
298 return;
299 }
300#endif // QOS_DLS_SUPPORT //
301
302 // Drop not my BSS frames
303 if (pRxD->MyBss == 0)
304 {
305 {
306 // release packet
307 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
308 return;
309 }
310 }
311
312 pAd->RalinkCounters.RxCountSinceLastNULL++;
313 if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable && (pHeader->FC.SubType & 0x08))
314 {
315 UCHAR *pData;
316 DBGPRINT(RT_DEBUG_TRACE,("bAPSDCapable\n"));
317
318 // Qos bit 4
319 pData = (PUCHAR)pHeader + LENGTH_802_11;
320 if ((*pData >> 4) & 0x01)
321 {
322 DBGPRINT(RT_DEBUG_TRACE,("RxDone- Rcv EOSP frame, driver may fall into sleep\n"));
323 pAd->CommonCfg.bInServicePeriod = FALSE;
324
325 // Force driver to fall into sleep mode when rcv EOSP frame
326 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
327 {
328 USHORT TbttNumToNextWakeUp;
329 USHORT NextDtim = pAd->StaCfg.DtimPeriod;
330 ULONG Now;
331
332 NdisGetSystemUpTime(&Now);
333 NextDtim -= (USHORT)(Now - pAd->StaCfg.LastBeaconRxTime)/pAd->CommonCfg.BeaconPeriod;
334
335 TbttNumToNextWakeUp = pAd->StaCfg.DefaultListenCount;
336 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim))
337 TbttNumToNextWakeUp = NextDtim;
338
339 MlmeSetPsmBit(pAd, PWR_SAVE);
340 // if WMM-APSD is failed, try to disable following line
341 AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
342 }
343 }
344
345 if ((pHeader->FC.MoreData) && (pAd->CommonCfg.bInServicePeriod))
346 {
347 DBGPRINT(RT_DEBUG_TRACE,("Sending another trigger frame when More Data bit is set to 1\n"));
348 }
349 }
350
351 // Drop NULL, CF-ACK(no data), CF-POLL(no data), and CF-ACK+CF-POLL(no data) data frame
352 if ((pHeader->FC.SubType & 0x04)) // bit 2 : no DATA
353 {
354 // release packet
355 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
356 return;
357 }
358
359 // Drop not my BSS frame (we can not only check the MyBss bit in RxD)
360#ifdef QOS_DLS_SUPPORT
361 if (!pAd->CommonCfg.bDLSCapable)
362 {
363#endif // QOS_DLS_SUPPORT //
364 if (INFRA_ON(pAd))
365 {
366 // Infrastructure mode, check address 2 for BSSID
367 if (!RTMPEqualMemory(&pHeader->Addr2, &pAd->CommonCfg.Bssid, 6))
368 {
369 // Receive frame not my BSSID
370 // release packet
371 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
372 return;
373 }
374 }
375 else // Ad-Hoc mode or Not associated
376 {
377 // Ad-Hoc mode, check address 3 for BSSID
378 if (!RTMPEqualMemory(&pHeader->Addr3, &pAd->CommonCfg.Bssid, 6))
379 {
380 // Receive frame not my BSSID
381 // release packet
382 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
383 return;
384 }
385 }
386#ifdef QOS_DLS_SUPPORT
387 }
388#endif // QOS_DLS_SUPPORT //
389
390 //
391 // find pEntry
392 //
393 if (pRxWI->WirelessCliID < MAX_LEN_OF_MAC_TABLE)
394 {
395 pEntry = &pAd->MacTab.Content[pRxWI->WirelessCliID];
396 }
397 else
398 {
399 // 1. release packet if infra mode
400 // 2. new a pEntry if ad-hoc mode
401 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
402 return;
403 }
404
405 // infra or ad-hoc
406 if (INFRA_ON(pAd))
407 {
408 RX_BLK_SET_FLAG(pRxBlk, fRX_INFRA);
409#ifdef QOS_DLS_SUPPORT
410 if ((pHeader->FC.FrDs == 0) && (pHeader->FC.ToDs == 0))
411 RX_BLK_SET_FLAG(pRxBlk, fRX_DLS);
412 else
413#endif // QOS_DLS_SUPPORT //
414 ASSERT(pRxWI->WirelessCliID == BSSID_WCID);
415 }
416
417 // check Atheros Client
418 if ((pEntry->bIAmBadAtheros == FALSE) && (pRxD->AMPDU == 1) && (pHeader->FC.Retry ))
419 {
420 pEntry->bIAmBadAtheros = TRUE;
421 pAd->CommonCfg.IOTestParm.bCurrentAtheros = TRUE;
422 pAd->CommonCfg.IOTestParm.bLastAtheros = TRUE;
423 if (!STA_AES_ON(pAd))
424 {
425 AsicUpdateProtect(pAd, 8, ALLN_SETPROTECT, TRUE, FALSE);
426 }
427 }
428 }
429
430 pRxBlk->pData = (UCHAR *)pHeader;
431
432 //
433 // update RxBlk->pData, DataSize
434 // 802.11 Header, QOS, HTC, Hw Padding
435 //
436
437 // 1. skip 802.11 HEADER
438 {
439 pRxBlk->pData += LENGTH_802_11;
440 pRxBlk->DataSize -= LENGTH_802_11;
441 }
442
443 // 2. QOS
444 if (pHeader->FC.SubType & 0x08)
445 {
446 RX_BLK_SET_FLAG(pRxBlk, fRX_QOS);
447 UserPriority = *(pRxBlk->pData) & 0x0f;
448 // bit 7 in QoS Control field signals the HT A-MSDU format
449 if ((*pRxBlk->pData) & 0x80)
450 {
451 RX_BLK_SET_FLAG(pRxBlk, fRX_AMSDU);
452 }
453
454 // skip QOS contorl field
455 pRxBlk->pData += 2;
456 pRxBlk->DataSize -=2;
457 }
458 pRxBlk->UserPriority = UserPriority;
459
460 // 3. Order bit: A-Ralink or HTC+
461 if (pHeader->FC.Order)
462 {
463#ifdef AGGREGATION_SUPPORT
464 if ((pRxWI->PHYMODE <= MODE_OFDM) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)))
465 {
466 RX_BLK_SET_FLAG(pRxBlk, fRX_ARALINK);
467 }
468 else
469#endif
470 {
471#ifdef DOT11_N_SUPPORT
472 RX_BLK_SET_FLAG(pRxBlk, fRX_HTC);
473 // skip HTC contorl field
474 pRxBlk->pData += 4;
475 pRxBlk->DataSize -= 4;
476#endif // DOT11_N_SUPPORT //
477 }
478 }
479
480 // 4. skip HW padding
481 if (pRxD->L2PAD)
482 {
483 // just move pData pointer
484 // because DataSize excluding HW padding
485 RX_BLK_SET_FLAG(pRxBlk, fRX_PAD);
486 pRxBlk->pData += 2;
487 }
488
489#ifdef DOT11_N_SUPPORT
490 if (pRxD->BA)
491 {
492 RX_BLK_SET_FLAG(pRxBlk, fRX_AMPDU);
493 }
494#endif // DOT11_N_SUPPORT //
495
496
497 //
498 // Case I Process Broadcast & Multicast data frame
499 //
500 if (pRxD->Bcast || pRxD->Mcast)
501 {
502 INC_COUNTER64(pAd->WlanCounters.MulticastReceivedFrameCount);
503
504 // Drop Mcast/Bcast frame with fragment bit on
505 if (pHeader->FC.MoreFrag)
506 {
507 // release packet
508 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
509 return;
510 }
511
512 // Filter out Bcast frame which AP relayed for us
513 if (pHeader->FC.FrDs && MAC_ADDR_EQUAL(pHeader->Addr3, pAd->CurrentAddress))
514 {
515 // release packet
516 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
517 return;
518 }
519
520 Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
521 return;
522 }
523 else if (pRxD->U2M)
524 {
525 pAd->LastRxRate = (USHORT)((pRxWI->MCS) + (pRxWI->BW <<7) + (pRxWI->ShortGI <<8)+ (pRxWI->PHYMODE <<14)) ;
526
527
528#ifdef QOS_DLS_SUPPORT
529 if (RX_BLK_TEST_FLAG(pRxBlk, fRX_DLS))
530 {
531 MAC_TABLE_ENTRY *pDlsEntry = NULL;
532
533 pDlsEntry = DlsEntryTableLookupByWcid(pAd, pRxWI->WirelessCliID, pHeader->Addr2, TRUE);
534 if(pDlsEntry)
535 Update_Rssi_Sample(pAd, &pDlsEntry->RssiSample, pRxWI);
536 }
537 else
538#endif // QOS_DLS_SUPPORT //
539 if (ADHOC_ON(pAd))
540 {
541 pEntry = MacTableLookup(pAd, pHeader->Addr2);
542 if (pEntry)
543 Update_Rssi_Sample(pAd, &pEntry->RssiSample, pRxWI);
544 }
545
546
547 Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI);
548
549 pAd->StaCfg.LastSNR0 = (UCHAR)(pRxWI->SNR0);
550 pAd->StaCfg.LastSNR1 = (UCHAR)(pRxWI->SNR1);
551
552 pAd->RalinkCounters.OneSecRxOkDataCnt++;
553
554
555 if (!((pHeader->Frag == 0) && (pHeader->FC.MoreFrag == 0)))
556 {
557 // re-assemble the fragmented packets
558 // return complete frame (pRxPacket) or NULL
559 bFragment = TRUE;
560 pRxPacket = RTMPDeFragmentDataFrame(pAd, pRxBlk);
561 }
562
563 if (pRxPacket)
564 {
565 pEntry = &pAd->MacTab.Content[pRxWI->WirelessCliID];
566
567 // process complete frame
568 if (bFragment && (pRxD->Decrypted) && (pEntry->WepStatus == Ndis802_11Encryption2Enabled))
569 {
570 // Minus MIC length
571 pRxBlk->DataSize -= 8;
572
573 // For TKIP frame, calculate the MIC value
574 if (STACheckTkipMICValue(pAd, pEntry, pRxBlk) == FALSE)
575 {
576 return;
577 }
578 }
579
580 STARxDataFrameAnnounce(pAd, pEntry, pRxBlk, FromWhichBSSID);
581 return;
582 }
583 else
584 {
585 // just return
586 // because RTMPDeFragmentDataFrame() will release rx packet,
587 // if packet is fragmented
588 return;
589 }
590 }
591
592 ASSERT(0);
593 // release packet
594 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
595}
596
597VOID STAHandleRxMgmtFrame(
598 IN PRTMP_ADAPTER pAd,
599 IN RX_BLK *pRxBlk)
600{
601 PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
602 PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
603 PHEADER_802_11 pHeader = pRxBlk->pHeader;
604 PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
605
606 do
607 {
608
609 // We should collect RSSI not only U2M data but also my beacon
610 if ((pHeader->FC.SubType == SUBTYPE_BEACON) && (MAC_ADDR_EQUAL(&pAd->CommonCfg.Bssid, &pHeader->Addr2))
611 && (pAd->RxAnt.EvaluatePeriod == 0))
612 {
613 Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI);
614
615 pAd->StaCfg.LastSNR0 = (UCHAR)(pRxWI->SNR0);
616 pAd->StaCfg.LastSNR1 = (UCHAR)(pRxWI->SNR1);
617 }
618
619#ifdef RT30xx
620 // collect rssi information for antenna diversity
621 if (pAd->NicConfig2.field.AntDiversity)
622 {
623 if ((pRxD->U2M) || ((pHeader->FC.SubType == SUBTYPE_BEACON) && (MAC_ADDR_EQUAL(&pAd->CommonCfg.Bssid, &pHeader->Addr2))))
624 {
625 COLLECT_RX_ANTENNA_AVERAGE_RSSI(pAd, ConvertToRssi(pAd, (UCHAR)pRxWI->RSSI0, RSSI_0), 0); //Note: RSSI2 not used on RT73
626 pAd->StaCfg.NumOfAvgRssiSample ++;
627 }
628 }
629#endif // RT30xx //
630
631 // First check the size, it MUST not exceed the mlme queue size
632 if (pRxWI->MPDUtotalByteCount > MGMT_DMA_BUFFER_SIZE)
633 {
634 DBGPRINT_ERR(("STAHandleRxMgmtFrame: frame too large, size = %d \n", pRxWI->MPDUtotalByteCount));
635 break;
636 }
637
638 REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->WirelessCliID, pHeader, pRxWI->MPDUtotalByteCount,
639 pRxWI->RSSI0, pRxWI->RSSI1, pRxWI->RSSI2, pRxD->PlcpSignal);
640 } while (FALSE);
641
642 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_SUCCESS);
643}
644
645VOID STAHandleRxControlFrame(
646 IN PRTMP_ADAPTER pAd,
647 IN RX_BLK *pRxBlk)
648{
649#ifdef DOT11_N_SUPPORT
650 PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
651#endif // DOT11_N_SUPPORT //
652 PHEADER_802_11 pHeader = pRxBlk->pHeader;
653 PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
654
655 switch (pHeader->FC.SubType)
656 {
657 case SUBTYPE_BLOCK_ACK_REQ:
658#ifdef DOT11_N_SUPPORT
659 {
660 CntlEnqueueForRecv(pAd, pRxWI->WirelessCliID, (pRxWI->MPDUtotalByteCount), (PFRAME_BA_REQ)pHeader);
661 }
662 break;
663#endif // DOT11_N_SUPPORT //
664 case SUBTYPE_BLOCK_ACK:
665 case SUBTYPE_ACK:
666 default:
667 break;
668 }
669
670 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
671}
672
673
674/*
675 ========================================================================
676
677 Routine Description:
678 Process RxDone interrupt, running in DPC level
679
680 Arguments:
681 pAd Pointer to our adapter
682
683 Return Value:
684 None
685
686 IRQL = DISPATCH_LEVEL
687
688 Note:
689 This routine has to maintain Rx ring read pointer.
690 Need to consider QOS DATA format when converting to 802.3
691 ========================================================================
692*/
693BOOLEAN STARxDoneInterruptHandle(
694 IN PRTMP_ADAPTER pAd,
695 IN BOOLEAN argc)
696{
697 NDIS_STATUS Status;
698 UINT32 RxProcessed, RxPending;
699 BOOLEAN bReschedule = FALSE;
700 RT28XX_RXD_STRUC *pRxD;
701 UCHAR *pData;
702 PRXWI_STRUC pRxWI;
703 PNDIS_PACKET pRxPacket;
704 PHEADER_802_11 pHeader;
705 RX_BLK RxCell;
706
707 RxProcessed = RxPending = 0;
708
709 // process whole rx ring
710 while (1)
711 {
712
713 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF |
714 fRTMP_ADAPTER_RESET_IN_PROGRESS |
715 fRTMP_ADAPTER_HALT_IN_PROGRESS |
716 fRTMP_ADAPTER_NIC_NOT_EXIST) ||
717 !RTMP_TEST_FLAG(pAd,fRTMP_ADAPTER_START_UP))
718 {
719 break;
720 }
721
722
723 RxProcessed ++; // test
724
725 // 1. allocate a new data packet into rx ring to replace received packet
726 // then processing the received packet
727 // 2. the callee must take charge of release of packet
728 // 3. As far as driver is concerned ,
729 // the rx packet must
730 // a. be indicated to upper layer or
731 // b. be released if it is discarded
732 pRxPacket = GetPacketFromRxRing(pAd, &(RxCell.RxD), &bReschedule, &RxPending);
733 if (pRxPacket == NULL)
734 {
735 // no more packet to process
736 break;
737 }
738
739 // get rx ring descriptor
740 pRxD = &(RxCell.RxD);
741 // get rx data buffer
742 pData = GET_OS_PKT_DATAPTR(pRxPacket);
743 pRxWI = (PRXWI_STRUC) pData;
744 pHeader = (PHEADER_802_11) (pData+RXWI_SIZE) ;
745
746#ifdef RT_BIG_ENDIAN
747 RTMPFrameEndianChange(pAd, (PUCHAR)pHeader, DIR_READ, TRUE);
748 RTMPWIEndianChange((PUCHAR)pRxWI, TYPE_RXWI);
749#endif
750
751 // build RxCell
752 RxCell.pRxWI = pRxWI;
753 RxCell.pHeader = pHeader;
754 RxCell.pRxPacket = pRxPacket;
755 RxCell.pData = (UCHAR *) pHeader;
756 RxCell.DataSize = pRxWI->MPDUtotalByteCount;
757 RxCell.Flags = 0;
758
759 // Increase Total receive byte counter after real data received no mater any error or not
760 pAd->RalinkCounters.ReceivedByteCount += pRxWI->MPDUtotalByteCount;
761 pAd->RalinkCounters.RxCount ++;
762
763 INC_COUNTER64(pAd->WlanCounters.ReceivedFragmentCount);
764
765 if (pRxWI->MPDUtotalByteCount < 14)
766 Status = NDIS_STATUS_FAILURE;
767
768 if (MONITOR_ON(pAd))
769 {
770 send_monitor_packets(pAd, &RxCell);
771 break;
772 }
773 /* RT2870 invokes STARxDoneInterruptHandle() in rtusb_bulk.c */
774#ifdef RALINK_ATE
775 if (ATE_ON(pAd))
776 {
777 pAd->ate.RxCntPerSec++;
778 ATESampleRssi(pAd, pRxWI);
779#ifdef RALINK_28xx_QA
780 if (pAd->ate.bQARxStart == TRUE)
781 {
782 /* (*pRxD) has been swapped in GetPacketFromRxRing() */
783 ATE_QA_Statistics(pAd, pRxWI, pRxD, pHeader);
784 }
785#endif // RALINK_28xx_QA //
786 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_SUCCESS);
787 continue;
788 }
789#endif // RALINK_ATE //
790
791 // Check for all RxD errors
792 Status = RTMPCheckRxError(pAd, pHeader, pRxWI, pRxD);
793
794 // Handle the received frame
795 if (Status == NDIS_STATUS_SUCCESS)
796 {
797 switch (pHeader->FC.Type)
798 {
799 // CASE I, receive a DATA frame
800 case BTYPE_DATA:
801 {
802 // process DATA frame
803 STAHandleRxDataFrame(pAd, &RxCell);
804 }
805 break;
806 // CASE II, receive a MGMT frame
807 case BTYPE_MGMT:
808 {
809 STAHandleRxMgmtFrame(pAd, &RxCell);
810 }
811 break;
812 // CASE III. receive a CNTL frame
813 case BTYPE_CNTL:
814 {
815 STAHandleRxControlFrame(pAd, &RxCell);
816 }
817 break;
818 // discard other type
819 default:
820 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
821 break;
822 }
823 }
824 else
825 {
826 pAd->Counters8023.RxErrors++;
827 // discard this frame
828 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
829 }
830 }
831
832 return bReschedule;
833}
834
835/*
836 ========================================================================
837
838 Routine Description:
839 Arguments:
840 pAd Pointer to our adapter
841
842 IRQL = DISPATCH_LEVEL
843
844 ========================================================================
845*/
846VOID RTMPHandleTwakeupInterrupt(
847 IN PRTMP_ADAPTER pAd)
848{
849 AsicForceWakeup(pAd, FALSE);
850}
851
852/*
853========================================================================
854Routine Description:
855 Early checking and OS-depened parsing for Tx packet send to our STA driver.
856
857Arguments:
858 NDIS_HANDLE MiniportAdapterContext Pointer refer to the device handle, i.e., the pAd.
859 PPNDIS_PACKET ppPacketArray The packet array need to do transmission.
860 UINT NumberOfPackets Number of packet in packet array.
861
862Return Value:
863 NONE
864
865Note:
866 This function do early checking and classification for send-out packet.
867 You only can put OS-depened & STA related code in here.
868========================================================================
869*/
870VOID STASendPackets(
871 IN NDIS_HANDLE MiniportAdapterContext,
872 IN PPNDIS_PACKET ppPacketArray,
873 IN UINT NumberOfPackets)
874{
875 UINT Index;
876 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) MiniportAdapterContext;
877 PNDIS_PACKET pPacket;
878 BOOLEAN allowToSend = FALSE;
879
880
881 for (Index = 0; Index < NumberOfPackets; Index++)
882 {
883 pPacket = ppPacketArray[Index];
884
885 do
886 {
887
888 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
889 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) ||
890 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
891 {
892 // Drop send request since hardware is in reset state
893 break;
894 }
895 else if (!INFRA_ON(pAd) && !ADHOC_ON(pAd))
896 {
897 // Drop send request since there are no physical connection yet
898 break;
899 }
900 else
901 {
902 // Record that orignal packet source is from NDIS layer,so that
903 // later on driver knows how to release this NDIS PACKET
904#ifdef QOS_DLS_SUPPORT
905 MAC_TABLE_ENTRY *pEntry;
906 PUCHAR pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
907
908 pEntry = MacTableLookup(pAd, pSrcBufVA);
909 if (pEntry && (pEntry->ValidAsDls == TRUE))
910 {
911 RTMP_SET_PACKET_WCID(pPacket, pEntry->Aid);
912 }
913 else
914#endif // QOS_DLS_SUPPORT //
915 RTMP_SET_PACKET_WCID(pPacket, 0); // this field is useless when in STA mode
916 RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
917 NDIS_SET_PACKET_STATUS(pPacket, NDIS_STATUS_PENDING);
918 pAd->RalinkCounters.PendingNdisPacketCount++;
919
920 allowToSend = TRUE;
921 }
922 } while(FALSE);
923
924 if (allowToSend == TRUE)
925 STASendPacket(pAd, pPacket);
926 else
927 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
928 }
929
930 // Dequeue outgoing frames from TxSwQueue[] and process it
931 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
932
933}
934
935
936/*
937========================================================================
938Routine Description:
939 This routine is used to do packet parsing and classification for Tx packet
940 to STA device, and it will en-queue packets to our TxSwQueue depends on AC
941 class.
942
943Arguments:
944 pAd Pointer to our adapter
945 pPacket Pointer to send packet
946
947Return Value:
948 NDIS_STATUS_SUCCESS If succes to queue the packet into TxSwQueue.
949 NDIS_STATUS_FAILURE If failed to do en-queue.
950
951Note:
952 You only can put OS-indepened & STA related code in here.
953========================================================================
954*/
955NDIS_STATUS STASendPacket(
956 IN PRTMP_ADAPTER pAd,
957 IN PNDIS_PACKET pPacket)
958{
959 PACKET_INFO PacketInfo;
960 PUCHAR pSrcBufVA;
961 UINT SrcBufLen;
962 UINT AllowFragSize;
963 UCHAR NumberOfFrag;
964// UCHAR RTSRequired;
965 UCHAR QueIdx, UserPriority;
966 MAC_TABLE_ENTRY *pEntry = NULL;
967 unsigned int IrqFlags;
968 UCHAR FlgIsIP = 0;
969 UCHAR Rate;
970
971 // Prepare packet information structure for buffer descriptor
972 // chained within a single NDIS packet.
973 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
974
975 if (pSrcBufVA == NULL)
976 {
977 DBGPRINT(RT_DEBUG_ERROR,("STASendPacket --> pSrcBufVA == NULL !!!SrcBufLen=%x\n",SrcBufLen));
978 // Resourece is low, system did not allocate virtual address
979 // return NDIS_STATUS_FAILURE directly to upper layer
980 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
981 return NDIS_STATUS_FAILURE;
982 }
983
984
985 if (SrcBufLen < 14)
986 {
987 DBGPRINT(RT_DEBUG_ERROR,("STASendPacket --> Ndis Packet buffer error !!!\n"));
988 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
989 return (NDIS_STATUS_FAILURE);
990 }
991
992 // In HT rate adhoc mode, A-MPDU is often used. So need to lookup BA Table and MAC Entry.
993 // Note multicast packets in adhoc also use BSSID_WCID index.
994 {
995 if(INFRA_ON(pAd))
996 {
997#ifdef QOS_DLS_SUPPORT
998 USHORT tmpWcid;
999
1000 tmpWcid = RTMP_GET_PACKET_WCID(pPacket);
1001 if (VALID_WCID(tmpWcid) &&
1002 (pAd->MacTab.Content[tmpWcid].ValidAsDls== TRUE))
1003 {
1004 pEntry = &pAd->MacTab.Content[tmpWcid];
1005 Rate = pAd->MacTab.Content[tmpWcid].CurrTxRate;
1006 }
1007 else
1008#endif // QOS_DLS_SUPPORT //
1009 {
1010 pEntry = &pAd->MacTab.Content[BSSID_WCID];
1011 RTMP_SET_PACKET_WCID(pPacket, BSSID_WCID);
1012 Rate = pAd->CommonCfg.TxRate;
1013 }
1014 }
1015 else if (ADHOC_ON(pAd))
1016 {
1017 if (*pSrcBufVA & 0x01)
1018 {
1019 RTMP_SET_PACKET_WCID(pPacket, MCAST_WCID);
1020 pEntry = &pAd->MacTab.Content[MCAST_WCID];
1021 }
1022 else
1023 {
1024 pEntry = MacTableLookup(pAd, pSrcBufVA);
1025 }
1026 Rate = pAd->CommonCfg.TxRate;
1027 }
1028 }
1029
1030 if (!pEntry)
1031 {
1032 DBGPRINT(RT_DEBUG_ERROR,("STASendPacket->Cannot find pEntry(%2x:%2x:%2x:%2x:%2x:%2x) in MacTab!\n", PRINT_MAC(pSrcBufVA)));
1033 // Resourece is low, system did not allocate virtual address
1034 // return NDIS_STATUS_FAILURE directly to upper layer
1035 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
1036 return NDIS_STATUS_FAILURE;
1037 }
1038
1039 if (ADHOC_ON(pAd)
1040 )
1041 {
1042 RTMP_SET_PACKET_WCID(pPacket, (UCHAR)pEntry->Aid);
1043 }
1044
1045 //
1046 // Check the Ethernet Frame type of this packet, and set the RTMP_SET_PACKET_SPECIFIC flags.
1047 // Here we set the PACKET_SPECIFIC flags(LLC, VLAN, DHCP/ARP, EAPOL).
1048 RTMPCheckEtherType(pAd, pPacket);
1049
1050
1051
1052 //
1053 // WPA 802.1x secured port control - drop all non-802.1x frame before port secured
1054 //
1055 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
1056 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
1057 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
1058 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
1059#ifdef WPA_SUPPLICANT_SUPPORT
1060 || (pAd->StaCfg.IEEE8021X == TRUE)
1061#endif // WPA_SUPPLICANT_SUPPORT //
1062#ifdef LEAP_SUPPORT
1063 || (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
1064#endif // LEAP_SUPPORT //
1065 )
1066 && ((pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED) || (pAd->StaCfg.MicErrCnt >= 2))
1067 && (RTMP_GET_PACKET_EAPOL(pPacket)== FALSE)
1068 )
1069 {
1070 DBGPRINT(RT_DEBUG_TRACE,("STASendPacket --> Drop packet before port secured !!!\n"));
1071 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
1072
1073 return (NDIS_STATUS_FAILURE);
1074 }
1075
1076
1077 // STEP 1. Decide number of fragments required to deliver this MSDU.
1078 // The estimation here is not very accurate because difficult to
1079 // take encryption overhead into consideration here. The result
1080 // "NumberOfFrag" is then just used to pre-check if enough free
1081 // TXD are available to hold this MSDU.
1082
1083
1084 if (*pSrcBufVA & 0x01) // fragmentation not allowed on multicast & broadcast
1085 NumberOfFrag = 1;
1086 else if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED))
1087 NumberOfFrag = 1; // Aggregation overwhelms fragmentation
1088 else if (CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_AMSDU_INUSED))
1089 NumberOfFrag = 1; // Aggregation overwhelms fragmentation
1090#ifdef DOT11_N_SUPPORT
1091 else if ((pAd->StaCfg.HTPhyMode.field.MODE == MODE_HTMIX) || (pAd->StaCfg.HTPhyMode.field.MODE == MODE_HTGREENFIELD))
1092 NumberOfFrag = 1; // MIMO RATE overwhelms fragmentation
1093#endif // DOT11_N_SUPPORT //
1094 else
1095 {
1096 // The calculated "NumberOfFrag" is a rough estimation because of various
1097 // encryption/encapsulation overhead not taken into consideration. This number is just
1098 // used to make sure enough free TXD are available before fragmentation takes place.
1099 // In case the actual required number of fragments of an NDIS packet
1100 // excceeds "NumberOfFrag"caculated here and not enough free TXD available, the
1101 // last fragment (i.e. last MPDU) will be dropped in RTMPHardTransmit() due to out of
1102 // resource, and the NDIS packet will be indicated NDIS_STATUS_FAILURE. This should
1103 // rarely happen and the penalty is just like a TX RETRY fail. Affordable.
1104
1105 AllowFragSize = (pAd->CommonCfg.FragmentThreshold) - LENGTH_802_11 - LENGTH_CRC;
1106 NumberOfFrag = ((PacketInfo.TotalPacketLength - LENGTH_802_3 + LENGTH_802_1_H) / AllowFragSize) + 1;
1107 // To get accurate number of fragmentation, Minus 1 if the size just match to allowable fragment size
1108 if (((PacketInfo.TotalPacketLength - LENGTH_802_3 + LENGTH_802_1_H) % AllowFragSize) == 0)
1109 {
1110 NumberOfFrag--;
1111 }
1112 }
1113
1114 // Save fragment number to Ndis packet reserved field
1115 RTMP_SET_PACKET_FRAGMENTS(pPacket, NumberOfFrag);
1116
1117
1118 // STEP 2. Check the requirement of RTS:
1119 // If multiple fragment required, RTS is required only for the first fragment
1120 // if the fragment size large than RTS threshold
1121 // For RT28xx, Let ASIC send RTS/CTS
1122 RTMP_SET_PACKET_RTS(pPacket, 0);
1123 RTMP_SET_PACKET_TXRATE(pPacket, pAd->CommonCfg.TxRate);
1124
1125 //
1126 // STEP 3. Traffic classification. outcome = <UserPriority, QueIdx>
1127 //
1128 UserPriority = 0;
1129 QueIdx = QID_AC_BE;
1130 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
1131 CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE))
1132 {
1133 USHORT Protocol;
1134 UCHAR LlcSnapLen = 0, Byte0, Byte1;
1135 do
1136 {
1137 // get Ethernet protocol field
1138 Protocol = (USHORT)((pSrcBufVA[12] << 8) + pSrcBufVA[13]);
1139 if (Protocol <= 1500)
1140 {
1141 // get Ethernet protocol field from LLC/SNAP
1142 if (Sniff2BytesFromNdisBuffer(PacketInfo.pFirstBuffer, LENGTH_802_3 + 6, &Byte0, &Byte1) != NDIS_STATUS_SUCCESS)
1143 break;
1144
1145 Protocol = (USHORT)((Byte0 << 8) + Byte1);
1146 LlcSnapLen = 8;
1147 }
1148
1149 // always AC_BE for non-IP packet
1150 if (Protocol != 0x0800)
1151 break;
1152
1153 // get IP header
1154 if (Sniff2BytesFromNdisBuffer(PacketInfo.pFirstBuffer, LENGTH_802_3 + LlcSnapLen, &Byte0, &Byte1) != NDIS_STATUS_SUCCESS)
1155 break;
1156
1157 // return AC_BE if packet is not IPv4
1158 if ((Byte0 & 0xf0) != 0x40)
1159 break;
1160
1161 FlgIsIP = 1;
1162 UserPriority = (Byte1 & 0xe0) >> 5;
1163 QueIdx = MapUserPriorityToAccessCategory[UserPriority];
1164
1165 // TODO: have to check ACM bit. apply TSPEC if ACM is ON
1166 // TODO: downgrade UP & QueIdx before passing ACM
1167 if (pAd->CommonCfg.APEdcaParm.bACM[QueIdx])
1168 {
1169 UserPriority = 0;
1170 QueIdx = QID_AC_BE;
1171 }
1172 } while (FALSE);
1173 }
1174
1175 RTMP_SET_PACKET_UP(pPacket, UserPriority);
1176
1177
1178
1179 // Make sure SendTxWait queue resource won't be used by other threads
1180 RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
1181 if (pAd->TxSwQueue[QueIdx].Number >= MAX_PACKETS_IN_QUEUE)
1182 {
1183 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
1184#ifdef BLOCK_NET_IF
1185 StopNetIfQueue(pAd, QueIdx, pPacket);
1186#endif // BLOCK_NET_IF //
1187 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
1188
1189 return NDIS_STATUS_FAILURE;
1190 }
1191 else
1192 {
1193 InsertTailQueue(&pAd->TxSwQueue[QueIdx], PACKET_TO_QUEUE_ENTRY(pPacket));
1194 }
1195 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
1196
1197#ifdef DOT11_N_SUPPORT
1198 if ((pAd->CommonCfg.BACapability.field.AutoBA == TRUE)&&
1199 IS_HT_STA(pEntry))
1200 {
1201 //PMAC_TABLE_ENTRY pMacEntry = &pAd->MacTab.Content[BSSID_WCID];
1202 if (((pEntry->TXBAbitmap & (1<<UserPriority)) == 0) &&
1203 ((pEntry->BADeclineBitmap & (1<<UserPriority)) == 0) &&
1204 (pEntry->PortSecured == WPA_802_1X_PORT_SECURED)
1205 // For IOT compatibility, if
1206 // 1. It is Ralink chip or
1207 // 2. It is OPEN or AES mode,
1208 // then BA session can be bulit.
1209 && ((pEntry->ValidAsCLI && pAd->MlmeAux.APRalinkIe != 0x0) ||
1210 (pEntry->WepStatus == Ndis802_11WEPDisabled || pEntry->WepStatus == Ndis802_11Encryption3Enabled))
1211 )
1212 {
1213 BAOriSessionSetUp(pAd, pEntry, 0, 0, 10, FALSE);
1214 }
1215 }
1216#endif // DOT11_N_SUPPORT //
1217
1218 pAd->RalinkCounters.OneSecOsTxCount[QueIdx]++; // TODO: for debug only. to be removed
1219 return NDIS_STATUS_SUCCESS;
1220}
1221
1222
1223/*
1224 ========================================================================
1225
1226 Routine Description:
1227 This subroutine will scan through releative ring descriptor to find
1228 out avaliable free ring descriptor and compare with request size.
1229
1230 Arguments:
1231 pAd Pointer to our adapter
1232 QueIdx Selected TX Ring
1233
1234 Return Value:
1235 NDIS_STATUS_FAILURE Not enough free descriptor
1236 NDIS_STATUS_SUCCESS Enough free descriptor
1237
1238 IRQL = PASSIVE_LEVEL
1239 IRQL = DISPATCH_LEVEL
1240
1241 Note:
1242
1243 ========================================================================
1244*/
1245
1246#ifdef RT2870
1247/*
1248 Actually, this function used to check if the TxHardware Queue still has frame need to send.
1249 If no frame need to send, go to sleep, else, still wake up.
1250*/
1251NDIS_STATUS RTMPFreeTXDRequest(
1252 IN PRTMP_ADAPTER pAd,
1253 IN UCHAR QueIdx,
1254 IN UCHAR NumberRequired,
1255 IN PUCHAR FreeNumberIs)
1256{
1257 //ULONG FreeNumber = 0;
1258 NDIS_STATUS Status = NDIS_STATUS_FAILURE;
1259 unsigned long IrqFlags;
1260 HT_TX_CONTEXT *pHTTXContext;
1261
1262 switch (QueIdx)
1263 {
1264 case QID_AC_BK:
1265 case QID_AC_BE:
1266 case QID_AC_VI:
1267 case QID_AC_VO:
1268 case QID_HCCA:
1269 {
1270 pHTTXContext = &pAd->TxContext[QueIdx];
1271 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
1272 if ((pHTTXContext->CurWritePosition != pHTTXContext->ENextBulkOutPosition) ||
1273 (pHTTXContext->IRPPending == TRUE))
1274 {
1275 Status = NDIS_STATUS_FAILURE;
1276 }
1277 else
1278 {
1279 Status = NDIS_STATUS_SUCCESS;
1280 }
1281 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
1282 }
1283 break;
1284
1285 case QID_MGMT:
1286 if (pAd->MgmtRing.TxSwFreeIdx != MGMT_RING_SIZE)
1287 Status = NDIS_STATUS_FAILURE;
1288 else
1289 Status = NDIS_STATUS_SUCCESS;
1290 break;
1291
1292 default:
1293 DBGPRINT(RT_DEBUG_ERROR,("RTMPFreeTXDRequest::Invalid QueIdx(=%d)\n", QueIdx));
1294 break;
1295 }
1296
1297 return (Status);
1298
1299}
1300#endif // RT2870 //
1301
1302
1303VOID RTMPSendDisassociationFrame(
1304 IN PRTMP_ADAPTER pAd)
1305{
1306}
1307
1308VOID RTMPSendNullFrame(
1309 IN PRTMP_ADAPTER pAd,
1310 IN UCHAR TxRate,
1311 IN BOOLEAN bQosNull)
1312{
1313 UCHAR NullFrame[48];
1314 ULONG Length;
1315 PHEADER_802_11 pHeader_802_11;
1316
1317
1318#ifdef RALINK_ATE
1319 if(ATE_ON(pAd))
1320 {
1321 return;
1322 }
1323#endif // RALINK_ATE //
1324
1325 // WPA 802.1x secured port control
1326 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
1327 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
1328 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
1329 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
1330#ifdef WPA_SUPPLICANT_SUPPORT
1331 || (pAd->StaCfg.IEEE8021X == TRUE)
1332#endif
1333 ) &&
1334 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
1335 {
1336 return;
1337 }
1338
1339 NdisZeroMemory(NullFrame, 48);
1340 Length = sizeof(HEADER_802_11);
1341
1342 pHeader_802_11 = (PHEADER_802_11) NullFrame;
1343
1344 pHeader_802_11->FC.Type = BTYPE_DATA;
1345 pHeader_802_11->FC.SubType = SUBTYPE_NULL_FUNC;
1346 pHeader_802_11->FC.ToDs = 1;
1347 COPY_MAC_ADDR(pHeader_802_11->Addr1, pAd->CommonCfg.Bssid);
1348 COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
1349 COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid);
1350
1351 if (pAd->CommonCfg.bAPSDForcePowerSave)
1352 {
1353 pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
1354 }
1355 else
1356 {
1357 pHeader_802_11->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE) ? 1: 0;
1358 }
1359 pHeader_802_11->Duration = pAd->CommonCfg.Dsifs + RTMPCalcDuration(pAd, TxRate, 14);
1360
1361 pAd->Sequence++;
1362 pHeader_802_11->Sequence = pAd->Sequence;
1363
1364 // Prepare QosNull function frame
1365 if (bQosNull)
1366 {
1367 pHeader_802_11->FC.SubType = SUBTYPE_QOS_NULL;
1368
1369 // copy QOS control bytes
1370 NullFrame[Length] = 0;
1371 NullFrame[Length+1] = 0;
1372 Length += 2;// if pad with 2 bytes for alignment, APSD will fail
1373 }
1374
1375 HAL_KickOutNullFrameTx(pAd, 0, NullFrame, Length);
1376
1377}
1378
1379// IRQL = DISPATCH_LEVEL
1380VOID RTMPSendRTSFrame(
1381 IN PRTMP_ADAPTER pAd,
1382 IN PUCHAR pDA,
1383 IN unsigned int NextMpduSize,
1384 IN UCHAR TxRate,
1385 IN UCHAR RTSRate,
1386 IN USHORT AckDuration,
1387 IN UCHAR QueIdx,
1388 IN UCHAR FrameGap)
1389{
1390}
1391
1392
1393
1394// --------------------------------------------------------
1395// FIND ENCRYPT KEY AND DECIDE CIPHER ALGORITHM
1396// Find the WPA key, either Group or Pairwise Key
1397// LEAP + TKIP also use WPA key.
1398// --------------------------------------------------------
1399// Decide WEP bit and cipher suite to be used. Same cipher suite should be used for whole fragment burst
1400// In Cisco CCX 2.0 Leap Authentication
1401// WepStatus is Ndis802_11Encryption1Enabled but the key will use PairwiseKey
1402// Instead of the SharedKey, SharedKey Length may be Zero.
1403VOID STAFindCipherAlgorithm(
1404 IN PRTMP_ADAPTER pAd,
1405 IN TX_BLK *pTxBlk)
1406{
1407 NDIS_802_11_ENCRYPTION_STATUS Cipher; // To indicate cipher used for this packet
1408 UCHAR CipherAlg = CIPHER_NONE; // cipher alogrithm
1409 UCHAR KeyIdx = 0xff;
1410 PUCHAR pSrcBufVA;
1411 PCIPHER_KEY pKey = NULL;
1412
1413 pSrcBufVA = GET_OS_PKT_DATAPTR(pTxBlk->pPacket);
1414
1415 {
1416 // Select Cipher
1417 if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd)))
1418 Cipher = pAd->StaCfg.GroupCipher; // Cipher for Multicast or Broadcast
1419 else
1420 Cipher = pAd->StaCfg.PairCipher; // Cipher for Unicast
1421
1422 if (RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket))
1423 {
1424 ASSERT(pAd->SharedKey[BSS0][0].CipherAlg <= CIPHER_CKIP128);
1425
1426 // 4-way handshaking frame must be clear
1427 if (!(TX_BLK_TEST_FLAG(pTxBlk, fTX_bClearEAPFrame)) && (pAd->SharedKey[BSS0][0].CipherAlg) &&
1428 (pAd->SharedKey[BSS0][0].KeyLen))
1429 {
1430 CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
1431 KeyIdx = 0;
1432 }
1433 }
1434 else if (Cipher == Ndis802_11Encryption1Enabled)
1435 {
1436#ifdef LEAP_SUPPORT
1437 if (pAd->StaCfg.CkipFlag & 0x10) // Cisco CKIP KP is on
1438 {
1439 if (LEAP_CCKM_ON(pAd))
1440 {
1441 if (((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd))))
1442 KeyIdx = 1;
1443 else
1444 KeyIdx = 0;
1445 }
1446 else
1447 KeyIdx = pAd->StaCfg.DefaultKeyId;
1448 }
1449 else if (pAd->StaCfg.CkipFlag & 0x08) // only CKIP CMIC
1450 KeyIdx = pAd->StaCfg.DefaultKeyId;
1451 else if (LEAP_CCKM_ON(pAd))
1452 {
1453 if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd)))
1454 KeyIdx = 1;
1455 else
1456 KeyIdx = 0;
1457 }
1458 else // standard WEP64 or WEP128
1459#endif // LEAP_SUPPORT //
1460 KeyIdx = pAd->StaCfg.DefaultKeyId;
1461 }
1462 else if ((Cipher == Ndis802_11Encryption2Enabled) ||
1463 (Cipher == Ndis802_11Encryption3Enabled))
1464 {
1465 if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd))) // multicast
1466 KeyIdx = pAd->StaCfg.DefaultKeyId;
1467 else if (pAd->SharedKey[BSS0][0].KeyLen)
1468 KeyIdx = 0;
1469 else
1470 KeyIdx = pAd->StaCfg.DefaultKeyId;
1471 }
1472
1473 if (KeyIdx == 0xff)
1474 CipherAlg = CIPHER_NONE;
1475 else if ((Cipher == Ndis802_11EncryptionDisabled) || (pAd->SharedKey[BSS0][KeyIdx].KeyLen == 0))
1476 CipherAlg = CIPHER_NONE;
1477#ifdef WPA_SUPPLICANT_SUPPORT
1478 else if ( pAd->StaCfg.WpaSupplicantUP &&
1479 (Cipher == Ndis802_11Encryption1Enabled) &&
1480 (pAd->StaCfg.IEEE8021X == TRUE) &&
1481 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
1482 CipherAlg = CIPHER_NONE;
1483#endif // WPA_SUPPLICANT_SUPPORT //
1484 else
1485 {
1486 //Header_802_11.FC.Wep = 1;
1487 CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
1488 pKey = &pAd->SharedKey[BSS0][KeyIdx];
1489 }
1490 }
1491
1492 pTxBlk->CipherAlg = CipherAlg;
1493 pTxBlk->pKey = pKey;
1494}
1495
1496
1497VOID STABuildCommon802_11Header(
1498 IN PRTMP_ADAPTER pAd,
1499 IN TX_BLK *pTxBlk)
1500{
1501
1502 HEADER_802_11 *pHeader_802_11;
1503#ifdef QOS_DLS_SUPPORT
1504 BOOLEAN bDLSFrame = FALSE;
1505 INT DlsEntryIndex = 0;
1506#endif // QOS_DLS_SUPPORT //
1507
1508 //
1509 // MAKE A COMMON 802.11 HEADER
1510 //
1511
1512 // normal wlan header size : 24 octets
1513 pTxBlk->MpduHeaderLen = sizeof(HEADER_802_11);
1514
1515 pHeader_802_11 = (HEADER_802_11 *) &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
1516
1517 NdisZeroMemory(pHeader_802_11, sizeof(HEADER_802_11));
1518
1519 pHeader_802_11->FC.FrDs = 0;
1520 pHeader_802_11->FC.Type = BTYPE_DATA;
1521 pHeader_802_11->FC.SubType = ((TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) ? SUBTYPE_QDATA : SUBTYPE_DATA);
1522
1523#ifdef QOS_DLS_SUPPORT
1524 if (INFRA_ON(pAd))
1525 {
1526 // Check if the frame can be sent through DLS direct link interface
1527 // If packet can be sent through DLS, then force aggregation disable. (Hard to determine peer STA's capability)
1528 DlsEntryIndex = RTMPCheckDLSFrame(pAd, pTxBlk->pSrcBufHeader);
1529 if (DlsEntryIndex >= 0)
1530 bDLSFrame = TRUE;
1531 else
1532 bDLSFrame = FALSE;
1533 }
1534#endif // QOS_DLS_SUPPORT //
1535
1536 if (pTxBlk->pMacEntry)
1537 {
1538 if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bForceNonQoS))
1539 {
1540 pHeader_802_11->Sequence = pTxBlk->pMacEntry->NonQosDataSeq;
1541 pTxBlk->pMacEntry->NonQosDataSeq = (pTxBlk->pMacEntry->NonQosDataSeq+1) & MAXSEQ;
1542 }
1543 else
1544 {
1545#ifdef QOS_DLS_SUPPORT
1546 if (bDLSFrame)
1547 {
1548 pHeader_802_11->Sequence = pAd->StaCfg.DLSEntry[DlsEntryIndex].Sequence;
1549 pAd->StaCfg.DLSEntry[DlsEntryIndex].Sequence = (pAd->StaCfg.DLSEntry[DlsEntryIndex].Sequence+1) & MAXSEQ;
1550 }
1551 else
1552#endif // QOS_DLS_SUPPORT //
1553 {
1554 pHeader_802_11->Sequence = pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority];
1555 pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority] = (pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority]+1) & MAXSEQ;
1556 }
1557 }
1558 }
1559 else
1560 {
1561 pHeader_802_11->Sequence = pAd->Sequence;
1562 pAd->Sequence = (pAd->Sequence+1) & MAXSEQ; // next sequence
1563 }
1564
1565 pHeader_802_11->Frag = 0;
1566
1567 pHeader_802_11->FC.MoreData = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData);
1568
1569 {
1570 if (INFRA_ON(pAd))
1571 {
1572#ifdef QOS_DLS_SUPPORT
1573 if (bDLSFrame)
1574 {
1575 COPY_MAC_ADDR(pHeader_802_11->Addr1, pTxBlk->pSrcBufHeader);
1576 COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
1577 COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid);
1578 pHeader_802_11->FC.ToDs = 0;
1579 }
1580 else
1581#endif // QOS_DLS_SUPPORT //
1582 {
1583 COPY_MAC_ADDR(pHeader_802_11->Addr1, pAd->CommonCfg.Bssid);
1584 COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
1585 COPY_MAC_ADDR(pHeader_802_11->Addr3, pTxBlk->pSrcBufHeader);
1586 pHeader_802_11->FC.ToDs = 1;
1587 }
1588 }
1589 else if (ADHOC_ON(pAd))
1590 {
1591 COPY_MAC_ADDR(pHeader_802_11->Addr1, pTxBlk->pSrcBufHeader);
1592 COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
1593 COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid);
1594 pHeader_802_11->FC.ToDs = 0;
1595 }
1596 }
1597
1598 if (pTxBlk->CipherAlg != CIPHER_NONE)
1599 pHeader_802_11->FC.Wep = 1;
1600
1601 // -----------------------------------------------------------------
1602 // STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later.
1603 // -----------------------------------------------------------------
1604 if (pAd->CommonCfg.bAPSDForcePowerSave)
1605 pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
1606 else
1607 pHeader_802_11->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
1608}
1609
1610#ifdef DOT11_N_SUPPORT
1611VOID STABuildCache802_11Header(
1612 IN RTMP_ADAPTER *pAd,
1613 IN TX_BLK *pTxBlk,
1614 IN UCHAR *pHeader)
1615{
1616 MAC_TABLE_ENTRY *pMacEntry;
1617 PHEADER_802_11 pHeader80211;
1618
1619 pHeader80211 = (PHEADER_802_11)pHeader;
1620 pMacEntry = pTxBlk->pMacEntry;
1621
1622 //
1623 // Update the cached 802.11 HEADER
1624 //
1625
1626 // normal wlan header size : 24 octets
1627 pTxBlk->MpduHeaderLen = sizeof(HEADER_802_11);
1628
1629 // More Bit
1630 pHeader80211->FC.MoreData = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData);
1631
1632 // Sequence
1633 pHeader80211->Sequence = pMacEntry->TxSeq[pTxBlk->UserPriority];
1634 pMacEntry->TxSeq[pTxBlk->UserPriority] = (pMacEntry->TxSeq[pTxBlk->UserPriority]+1) & MAXSEQ;
1635
1636 {
1637 // Check if the frame can be sent through DLS direct link interface
1638 // If packet can be sent through DLS, then force aggregation disable. (Hard to determine peer STA's capability)
1639#ifdef QOS_DLS_SUPPORT
1640 BOOLEAN bDLSFrame = FALSE;
1641 INT DlsEntryIndex = 0;
1642
1643 DlsEntryIndex = RTMPCheckDLSFrame(pAd, pTxBlk->pSrcBufHeader);
1644 if (DlsEntryIndex >= 0)
1645 bDLSFrame = TRUE;
1646 else
1647 bDLSFrame = FALSE;
1648#endif // QOS_DLS_SUPPORT //
1649
1650 // The addr3 of normal packet send from DS is Dest Mac address.
1651#ifdef QOS_DLS_SUPPORT
1652 if (bDLSFrame)
1653 {
1654 COPY_MAC_ADDR(pHeader80211->Addr1, pTxBlk->pSrcBufHeader);
1655 COPY_MAC_ADDR(pHeader80211->Addr3, pAd->CommonCfg.Bssid);
1656 pHeader80211->FC.ToDs = 0;
1657 }
1658 else
1659#endif // QOS_DLS_SUPPORT //
1660 if (ADHOC_ON(pAd))
1661 COPY_MAC_ADDR(pHeader80211->Addr3, pAd->CommonCfg.Bssid);
1662 else
1663 COPY_MAC_ADDR(pHeader80211->Addr3, pTxBlk->pSrcBufHeader);
1664 }
1665
1666 // -----------------------------------------------------------------
1667 // STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later.
1668 // -----------------------------------------------------------------
1669 if (pAd->CommonCfg.bAPSDForcePowerSave)
1670 pHeader80211->FC.PwrMgmt = PWR_SAVE;
1671 else
1672 pHeader80211->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
1673}
1674#endif // DOT11_N_SUPPORT //
1675
1676static inline PUCHAR STA_Build_ARalink_Frame_Header(
1677 IN RTMP_ADAPTER *pAd,
1678 IN TX_BLK *pTxBlk)
1679{
1680 PUCHAR pHeaderBufPtr;
1681 HEADER_802_11 *pHeader_802_11;
1682 PNDIS_PACKET pNextPacket;
1683 UINT32 nextBufLen;
1684 PQUEUE_ENTRY pQEntry;
1685
1686 STAFindCipherAlgorithm(pAd, pTxBlk);
1687 STABuildCommon802_11Header(pAd, pTxBlk);
1688
1689
1690 pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
1691 pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
1692
1693 // steal "order" bit to mark "aggregation"
1694 pHeader_802_11->FC.Order = 1;
1695
1696 // skip common header
1697 pHeaderBufPtr += pTxBlk->MpduHeaderLen;
1698
1699 if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM))
1700 {
1701 //
1702 // build QOS Control bytes
1703 //
1704 *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
1705
1706 *(pHeaderBufPtr+1) = 0;
1707 pHeaderBufPtr +=2;
1708 pTxBlk->MpduHeaderLen += 2;
1709 }
1710
1711 // padding at front of LLC header. LLC header should at 4-bytes aligment.
1712 pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
1713 pHeaderBufPtr = (PCHAR)ROUND_UP(pHeaderBufPtr, 4);
1714 pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
1715
1716 // For RA Aggregation,
1717 // put the 2nd MSDU length(extra 2-byte field) after QOS_CONTROL in little endian format
1718 pQEntry = pTxBlk->TxPacketList.Head;
1719 pNextPacket = QUEUE_ENTRY_TO_PKT(pQEntry);
1720 nextBufLen = GET_OS_PKT_LEN(pNextPacket);
1721 if (RTMP_GET_PACKET_VLAN(pNextPacket))
1722 nextBufLen -= LENGTH_802_1Q;
1723
1724 *pHeaderBufPtr = (UCHAR)nextBufLen & 0xff;
1725 *(pHeaderBufPtr+1) = (UCHAR)(nextBufLen >> 8);
1726
1727 pHeaderBufPtr += 2;
1728 pTxBlk->MpduHeaderLen += 2;
1729
1730 return pHeaderBufPtr;
1731
1732}
1733
1734#ifdef DOT11_N_SUPPORT
1735static inline PUCHAR STA_Build_AMSDU_Frame_Header(
1736 IN RTMP_ADAPTER *pAd,
1737 IN TX_BLK *pTxBlk)
1738{
1739 PUCHAR pHeaderBufPtr;//, pSaveBufPtr;
1740 HEADER_802_11 *pHeader_802_11;
1741
1742
1743 STAFindCipherAlgorithm(pAd, pTxBlk);
1744 STABuildCommon802_11Header(pAd, pTxBlk);
1745
1746 pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
1747 pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
1748
1749 // skip common header
1750 pHeaderBufPtr += pTxBlk->MpduHeaderLen;
1751
1752 //
1753 // build QOS Control bytes
1754 //
1755 *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
1756
1757 //
1758 // A-MSDU packet
1759 //
1760 *pHeaderBufPtr |= 0x80;
1761
1762 *(pHeaderBufPtr+1) = 0;
1763 pHeaderBufPtr +=2;
1764 pTxBlk->MpduHeaderLen += 2;
1765
1766 //pSaveBufPtr = pHeaderBufPtr;
1767
1768 //
1769 // padding at front of LLC header
1770 // LLC header should locate at 4-octets aligment
1771 //
1772 // @@@ MpduHeaderLen excluding padding @@@
1773 //
1774 pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
1775 pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
1776 pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
1777
1778 return pHeaderBufPtr;
1779
1780}
1781
1782
1783VOID STA_AMPDU_Frame_Tx(
1784 IN PRTMP_ADAPTER pAd,
1785 IN TX_BLK *pTxBlk)
1786{
1787 HEADER_802_11 *pHeader_802_11;
1788 PUCHAR pHeaderBufPtr;
1789 USHORT FreeNumber;
1790 MAC_TABLE_ENTRY *pMacEntry;
1791 BOOLEAN bVLANPkt;
1792 PQUEUE_ENTRY pQEntry;
1793
1794 ASSERT(pTxBlk);
1795
1796 while(pTxBlk->TxPacketList.Head)
1797 {
1798 pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
1799 pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
1800 if ( RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
1801 {
1802 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
1803 continue;
1804 }
1805
1806 bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
1807
1808 pMacEntry = pTxBlk->pMacEntry;
1809 if (pMacEntry->isCached)
1810 {
1811 // NOTE: Please make sure the size of pMacEntry->CachedBuf[] is smaller than pTxBlk->HeaderBuf[]!!!!
1812 NdisMoveMemory((PUCHAR)&pTxBlk->HeaderBuf[TXINFO_SIZE], (PUCHAR)&pMacEntry->CachedBuf[0], TXWI_SIZE + sizeof(HEADER_802_11));
1813 pHeaderBufPtr = (PUCHAR)(&pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE]);
1814 STABuildCache802_11Header(pAd, pTxBlk, pHeaderBufPtr);
1815 }
1816 else
1817 {
1818 STAFindCipherAlgorithm(pAd, pTxBlk);
1819 STABuildCommon802_11Header(pAd, pTxBlk);
1820
1821 pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
1822 }
1823
1824
1825 pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
1826
1827 // skip common header
1828 pHeaderBufPtr += pTxBlk->MpduHeaderLen;
1829
1830 //
1831 // build QOS Control bytes
1832 //
1833 *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
1834 *(pHeaderBufPtr+1) = 0;
1835 pHeaderBufPtr +=2;
1836 pTxBlk->MpduHeaderLen += 2;
1837
1838 //
1839 // build HTC+
1840 // HTC control filed following QoS field
1841 //
1842 if ((pAd->CommonCfg.bRdg == TRUE) && CLIENT_STATUS_TEST_FLAG(pTxBlk->pMacEntry, fCLIENT_STATUS_RDG_CAPABLE))
1843 {
1844 if (pMacEntry->isCached == FALSE)
1845 {
1846 // mark HTC bit
1847 pHeader_802_11->FC.Order = 1;
1848
1849 NdisZeroMemory(pHeaderBufPtr, 4);
1850 *(pHeaderBufPtr+3) |= 0x80;
1851 }
1852 pHeaderBufPtr += 4;
1853 pTxBlk->MpduHeaderLen += 4;
1854 }
1855
1856 //pTxBlk->MpduHeaderLen = pHeaderBufPtr - pTxBlk->HeaderBuf - TXWI_SIZE - TXINFO_SIZE;
1857 ASSERT(pTxBlk->MpduHeaderLen >= 24);
1858
1859 // skip 802.3 header
1860 pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
1861 pTxBlk->SrcBufLen -= LENGTH_802_3;
1862
1863 // skip vlan tag
1864 if (bVLANPkt)
1865 {
1866 pTxBlk->pSrcBufData += LENGTH_802_1Q;
1867 pTxBlk->SrcBufLen -= LENGTH_802_1Q;
1868 }
1869
1870 //
1871 // padding at front of LLC header
1872 // LLC header should locate at 4-octets aligment
1873 //
1874 // @@@ MpduHeaderLen excluding padding @@@
1875 //
1876 pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
1877 pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
1878 pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
1879
1880 {
1881
1882 //
1883 // Insert LLC-SNAP encapsulation - 8 octets
1884 //
1885 EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData-2, pTxBlk->pExtraLlcSnapEncap);
1886 if (pTxBlk->pExtraLlcSnapEncap)
1887 {
1888 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
1889 pHeaderBufPtr += 6;
1890 // get 2 octets (TypeofLen)
1891 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
1892 pHeaderBufPtr += 2;
1893 pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
1894 }
1895
1896 }
1897
1898 if (pMacEntry->isCached)
1899 {
1900 RTMPWriteTxWI_Cache(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
1901 }
1902 else
1903 {
1904 RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
1905
1906 NdisZeroMemory((PUCHAR)(&pMacEntry->CachedBuf[0]), sizeof(pMacEntry->CachedBuf));
1907 NdisMoveMemory((PUCHAR)(&pMacEntry->CachedBuf[0]), (PUCHAR)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), (pHeaderBufPtr - (PUCHAR)(&pTxBlk->HeaderBuf[TXINFO_SIZE])));
1908 pMacEntry->isCached = TRUE;
1909 }
1910
1911 // calculate Transmitted AMPDU count and ByteCount
1912 {
1913 pAd->RalinkCounters.TransmittedMPDUsInAMPDUCount.u.LowPart ++;
1914 pAd->RalinkCounters.TransmittedOctetsInAMPDUCount.QuadPart += pTxBlk->SrcBufLen;
1915 }
1916
1917 //FreeNumber = GET_TXRING_FREENO(pAd, QueIdx);
1918
1919 HAL_WriteTxResource(pAd, pTxBlk, TRUE, &FreeNumber);
1920
1921 //
1922 // Kick out Tx
1923 //
1924 HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
1925
1926 pAd->RalinkCounters.KickTxCount++;
1927 pAd->RalinkCounters.OneSecTxDoneCount++;
1928 }
1929
1930}
1931
1932
1933VOID STA_AMSDU_Frame_Tx(
1934 IN PRTMP_ADAPTER pAd,
1935 IN TX_BLK *pTxBlk)
1936{
1937 PUCHAR pHeaderBufPtr;
1938 USHORT FreeNumber;
1939 USHORT subFramePayloadLen = 0; // AMSDU Subframe length without AMSDU-Header / Padding.
1940 USHORT totalMPDUSize=0;
1941 UCHAR *subFrameHeader;
1942 UCHAR padding = 0;
1943 USHORT FirstTx = 0, LastTxIdx = 0;
1944 BOOLEAN bVLANPkt;
1945 int frameNum = 0;
1946 PQUEUE_ENTRY pQEntry;
1947
1948
1949 ASSERT(pTxBlk);
1950
1951 ASSERT((pTxBlk->TxPacketList.Number > 1));
1952
1953 while(pTxBlk->TxPacketList.Head)
1954 {
1955 pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
1956 pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
1957 if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
1958 {
1959 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
1960 continue;
1961 }
1962
1963 bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
1964
1965 // skip 802.3 header
1966 pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
1967 pTxBlk->SrcBufLen -= LENGTH_802_3;
1968
1969 // skip vlan tag
1970 if (bVLANPkt)
1971 {
1972 pTxBlk->pSrcBufData += LENGTH_802_1Q;
1973 pTxBlk->SrcBufLen -= LENGTH_802_1Q;
1974 }
1975
1976 if (frameNum == 0)
1977 {
1978 pHeaderBufPtr = STA_Build_AMSDU_Frame_Header(pAd, pTxBlk);
1979
1980 // NOTE: TxWI->MPDUtotalByteCount will be updated after final frame was handled.
1981 RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
1982 }
1983 else
1984 {
1985 pHeaderBufPtr = &pTxBlk->HeaderBuf[0];
1986 padding = ROUND_UP(LENGTH_AMSDU_SUBFRAMEHEAD + subFramePayloadLen, 4) - (LENGTH_AMSDU_SUBFRAMEHEAD + subFramePayloadLen);
1987 NdisZeroMemory(pHeaderBufPtr, padding + LENGTH_AMSDU_SUBFRAMEHEAD);
1988 pHeaderBufPtr += padding;
1989 pTxBlk->MpduHeaderLen = padding;
1990 }
1991
1992 //
1993 // A-MSDU subframe
1994 // DA(6)+SA(6)+Length(2) + LLC/SNAP Encap
1995 //
1996 subFrameHeader = pHeaderBufPtr;
1997 subFramePayloadLen = pTxBlk->SrcBufLen;
1998
1999 NdisMoveMemory(subFrameHeader, pTxBlk->pSrcBufHeader, 12);
2000
2001
2002 pHeaderBufPtr += LENGTH_AMSDU_SUBFRAMEHEAD;
2003 pTxBlk->MpduHeaderLen += LENGTH_AMSDU_SUBFRAMEHEAD;
2004
2005
2006 //
2007 // Insert LLC-SNAP encapsulation - 8 octets
2008 //
2009 EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData-2, pTxBlk->pExtraLlcSnapEncap);
2010
2011 subFramePayloadLen = pTxBlk->SrcBufLen;
2012
2013 if (pTxBlk->pExtraLlcSnapEncap)
2014 {
2015 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
2016 pHeaderBufPtr += 6;
2017 // get 2 octets (TypeofLen)
2018 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
2019 pHeaderBufPtr += 2;
2020 pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
2021 subFramePayloadLen += LENGTH_802_1_H;
2022 }
2023
2024 // update subFrame Length field
2025 subFrameHeader[12] = (subFramePayloadLen & 0xFF00) >> 8;
2026 subFrameHeader[13] = subFramePayloadLen & 0xFF;
2027
2028 totalMPDUSize += pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
2029
2030 if (frameNum ==0)
2031 FirstTx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
2032 else
2033 LastTxIdx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
2034
2035 frameNum++;
2036
2037 pAd->RalinkCounters.KickTxCount++;
2038 pAd->RalinkCounters.OneSecTxDoneCount++;
2039
2040 // calculate Transmitted AMSDU Count and ByteCount
2041 {
2042 pAd->RalinkCounters.TransmittedAMSDUCount.u.LowPart ++;
2043 pAd->RalinkCounters.TransmittedOctetsInAMSDU.QuadPart += totalMPDUSize;
2044 }
2045
2046 }
2047
2048 HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, FirstTx);
2049 HAL_LastTxIdx(pAd, pTxBlk->QueIdx, LastTxIdx);
2050
2051 //
2052 // Kick out Tx
2053 //
2054 HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
2055}
2056#endif // DOT11_N_SUPPORT //
2057
2058VOID STA_Legacy_Frame_Tx(
2059 IN PRTMP_ADAPTER pAd,
2060 IN TX_BLK *pTxBlk)
2061{
2062 HEADER_802_11 *pHeader_802_11;
2063 PUCHAR pHeaderBufPtr;
2064 USHORT FreeNumber;
2065 BOOLEAN bVLANPkt;
2066 PQUEUE_ENTRY pQEntry;
2067
2068 ASSERT(pTxBlk);
2069
2070
2071 pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
2072 pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
2073 if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
2074 {
2075 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
2076 return;
2077 }
2078
2079 if (pTxBlk->TxFrameType == TX_MCAST_FRAME)
2080 {
2081 INC_COUNTER64(pAd->WlanCounters.MulticastTransmittedFrameCount);
2082 }
2083
2084 if (RTMP_GET_PACKET_RTS(pTxBlk->pPacket))
2085 TX_BLK_SET_FLAG(pTxBlk, fTX_bRtsRequired);
2086 else
2087 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bRtsRequired);
2088
2089 bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
2090
2091 if (pTxBlk->TxRate < pAd->CommonCfg.MinTxRate)
2092 pTxBlk->TxRate = pAd->CommonCfg.MinTxRate;
2093
2094 STAFindCipherAlgorithm(pAd, pTxBlk);
2095 STABuildCommon802_11Header(pAd, pTxBlk);
2096
2097
2098 // skip 802.3 header
2099 pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
2100 pTxBlk->SrcBufLen -= LENGTH_802_3;
2101
2102 // skip vlan tag
2103 if (bVLANPkt)
2104 {
2105 pTxBlk->pSrcBufData += LENGTH_802_1Q;
2106 pTxBlk->SrcBufLen -= LENGTH_802_1Q;
2107 }
2108
2109 pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
2110 pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
2111
2112 // skip common header
2113 pHeaderBufPtr += pTxBlk->MpduHeaderLen;
2114
2115 if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM))
2116 {
2117 //
2118 // build QOS Control bytes
2119 //
2120 *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
2121 *(pHeaderBufPtr+1) = 0;
2122 pHeaderBufPtr +=2;
2123 pTxBlk->MpduHeaderLen += 2;
2124 }
2125
2126 // The remaining content of MPDU header should locate at 4-octets aligment
2127 pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
2128 pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
2129 pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
2130
2131 {
2132
2133 //
2134 // Insert LLC-SNAP encapsulation - 8 octets
2135 //
2136 //
2137 // if original Ethernet frame contains no LLC/SNAP,
2138 // then an extra LLC/SNAP encap is required
2139 //
2140 EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(pTxBlk->pSrcBufHeader, pTxBlk->pExtraLlcSnapEncap);
2141 if (pTxBlk->pExtraLlcSnapEncap)
2142 {
2143 UCHAR vlan_size;
2144
2145 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
2146 pHeaderBufPtr += 6;
2147 // skip vlan tag
2148 vlan_size = (bVLANPkt) ? LENGTH_802_1Q : 0;
2149 // get 2 octets (TypeofLen)
2150 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufHeader+12+vlan_size, 2);
2151 pHeaderBufPtr += 2;
2152 pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
2153 }
2154
2155 }
2156
2157 //
2158 // prepare for TXWI
2159 // use Wcid as Key Index
2160 //
2161
2162 RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
2163
2164 //FreeNumber = GET_TXRING_FREENO(pAd, QueIdx);
2165
2166 HAL_WriteTxResource(pAd, pTxBlk, TRUE, &FreeNumber);
2167
2168 pAd->RalinkCounters.KickTxCount++;
2169 pAd->RalinkCounters.OneSecTxDoneCount++;
2170
2171 //
2172 // Kick out Tx
2173 //
2174 HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
2175}
2176
2177
2178VOID STA_ARalink_Frame_Tx(
2179 IN PRTMP_ADAPTER pAd,
2180 IN TX_BLK *pTxBlk)
2181{
2182 PUCHAR pHeaderBufPtr;
2183 USHORT FreeNumber;
2184 USHORT totalMPDUSize=0;
2185 USHORT FirstTx, LastTxIdx;
2186 int frameNum = 0;
2187 BOOLEAN bVLANPkt;
2188 PQUEUE_ENTRY pQEntry;
2189
2190
2191 ASSERT(pTxBlk);
2192
2193 ASSERT((pTxBlk->TxPacketList.Number== 2));
2194
2195
2196 FirstTx = LastTxIdx = 0; // Is it ok init they as 0?
2197 while(pTxBlk->TxPacketList.Head)
2198 {
2199 pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
2200 pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
2201
2202 if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
2203 {
2204 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
2205 continue;
2206 }
2207
2208 bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
2209
2210 // skip 802.3 header
2211 pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
2212 pTxBlk->SrcBufLen -= LENGTH_802_3;
2213
2214 // skip vlan tag
2215 if (bVLANPkt)
2216 {
2217 pTxBlk->pSrcBufData += LENGTH_802_1Q;
2218 pTxBlk->SrcBufLen -= LENGTH_802_1Q;
2219 }
2220
2221 if (frameNum == 0)
2222 { // For first frame, we need to create the 802.11 header + padding(optional) + RA-AGG-LEN + SNAP Header
2223
2224 pHeaderBufPtr = STA_Build_ARalink_Frame_Header(pAd, pTxBlk);
2225
2226 // It's ok write the TxWI here, because the TxWI->MPDUtotalByteCount
2227 // will be updated after final frame was handled.
2228 RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
2229
2230
2231 //
2232 // Insert LLC-SNAP encapsulation - 8 octets
2233 //
2234 EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData-2, pTxBlk->pExtraLlcSnapEncap);
2235
2236 if (pTxBlk->pExtraLlcSnapEncap)
2237 {
2238 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
2239 pHeaderBufPtr += 6;
2240 // get 2 octets (TypeofLen)
2241 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
2242 pHeaderBufPtr += 2;
2243 pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
2244 }
2245 }
2246 else
2247 { // For second aggregated frame, we need create the 802.3 header to headerBuf, because PCI will copy it to SDPtr0.
2248
2249 pHeaderBufPtr = &pTxBlk->HeaderBuf[0];
2250 pTxBlk->MpduHeaderLen = 0;
2251
2252 // A-Ralink sub-sequent frame header is the same as 802.3 header.
2253 // DA(6)+SA(6)+FrameType(2)
2254 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufHeader, 12);
2255 pHeaderBufPtr += 12;
2256 // get 2 octets (TypeofLen)
2257 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
2258 pHeaderBufPtr += 2;
2259 pTxBlk->MpduHeaderLen = LENGTH_ARALINK_SUBFRAMEHEAD;
2260 }
2261
2262 totalMPDUSize += pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
2263
2264 //FreeNumber = GET_TXRING_FREENO(pAd, QueIdx);
2265 if (frameNum ==0)
2266 FirstTx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
2267 else
2268 LastTxIdx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
2269
2270 frameNum++;
2271
2272 pAd->RalinkCounters.OneSecTxAggregationCount++;
2273 pAd->RalinkCounters.KickTxCount++;
2274 pAd->RalinkCounters.OneSecTxDoneCount++;
2275
2276 }
2277
2278 HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, FirstTx);
2279 HAL_LastTxIdx(pAd, pTxBlk->QueIdx, LastTxIdx);
2280
2281 //
2282 // Kick out Tx
2283 //
2284 HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
2285
2286}
2287
2288
2289VOID STA_Fragment_Frame_Tx(
2290 IN RTMP_ADAPTER *pAd,
2291 IN TX_BLK *pTxBlk)
2292{
2293 HEADER_802_11 *pHeader_802_11;
2294 PUCHAR pHeaderBufPtr;
2295 USHORT FreeNumber;
2296 UCHAR fragNum = 0;
2297 PACKET_INFO PacketInfo;
2298 USHORT EncryptionOverhead = 0;
2299 UINT32 FreeMpduSize, SrcRemainingBytes;
2300 USHORT AckDuration;
2301 UINT NextMpduSize;
2302 BOOLEAN bVLANPkt;
2303 PQUEUE_ENTRY pQEntry;
2304
2305
2306 ASSERT(pTxBlk);
2307
2308 pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
2309 pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
2310 if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
2311 {
2312 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
2313 return;
2314 }
2315
2316 ASSERT(TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag));
2317 bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
2318
2319 STAFindCipherAlgorithm(pAd, pTxBlk);
2320 STABuildCommon802_11Header(pAd, pTxBlk);
2321
2322 if (pTxBlk->CipherAlg == CIPHER_TKIP)
2323 {
2324 pTxBlk->pPacket = duplicate_pkt_with_TKIP_MIC(pAd, pTxBlk->pPacket);
2325 if (pTxBlk->pPacket == NULL)
2326 return;
2327 RTMP_QueryPacketInfo(pTxBlk->pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen);
2328 }
2329
2330 // skip 802.3 header
2331 pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
2332 pTxBlk->SrcBufLen -= LENGTH_802_3;
2333
2334
2335 // skip vlan tag
2336 if (bVLANPkt)
2337 {
2338 pTxBlk->pSrcBufData += LENGTH_802_1Q;
2339 pTxBlk->SrcBufLen -= LENGTH_802_1Q;
2340 }
2341
2342 pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
2343 pHeader_802_11 = (HEADER_802_11 *)pHeaderBufPtr;
2344
2345
2346 // skip common header
2347 pHeaderBufPtr += pTxBlk->MpduHeaderLen;
2348
2349 if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM))
2350 {
2351 //
2352 // build QOS Control bytes
2353 //
2354 *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
2355
2356 *(pHeaderBufPtr+1) = 0;
2357 pHeaderBufPtr +=2;
2358 pTxBlk->MpduHeaderLen += 2;
2359 }
2360
2361 //
2362 // padding at front of LLC header
2363 // LLC header should locate at 4-octets aligment
2364 //
2365 pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
2366 pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
2367 pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
2368
2369
2370
2371 //
2372 // Insert LLC-SNAP encapsulation - 8 octets
2373 //
2374 //
2375 // if original Ethernet frame contains no LLC/SNAP,
2376 // then an extra LLC/SNAP encap is required
2377 //
2378 EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(pTxBlk->pSrcBufHeader, pTxBlk->pExtraLlcSnapEncap);
2379 if (pTxBlk->pExtraLlcSnapEncap)
2380 {
2381 UCHAR vlan_size;
2382
2383 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
2384 pHeaderBufPtr += 6;
2385 // skip vlan tag
2386 vlan_size = (bVLANPkt) ? LENGTH_802_1Q : 0;
2387 // get 2 octets (TypeofLen)
2388 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufHeader+12+vlan_size, 2);
2389 pHeaderBufPtr += 2;
2390 pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
2391 }
2392
2393
2394 // If TKIP is used and fragmentation is required. Driver has to
2395 // append TKIP MIC at tail of the scatter buffer
2396 // MAC ASIC will only perform IV/EIV/ICV insertion but no TKIP MIC
2397 if (pTxBlk->CipherAlg == CIPHER_TKIP)
2398 {
2399
2400 // NOTE: DON'T refer the skb->len directly after following copy. Becasue the length is not adjust
2401 // to correct lenght, refer to pTxBlk->SrcBufLen for the packet length in following progress.
2402 NdisMoveMemory(pTxBlk->pSrcBufData + pTxBlk->SrcBufLen, &pAd->PrivateInfo.Tx.MIC[0], 8);
2403 //skb_put((RTPKT_TO_OSPKT(pTxBlk->pPacket))->tail, 8);
2404 pTxBlk->SrcBufLen += 8;
2405 pTxBlk->TotalFrameLen += 8;
2406 pTxBlk->CipherAlg = CIPHER_TKIP_NO_MIC;
2407 }
2408
2409 //
2410 // calcuate the overhead bytes that encryption algorithm may add. This
2411 // affects the calculate of "duration" field
2412 //
2413 if ((pTxBlk->CipherAlg == CIPHER_WEP64) || (pTxBlk->CipherAlg == CIPHER_WEP128))
2414 EncryptionOverhead = 8; //WEP: IV[4] + ICV[4];
2415 else if (pTxBlk->CipherAlg == CIPHER_TKIP_NO_MIC)
2416 EncryptionOverhead = 12;//TKIP: IV[4] + EIV[4] + ICV[4], MIC will be added to TotalPacketLength
2417 else if (pTxBlk->CipherAlg == CIPHER_TKIP)
2418 EncryptionOverhead = 20;//TKIP: IV[4] + EIV[4] + ICV[4] + MIC[8]
2419 else if (pTxBlk->CipherAlg == CIPHER_AES)
2420 EncryptionOverhead = 16; // AES: IV[4] + EIV[4] + MIC[8]
2421 else
2422 EncryptionOverhead = 0;
2423
2424 // decide how much time an ACK/CTS frame will consume in the air
2425 AckDuration = RTMPCalcDuration(pAd, pAd->CommonCfg.ExpectedACKRate[pTxBlk->TxRate], 14);
2426
2427 // Init the total payload length of this frame.
2428 SrcRemainingBytes = pTxBlk->SrcBufLen;
2429
2430 pTxBlk->TotalFragNum = 0xff;
2431
2432 do {
2433
2434 FreeMpduSize = pAd->CommonCfg.FragmentThreshold - LENGTH_CRC;
2435
2436 FreeMpduSize -= pTxBlk->MpduHeaderLen;
2437
2438 if (SrcRemainingBytes <= FreeMpduSize)
2439 { // this is the last or only fragment
2440
2441 pTxBlk->SrcBufLen = SrcRemainingBytes;
2442
2443 pHeader_802_11->FC.MoreFrag = 0;
2444 pHeader_802_11->Duration = pAd->CommonCfg.Dsifs + AckDuration;
2445
2446 // Indicate the lower layer that this's the last fragment.
2447 pTxBlk->TotalFragNum = fragNum;
2448 }
2449 else
2450 { // more fragment is required
2451
2452 pTxBlk->SrcBufLen = FreeMpduSize;
2453
2454 NextMpduSize = min(((UINT)SrcRemainingBytes - pTxBlk->SrcBufLen), ((UINT)pAd->CommonCfg.FragmentThreshold));
2455 pHeader_802_11->FC.MoreFrag = 1;
2456 pHeader_802_11->Duration = (3 * pAd->CommonCfg.Dsifs) + (2 * AckDuration) + RTMPCalcDuration(pAd, pTxBlk->TxRate, NextMpduSize + EncryptionOverhead);
2457 }
2458
2459 if (fragNum == 0)
2460 pTxBlk->FrameGap = IFS_HTTXOP;
2461 else
2462 pTxBlk->FrameGap = IFS_SIFS;
2463
2464 RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
2465
2466 HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, &FreeNumber);
2467
2468 pAd->RalinkCounters.KickTxCount++;
2469 pAd->RalinkCounters.OneSecTxDoneCount++;
2470
2471 // Update the frame number, remaining size of the NDIS packet payload.
2472
2473 // space for 802.11 header.
2474 if (fragNum == 0 && pTxBlk->pExtraLlcSnapEncap)
2475 pTxBlk->MpduHeaderLen -= LENGTH_802_1_H;
2476
2477 fragNum++;
2478 SrcRemainingBytes -= pTxBlk->SrcBufLen;
2479 pTxBlk->pSrcBufData += pTxBlk->SrcBufLen;
2480
2481 pHeader_802_11->Frag++; // increase Frag #
2482
2483 }while(SrcRemainingBytes > 0);
2484
2485 //
2486 // Kick out Tx
2487 //
2488 HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
2489}
2490
2491
2492#define RELEASE_FRAMES_OF_TXBLK(_pAd, _pTxBlk, _pQEntry, _Status) \
2493 while(_pTxBlk->TxPacketList.Head) \
2494 { \
2495 _pQEntry = RemoveHeadQueue(&_pTxBlk->TxPacketList); \
2496 RELEASE_NDIS_PACKET(_pAd, QUEUE_ENTRY_TO_PACKET(_pQEntry), _Status); \
2497 }
2498
2499
2500/*
2501 ========================================================================
2502
2503 Routine Description:
2504 Copy frame from waiting queue into relative ring buffer and set
2505 appropriate ASIC register to kick hardware encryption before really
2506 sent out to air.
2507
2508 Arguments:
2509 pAd Pointer to our adapter
2510 PNDIS_PACKET Pointer to outgoing Ndis frame
2511 NumberOfFrag Number of fragment required
2512
2513 Return Value:
2514 None
2515
2516 IRQL = DISPATCH_LEVEL
2517
2518 Note:
2519
2520 ========================================================================
2521*/
2522NDIS_STATUS STAHardTransmit(
2523 IN PRTMP_ADAPTER pAd,
2524 IN TX_BLK *pTxBlk,
2525 IN UCHAR QueIdx)
2526{
2527 NDIS_PACKET *pPacket;
2528 PQUEUE_ENTRY pQEntry;
2529
2530 // ---------------------------------------------
2531 // STEP 0. DO SANITY CHECK AND SOME EARLY PREPARATION.
2532 // ---------------------------------------------
2533 //
2534 ASSERT(pTxBlk->TxPacketList.Number);
2535 if (pTxBlk->TxPacketList.Head == NULL)
2536 {
2537 DBGPRINT(RT_DEBUG_ERROR, ("pTxBlk->TotalFrameNum == %ld!\n", pTxBlk->TxPacketList.Number));
2538 return NDIS_STATUS_FAILURE;
2539 }
2540
2541 pPacket = QUEUE_ENTRY_TO_PACKET(pTxBlk->TxPacketList.Head);
2542
2543 // ------------------------------------------------------------------
2544 // STEP 1. WAKE UP PHY
2545 // outgoing frame always wakeup PHY to prevent frame lost and
2546 // turn off PSM bit to improve performance
2547 // ------------------------------------------------------------------
2548 // not to change PSM bit, just send this frame out?
2549 if ((pAd->StaCfg.Psm == PWR_SAVE) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
2550 {
2551 DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicForceWakeup At HardTx\n"));
2552 AsicForceWakeup(pAd, TRUE);
2553 }
2554
2555 // It should not change PSM bit, when APSD turn on.
2556 if ((!(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable) && (pAd->CommonCfg.bAPSDForcePowerSave == FALSE))
2557 || (RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket))
2558 || (RTMP_GET_PACKET_WAI(pTxBlk->pPacket)))
2559 {
2560 if ((pAd->StaCfg.Psm == PWR_SAVE) &&
2561 (pAd->StaCfg.WindowsPowerMode == Ndis802_11PowerModeFast_PSP))
2562 MlmeSetPsmBit(pAd, PWR_ACTIVE);
2563 }
2564
2565 switch (pTxBlk->TxFrameType)
2566 {
2567#ifdef DOT11_N_SUPPORT
2568 case TX_AMPDU_FRAME:
2569 STA_AMPDU_Frame_Tx(pAd, pTxBlk);
2570 break;
2571 case TX_AMSDU_FRAME:
2572 STA_AMSDU_Frame_Tx(pAd, pTxBlk);
2573 break;
2574#endif // DOT11_N_SUPPORT //
2575 case TX_LEGACY_FRAME:
2576 STA_Legacy_Frame_Tx(pAd, pTxBlk);
2577 break;
2578 case TX_MCAST_FRAME:
2579 STA_Legacy_Frame_Tx(pAd, pTxBlk);
2580 break;
2581 case TX_RALINK_FRAME:
2582 STA_ARalink_Frame_Tx(pAd, pTxBlk);
2583 break;
2584 case TX_FRAG_FRAME:
2585 STA_Fragment_Frame_Tx(pAd, pTxBlk);
2586 break;
2587 default:
2588 {
2589 // It should not happened!
2590 DBGPRINT(RT_DEBUG_ERROR, ("Send a pacekt was not classified!! It should not happen!\n"));
2591 while(pTxBlk->TxPacketList.Number)
2592 {
2593 pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
2594 pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
2595 if (pPacket)
2596 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
2597 }
2598 }
2599 break;
2600 }
2601
2602 return (NDIS_STATUS_SUCCESS);
2603
2604}
2605
2606ULONG HashBytesPolynomial(UCHAR *value, unsigned int len)
2607{
2608 unsigned char *word = value;
2609 unsigned int ret = 0;
2610 unsigned int i;
2611
2612 for(i=0; i < len; i++)
2613 {
2614 int mod = i % 32;
2615 ret ^=(unsigned int) (word[i]) << mod;
2616 ret ^=(unsigned int) (word[i]) >> (32 - mod);
2617 }
2618 return ret;
2619}
2620
2621VOID Sta_Announce_or_Forward_802_3_Packet(
2622 IN PRTMP_ADAPTER pAd,
2623 IN PNDIS_PACKET pPacket,
2624 IN UCHAR FromWhichBSSID)
2625{
2626 if (TRUE
2627 )
2628 {
2629 announce_802_3_packet(pAd, pPacket);
2630 }
2631 else
2632 {
2633 // release packet
2634 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
2635 }
2636}
2637
diff --git a/drivers/staging/rt3070/sta/sanity.c b/drivers/staging/rt3070/sta/sanity.c
new file mode 100644
index 000000000000..239872464bed
--- /dev/null
+++ b/drivers/staging/rt3070/sta/sanity.c
@@ -0,0 +1,420 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 sanity.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 John Chang 2004-09-01 add WMM support
36*/
37#include "../rt_config.h"
38
39extern UCHAR CISCO_OUI[];
40
41extern UCHAR WPA_OUI[];
42extern UCHAR RSN_OUI[];
43extern UCHAR WME_INFO_ELEM[];
44extern UCHAR WME_PARM_ELEM[];
45extern UCHAR Ccx2QosInfo[];
46extern UCHAR RALINK_OUI[];
47extern UCHAR BROADCOM_OUI[];
48
49/*
50 ==========================================================================
51 Description:
52 MLME message sanity check
53 Return:
54 TRUE if all parameters are OK, FALSE otherwise
55 ==========================================================================
56 */
57BOOLEAN MlmeStartReqSanity(
58 IN PRTMP_ADAPTER pAd,
59 IN VOID *Msg,
60 IN ULONG MsgLen,
61 OUT CHAR Ssid[],
62 OUT UCHAR *pSsidLen)
63{
64 MLME_START_REQ_STRUCT *Info;
65
66 Info = (MLME_START_REQ_STRUCT *)(Msg);
67
68 if (Info->SsidLen > MAX_LEN_OF_SSID)
69 {
70 DBGPRINT(RT_DEBUG_TRACE, ("MlmeStartReqSanity fail - wrong SSID length\n"));
71 return FALSE;
72 }
73
74 *pSsidLen = Info->SsidLen;
75 NdisMoveMemory(Ssid, Info->Ssid, *pSsidLen);
76
77 return TRUE;
78}
79
80/*
81 ==========================================================================
82 Description:
83 MLME message sanity check
84 Return:
85 TRUE if all parameters are OK, FALSE otherwise
86
87 IRQL = DISPATCH_LEVEL
88
89 ==========================================================================
90 */
91BOOLEAN PeerAssocRspSanity(
92 IN PRTMP_ADAPTER pAd,
93 IN VOID *pMsg,
94 IN ULONG MsgLen,
95 OUT PUCHAR pAddr2,
96 OUT USHORT *pCapabilityInfo,
97 OUT USHORT *pStatus,
98 OUT USHORT *pAid,
99 OUT UCHAR SupRate[],
100 OUT UCHAR *pSupRateLen,
101 OUT UCHAR ExtRate[],
102 OUT UCHAR *pExtRateLen,
103 OUT HT_CAPABILITY_IE *pHtCapability,
104 OUT ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
105 OUT UCHAR *pHtCapabilityLen,
106 OUT UCHAR *pAddHtInfoLen,
107 OUT UCHAR *pNewExtChannelOffset,
108 OUT PEDCA_PARM pEdcaParm,
109 OUT UCHAR *pCkipFlag)
110{
111 CHAR IeType, *Ptr;
112 PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
113 PEID_STRUCT pEid;
114 ULONG Length = 0;
115
116 *pNewExtChannelOffset = 0xff;
117 *pHtCapabilityLen = 0;
118 *pAddHtInfoLen = 0;
119 COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
120 Ptr = pFrame->Octet;
121 Length += LENGTH_802_11;
122
123 NdisMoveMemory(pCapabilityInfo, &pFrame->Octet[0], 2);
124 Length += 2;
125 NdisMoveMemory(pStatus, &pFrame->Octet[2], 2);
126 Length += 2;
127 *pCkipFlag = 0;
128 *pExtRateLen = 0;
129 pEdcaParm->bValid = FALSE;
130
131 if (*pStatus != MLME_SUCCESS)
132 return TRUE;
133
134 NdisMoveMemory(pAid, &pFrame->Octet[4], 2);
135 Length += 2;
136
137 // Aid already swaped byte order in RTMPFrameEndianChange() for big endian platform
138 *pAid = (*pAid) & 0x3fff; // AID is low 14-bit
139
140 // -- get supported rates from payload and advance the pointer
141 IeType = pFrame->Octet[6];
142 *pSupRateLen = pFrame->Octet[7];
143 if ((IeType != IE_SUPP_RATES) || (*pSupRateLen > MAX_LEN_OF_SUPPORTED_RATES))
144 {
145 DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspSanity fail - wrong SupportedRates IE\n"));
146 return FALSE;
147 }
148 else
149 NdisMoveMemory(SupRate, &pFrame->Octet[8], *pSupRateLen);
150
151 Length = Length + 2 + *pSupRateLen;
152
153 // many AP implement proprietary IEs in non-standard order, we'd better
154 // tolerate mis-ordered IEs to get best compatibility
155 pEid = (PEID_STRUCT) &pFrame->Octet[8 + (*pSupRateLen)];
156
157 // get variable fields from payload and advance the pointer
158 while ((Length + 2 + pEid->Len) <= MsgLen)
159 {
160 switch (pEid->Eid)
161 {
162 case IE_EXT_SUPP_RATES:
163 if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES)
164 {
165 NdisMoveMemory(ExtRate, pEid->Octet, pEid->Len);
166 *pExtRateLen = pEid->Len;
167 }
168 break;
169
170 case IE_HT_CAP:
171 case IE_HT_CAP2:
172 if (pEid->Len >= SIZE_HT_CAP_IE) //Note: allow extension.!!
173 {
174 NdisMoveMemory(pHtCapability, pEid->Octet, SIZE_HT_CAP_IE);
175
176 *(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo));
177 *(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
178
179 *pHtCapabilityLen = SIZE_HT_CAP_IE;
180 }
181 else
182 {
183 DBGPRINT(RT_DEBUG_WARN, ("PeerAssocRspSanity - wrong IE_HT_CAP. \n"));
184 }
185
186 break;
187#ifdef DOT11_N_SUPPORT
188 case IE_ADD_HT:
189 case IE_ADD_HT2:
190 if (pEid->Len >= sizeof(ADD_HT_INFO_IE))
191 {
192 // This IE allows extension, but we can ignore extra bytes beyond our knowledge , so only
193 // copy first sizeof(ADD_HT_INFO_IE)
194 NdisMoveMemory(pAddHtInfo, pEid->Octet, sizeof(ADD_HT_INFO_IE));
195
196 *(USHORT *)(&pAddHtInfo->AddHtInfo2) = cpu2le16(*(USHORT *)(&pAddHtInfo->AddHtInfo2));
197 *(USHORT *)(&pAddHtInfo->AddHtInfo3) = cpu2le16(*(USHORT *)(&pAddHtInfo->AddHtInfo3));
198
199 *pAddHtInfoLen = SIZE_ADD_HT_INFO_IE;
200 }
201 else
202 {
203 DBGPRINT(RT_DEBUG_WARN, ("PeerAssocRspSanity - wrong IE_ADD_HT. \n"));
204 }
205
206 break;
207 case IE_SECONDARY_CH_OFFSET:
208 if (pEid->Len == 1)
209 {
210 *pNewExtChannelOffset = pEid->Octet[0];
211 }
212 else
213 {
214 DBGPRINT(RT_DEBUG_WARN, ("PeerAssocRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n"));
215 }
216#endif // DOT11_N_SUPPORT //
217 break;
218 case IE_AIRONET_CKIP:
219 // 0. Check Aironet IE length, it must be larger or equal to 28
220 // Cisco's AP VxWork version(will not be supported) used this IE length as 28
221 // Cisco's AP IOS version used this IE length as 30
222 if (pEid->Len < (CKIP_NEGOTIATION_LENGTH - 2))
223 break;
224
225 // 1. Copy CKIP flag byte to buffer for process
226 *pCkipFlag = *(pEid->Octet + 8);
227 break;
228
229 case IE_AIRONET_IPADDRESS:
230 if (pEid->Len != 0x0A)
231 break;
232
233 // Get Cisco Aironet IP information
234 if (NdisEqualMemory(pEid->Octet, CISCO_OUI, 3) == 1)
235 NdisMoveMemory(pAd->StaCfg.AironetIPAddress, pEid->Octet + 4, 4);
236 break;
237
238 // CCX2, WMM use the same IE value
239 // case IE_CCX_V2:
240 case IE_VENDOR_SPECIFIC:
241 // handle WME PARAMTER ELEMENT
242 if (NdisEqualMemory(pEid->Octet, WME_PARM_ELEM, 6) && (pEid->Len == 24))
243 {
244 PUCHAR ptr;
245 int i;
246
247 // parsing EDCA parameters
248 pEdcaParm->bValid = TRUE;
249 pEdcaParm->bQAck = FALSE; // pEid->Octet[0] & 0x10;
250 pEdcaParm->bQueueRequest = FALSE; // pEid->Octet[0] & 0x20;
251 pEdcaParm->bTxopRequest = FALSE; // pEid->Octet[0] & 0x40;
252 //pEdcaParm->bMoreDataAck = FALSE; // pEid->Octet[0] & 0x80;
253 pEdcaParm->EdcaUpdateCount = pEid->Octet[6] & 0x0f;
254 pEdcaParm->bAPSDCapable = (pEid->Octet[6] & 0x80) ? 1 : 0;
255 ptr = &pEid->Octet[8];
256 for (i=0; i<4; i++)
257 {
258 UCHAR aci = (*ptr & 0x60) >> 5; // b5~6 is AC INDEX
259 pEdcaParm->bACM[aci] = (((*ptr) & 0x10) == 0x10); // b5 is ACM
260 pEdcaParm->Aifsn[aci] = (*ptr) & 0x0f; // b0~3 is AIFSN
261 pEdcaParm->Cwmin[aci] = *(ptr+1) & 0x0f; // b0~4 is Cwmin
262 pEdcaParm->Cwmax[aci] = *(ptr+1) >> 4; // b5~8 is Cwmax
263 pEdcaParm->Txop[aci] = *(ptr+2) + 256 * (*(ptr+3)); // in unit of 32-us
264 ptr += 4; // point to next AC
265 }
266 }
267
268 // handle CCX IE
269 else
270 {
271 // 0. Check the size and CCX admin control
272 if (pAd->StaCfg.CCXControl.field.Enable == 0)
273 break;
274 if (pEid->Len != 5)
275 break;
276
277 // Turn CCX2 if matched
278 if (NdisEqualMemory(pEid->Octet, Ccx2IeInfo, 5) == 1)
279 pAd->StaCfg.CCXEnable = TRUE;
280 break;
281 }
282 break;
283
284 default:
285 DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspSanity - ignore unrecognized EID = %d\n", pEid->Eid));
286 break;
287 }
288
289 Length = Length + 2 + pEid->Len;
290 pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
291 }
292
293 // Force CCX2 enable to TRUE for those AP didn't replay CCX v2 IE, we still force it to be on
294 if (pAd->StaCfg.CCXControl.field.Enable == 1)
295 pAd->StaCfg.CCXEnable = TRUE;
296
297 return TRUE;
298}
299
300/*
301 ==========================================================================
302 Description:
303 MLME message sanity check
304 Return:
305 TRUE if all parameters are OK, FALSE otherwise
306
307 IRQL = DISPATCH_LEVEL
308
309 ==========================================================================
310 */
311BOOLEAN PeerProbeReqSanity(
312 IN PRTMP_ADAPTER pAd,
313 IN VOID *Msg,
314 IN ULONG MsgLen,
315 OUT PUCHAR pAddr2,
316 OUT CHAR Ssid[],
317 OUT UCHAR *pSsidLen)
318{
319 UCHAR Idx;
320 UCHAR RateLen;
321 CHAR IeType;
322 PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
323
324 COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
325
326 if ((pFrame->Octet[0] != IE_SSID) || (pFrame->Octet[1] > MAX_LEN_OF_SSID))
327 {
328 DBGPRINT(RT_DEBUG_TRACE, ("PeerProbeReqSanity fail - wrong SSID IE(Type=%d,Len=%d)\n",pFrame->Octet[0],pFrame->Octet[1]));
329 return FALSE;
330 }
331
332 *pSsidLen = pFrame->Octet[1];
333 NdisMoveMemory(Ssid, &pFrame->Octet[2], *pSsidLen);
334
335 Idx = *pSsidLen + 2;
336
337 // -- get supported rates from payload and advance the pointer
338 IeType = pFrame->Octet[Idx];
339 RateLen = pFrame->Octet[Idx + 1];
340 if (IeType != IE_SUPP_RATES)
341 {
342 DBGPRINT(RT_DEBUG_TRACE, ("PeerProbeReqSanity fail - wrong SupportRates IE(Type=%d,Len=%d)\n",pFrame->Octet[Idx],pFrame->Octet[Idx+1]));
343 return FALSE;
344 }
345 else
346 {
347 if ((pAd->CommonCfg.PhyMode == PHY_11G) && (RateLen < 8))
348 return (FALSE);
349 }
350
351 return TRUE;
352}
353
354/*
355 ==========================================================================
356 Description:
357
358 IRQL = DISPATCH_LEVEL
359
360 ==========================================================================
361 */
362BOOLEAN GetTimBit(
363 IN CHAR *Ptr,
364 IN USHORT Aid,
365 OUT UCHAR *TimLen,
366 OUT UCHAR *BcastFlag,
367 OUT UCHAR *DtimCount,
368 OUT UCHAR *DtimPeriod,
369 OUT UCHAR *MessageToMe)
370{
371 UCHAR BitCntl, N1, N2, MyByte, MyBit;
372 CHAR *IdxPtr;
373
374 IdxPtr = Ptr;
375
376 IdxPtr ++;
377 *TimLen = *IdxPtr;
378
379 // get DTIM Count from TIM element
380 IdxPtr ++;
381 *DtimCount = *IdxPtr;
382
383 // get DTIM Period from TIM element
384 IdxPtr++;
385 *DtimPeriod = *IdxPtr;
386
387 // get Bitmap Control from TIM element
388 IdxPtr++;
389 BitCntl = *IdxPtr;
390
391 if ((*DtimCount == 0) && (BitCntl & 0x01))
392 *BcastFlag = TRUE;
393 else
394 *BcastFlag = FALSE;
395
396 // Parse Partial Virtual Bitmap from TIM element
397 N1 = BitCntl & 0xfe; // N1 is the first bitmap byte#
398 N2 = *TimLen - 4 + N1; // N2 is the last bitmap byte#
399
400 if ((Aid < (N1 << 3)) || (Aid >= ((N2 + 1) << 3)))
401 *MessageToMe = FALSE;
402 else
403 {
404 MyByte = (Aid >> 3) - N1; // my byte position in the bitmap byte-stream
405 MyBit = Aid % 16 - ((MyByte & 0x01)? 8:0);
406
407 IdxPtr += (MyByte + 1);
408
409 //if (*IdxPtr)
410 // DBGPRINT(RT_DEBUG_WARN, ("TIM bitmap = 0x%02x\n", *IdxPtr));
411
412 if (*IdxPtr & (0x01 << MyBit))
413 *MessageToMe = TRUE;
414 else
415 *MessageToMe = FALSE;
416 }
417
418 return TRUE;
419}
420
diff --git a/drivers/staging/rt3070/sta/sync.c b/drivers/staging/rt3070/sta/sync.c
new file mode 100644
index 000000000000..2b5b3b07661d
--- /dev/null
+++ b/drivers/staging/rt3070/sta/sync.c
@@ -0,0 +1,1755 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 sync.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 John Chang 2004-09-01 modified for rt2561/2661
36 Jan Lee 2006-08-01 modified for rt2860 for 802.11n
37*/
38#include "../rt_config.h"
39
40#define ADHOC_ENTRY_BEACON_LOST_TIME (2*OS_HZ) // 2 sec
41
42/*
43 ==========================================================================
44 Description:
45 The sync state machine,
46 Parameters:
47 Sm - pointer to the state machine
48 Note:
49 the state machine looks like the following
50
51 ==========================================================================
52 */
53VOID SyncStateMachineInit(
54 IN PRTMP_ADAPTER pAd,
55 IN STATE_MACHINE *Sm,
56 OUT STATE_MACHINE_FUNC Trans[])
57{
58 StateMachineInit(Sm, Trans, MAX_SYNC_STATE, MAX_SYNC_MSG, (STATE_MACHINE_FUNC)Drop, SYNC_IDLE, SYNC_MACHINE_BASE);
59
60 // column 1
61 StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)MlmeScanReqAction);
62 StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)MlmeJoinReqAction);
63 StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)MlmeStartReqAction);
64 StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeacon);
65 StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_PROBE_REQ, (STATE_MACHINE_FUNC)PeerProbeReqAction);
66
67 //column 2
68 StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenScan);
69 StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenJoin);
70 StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenStart);
71 StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeaconAtJoinAction);
72 StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_BEACON_TIMEOUT, (STATE_MACHINE_FUNC)BeaconTimeoutAtJoinAction);
73
74 // column 3
75 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenScan);
76 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenJoin);
77 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenStart);
78 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeaconAtScanAction);
79 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_PROBE_RSP, (STATE_MACHINE_FUNC)PeerBeaconAtScanAction);
80 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_SCAN_TIMEOUT, (STATE_MACHINE_FUNC)ScanTimeoutAction);
81
82 // timer init
83 RTMPInitTimer(pAd, &pAd->MlmeAux.BeaconTimer, GET_TIMER_FUNCTION(BeaconTimeout), pAd, FALSE);
84 RTMPInitTimer(pAd, &pAd->MlmeAux.ScanTimer, GET_TIMER_FUNCTION(ScanTimeout), pAd, FALSE);
85}
86
87/*
88 ==========================================================================
89 Description:
90 Beacon timeout handler, executed in timer thread
91
92 IRQL = DISPATCH_LEVEL
93
94 ==========================================================================
95 */
96VOID BeaconTimeout(
97 IN PVOID SystemSpecific1,
98 IN PVOID FunctionContext,
99 IN PVOID SystemSpecific2,
100 IN PVOID SystemSpecific3)
101{
102 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
103
104 DBGPRINT(RT_DEBUG_TRACE,("SYNC - BeaconTimeout\n"));
105
106 // Do nothing if the driver is starting halt state.
107 // This might happen when timer already been fired before cancel timer with mlmehalt
108 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
109 return;
110
111#ifdef DOT11_N_SUPPORT
112 if ((pAd->CommonCfg.BBPCurrentBW == BW_40)
113 )
114 {
115 UCHAR BBPValue = 0;
116 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
117 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
118 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
119 BBPValue &= (~0x18);
120 BBPValue |= 0x10;
121 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
122 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",pAd->CommonCfg.CentralChannel, pAd->ScanTab.BssNr));
123 }
124#endif // DOT11_N_SUPPORT //
125
126 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_BEACON_TIMEOUT, 0, NULL);
127 RT28XX_MLME_HANDLER(pAd);
128}
129
130/*
131 ==========================================================================
132 Description:
133 Scan timeout handler, executed in timer thread
134
135 IRQL = DISPATCH_LEVEL
136
137 ==========================================================================
138 */
139VOID ScanTimeout(
140 IN PVOID SystemSpecific1,
141 IN PVOID FunctionContext,
142 IN PVOID SystemSpecific2,
143 IN PVOID SystemSpecific3)
144{
145 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
146
147
148 // Do nothing if the driver is starting halt state.
149 // This might happen when timer already been fired before cancel timer with mlmehalt
150 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
151 return;
152
153 if (MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_SCAN_TIMEOUT, 0, NULL))
154 {
155 RT28XX_MLME_HANDLER(pAd);
156 }
157 else
158 {
159 // To prevent SyncMachine.CurrState is SCAN_LISTEN forever.
160 pAd->MlmeAux.Channel = 0;
161 ScanNextChannel(pAd);
162 if (pAd->CommonCfg.bWirelessEvent)
163 {
164 RTMPSendWirelessEvent(pAd, IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
165 }
166 }
167}
168
169/*
170 ==========================================================================
171 Description:
172 MLME SCAN req state machine procedure
173 ==========================================================================
174 */
175VOID MlmeScanReqAction(
176 IN PRTMP_ADAPTER pAd,
177 IN MLME_QUEUE_ELEM *Elem)
178{
179 UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen, ScanType, BssType, BBPValue = 0;
180 BOOLEAN TimerCancelled;
181 ULONG Now;
182 USHORT Status;
183 PHEADER_802_11 pHdr80211;
184 PUCHAR pOutBuffer = NULL;
185 NDIS_STATUS NStatus;
186
187 // Check the total scan tries for one single OID command
188 // If this is the CCX 2.0 Case, skip that!
189 if ( !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
190 {
191 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeScanReqAction before Startup\n"));
192 return;
193 }
194
195 // Increase the scan retry counters.
196 pAd->StaCfg.ScanCnt++;
197
198
199 // first check the parameter sanity
200 if (MlmeScanReqSanity(pAd,
201 Elem->Msg,
202 Elem->MsgLen,
203 &BssType,
204 Ssid,
205 &SsidLen,
206 &ScanType))
207 {
208
209 // Check for channel load and noise hist request
210 // Suspend MSDU only at scan request, not the last two mentioned
211 if ((ScanType == SCAN_CISCO_NOISE) || (ScanType == SCAN_CISCO_CHANNEL_LOAD))
212 {
213 if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
214 RTMPSuspendMsduTransmission(pAd); // Suspend MSDU transmission here
215 }
216 else
217 {
218 // Suspend MSDU transmission here
219 RTMPSuspendMsduTransmission(pAd);
220 }
221
222 //
223 // To prevent data lost.
224 // Send an NULL data with turned PSM bit on to current associated AP before SCAN progress.
225 // And should send an NULL data with turned PSM bit off to AP, when scan progress done
226 //
227 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (INFRA_ON(pAd)))
228 {
229 NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);
230 if (NStatus == NDIS_STATUS_SUCCESS)
231 {
232 pHdr80211 = (PHEADER_802_11) pOutBuffer;
233 MgtMacHeaderInit(pAd, pHdr80211, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
234 pHdr80211->Duration = 0;
235 pHdr80211->FC.Type = BTYPE_DATA;
236 pHdr80211->FC.PwrMgmt = PWR_SAVE;
237
238 // Send using priority queue
239 MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
240 DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqAction -- Send PSM Data frame for off channel RM\n"));
241 MlmeFreeMemory(pAd, pOutBuffer);
242 RTMPusecDelay(5000);
243 }
244 }
245
246 NdisGetSystemUpTime(&Now);
247 pAd->StaCfg.LastScanTime = Now;
248 // reset all the timers
249 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
250 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
251
252 // record desired BSS parameters
253 pAd->MlmeAux.BssType = BssType;
254 pAd->MlmeAux.ScanType = ScanType;
255 pAd->MlmeAux.SsidLen = SsidLen;
256 NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
257 NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
258
259 // start from the first channel
260 pAd->MlmeAux.Channel = FirstChannel(pAd);
261
262 // Change the scan channel when dealing with CCX beacon report
263 if ((ScanType == SCAN_CISCO_PASSIVE) || (ScanType == SCAN_CISCO_ACTIVE) ||
264 (ScanType == SCAN_CISCO_CHANNEL_LOAD) || (ScanType == SCAN_CISCO_NOISE))
265 pAd->MlmeAux.Channel = pAd->StaCfg.CCXScanChannel;
266
267 // Let BBP register at 20MHz to do scan
268 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
269 BBPValue &= (~0x18);
270 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
271 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n"));
272 ScanNextChannel(pAd);
273 }
274 else
275 {
276 DBGPRINT_ERR(("SYNC - MlmeScanReqAction() sanity check fail\n"));
277 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
278 Status = MLME_INVALID_FORMAT;
279 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
280 }
281}
282
283/*
284 ==========================================================================
285 Description:
286 MLME JOIN req state machine procedure
287 ==========================================================================
288 */
289VOID MlmeJoinReqAction(
290 IN PRTMP_ADAPTER pAd,
291 IN MLME_QUEUE_ELEM *Elem)
292{
293 UCHAR BBPValue = 0;
294 BSS_ENTRY *pBss;
295 BOOLEAN TimerCancelled;
296 HEADER_802_11 Hdr80211;
297 NDIS_STATUS NStatus;
298 ULONG FrameLen = 0;
299 PUCHAR pOutBuffer = NULL;
300 PUCHAR pSupRate = NULL;
301 UCHAR SupRateLen;
302 PUCHAR pExtRate = NULL;
303 UCHAR ExtRateLen;
304 UCHAR ASupRate[] = {0x8C, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6C};
305 UCHAR ASupRateLen = sizeof(ASupRate)/sizeof(UCHAR);
306 MLME_JOIN_REQ_STRUCT *pInfo = (MLME_JOIN_REQ_STRUCT *)(Elem->Msg);
307
308 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeJoinReqAction(BSS #%ld)\n", pInfo->BssIdx));
309
310
311 // reset all the timers
312 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
313 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
314
315 pBss = &pAd->MlmeAux.SsidBssTab.BssEntry[pInfo->BssIdx];
316
317 // record the desired SSID & BSSID we're waiting for
318 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pBss->Bssid);
319
320 // If AP's SSID is not hidden, it is OK for updating ssid to MlmeAux again.
321 if (pBss->Hidden == 0)
322 {
323 NdisMoveMemory(pAd->MlmeAux.Ssid, pBss->Ssid, pBss->SsidLen);
324 pAd->MlmeAux.SsidLen = pBss->SsidLen;
325 }
326
327 pAd->MlmeAux.BssType = pBss->BssType;
328 pAd->MlmeAux.Channel = pBss->Channel;
329 pAd->MlmeAux.CentralChannel = pBss->CentralChannel;
330
331#ifdef EXT_BUILD_CHANNEL_LIST
332 // Country IE of the AP will be evaluated and will be used.
333 if ((pAd->StaCfg.IEEE80211dClientMode != Rt802_11_D_None) &&
334 (pBss->bHasCountryIE == TRUE))
335 {
336 NdisMoveMemory(&pAd->CommonCfg.CountryCode[0], &pBss->CountryString[0], 2);
337 if (pBss->CountryString[2] == 'I')
338 pAd->CommonCfg.Geography = IDOR;
339 else if (pBss->CountryString[2] == 'O')
340 pAd->CommonCfg.Geography = ODOR;
341 else
342 pAd->CommonCfg.Geography = BOTH;
343 BuildChannelListEx(pAd);
344 }
345#endif // EXT_BUILD_CHANNEL_LIST //
346
347 // Let BBP register at 20MHz to do scan
348 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
349 BBPValue &= (~0x18);
350 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
351 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n"));
352
353 // switch channel and waiting for beacon timer
354 AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE);
355 AsicLockChannel(pAd, pAd->MlmeAux.Channel);
356 RTMPSetTimer(&pAd->MlmeAux.BeaconTimer, JOIN_TIMEOUT);
357
358 do
359 {
360 if (((pAd->CommonCfg.bIEEE80211H == 1) &&
361 (pAd->MlmeAux.Channel > 14) &&
362 RadarChannelCheck(pAd, pAd->MlmeAux.Channel))
363#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
364 || (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
365#endif // CARRIER_DETECTION_SUPPORT //
366 )
367 {
368 //
369 // We can't send any Probe request frame to meet 802.11h.
370 //
371 if (pBss->Hidden == 0)
372 break;
373 }
374
375 //
376 // send probe request
377 //
378 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
379 if (NStatus == NDIS_STATUS_SUCCESS)
380 {
381 if (pAd->MlmeAux.Channel <= 14)
382 {
383 pSupRate = pAd->CommonCfg.SupRate;
384 SupRateLen = pAd->CommonCfg.SupRateLen;
385 pExtRate = pAd->CommonCfg.ExtRate;
386 ExtRateLen = pAd->CommonCfg.ExtRateLen;
387 }
388 else
389 {
390 //
391 // Overwrite Support Rate, CCK rate are not allowed
392 //
393 pSupRate = ASupRate;
394 SupRateLen = ASupRateLen;
395 ExtRateLen = 0;
396 }
397
398 if (pAd->MlmeAux.BssType == BSS_INFRA)
399 MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, pAd->MlmeAux.Bssid, pAd->MlmeAux.Bssid);
400 else
401 MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
402
403 MakeOutgoingFrame(pOutBuffer, &FrameLen,
404 sizeof(HEADER_802_11), &Hdr80211,
405 1, &SsidIe,
406 1, &pAd->MlmeAux.SsidLen,
407 pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid,
408 1, &SupRateIe,
409 1, &SupRateLen,
410 SupRateLen, pSupRate,
411 END_OF_ARGS);
412
413 if (ExtRateLen)
414 {
415 ULONG Tmp;
416 MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
417 1, &ExtRateIe,
418 1, &ExtRateLen,
419 ExtRateLen, pExtRate,
420 END_OF_ARGS);
421 FrameLen += Tmp;
422 }
423
424
425 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
426 MlmeFreeMemory(pAd, pOutBuffer);
427 }
428 } while (FALSE);
429
430 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - Switch to ch %d, Wait BEACON from %02x:%02x:%02x:%02x:%02x:%02x\n",
431 pBss->Channel, pBss->Bssid[0], pBss->Bssid[1], pBss->Bssid[2], pBss->Bssid[3], pBss->Bssid[4], pBss->Bssid[5]));
432
433 pAd->Mlme.SyncMachine.CurrState = JOIN_WAIT_BEACON;
434}
435
436/*
437 ==========================================================================
438 Description:
439 MLME START Request state machine procedure, starting an IBSS
440 ==========================================================================
441 */
442VOID MlmeStartReqAction(
443 IN PRTMP_ADAPTER pAd,
444 IN MLME_QUEUE_ELEM *Elem)
445{
446 UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen;
447 BOOLEAN TimerCancelled;
448
449 // New for WPA security suites
450 UCHAR VarIE[MAX_VIE_LEN]; // Total VIE length = MAX_VIE_LEN - -5
451 NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
452 LARGE_INTEGER TimeStamp;
453 BOOLEAN Privacy;
454 USHORT Status;
455
456 // Init Variable IE structure
457 pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
458 pVIE->Length = 0;
459 TimeStamp.u.LowPart = 0;
460 TimeStamp.u.HighPart = 0;
461
462 if (MlmeStartReqSanity(pAd, Elem->Msg, Elem->MsgLen, Ssid, &SsidLen))
463 {
464 // reset all the timers
465 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
466 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
467
468 //
469 // Start a new IBSS. All IBSS parameters are decided now....
470 //
471 DBGPRINT(RT_DEBUG_TRACE, ("MlmeStartReqAction - Start a new IBSS. All IBSS parameters are decided now.... \n"));
472 pAd->MlmeAux.BssType = BSS_ADHOC;
473 NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
474 pAd->MlmeAux.SsidLen = SsidLen;
475
476 // generate a radom number as BSSID
477 MacAddrRandomBssid(pAd, pAd->MlmeAux.Bssid);
478 DBGPRINT(RT_DEBUG_TRACE, ("MlmeStartReqAction - generate a radom number as BSSID \n"));
479
480 Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
481 (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
482 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
483 pAd->MlmeAux.CapabilityInfo = CAP_GENERATE(0,1,Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 1, 0);
484 pAd->MlmeAux.BeaconPeriod = pAd->CommonCfg.BeaconPeriod;
485 pAd->MlmeAux.AtimWin = pAd->StaCfg.AtimWin;
486 pAd->MlmeAux.Channel = pAd->CommonCfg.Channel;
487
488 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
489 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.CentralChannel;
490
491 pAd->MlmeAux.SupRateLen= pAd->CommonCfg.SupRateLen;
492 NdisMoveMemory(pAd->MlmeAux.SupRate, pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES);
493 RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen);
494 pAd->MlmeAux.ExtRateLen = pAd->CommonCfg.ExtRateLen;
495 NdisMoveMemory(pAd->MlmeAux.ExtRate, pAd->CommonCfg.ExtRate, MAX_LEN_OF_SUPPORTED_RATES);
496 RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen);
497#ifdef DOT11_N_SUPPORT
498 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
499 {
500 RTMPUpdateHTIE(&pAd->CommonCfg.DesiredHtPhy, &pAd->StaCfg.DesiredHtPhyInfo.MCSSet[0], &pAd->MlmeAux.HtCapability, &pAd->MlmeAux.AddHtInfo);
501 pAd->MlmeAux.HtCapabilityLen = sizeof(HT_CAPABILITY_IE);
502 // Not turn pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE here.
503 DBGPRINT(RT_DEBUG_TRACE, ("SYNC -pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE\n"));
504 }
505 else
506#endif // DOT11_N_SUPPORT //
507 {
508 pAd->MlmeAux.HtCapabilityLen = 0;
509 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
510 }
511 // temporarily not support QOS in IBSS
512 NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));
513 NdisZeroMemory(&pAd->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));
514 NdisZeroMemory(&pAd->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));
515
516 AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE);
517 AsicLockChannel(pAd, pAd->MlmeAux.Channel);
518
519 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeStartReqAction(ch= %d,sup rates= %d, ext rates=%d)\n",
520 pAd->MlmeAux.Channel, pAd->MlmeAux.SupRateLen, pAd->MlmeAux.ExtRateLen));
521
522 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
523 Status = MLME_SUCCESS;
524 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
525 }
526 else
527 {
528 DBGPRINT_ERR(("SYNC - MlmeStartReqAction() sanity check fail.\n"));
529 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
530 Status = MLME_INVALID_FORMAT;
531 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
532 }
533}
534
535/*
536 ==========================================================================
537 Description:
538 peer sends beacon back when scanning
539 ==========================================================================
540 */
541VOID PeerBeaconAtScanAction(
542 IN PRTMP_ADAPTER pAd,
543 IN MLME_QUEUE_ELEM *Elem)
544{
545 UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
546 UCHAR Ssid[MAX_LEN_OF_SSID], BssType, Channel, NewChannel,
547 SsidLen, DtimCount, DtimPeriod, BcastFlag, MessageToMe;
548 CF_PARM CfParm;
549 USHORT BeaconPeriod, AtimWin, CapabilityInfo;
550 PFRAME_802_11 pFrame;
551 LARGE_INTEGER TimeStamp;
552 UCHAR Erp;
553 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
554 UCHAR SupRateLen, ExtRateLen;
555 USHORT LenVIE;
556 UCHAR CkipFlag;
557 UCHAR AironetCellPowerLimit;
558 EDCA_PARM EdcaParm;
559 QBSS_LOAD_PARM QbssLoad;
560 QOS_CAPABILITY_PARM QosCapability;
561 ULONG RalinkIe;
562 UCHAR VarIE[MAX_VIE_LEN]; // Total VIE length = MAX_VIE_LEN - -5
563 NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
564 HT_CAPABILITY_IE HtCapability;
565 ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
566 UCHAR HtCapabilityLen = 0, PreNHtCapabilityLen = 0;
567 UCHAR AddHtInfoLen;
568 UCHAR NewExtChannelOffset = 0xff;
569
570
571 // NdisFillMemory(Ssid, MAX_LEN_OF_SSID, 0x00);
572 pFrame = (PFRAME_802_11) Elem->Msg;
573 // Init Variable IE structure
574 pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
575 pVIE->Length = 0;
576#ifdef DOT11_N_SUPPORT
577 RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
578 RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE));
579#endif // DOT11_N_SUPPORT //
580
581 if (PeerBeaconAndProbeRspSanity(pAd,
582 Elem->Msg,
583 Elem->MsgLen,
584 Elem->Channel,
585 Addr2,
586 Bssid,
587 Ssid,
588 &SsidLen,
589 &BssType,
590 &BeaconPeriod,
591 &Channel,
592 &NewChannel,
593 &TimeStamp,
594 &CfParm,
595 &AtimWin,
596 &CapabilityInfo,
597 &Erp,
598 &DtimCount,
599 &DtimPeriod,
600 &BcastFlag,
601 &MessageToMe,
602 SupRate,
603 &SupRateLen,
604 ExtRate,
605 &ExtRateLen,
606 &CkipFlag,
607 &AironetCellPowerLimit,
608 &EdcaParm,
609 &QbssLoad,
610 &QosCapability,
611 &RalinkIe,
612 &HtCapabilityLen,
613 &PreNHtCapabilityLen,
614 &HtCapability,
615 &AddHtInfoLen,
616 &AddHtInfo,
617 &NewExtChannelOffset,
618 &LenVIE,
619 pVIE))
620 {
621 ULONG Idx;
622 CHAR Rssi = 0;
623
624 Idx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
625 if (Idx != BSS_NOT_FOUND)
626 Rssi = pAd->ScanTab.BssEntry[Idx].Rssi;
627
628 Rssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
629
630
631#ifdef DOT11_N_SUPPORT
632 if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
633 HtCapabilityLen = SIZE_HT_CAP_IE;
634#endif // DOT11_N_SUPPORT //
635 if ((pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED) && (Channel == pAd->StaCfg.CCXScanChannel))
636 {
637 Idx = BssTableSetEntry(pAd, &pAd->StaCfg.CCXBssTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
638 &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen,ExtRate, ExtRateLen, &HtCapability,
639 &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, Rssi, TimeStamp, CkipFlag,
640 &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
641 if (Idx != BSS_NOT_FOUND)
642 {
643 NdisMoveMemory(pAd->StaCfg.CCXBssTab.BssEntry[Idx].PTSF, &Elem->Msg[24], 4);
644 NdisMoveMemory(&pAd->StaCfg.CCXBssTab.BssEntry[Idx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4);
645 NdisMoveMemory(&pAd->StaCfg.CCXBssTab.BssEntry[Idx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4);
646 if (pAd->StaCfg.CCXReqType == MSRN_TYPE_BEACON_REQ)
647 AironetAddBeaconReport(pAd, Idx, Elem);
648 }
649 }
650 else
651 {
652 Idx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
653 &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, &HtCapability,
654 &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, Rssi, TimeStamp, CkipFlag,
655 &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
656#ifdef DOT11_N_SUPPORT
657#ifdef DOT11N_DRAFT3
658 if (pAd->ChannelList[pAd->CommonCfg.ChannelListIdx].bEffectedChannel == TRUE)
659 {
660 UCHAR RegClass;
661 PeerBeaconAndProbeRspSanity2(pAd, Elem->Msg, Elem->MsgLen, &RegClass);
662 TriEventTableSetEntry(pAd, &pAd->CommonCfg.TriggerEventTab, Bssid, &HtCapability, HtCapabilityLen, RegClass, Channel);
663 }
664#endif // DOT11N_DRAFT3 //
665#endif // DOT11_N_SUPPORT //
666 if (Idx != BSS_NOT_FOUND)
667 {
668 NdisMoveMemory(pAd->ScanTab.BssEntry[Idx].PTSF, &Elem->Msg[24], 4);
669 NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4);
670 NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4);
671 }
672 }
673 }
674 // sanity check fail, ignored
675}
676
677/*
678 ==========================================================================
679 Description:
680 When waiting joining the (I)BSS, beacon received from external
681 ==========================================================================
682 */
683VOID PeerBeaconAtJoinAction(
684 IN PRTMP_ADAPTER pAd,
685 IN MLME_QUEUE_ELEM *Elem)
686{
687 UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
688 UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen, BssType, Channel, MessageToMe,
689 DtimCount, DtimPeriod, BcastFlag, NewChannel;
690 LARGE_INTEGER TimeStamp;
691 USHORT BeaconPeriod, AtimWin, CapabilityInfo;
692 CF_PARM Cf;
693 BOOLEAN TimerCancelled;
694 UCHAR Erp;
695 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
696 UCHAR SupRateLen, ExtRateLen;
697 UCHAR CkipFlag;
698 USHORT LenVIE;
699 UCHAR AironetCellPowerLimit;
700 EDCA_PARM EdcaParm;
701 QBSS_LOAD_PARM QbssLoad;
702 QOS_CAPABILITY_PARM QosCapability;
703 USHORT Status;
704 UCHAR VarIE[MAX_VIE_LEN]; // Total VIE length = MAX_VIE_LEN - -5
705 NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
706 ULONG RalinkIe;
707 ULONG Idx;
708 HT_CAPABILITY_IE HtCapability;
709 ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
710 UCHAR HtCapabilityLen = 0, PreNHtCapabilityLen = 0;
711 UCHAR AddHtInfoLen;
712 UCHAR NewExtChannelOffset = 0xff;
713#ifdef DOT11_N_SUPPORT
714 UCHAR CentralChannel;
715#endif // DOT11_N_SUPPORT //
716
717 // Init Variable IE structure
718 pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
719 pVIE->Length = 0;
720 RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
721 RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE));
722
723
724 if (PeerBeaconAndProbeRspSanity(pAd,
725 Elem->Msg,
726 Elem->MsgLen,
727 Elem->Channel,
728 Addr2,
729 Bssid,
730 Ssid,
731 &SsidLen,
732 &BssType,
733 &BeaconPeriod,
734 &Channel,
735 &NewChannel,
736 &TimeStamp,
737 &Cf,
738 &AtimWin,
739 &CapabilityInfo,
740 &Erp,
741 &DtimCount,
742 &DtimPeriod,
743 &BcastFlag,
744 &MessageToMe,
745 SupRate,
746 &SupRateLen,
747 ExtRate,
748 &ExtRateLen,
749 &CkipFlag,
750 &AironetCellPowerLimit,
751 &EdcaParm,
752 &QbssLoad,
753 &QosCapability,
754 &RalinkIe,
755 &HtCapabilityLen,
756 &PreNHtCapabilityLen,
757 &HtCapability,
758 &AddHtInfoLen,
759 &AddHtInfo,
760 &NewExtChannelOffset,
761 &LenVIE,
762 pVIE))
763 {
764 // Disqualify 11b only adhoc when we are in 11g only adhoc mode
765 if ((BssType == BSS_ADHOC) && (pAd->CommonCfg.PhyMode == PHY_11G) && ((SupRateLen+ExtRateLen)< 12))
766 return;
767
768 // BEACON from desired BSS/IBSS found. We should be able to decide most
769 // BSS parameters here.
770 // Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATEION?
771 // Do we need to receover back all parameters belonging to previous BSS?
772 // A. Should be not. There's no back-door recover to previous AP. It still need
773 // a new JOIN-AUTH-ASSOC sequence.
774 if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Bssid))
775 {
776 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - receive desired BEACON at JoinWaitBeacon... Channel = %d\n", Channel));
777 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
778
779 // Update RSSI to prevent No signal display when cards first initialized
780 pAd->StaCfg.RssiSample.LastRssi0 = ConvertToRssi(pAd, Elem->Rssi0, RSSI_0);
781 pAd->StaCfg.RssiSample.LastRssi1 = ConvertToRssi(pAd, Elem->Rssi1, RSSI_1);
782 pAd->StaCfg.RssiSample.LastRssi2 = ConvertToRssi(pAd, Elem->Rssi2, RSSI_2);
783 pAd->StaCfg.RssiSample.AvgRssi0 = pAd->StaCfg.RssiSample.LastRssi0;
784 pAd->StaCfg.RssiSample.AvgRssi0X8 = pAd->StaCfg.RssiSample.AvgRssi0 << 3;
785 pAd->StaCfg.RssiSample.AvgRssi1 = pAd->StaCfg.RssiSample.LastRssi1;
786 pAd->StaCfg.RssiSample.AvgRssi1X8 = pAd->StaCfg.RssiSample.AvgRssi1 << 3;
787 pAd->StaCfg.RssiSample.AvgRssi2 = pAd->StaCfg.RssiSample.LastRssi2;
788 pAd->StaCfg.RssiSample.AvgRssi2X8 = pAd->StaCfg.RssiSample.AvgRssi2 << 3;
789
790 //
791 // We need to check if SSID only set to any, then we can record the current SSID.
792 // Otherwise will cause hidden SSID association failed.
793 //
794 if (pAd->MlmeAux.SsidLen == 0)
795 {
796 NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
797 pAd->MlmeAux.SsidLen = SsidLen;
798 }
799 else
800 {
801 Idx = BssSsidTableSearch(&pAd->ScanTab, Bssid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Channel);
802
803 if (Idx != BSS_NOT_FOUND)
804 {
805 //
806 // Multiple SSID case, used correct CapabilityInfo
807 //
808 CapabilityInfo = pAd->ScanTab.BssEntry[Idx].CapabilityInfo;
809 }
810 }
811 NdisMoveMemory(pAd->MlmeAux.Bssid, Bssid, MAC_ADDR_LEN);
812 pAd->MlmeAux.CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO;
813 pAd->MlmeAux.BssType = BssType;
814 pAd->MlmeAux.BeaconPeriod = BeaconPeriod;
815 pAd->MlmeAux.Channel = Channel;
816 pAd->MlmeAux.AtimWin = AtimWin;
817 pAd->MlmeAux.CfpPeriod = Cf.CfpPeriod;
818 pAd->MlmeAux.CfpMaxDuration = Cf.CfpMaxDuration;
819 pAd->MlmeAux.APRalinkIe = RalinkIe;
820
821 // Copy AP's supported rate to MlmeAux for creating assoication request
822 // Also filter out not supported rate
823 pAd->MlmeAux.SupRateLen = SupRateLen;
824 NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate, SupRateLen);
825 RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen);
826 pAd->MlmeAux.ExtRateLen = ExtRateLen;
827 NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate, ExtRateLen);
828 RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen);
829
830 NdisZeroMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, 16);
831#ifdef DOT11_N_SUPPORT
832 pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset;
833 pAd->MlmeAux.HtCapabilityLen = HtCapabilityLen;
834
835 // filter out un-supported ht rates
836 if (((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0)) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
837 {
838 RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
839 RTMPMoveMemory(&pAd->MlmeAux.AddHtInfo, &AddHtInfo, SIZE_ADD_HT_INFO_IE);
840
841 // StaActive.SupportedHtPhy.MCSSet stores Peer AP's 11n Rx capability
842 NdisMoveMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, HtCapability.MCSSet, 16);
843 pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset;
844 pAd->MlmeAux.HtCapabilityLen = SIZE_HT_CAP_IE;
845 pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
846 if (PreNHtCapabilityLen > 0)
847 pAd->StaActive.SupportedPhyInfo.bPreNHt = TRUE;
848 RTMPCheckHt(pAd, BSSID_WCID, &HtCapability, &AddHtInfo);
849 // Copy AP Parameter to StaActive. This is also in LinkUp.
850 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction! (MpduDensity=%d, MaxRAmpduFactor=%d, BW=%d)\n",
851 pAd->StaActive.SupportedHtPhy.MpduDensity, pAd->StaActive.SupportedHtPhy.MaxRAmpduFactor, HtCapability.HtCapInfo.ChannelWidth));
852
853 if (AddHtInfoLen > 0)
854 {
855 CentralChannel = AddHtInfo.ControlChan;
856 // Check again the Bandwidth capability of this AP.
857 if ((AddHtInfo.ControlChan > 2)&& (AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW) && (HtCapability.HtCapInfo.ChannelWidth == BW_40))
858 {
859 CentralChannel = AddHtInfo.ControlChan - 2;
860 }
861 else if ((AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) && (HtCapability.HtCapInfo.ChannelWidth == BW_40))
862 {
863 CentralChannel = AddHtInfo.ControlChan + 2;
864 }
865
866 // Check Error .
867 if (pAd->MlmeAux.CentralChannel != CentralChannel)
868 DBGPRINT(RT_DEBUG_ERROR, ("PeerBeaconAtJoinAction HT===>Beacon Central Channel = %d, Control Channel = %d. Mlmeaux CentralChannel = %d\n", CentralChannel, AddHtInfo.ControlChan, pAd->MlmeAux.CentralChannel));
869
870 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction HT===>Central Channel = %d, Control Channel = %d, .\n", CentralChannel, AddHtInfo.ControlChan));
871
872 }
873
874 }
875 else
876#endif // DOT11_N_SUPPORT //
877 {
878 // To prevent error, let legacy AP must have same CentralChannel and Channel.
879 if ((HtCapabilityLen == 0) && (PreNHtCapabilityLen == 0))
880 pAd->MlmeAux.CentralChannel = pAd->MlmeAux.Channel;
881
882 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
883 RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
884 RTMPZeroMemory(&pAd->MlmeAux.AddHtInfo, SIZE_ADD_HT_INFO_IE);
885 }
886
887 RTMPUpdateMlmeRate(pAd);
888
889 // copy QOS related information
890 if ((pAd->CommonCfg.bWmmCapable)
891#ifdef DOT11_N_SUPPORT
892 || (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
893#endif // DOT11_N_SUPPORT //
894 )
895 {
896 NdisMoveMemory(&pAd->MlmeAux.APEdcaParm, &EdcaParm, sizeof(EDCA_PARM));
897 NdisMoveMemory(&pAd->MlmeAux.APQbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM));
898 NdisMoveMemory(&pAd->MlmeAux.APQosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM));
899 }
900 else
901 {
902 NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));
903 NdisZeroMemory(&pAd->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));
904 NdisZeroMemory(&pAd->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));
905 }
906
907 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n",
908 pAd->MlmeAux.SupRateLen, pAd->MlmeAux.ExtRateLen));
909
910#ifdef LEAP_SUPPORT
911 // Update CkipFlag
912 pAd->StaCfg.CkipFlag = CkipFlag;
913
914 // Keep TimeStamp for Re-Association used.
915 if (LEAP_CCKM_ON(pAd) && (pAd->StaCfg.CCKMLinkUpFlag == TRUE))
916 pAd->StaCfg.CCKMBeaconAtJoinTimeStamp = TimeStamp;
917#endif // LEAP_SUPPORT //
918
919 if (AironetCellPowerLimit != 0xFF)
920 {
921 //We need to change our TxPower for CCX 2.0 AP Control of Client Transmit Power
922 ChangeToCellPowerLimit(pAd, AironetCellPowerLimit);
923 }
924 else //Used the default TX Power Percentage.
925 pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
926
927 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
928 Status = MLME_SUCCESS;
929 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
930 }
931 // not to me BEACON, ignored
932 }
933 // sanity check fail, ignore this frame
934}
935
936/*
937 ==========================================================================
938 Description:
939 receive BEACON from peer
940
941 IRQL = DISPATCH_LEVEL
942
943 ==========================================================================
944 */
945VOID PeerBeacon(
946 IN PRTMP_ADAPTER pAd,
947 IN MLME_QUEUE_ELEM *Elem)
948{
949 UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
950 CHAR Ssid[MAX_LEN_OF_SSID];
951 CF_PARM CfParm;
952 UCHAR SsidLen, MessageToMe=0, BssType, Channel, NewChannel, index=0;
953 UCHAR DtimCount=0, DtimPeriod=0, BcastFlag=0;
954 USHORT CapabilityInfo, AtimWin, BeaconPeriod;
955 LARGE_INTEGER TimeStamp;
956 USHORT TbttNumToNextWakeUp;
957 UCHAR Erp;
958 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
959 UCHAR SupRateLen, ExtRateLen;
960 UCHAR CkipFlag;
961 USHORT LenVIE;
962 UCHAR AironetCellPowerLimit;
963 EDCA_PARM EdcaParm;
964 QBSS_LOAD_PARM QbssLoad;
965 QOS_CAPABILITY_PARM QosCapability;
966 ULONG RalinkIe;
967 // New for WPA security suites
968 UCHAR VarIE[MAX_VIE_LEN]; // Total VIE length = MAX_VIE_LEN - -5
969 NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
970 HT_CAPABILITY_IE HtCapability;
971 ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
972 UCHAR HtCapabilityLen, PreNHtCapabilityLen;
973 UCHAR AddHtInfoLen;
974 UCHAR NewExtChannelOffset = 0xff;
975
976
977#ifdef RALINK_ATE
978 if (ATE_ON(pAd))
979 {
980 return;
981 }
982#endif // RALINK_ATE //
983
984 if (!(INFRA_ON(pAd) || ADHOC_ON(pAd)
985 ))
986 return;
987
988 // Init Variable IE structure
989 pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
990 pVIE->Length = 0;
991 RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
992 RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE));
993
994 if (PeerBeaconAndProbeRspSanity(pAd,
995 Elem->Msg,
996 Elem->MsgLen,
997 Elem->Channel,
998 Addr2,
999 Bssid,
1000 Ssid,
1001 &SsidLen,
1002 &BssType,
1003 &BeaconPeriod,
1004 &Channel,
1005 &NewChannel,
1006 &TimeStamp,
1007 &CfParm,
1008 &AtimWin,
1009 &CapabilityInfo,
1010 &Erp,
1011 &DtimCount,
1012 &DtimPeriod,
1013 &BcastFlag,
1014 &MessageToMe,
1015 SupRate,
1016 &SupRateLen,
1017 ExtRate,
1018 &ExtRateLen,
1019 &CkipFlag,
1020 &AironetCellPowerLimit,
1021 &EdcaParm,
1022 &QbssLoad,
1023 &QosCapability,
1024 &RalinkIe,
1025 &HtCapabilityLen,
1026 &PreNHtCapabilityLen,
1027 &HtCapability,
1028 &AddHtInfoLen,
1029 &AddHtInfo,
1030 &NewExtChannelOffset,
1031 &LenVIE,
1032 pVIE))
1033 {
1034 BOOLEAN is_my_bssid, is_my_ssid;
1035 ULONG Bssidx, Now;
1036 BSS_ENTRY *pBss;
1037 CHAR RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
1038
1039 is_my_bssid = MAC_ADDR_EQUAL(Bssid, pAd->CommonCfg.Bssid)? TRUE : FALSE;
1040 is_my_ssid = SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen)? TRUE:FALSE;
1041
1042
1043 // ignore BEACON not for my SSID
1044 if ((! is_my_ssid) && (! is_my_bssid))
1045 return;
1046
1047 // It means STA waits disassoc completely from this AP, ignores this beacon.
1048 if (pAd->Mlme.CntlMachine.CurrState == CNTL_WAIT_DISASSOC)
1049 return;
1050
1051#ifdef DOT11_N_SUPPORT
1052 // Copy Control channel for this BSSID.
1053 if (AddHtInfoLen != 0)
1054 Channel = AddHtInfo.ControlChan;
1055
1056 if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
1057 HtCapabilityLen = SIZE_HT_CAP_IE;
1058#endif // DOT11_N_SUPPORT //
1059
1060 //
1061 // Housekeeping "SsidBssTab" table for later-on ROAMing usage.
1062 //
1063 Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
1064 if (Bssidx == BSS_NOT_FOUND)
1065 {
1066 // discover new AP of this network, create BSS entry
1067 Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
1068 &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,
1069 &HtCapability, &AddHtInfo,HtCapabilityLen,AddHtInfoLen,NewExtChannelOffset, Channel,
1070 RealRssi, TimeStamp, CkipFlag, &EdcaParm, &QosCapability,
1071 &QbssLoad, LenVIE, pVIE);
1072 if (Bssidx == BSS_NOT_FOUND) // return if BSS table full
1073 return;
1074
1075 NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].PTSF, &Elem->Msg[24], 4);
1076 NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4);
1077 NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4);
1078
1079
1080
1081 }
1082
1083 if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0) && (Channel != NewChannel))
1084 {
1085 // Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection).
1086 // In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results.
1087 AsicSwitchChannel(pAd, 1, FALSE);
1088 AsicLockChannel(pAd, 1);
1089 LinkDown(pAd, FALSE);
1090 MlmeQueueInit(&pAd->Mlme.Queue);
1091 BssTableInit(&pAd->ScanTab);
1092 RTMPusecDelay(1000000); // use delay to prevent STA do reassoc
1093
1094 // channel sanity check
1095 for (index = 0 ; index < pAd->ChannelListNum; index++)
1096 {
1097 if (pAd->ChannelList[index].Channel == NewChannel)
1098 {
1099 pAd->ScanTab.BssEntry[Bssidx].Channel = NewChannel;
1100 pAd->CommonCfg.Channel = NewChannel;
1101 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1102 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1103 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeacon - STA receive channel switch announcement IE (New Channel =%d)\n", NewChannel));
1104 break;
1105 }
1106 }
1107
1108 if (index >= pAd->ChannelListNum)
1109 {
1110 DBGPRINT_ERR(("PeerBeacon(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum));
1111 }
1112 }
1113
1114 // if the ssid matched & bssid unmatched, we should select the bssid with large value.
1115 // This might happened when two STA start at the same time
1116 if ((! is_my_bssid) && ADHOC_ON(pAd))
1117 {
1118 INT i;
1119
1120 // Add the safeguard against the mismatch of adhoc wep status
1121 if (pAd->StaCfg.WepStatus != pAd->ScanTab.BssEntry[Bssidx].WepStatus)
1122 {
1123 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - Not matched wep status %d %d\n", pAd->StaCfg.WepStatus, pAd->ScanTab.BssEntry[Bssidx].WepStatus));
1124 DBGPRINT(RT_DEBUG_TRACE, ("bssid=%s\n", pAd->ScanTab.BssEntry[Bssidx].Bssid));
1125 return;
1126 }
1127
1128 // collapse into the ADHOC network which has bigger BSSID value.
1129 for (i = 0; i < 6; i++)
1130 {
1131 if (Bssid[i] > pAd->CommonCfg.Bssid[i])
1132 {
1133 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - merge to the IBSS with bigger BSSID=%02x:%02x:%02x:%02x:%02x:%02x\n",
1134 Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
1135 AsicDisableSync(pAd);
1136 COPY_MAC_ADDR(pAd->CommonCfg.Bssid, Bssid);
1137 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1138 MakeIbssBeacon(pAd); // re-build BEACON frame
1139 AsicEnableIbssSync(pAd); // copy BEACON frame to on-chip memory
1140 is_my_bssid = TRUE;
1141 break;
1142 }
1143 else if (Bssid[i] < pAd->CommonCfg.Bssid[i])
1144 break;
1145 }
1146 }
1147
1148
1149 NdisGetSystemUpTime(&Now);
1150 pBss = &pAd->ScanTab.BssEntry[Bssidx];
1151 pBss->Rssi = RealRssi; // lastest RSSI
1152 pBss->LastBeaconRxTime = Now; // last RX timestamp
1153
1154 //
1155 // BEACON from my BSSID - either IBSS or INFRA network
1156 //
1157 if (is_my_bssid)
1158 {
1159 RXWI_STRUC RxWI;
1160
1161 pAd->StaCfg.DtimCount = DtimCount;
1162 pAd->StaCfg.DtimPeriod = DtimPeriod;
1163 pAd->StaCfg.LastBeaconRxTime = Now;
1164
1165
1166 RxWI.RSSI0 = Elem->Rssi0;
1167 RxWI.RSSI1 = Elem->Rssi1;
1168 RxWI.RSSI2 = Elem->Rssi2;
1169
1170 Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, &RxWI);
1171 if (AironetCellPowerLimit != 0xFF)
1172 {
1173 //
1174 // We get the Cisco (ccx) "TxPower Limit" required
1175 // Changed to appropriate TxPower Limit for Ciso Compatible Extensions
1176 //
1177 ChangeToCellPowerLimit(pAd, AironetCellPowerLimit);
1178 }
1179 else
1180 {
1181 //
1182 // AironetCellPowerLimit equal to 0xFF means the Cisco (ccx) "TxPower Limit" not exist.
1183 // Used the default TX Power Percentage, that set from UI.
1184 //
1185 pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
1186 }
1187
1188 if (ADHOC_ON(pAd) && (CAP_IS_IBSS_ON(CapabilityInfo)))
1189 {
1190 UCHAR MaxSupportedRateIn500Kbps = 0;
1191 UCHAR idx;
1192 MAC_TABLE_ENTRY *pEntry;
1193
1194 // supported rates array may not be sorted. sort it and find the maximum rate
1195 for (idx=0; idx<SupRateLen; idx++)
1196 {
1197 if (MaxSupportedRateIn500Kbps < (SupRate[idx] & 0x7f))
1198 MaxSupportedRateIn500Kbps = SupRate[idx] & 0x7f;
1199 }
1200
1201 for (idx=0; idx<ExtRateLen; idx++)
1202 {
1203 if (MaxSupportedRateIn500Kbps < (ExtRate[idx] & 0x7f))
1204 MaxSupportedRateIn500Kbps = ExtRate[idx] & 0x7f;
1205 }
1206
1207 // look up the existing table
1208 pEntry = MacTableLookup(pAd, Addr2);
1209
1210 // Ad-hoc mode is using MAC address as BA session. So we need to continuously find newly joined adhoc station by receiving beacon.
1211 // To prevent always check this, we use wcid == RESERVED_WCID to recognize it as newly joined adhoc station.
1212 if ((ADHOC_ON(pAd) && (Elem->Wcid == RESERVED_WCID)) ||
1213 (pEntry && ((pEntry->LastBeaconRxTime + ADHOC_ENTRY_BEACON_LOST_TIME) < Now)))
1214 {
1215 if (pEntry == NULL)
1216 // Another adhoc joining, add to our MAC table.
1217 pEntry = MacTableInsertEntry(pAd, Addr2, BSS0, FALSE);
1218
1219 if (StaAddMacTableEntry(pAd, pEntry, MaxSupportedRateIn500Kbps, &HtCapability, HtCapabilityLen, CapabilityInfo) == FALSE)
1220 {
1221 DBGPRINT(RT_DEBUG_TRACE, ("ADHOC - Add Entry failed.\n"));
1222 return;
1223 }
1224
1225 if (pEntry &&
1226 (Elem->Wcid == RESERVED_WCID))
1227 {
1228 idx = pAd->StaCfg.DefaultKeyId;
1229 RT28XX_STA_SECURITY_INFO_ADD(pAd, BSS0, idx, pEntry);
1230 }
1231 }
1232
1233 if (pEntry && pEntry->ValidAsCLI)
1234 pEntry->LastBeaconRxTime = Now;
1235
1236 // At least another peer in this IBSS, declare MediaState as CONNECTED
1237 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1238 {
1239 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1240
1241 pAd->IndicateMediaState = NdisMediaStateConnected;
1242 RTMP_IndicateMediaState(pAd);
1243 pAd->ExtraInfo = GENERAL_LINK_UP;
1244 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1245
1246 // 2003/03/12 - john
1247 // Make sure this entry in "ScanTab" table, thus complies to Microsoft's policy that
1248 // "site survey" result should always include the current connected network.
1249 //
1250 Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
1251 if (Bssidx == BSS_NOT_FOUND)
1252 {
1253 Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
1254 &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, &HtCapability,
1255 &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, RealRssi, TimeStamp, 0,
1256 &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
1257 }
1258 DBGPRINT(RT_DEBUG_TRACE, ("ADHOC fOP_STATUS_MEDIA_STATE_CONNECTED.\n"));
1259 }
1260 }
1261
1262 if (INFRA_ON(pAd))
1263 {
1264 BOOLEAN bUseShortSlot, bUseBGProtection;
1265
1266 // decide to use/change to -
1267 // 1. long slot (20 us) or short slot (9 us) time
1268 // 2. turn on/off RTS/CTS and/or CTS-to-self protection
1269 // 3. short preamble
1270
1271 //bUseShortSlot = pAd->CommonCfg.bUseShortSlotTime && CAP_IS_SHORT_SLOT(CapabilityInfo);
1272 bUseShortSlot = CAP_IS_SHORT_SLOT(CapabilityInfo);
1273 if (bUseShortSlot != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED))
1274 AsicSetSlotTime(pAd, bUseShortSlot);
1275
1276 bUseBGProtection = (pAd->CommonCfg.UseBGProtection == 1) || // always use
1277 ((pAd->CommonCfg.UseBGProtection == 0) && ERP_IS_USE_PROTECTION(Erp));
1278
1279 if (pAd->CommonCfg.Channel > 14) // always no BG protection in A-band. falsely happened when switching A/G band to a dual-band AP
1280 bUseBGProtection = FALSE;
1281
1282 if (bUseBGProtection != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
1283 {
1284 if (bUseBGProtection)
1285 {
1286 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
1287 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, (OFDMSETPROTECT|CCKSETPROTECT|ALLN_SETPROTECT),FALSE,(pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1));
1288 }
1289 else
1290 {
1291 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
1292 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, (OFDMSETPROTECT|CCKSETPROTECT|ALLN_SETPROTECT),TRUE,(pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1));
1293 }
1294
1295 DBGPRINT(RT_DEBUG_WARN, ("SYNC - AP changed B/G protection to %d\n", bUseBGProtection));
1296 }
1297
1298#ifdef DOT11_N_SUPPORT
1299 // check Ht protection mode. and adhere to the Non-GF device indication by AP.
1300 if ((AddHtInfoLen != 0) &&
1301 ((AddHtInfo.AddHtInfo2.OperaionMode != pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode) ||
1302 (AddHtInfo.AddHtInfo2.NonGfPresent != pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent)))
1303 {
1304 pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent = AddHtInfo.AddHtInfo2.NonGfPresent;
1305 pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode = AddHtInfo.AddHtInfo2.OperaionMode;
1306 if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
1307 {
1308 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE);
1309 }
1310 else
1311 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
1312
1313 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP changed N OperaionMode to %d\n", pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode));
1314 }
1315#endif // DOT11_N_SUPPORT //
1316
1317 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED) &&
1318 ERP_IS_USE_BARKER_PREAMBLE(Erp))
1319 {
1320 MlmeSetTxPreamble(pAd, Rt802_11PreambleLong);
1321 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP forced to use LONG preamble\n"));
1322 }
1323
1324 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
1325 (EdcaParm.bValid == TRUE) &&
1326 (EdcaParm.EdcaUpdateCount != pAd->CommonCfg.APEdcaParm.EdcaUpdateCount))
1327 {
1328 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP change EDCA parameters(from %d to %d)\n",
1329 pAd->CommonCfg.APEdcaParm.EdcaUpdateCount,
1330 EdcaParm.EdcaUpdateCount));
1331 AsicSetEdcaParm(pAd, &EdcaParm);
1332 }
1333
1334 // copy QOS related information
1335 NdisMoveMemory(&pAd->CommonCfg.APQbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM));
1336 NdisMoveMemory(&pAd->CommonCfg.APQosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM));
1337 }
1338
1339 // only INFRASTRUCTURE mode support power-saving feature
1340 if ((INFRA_ON(pAd) && (pAd->StaCfg.Psm == PWR_SAVE)) || (pAd->CommonCfg.bAPSDForcePowerSave))
1341 {
1342 UCHAR FreeNumber;
1343 // 1. AP has backlogged unicast-to-me frame, stay AWAKE, send PSPOLL
1344 // 2. AP has backlogged broadcast/multicast frame and we want those frames, stay AWAKE
1345 // 3. we have outgoing frames in TxRing or MgmtRing, better stay AWAKE
1346 // 4. Psm change to PWR_SAVE, but AP not been informed yet, we better stay AWAKE
1347 // 5. otherwise, put PHY back to sleep to save battery.
1348 if (MessageToMe)
1349 {
1350 if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable &&
1351 pAd->CommonCfg.bAPSDAC_BE && pAd->CommonCfg.bAPSDAC_BK && pAd->CommonCfg.bAPSDAC_VI && pAd->CommonCfg.bAPSDAC_VO)
1352 {
1353 pAd->CommonCfg.bNeedSendTriggerFrame = TRUE;
1354 }
1355 else
1356 RT28XX_PS_POLL_ENQUEUE(pAd);
1357 }
1358 else if (BcastFlag && (DtimCount == 0) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM))
1359 {
1360 }
1361 else if ((pAd->TxSwQueue[QID_AC_BK].Number != 0) ||
1362 (pAd->TxSwQueue[QID_AC_BE].Number != 0) ||
1363 (pAd->TxSwQueue[QID_AC_VI].Number != 0) ||
1364 (pAd->TxSwQueue[QID_AC_VO].Number != 0) ||
1365 (RTMPFreeTXDRequest(pAd, QID_AC_BK, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
1366 (RTMPFreeTXDRequest(pAd, QID_AC_BE, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
1367 (RTMPFreeTXDRequest(pAd, QID_AC_VI, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
1368 (RTMPFreeTXDRequest(pAd, QID_AC_VO, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
1369 (RTMPFreeTXDRequest(pAd, QID_MGMT, MGMT_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS))
1370 {
1371 // TODO: consider scheduled HCCA. might not be proper to use traditional DTIM-based power-saving scheme
1372 // can we cheat here (i.e. just check MGMT & AC_BE) for better performance?
1373 }
1374 else
1375 {
1376 USHORT NextDtim = DtimCount;
1377
1378 if (NextDtim == 0)
1379 NextDtim = DtimPeriod;
1380
1381 TbttNumToNextWakeUp = pAd->StaCfg.DefaultListenCount;
1382 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim))
1383 TbttNumToNextWakeUp = NextDtim;
1384
1385 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
1386 {
1387 AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
1388 }
1389 }
1390 }
1391 }
1392 // not my BSSID, ignore it
1393 }
1394 // sanity check fail, ignore this frame
1395}
1396
1397/*
1398 ==========================================================================
1399 Description:
1400 Receive PROBE REQ from remote peer when operating in IBSS mode
1401 ==========================================================================
1402 */
1403VOID PeerProbeReqAction(
1404 IN PRTMP_ADAPTER pAd,
1405 IN MLME_QUEUE_ELEM *Elem)
1406{
1407 UCHAR Addr2[MAC_ADDR_LEN];
1408 CHAR Ssid[MAX_LEN_OF_SSID];
1409 UCHAR SsidLen;
1410#ifdef DOT11_N_SUPPORT
1411 UCHAR HtLen, AddHtLen, NewExtLen;
1412#endif // DOT11_N_SUPPORT //
1413 HEADER_802_11 ProbeRspHdr;
1414 NDIS_STATUS NStatus;
1415 PUCHAR pOutBuffer = NULL;
1416 ULONG FrameLen = 0;
1417 LARGE_INTEGER FakeTimestamp;
1418 UCHAR DsLen = 1, IbssLen = 2;
1419 UCHAR LocalErpIe[3] = {IE_ERP, 1, 0};
1420 BOOLEAN Privacy;
1421 USHORT CapabilityInfo;
1422 UCHAR RSNIe = IE_WPA;
1423
1424 if (! ADHOC_ON(pAd))
1425 return;
1426
1427 if (PeerProbeReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, Ssid, &SsidLen))
1428 {
1429 if ((SsidLen == 0) || SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen))
1430 {
1431 // allocate and send out ProbeRsp frame
1432 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1433 if (NStatus != NDIS_STATUS_SUCCESS)
1434 return;
1435
1436 //pAd->StaCfg.AtimWin = 0; // ??????
1437
1438 Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
1439 (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
1440 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
1441 CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
1442
1443 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1444 sizeof(HEADER_802_11), &ProbeRspHdr,
1445 TIMESTAMP_LEN, &FakeTimestamp,
1446 2, &pAd->CommonCfg.BeaconPeriod,
1447 2, &CapabilityInfo,
1448 1, &SsidIe,
1449 1, &pAd->CommonCfg.SsidLen,
1450 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
1451 1, &SupRateIe,
1452 1, &pAd->StaActive.SupRateLen,
1453 pAd->StaActive.SupRateLen, pAd->StaActive.SupRate,
1454 1, &DsIe,
1455 1, &DsLen,
1456 1, &pAd->CommonCfg.Channel,
1457 1, &IbssIe,
1458 1, &IbssLen,
1459 2, &pAd->StaActive.AtimWin,
1460 END_OF_ARGS);
1461
1462 if (pAd->StaActive.ExtRateLen)
1463 {
1464 ULONG tmp;
1465 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
1466 3, LocalErpIe,
1467 1, &ExtRateIe,
1468 1, &pAd->StaActive.ExtRateLen,
1469 pAd->StaActive.ExtRateLen, &pAd->StaActive.ExtRate,
1470 END_OF_ARGS);
1471 FrameLen += tmp;
1472 }
1473
1474 // If adhoc secruity is set for WPA-None, append the cipher suite IE
1475 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1476 {
1477 ULONG tmp;
1478 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
1479 1, &RSNIe,
1480 1, &pAd->StaCfg.RSNIE_Len,
1481 pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
1482 END_OF_ARGS);
1483 FrameLen += tmp;
1484 }
1485#ifdef DOT11_N_SUPPORT
1486 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
1487 {
1488 ULONG TmpLen;
1489 UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
1490 HtLen = sizeof(pAd->CommonCfg.HtCapability);
1491 AddHtLen = sizeof(pAd->CommonCfg.AddHTInfo);
1492 NewExtLen = 1;
1493 //New extension channel offset IE is included in Beacon, Probe Rsp or channel Switch Announcement Frame
1494 if (pAd->bBroadComHT == TRUE)
1495 {
1496 MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
1497 1, &WpaIe,
1498 4, &BROADCOM[0],
1499 pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability,
1500 END_OF_ARGS);
1501 }
1502 else
1503 {
1504 MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
1505 1, &HtCapIe,
1506 1, &HtLen,
1507 sizeof(HT_CAPABILITY_IE), &pAd->CommonCfg.HtCapability,
1508 1, &AddHtInfoIe,
1509 1, &AddHtLen,
1510 sizeof(ADD_HT_INFO_IE), &pAd->CommonCfg.AddHTInfo,
1511 1, &NewExtChanIe,
1512 1, &NewExtLen,
1513 sizeof(NEW_EXT_CHAN_IE), &pAd->CommonCfg.NewExtChanOffset,
1514 END_OF_ARGS);
1515 }
1516 FrameLen += TmpLen;
1517 }
1518#endif // DOT11_N_SUPPORT //
1519 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1520 MlmeFreeMemory(pAd, pOutBuffer);
1521 }
1522 }
1523}
1524
1525VOID BeaconTimeoutAtJoinAction(
1526 IN PRTMP_ADAPTER pAd,
1527 IN MLME_QUEUE_ELEM *Elem)
1528{
1529 USHORT Status;
1530 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BeaconTimeoutAtJoinAction\n"));
1531 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1532 Status = MLME_REJ_TIMEOUT;
1533 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
1534}
1535
1536/*
1537 ==========================================================================
1538 Description:
1539 Scan timeout procedure. basically add channel index by 1 and rescan
1540 ==========================================================================
1541 */
1542VOID ScanTimeoutAction(
1543 IN PRTMP_ADAPTER pAd,
1544 IN MLME_QUEUE_ELEM *Elem)
1545{
1546 pAd->MlmeAux.Channel = NextChannel(pAd, pAd->MlmeAux.Channel);
1547
1548 // Only one channel scanned for CISCO beacon request
1549 if ((pAd->MlmeAux.ScanType == SCAN_CISCO_ACTIVE) ||
1550 (pAd->MlmeAux.ScanType == SCAN_CISCO_PASSIVE) ||
1551 (pAd->MlmeAux.ScanType == SCAN_CISCO_NOISE) ||
1552 (pAd->MlmeAux.ScanType == SCAN_CISCO_CHANNEL_LOAD))
1553 pAd->MlmeAux.Channel = 0;
1554
1555 // this routine will stop if pAd->MlmeAux.Channel == 0
1556 ScanNextChannel(pAd);
1557}
1558
1559/*
1560 ==========================================================================
1561 Description:
1562 ==========================================================================
1563 */
1564VOID InvalidStateWhenScan(
1565 IN PRTMP_ADAPTER pAd,
1566 IN MLME_QUEUE_ELEM *Elem)
1567{
1568 USHORT Status;
1569 DBGPRINT(RT_DEBUG_TRACE, ("AYNC - InvalidStateWhenScan(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState));
1570 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1571 Status = MLME_STATE_MACHINE_REJECT;
1572 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
1573}
1574
1575/*
1576 ==========================================================================
1577 Description:
1578 ==========================================================================
1579 */
1580VOID InvalidStateWhenJoin(
1581 IN PRTMP_ADAPTER pAd,
1582 IN MLME_QUEUE_ELEM *Elem)
1583{
1584 USHORT Status;
1585 DBGPRINT(RT_DEBUG_TRACE, ("InvalidStateWhenJoin(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState));
1586 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1587 Status = MLME_STATE_MACHINE_REJECT;
1588 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
1589}
1590
1591/*
1592 ==========================================================================
1593 Description:
1594 ==========================================================================
1595 */
1596VOID InvalidStateWhenStart(
1597 IN PRTMP_ADAPTER pAd,
1598 IN MLME_QUEUE_ELEM *Elem)
1599{
1600 USHORT Status;
1601 DBGPRINT(RT_DEBUG_TRACE, ("InvalidStateWhenStart(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState));
1602 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1603 Status = MLME_STATE_MACHINE_REJECT;
1604 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
1605}
1606
1607/*
1608 ==========================================================================
1609 Description:
1610
1611 IRQL = DISPATCH_LEVEL
1612
1613 ==========================================================================
1614 */
1615VOID EnqueuePsPoll(
1616 IN PRTMP_ADAPTER pAd)
1617{
1618#ifdef RALINK_ATE
1619 if (ATE_ON(pAd))
1620 {
1621 return;
1622 }
1623#endif // RALINK_ATE //
1624
1625
1626 if (pAd->StaCfg.WindowsPowerMode == Ndis802_11PowerModeLegacy_PSP)
1627 pAd->PsPollFrame.FC.PwrMgmt = PWR_SAVE;
1628 MiniportMMRequest(pAd, 0, (PUCHAR)&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
1629}
1630
1631
1632/*
1633 ==========================================================================
1634 Description:
1635 ==========================================================================
1636 */
1637VOID EnqueueProbeRequest(
1638 IN PRTMP_ADAPTER pAd)
1639{
1640 NDIS_STATUS NState;
1641 PUCHAR pOutBuffer;
1642 ULONG FrameLen = 0;
1643 HEADER_802_11 Hdr80211;
1644
1645 DBGPRINT(RT_DEBUG_TRACE, ("force out a ProbeRequest ...\n"));
1646
1647 NState = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1648 if (NState == NDIS_STATUS_SUCCESS)
1649 {
1650 MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
1651
1652 // this ProbeRequest explicitly specify SSID to reduce unwanted ProbeResponse
1653 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1654 sizeof(HEADER_802_11), &Hdr80211,
1655 1, &SsidIe,
1656 1, &pAd->CommonCfg.SsidLen,
1657 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
1658 1, &SupRateIe,
1659 1, &pAd->StaActive.SupRateLen,
1660 pAd->StaActive.SupRateLen, pAd->StaActive.SupRate,
1661 END_OF_ARGS);
1662 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1663 MlmeFreeMemory(pAd, pOutBuffer);
1664 }
1665
1666}
1667
1668#ifdef DOT11_N_SUPPORT
1669#ifdef DOT11N_DRAFT3
1670VOID BuildEffectedChannelList(
1671 IN PRTMP_ADAPTER pAd)
1672{
1673 UCHAR EChannel[11];
1674 UCHAR i, j, k;
1675 UCHAR UpperChannel = 0, LowerChannel = 0;
1676
1677 RTMPZeroMemory(EChannel, 11);
1678 i = 0;
1679 // Find upper channel and lower channel.
1680 if (pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel)
1681 {
1682 UpperChannel = pAd->CommonCfg.Channel;
1683 LowerChannel = pAd->CommonCfg.CentralChannel;
1684 }
1685 else if (pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel)
1686 {
1687 UpperChannel = pAd->CommonCfg.CentralChannel;
1688 LowerChannel = pAd->CommonCfg.Channel;
1689 }
1690 else
1691 {
1692 return;
1693 }
1694
1695 // Record channels that is below lower channel..
1696 if (LowerChannel > 1)
1697 {
1698 EChannel[0] = LowerChannel - 1;
1699 i = 1;
1700 if (LowerChannel > 2)
1701 {
1702 EChannel[1] = LowerChannel - 2;
1703 i = 2;
1704 if (LowerChannel > 3)
1705 {
1706 EChannel[2] = LowerChannel - 3;
1707 i = 3;
1708 }
1709 }
1710 }
1711 // Record channels that is between lower channel and upper channel.
1712 for (k = LowerChannel;k < UpperChannel;k++)
1713 {
1714 EChannel[i] = k;
1715 i++;
1716 }
1717 // Record channels that is above upper channel..
1718 if (LowerChannel < 11)
1719 {
1720 EChannel[i] = UpperChannel + 1;
1721 i++;
1722 if (LowerChannel < 10)
1723 {
1724 EChannel[i] = LowerChannel + 2;
1725 i++;
1726 if (LowerChannel < 9)
1727 {
1728 EChannel[i] = LowerChannel + 3;
1729 i++;
1730 }
1731 }
1732 }
1733 //
1734 for (j = 0;j < i;j++)
1735 {
1736 for (k = 0;k < pAd->ChannelListNum;k++)
1737 {
1738 if (pAd->ChannelList[k].Channel == EChannel[j])
1739 {
1740 pAd->ChannelList[k].bEffectedChannel = TRUE;
1741 DBGPRINT(RT_DEBUG_TRACE,(" EffectedChannel( =%d)\n", EChannel[j]));
1742 break;
1743 }
1744 }
1745 }
1746}
1747#endif // DOT11N_DRAFT3 //
1748#endif // DOT11_N_SUPPORT //
1749
1750BOOLEAN ScanRunning(
1751 IN PRTMP_ADAPTER pAd)
1752{
1753 return (pAd->Mlme.SyncMachine.CurrState == SCAN_LISTEN) ? TRUE : FALSE;
1754}
1755
diff --git a/drivers/staging/rt3070/sta/wpa.c b/drivers/staging/rt3070/sta/wpa.c
new file mode 100644
index 000000000000..63d08306bf6f
--- /dev/null
+++ b/drivers/staging/rt3070/sta/wpa.c
@@ -0,0 +1,2099 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 wpa.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Jan Lee 03-07-22 Initial
36 Paul Lin 03-11-28 Modify for supplicant
37*/
38#include "../rt_config.h"
39
40#define WPARSNIE 0xdd
41#define WPA2RSNIE 0x30
42
43//extern UCHAR BIT8[];
44UCHAR CipherWpaPskTkip[] = {
45 0xDD, 0x16, // RSN IE
46 0x00, 0x50, 0xf2, 0x01, // oui
47 0x01, 0x00, // Version
48 0x00, 0x50, 0xf2, 0x02, // Multicast
49 0x01, 0x00, // Number of unicast
50 0x00, 0x50, 0xf2, 0x02, // unicast
51 0x01, 0x00, // number of authentication method
52 0x00, 0x50, 0xf2, 0x02 // authentication
53 };
54UCHAR CipherWpaPskTkipLen = (sizeof(CipherWpaPskTkip) / sizeof(UCHAR));
55
56UCHAR CipherWpaPskAes[] = {
57 0xDD, 0x16, // RSN IE
58 0x00, 0x50, 0xf2, 0x01, // oui
59 0x01, 0x00, // Version
60 0x00, 0x50, 0xf2, 0x04, // Multicast
61 0x01, 0x00, // Number of unicast
62 0x00, 0x50, 0xf2, 0x04, // unicast
63 0x01, 0x00, // number of authentication method
64 0x00, 0x50, 0xf2, 0x02 // authentication
65 };
66UCHAR CipherWpaPskAesLen = (sizeof(CipherWpaPskAes) / sizeof(UCHAR));
67
68UCHAR CipherSuiteCiscoCCKM[] = {
69 0xDD, 0x16, // RSN IE
70 0x00, 0x50, 0xf2, 0x01, // oui
71 0x01, 0x00, // Version
72 0x00, 0x40, 0x96, 0x01, // Multicast
73 0x01, 0x00, // Number of uicast
74 0x00, 0x40, 0x96, 0x01, // unicast
75 0x01, 0x00, // number of authentication method
76 0x00, 0x40, 0x96, 0x00 // Authentication
77 };
78UCHAR CipherSuiteCiscoCCKMLen = (sizeof(CipherSuiteCiscoCCKM) / sizeof(UCHAR));
79
80UCHAR CipherSuiteCiscoCCKM24[] = {
81 0xDD, 0x18, // RSN IE
82 0x00, 0x50, 0xf2, 0x01, // oui
83 0x01, 0x00, // Version
84 0x00, 0x40, 0x96, 0x01, // Multicast
85 0x01, 0x00, // Number of uicast
86 0x00, 0x40, 0x96, 0x01, // unicast
87 0x01, 0x00, // number of authentication method
88 0x00, 0x40, 0x96, 0x00,
89 0x28, 0x00// Authentication
90 };
91
92UCHAR CipherSuiteCiscoCCKM24Len = (sizeof(CipherSuiteCiscoCCKM24) / sizeof(UCHAR));
93
94UCHAR CipherSuiteCCXTkip[] = {
95 0xDD, 0x16, // RSN IE
96 0x00, 0x50, 0xf2, 0x01, // oui
97 0x01, 0x00, // Version
98 0x00, 0x50, 0xf2, 0x02, // Multicast
99 0x01, 0x00, // Number of unicast
100 0x00, 0x50, 0xf2, 0x02, // unicast
101 0x01, 0x00, // number of authentication method
102 0x00, 0x50, 0xf2, 0x01 // authentication
103 };
104UCHAR CipherSuiteCCXTkipLen = (sizeof(CipherSuiteCCXTkip) / sizeof(UCHAR));
105
106UCHAR CCX_LLC_HDR[] = {0xAA, 0xAA, 0x03, 0x00, 0x40, 0x96, 0x00, 0x02};
107UCHAR LLC_NORMAL[] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
108
109UCHAR EAPOL_FRAME[] = {0x88, 0x8E};
110
111BOOLEAN CheckRSNIE(
112 IN PRTMP_ADAPTER pAd,
113 IN PUCHAR pData,
114 IN UCHAR DataLen,
115 OUT UCHAR *Offset);
116
117void inc_byte_array(UCHAR *counter, int len);
118
119/*
120 ========================================================================
121
122 Routine Description:
123 Classify WPA EAP message type
124
125 Arguments:
126 EAPType Value of EAP message type
127 MsgType Internal Message definition for MLME state machine
128
129 Return Value:
130 TRUE Found appropriate message type
131 FALSE No appropriate message type
132
133 IRQL = DISPATCH_LEVEL
134
135 Note:
136 All these constants are defined in wpa.h
137 For supplicant, there is only EAPOL Key message avaliable
138
139 ========================================================================
140*/
141BOOLEAN WpaMsgTypeSubst(
142 IN UCHAR EAPType,
143 OUT INT *MsgType)
144{
145 switch (EAPType)
146 {
147 case EAPPacket:
148 *MsgType = MT2_EAPPacket;
149 break;
150 case EAPOLStart:
151 *MsgType = MT2_EAPOLStart;
152 break;
153 case EAPOLLogoff:
154 *MsgType = MT2_EAPOLLogoff;
155 break;
156 case EAPOLKey:
157 *MsgType = MT2_EAPOLKey;
158 break;
159 case EAPOLASFAlert:
160 *MsgType = MT2_EAPOLASFAlert;
161 break;
162 default:
163 return FALSE;
164 }
165 return TRUE;
166}
167
168/*
169 ==========================================================================
170 Description:
171 association state machine init, including state transition and timer init
172 Parameters:
173 S - pointer to the association state machine
174 ==========================================================================
175 */
176VOID WpaPskStateMachineInit(
177 IN PRTMP_ADAPTER pAd,
178 IN STATE_MACHINE *S,
179 OUT STATE_MACHINE_FUNC Trans[])
180{
181 StateMachineInit(S, Trans, MAX_WPA_PSK_STATE, MAX_WPA_PSK_MSG, (STATE_MACHINE_FUNC)Drop, WPA_PSK_IDLE, WPA_MACHINE_BASE);
182 StateMachineSetAction(S, WPA_PSK_IDLE, MT2_EAPOLKey, (STATE_MACHINE_FUNC)WpaEAPOLKeyAction);
183}
184
185/*
186 ==========================================================================
187 Description:
188 This is state machine function.
189 When receiving EAPOL packets which is for 802.1x key management.
190 Use both in WPA, and WPAPSK case.
191 In this function, further dispatch to different functions according to the received packet. 3 categories are :
192 1. normal 4-way pairwisekey and 2-way groupkey handshake
193 2. MIC error (Countermeasures attack) report packet from STA.
194 3. Request for pairwise/group key update from STA
195 Return:
196 ==========================================================================
197*/
198VOID WpaEAPOLKeyAction(
199 IN PRTMP_ADAPTER pAd,
200 IN MLME_QUEUE_ELEM *Elem)
201
202{
203 INT MsgType = EAPOL_MSG_INVALID;
204 PKEY_DESCRIPTER pKeyDesc;
205 PHEADER_802_11 pHeader; //red
206 UCHAR ZeroReplay[LEN_KEY_DESC_REPLAY];
207 UCHAR EapolVr;
208 KEY_INFO peerKeyInfo;
209
210 DBGPRINT(RT_DEBUG_TRACE, ("-----> WpaEAPOLKeyAction\n"));
211
212 // Get 802.11 header first
213 pHeader = (PHEADER_802_11) Elem->Msg;
214
215 // Get EAPoL-Key Descriptor
216 pKeyDesc = (PKEY_DESCRIPTER) &Elem->Msg[(LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H)];
217
218 NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
219 NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pKeyDesc->KeyInfo, sizeof(KEY_INFO));
220
221 *((USHORT *)&peerKeyInfo) = cpu2le16(*((USHORT *)&peerKeyInfo));
222
223
224 // 1. Check EAPOL frame version and type
225 EapolVr = (UCHAR) Elem->Msg[LENGTH_802_11+LENGTH_802_1_H];
226
227 if (((EapolVr != EAPOL_VER) && (EapolVr != EAPOL_VER2)) || ((pKeyDesc->Type != WPA1_KEY_DESC) && (pKeyDesc->Type != WPA2_KEY_DESC)))
228 {
229 DBGPRINT(RT_DEBUG_ERROR, ("Key descripter does not match with WPA rule\n"));
230 return;
231 }
232
233 // First validate replay counter, only accept message with larger replay counter
234 // Let equal pass, some AP start with all zero replay counter
235 NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY);
236
237 if((RTMPCompareMemory(pKeyDesc->ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1) &&
238 (RTMPCompareMemory(pKeyDesc->ReplayCounter, ZeroReplay, LEN_KEY_DESC_REPLAY) != 0))
239 {
240 DBGPRINT(RT_DEBUG_ERROR, (" ReplayCounter not match \n"));
241 return;
242 }
243
244 // Process WPA2PSK frame
245 if(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
246 {
247 if((peerKeyInfo.KeyType == PAIRWISEKEY) &&
248 (peerKeyInfo.EKD_DL == 0) &&
249 (peerKeyInfo.KeyAck == 1) &&
250 (peerKeyInfo.KeyMic == 0) &&
251 (peerKeyInfo.Secure == 0) &&
252 (peerKeyInfo.Error == 0) &&
253 (peerKeyInfo.Request == 0))
254 {
255 MsgType = EAPOL_PAIR_MSG_1;
256 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 1\n"));
257 } else if((peerKeyInfo.KeyType == PAIRWISEKEY) &&
258 (peerKeyInfo.EKD_DL == 1) &&
259 (peerKeyInfo.KeyAck == 1) &&
260 (peerKeyInfo.KeyMic == 1) &&
261 (peerKeyInfo.Secure == 1) &&
262 (peerKeyInfo.Error == 0) &&
263 (peerKeyInfo.Request == 0))
264 {
265 MsgType = EAPOL_PAIR_MSG_3;
266 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 3\n"));
267 } else if((peerKeyInfo.KeyType == GROUPKEY) &&
268 (peerKeyInfo.EKD_DL == 1) &&
269 (peerKeyInfo.KeyAck == 1) &&
270 (peerKeyInfo.KeyMic == 1) &&
271 (peerKeyInfo.Secure == 1) &&
272 (peerKeyInfo.Error == 0) &&
273 (peerKeyInfo.Request == 0))
274 {
275 MsgType = EAPOL_GROUP_MSG_1;
276 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Group Message 1\n"));
277 }
278
279 // We will assume link is up (assoc suceess and port not secured).
280 // All state has to be able to process message from previous state
281 switch(pAd->StaCfg.WpaState)
282 {
283 case SS_START:
284 if(MsgType == EAPOL_PAIR_MSG_1)
285 {
286 Wpa2PairMsg1Action(pAd, Elem);
287 pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
288 }
289 break;
290
291 case SS_WAIT_MSG_3:
292 if(MsgType == EAPOL_PAIR_MSG_1)
293 {
294 Wpa2PairMsg1Action(pAd, Elem);
295 pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
296 }
297 else if(MsgType == EAPOL_PAIR_MSG_3)
298 {
299 Wpa2PairMsg3Action(pAd, Elem);
300 pAd->StaCfg.WpaState = SS_WAIT_GROUP;
301 }
302 break;
303
304 case SS_WAIT_GROUP: // When doing group key exchange
305 case SS_FINISH: // This happened when update group key
306 if(MsgType == EAPOL_PAIR_MSG_1)
307 {
308 // Reset port secured variable
309 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
310 Wpa2PairMsg1Action(pAd, Elem);
311 pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
312 }
313 else if(MsgType == EAPOL_PAIR_MSG_3)
314 {
315 // Reset port secured variable
316 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
317 Wpa2PairMsg3Action(pAd, Elem);
318 pAd->StaCfg.WpaState = SS_WAIT_GROUP;
319 }
320 else if(MsgType == EAPOL_GROUP_MSG_1)
321 {
322 WpaGroupMsg1Action(pAd, Elem);
323 pAd->StaCfg.WpaState = SS_FINISH;
324 }
325 break;
326
327 default:
328 break;
329 }
330 }
331 // Process WPAPSK Frame
332 // Classify message Type, either pairwise message 1, 3, or group message 1 for supplicant
333 else if(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
334 {
335 if((peerKeyInfo.KeyType == PAIRWISEKEY) &&
336 (peerKeyInfo.KeyIndex == 0) &&
337 (peerKeyInfo.KeyAck == 1) &&
338 (peerKeyInfo.KeyMic == 0) &&
339 (peerKeyInfo.Secure == 0) &&
340 (peerKeyInfo.Error == 0) &&
341 (peerKeyInfo.Request == 0))
342 {
343 MsgType = EAPOL_PAIR_MSG_1;
344 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 1\n"));
345 }
346 else if((peerKeyInfo.KeyType == PAIRWISEKEY) &&
347 (peerKeyInfo.KeyIndex == 0) &&
348 (peerKeyInfo.KeyAck == 1) &&
349 (peerKeyInfo.KeyMic == 1) &&
350 (peerKeyInfo.Secure == 0) &&
351 (peerKeyInfo.Error == 0) &&
352 (peerKeyInfo.Request == 0))
353 {
354 MsgType = EAPOL_PAIR_MSG_3;
355 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 3\n"));
356 }
357 else if((peerKeyInfo.KeyType == GROUPKEY) &&
358 (peerKeyInfo.KeyIndex != 0) &&
359 (peerKeyInfo.KeyAck == 1) &&
360 (peerKeyInfo.KeyMic == 1) &&
361 (peerKeyInfo.Secure == 1) &&
362 (peerKeyInfo.Error == 0) &&
363 (peerKeyInfo.Request == 0))
364 {
365 MsgType = EAPOL_GROUP_MSG_1;
366 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Group Message 1\n"));
367 }
368
369 // We will assume link is up (assoc suceess and port not secured).
370 // All state has to be able to process message from previous state
371 switch(pAd->StaCfg.WpaState)
372 {
373 case SS_START:
374 if(MsgType == EAPOL_PAIR_MSG_1)
375 {
376 WpaPairMsg1Action(pAd, Elem);
377 pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
378 }
379 break;
380
381 case SS_WAIT_MSG_3:
382 if(MsgType == EAPOL_PAIR_MSG_1)
383 {
384 WpaPairMsg1Action(pAd, Elem);
385 pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
386 }
387 else if(MsgType == EAPOL_PAIR_MSG_3)
388 {
389 WpaPairMsg3Action(pAd, Elem);
390 pAd->StaCfg.WpaState = SS_WAIT_GROUP;
391 }
392 break;
393
394 case SS_WAIT_GROUP: // When doing group key exchange
395 case SS_FINISH: // This happened when update group key
396 if(MsgType == EAPOL_PAIR_MSG_1)
397 {
398 WpaPairMsg1Action(pAd, Elem);
399 pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
400 // Reset port secured variable
401 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
402 }
403 else if(MsgType == EAPOL_PAIR_MSG_3)
404 {
405 WpaPairMsg3Action(pAd, Elem);
406 pAd->StaCfg.WpaState = SS_WAIT_GROUP;
407 // Reset port secured variable
408 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
409 }
410 else if(MsgType == EAPOL_GROUP_MSG_1)
411 {
412 WpaGroupMsg1Action(pAd, Elem);
413 pAd->StaCfg.WpaState = SS_FINISH;
414 }
415 break;
416
417 default:
418 break;
419 }
420 }
421
422 DBGPRINT(RT_DEBUG_TRACE, ("<----- WpaEAPOLKeyAction\n"));
423}
424
425/*
426 ========================================================================
427
428 Routine Description:
429 Process Pairwise key 4-way handshaking
430
431 Arguments:
432 pAd Pointer to our adapter
433 Elem Message body
434
435 Return Value:
436 None
437
438 Note:
439
440 ========================================================================
441*/
442VOID WpaPairMsg1Action(
443 IN PRTMP_ADAPTER pAd,
444 IN MLME_QUEUE_ELEM *Elem)
445{
446 PHEADER_802_11 pHeader;
447 UCHAR *mpool, *PTK, *digest;
448 PUCHAR pOutBuffer = NULL;
449 UCHAR Header802_3[14];
450 ULONG FrameLen = 0;
451 PEAPOL_PACKET pMsg1;
452 EAPOL_PACKET Packet;
453 UCHAR Mic[16];
454
455 DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg1Action ----->\n"));
456
457 // allocate memory pool
458 os_alloc_mem(pAd, (PUCHAR *)&mpool, 256);
459
460 if (mpool == NULL)
461 return;
462
463 // PTK Len = 80.
464 PTK = (UCHAR *) ROUND_UP(mpool, 4);
465 // digest Len = 80.
466 digest = (UCHAR *) ROUND_UP(PTK + 80, 4);
467
468 pHeader = (PHEADER_802_11) Elem->Msg;
469
470 // Process message 1 from authenticator
471 pMsg1 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
472
473 // 1. Save Replay counter, it will use to verify message 3 and construct message 2
474 NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg1->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
475
476 // 2. Save ANonce
477 NdisMoveMemory(pAd->StaCfg.ANonce, pMsg1->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE);
478
479 // Generate random SNonce
480 GenRandom(pAd, pAd->CurrentAddress, pAd->StaCfg.SNonce);
481
482 // Calc PTK(ANonce, SNonce)
483 WpaCountPTK(pAd,
484 pAd->StaCfg.PMK,
485 pAd->StaCfg.ANonce,
486 pAd->CommonCfg.Bssid,
487 pAd->StaCfg.SNonce,
488 pAd->CurrentAddress,
489 PTK,
490 LEN_PTK);
491
492 // Save key to PTK entry
493 NdisMoveMemory(pAd->StaCfg.PTK, PTK, LEN_PTK);
494
495 // init 802.3 header and Fill Packet
496 MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
497
498 // Zero Message 2 body
499 NdisZeroMemory(&Packet, sizeof(Packet));
500 Packet.ProVer = EAPOL_VER;
501 Packet.ProType = EAPOLKey;
502 //
503 // Message 2 as EAPOL-Key(0,1,0,0,0,P,0,SNonce,MIC,RSN IE)
504 //
505 Packet.KeyDesc.Type = WPA1_KEY_DESC;
506 // 1. Key descriptor version and appropriate RSN IE
507 if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
508 {
509 Packet.KeyDesc.KeyInfo.KeyDescVer = 2;
510 }
511 else // TKIP
512 {
513 Packet.KeyDesc.KeyInfo.KeyDescVer = 1;
514 }
515
516 // fill in Data Material and its length
517 Packet.KeyDesc.KeyData[0] = IE_WPA;
518 Packet.KeyDesc.KeyData[1] = pAd->StaCfg.RSNIE_Len;
519 Packet.KeyDesc.KeyDataLen[1] = pAd->StaCfg.RSNIE_Len + 2;
520 NdisMoveMemory(&Packet.KeyDesc.KeyData[2], pAd->StaCfg.RSN_IE, pAd->StaCfg.RSNIE_Len);
521
522 // Update packet length after decide Key data payload
523 Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + Packet.KeyDesc.KeyDataLen[1];
524
525 // Update Key length
526 Packet.KeyDesc.KeyLength[0] = pMsg1->KeyDesc.KeyLength[0];
527 Packet.KeyDesc.KeyLength[1] = pMsg1->KeyDesc.KeyLength[1];
528 // 2. Key Type PeerKey
529 Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
530
531 // 3. KeyMic field presented
532 Packet.KeyDesc.KeyInfo.KeyMic = 1;
533
534 //Convert to little-endian format.
535 *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
536
537
538 // 4. Fill SNonce
539 NdisMoveMemory(Packet.KeyDesc.KeyNonce, pAd->StaCfg.SNonce, LEN_KEY_DESC_NONCE);
540
541 // 5. Key Replay Count
542 NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY);
543
544 // Send EAPOL(0, 1, 0, 0, 0, P, 0, SNonce, MIC, RSN_IE)
545 // Out buffer for transmitting message 2
546 MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory
547 if(pOutBuffer == NULL)
548 {
549 os_free_mem(pAd, mpool);
550 return;
551 }
552 // Prepare EAPOL frame for MIC calculation
553 // Be careful, only EAPOL frame is counted for MIC calculation
554 MakeOutgoingFrame(pOutBuffer, &FrameLen,
555 Packet.Body_Len[1] + 4, &Packet,
556 END_OF_ARGS);
557
558 // 6. Prepare and Fill MIC value
559 NdisZeroMemory(Mic, sizeof(Mic));
560 if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
561 { // AES
562
563 HMAC_SHA1(pOutBuffer, FrameLen, PTK, LEN_EAP_MICK, digest);
564 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
565 }
566 else
567 { // TKIP
568 hmac_md5(PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
569 }
570 NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
571
572 //hex_dump("MIC", Mic, LEN_KEY_DESC_MIC);
573
574 MakeOutgoingFrame(pOutBuffer, &FrameLen,
575 LENGTH_802_3, &Header802_3,
576 Packet.Body_Len[1] + 4, &Packet,
577 END_OF_ARGS);
578
579
580 // 5. Copy frame to Tx ring and send Msg 2 to authenticator
581 RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE);
582
583 MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
584 os_free_mem(pAd, (PUCHAR)mpool);
585
586 DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg1Action <-----\n"));
587}
588
589VOID Wpa2PairMsg1Action(
590 IN PRTMP_ADAPTER pAd,
591 IN MLME_QUEUE_ELEM *Elem)
592{
593 PHEADER_802_11 pHeader;
594 UCHAR *mpool, *PTK, *digest;
595 PUCHAR pOutBuffer = NULL;
596 UCHAR Header802_3[14];
597 ULONG FrameLen = 0;
598 PEAPOL_PACKET pMsg1;
599 EAPOL_PACKET Packet;
600 UCHAR Mic[16];
601
602 DBGPRINT(RT_DEBUG_TRACE, ("Wpa2PairMsg1Action ----->\n"));
603
604 // allocate memory pool
605 os_alloc_mem(pAd, (PUCHAR *)&mpool, 256);
606
607 if (mpool == NULL)
608 return;
609
610 // PTK Len = 80.
611 PTK = (UCHAR *) ROUND_UP(mpool, 4);
612 // digest Len = 80.
613 digest = (UCHAR *) ROUND_UP(PTK + 80, 4);
614
615 pHeader = (PHEADER_802_11) Elem->Msg;
616
617 // Process message 1 from authenticator
618 pMsg1 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
619
620 // 1. Save Replay counter, it will use to verify message 3 and construct message 2
621 NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg1->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
622
623 // 2. Save ANonce
624 NdisMoveMemory(pAd->StaCfg.ANonce, pMsg1->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE);
625
626 // Generate random SNonce
627 GenRandom(pAd, pAd->CurrentAddress, pAd->StaCfg.SNonce);
628
629 if(pMsg1->KeyDesc.KeyDataLen[1] > 0 )
630 {
631 // cached PMKID
632 }
633
634 // Calc PTK(ANonce, SNonce)
635 WpaCountPTK(pAd,
636 pAd->StaCfg.PMK,
637 pAd->StaCfg.ANonce,
638 pAd->CommonCfg.Bssid,
639 pAd->StaCfg.SNonce,
640 pAd->CurrentAddress,
641 PTK,
642 LEN_PTK);
643
644 // Save key to PTK entry
645 NdisMoveMemory(pAd->StaCfg.PTK, PTK, LEN_PTK);
646
647 // init 802.3 header and Fill Packet
648 MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
649
650 // Zero message 2 body
651 NdisZeroMemory(&Packet, sizeof(Packet));
652 Packet.ProVer = EAPOL_VER;
653 Packet.ProType = EAPOLKey;
654 //
655 // Message 2 as EAPOL-Key(0,1,0,0,0,P,0,SNonce,MIC,RSN IE)
656 //
657 Packet.KeyDesc.Type = WPA2_KEY_DESC;
658
659 // 1. Key descriptor version and appropriate RSN IE
660 if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
661 {
662 Packet.KeyDesc.KeyInfo.KeyDescVer = 2;
663 }
664 else // TKIP
665 {
666 Packet.KeyDesc.KeyInfo.KeyDescVer = 1;
667 }
668
669 // fill in Data Material and its length
670 Packet.KeyDesc.KeyData[0] = IE_WPA2;
671 Packet.KeyDesc.KeyData[1] = pAd->StaCfg.RSNIE_Len;
672 Packet.KeyDesc.KeyDataLen[1] = pAd->StaCfg.RSNIE_Len + 2;
673 NdisMoveMemory(&Packet.KeyDesc.KeyData[2], pAd->StaCfg.RSN_IE, pAd->StaCfg.RSNIE_Len);
674
675 // Update packet length after decide Key data payload
676 Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + Packet.KeyDesc.KeyDataLen[1];
677
678 // 2. Key Type PeerKey
679 Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
680
681 // 3. KeyMic field presented
682 Packet.KeyDesc.KeyInfo.KeyMic = 1;
683
684 // Update Key Length
685 Packet.KeyDesc.KeyLength[0] = 0;
686 Packet.KeyDesc.KeyLength[1] = pMsg1->KeyDesc.KeyLength[1];
687
688 // 4. Fill SNonce
689 NdisMoveMemory(Packet.KeyDesc.KeyNonce, pAd->StaCfg.SNonce, LEN_KEY_DESC_NONCE);
690
691 // 5. Key Replay Count
692 NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY);
693
694 // Convert to little-endian format.
695 *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
696
697 // Send EAPOL-Key(0,1,0,0,0,P,0,SNonce,MIC,RSN IE)
698 // Out buffer for transmitting message 2
699 MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory
700 if(pOutBuffer == NULL)
701 {
702 os_free_mem(pAd, mpool);
703 return;
704 }
705
706 // Prepare EAPOL frame for MIC calculation
707 // Be careful, only EAPOL frame is counted for MIC calculation
708 MakeOutgoingFrame(pOutBuffer, &FrameLen,
709 Packet.Body_Len[1] + 4, &Packet,
710 END_OF_ARGS);
711
712 // 6. Prepare and Fill MIC value
713 NdisZeroMemory(Mic, sizeof(Mic));
714 if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
715 {
716 // AES
717 HMAC_SHA1(pOutBuffer, FrameLen, PTK, LEN_EAP_MICK, digest);
718 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
719 }
720 else
721 {
722 hmac_md5(PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
723 }
724 NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
725
726
727 // Make Transmitting frame
728 MakeOutgoingFrame(pOutBuffer, &FrameLen,
729 LENGTH_802_3, &Header802_3,
730 Packet.Body_Len[1] + 4, &Packet,
731 END_OF_ARGS);
732
733
734 // 5. Copy frame to Tx ring
735 RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE);
736
737 MlmeFreeMemory(pAd, pOutBuffer);
738 os_free_mem(pAd, mpool);
739
740 DBGPRINT(RT_DEBUG_TRACE, ("Wpa2PairMsg1Action <-----\n"));
741
742}
743
744/*
745 ========================================================================
746
747 Routine Description:
748 Process Pairwise key 4-way handshaking
749
750 Arguments:
751 pAd Pointer to our adapter
752 Elem Message body
753
754 Return Value:
755 None
756
757 Note:
758
759 ========================================================================
760*/
761VOID WpaPairMsg3Action(
762 IN PRTMP_ADAPTER pAd,
763 IN MLME_QUEUE_ELEM *Elem)
764
765{
766 PHEADER_802_11 pHeader;
767 PUCHAR pOutBuffer = NULL;
768 UCHAR Header802_3[14];
769 ULONG FrameLen = 0;
770 EAPOL_PACKET Packet;
771 PEAPOL_PACKET pMsg3;
772 UCHAR Mic[16], OldMic[16];
773 MAC_TABLE_ENTRY *pEntry = NULL;
774 UCHAR skip_offset;
775 KEY_INFO peerKeyInfo;
776
777 DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg3Action ----->\n"));
778
779 // Record 802.11 header & the received EAPOL packet Msg3
780 pHeader = (PHEADER_802_11) Elem->Msg;
781 pMsg3 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
782
783 NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
784 NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pMsg3->KeyDesc.KeyInfo, sizeof(KEY_INFO));
785
786 *((USHORT*)&peerKeyInfo) = cpu2le16(*((USHORT*)&peerKeyInfo));
787
788
789 // 1. Verify cipher type match
790 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled && (peerKeyInfo.KeyDescVer != 2))
791 {
792 return;
793 }
794 else if(pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled && (peerKeyInfo.KeyDescVer != 1))
795 {
796 return;
797 }
798
799 // Verify RSN IE
800 //if (!RTMPEqualMemory(pMsg3->KeyDesc.KeyData, pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len))
801 if (!CheckRSNIE(pAd, pMsg3->KeyDesc.KeyData, pMsg3->KeyDesc.KeyDataLen[1], &skip_offset))
802 {
803 DBGPRINT(RT_DEBUG_ERROR, ("RSN_IE Different in Msg 3 of WPA1 4-way handshake!! \n"));
804 hex_dump("The original RSN_IE", pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len);
805 hex_dump("The received RSN_IE", pMsg3->KeyDesc.KeyData, pMsg3->KeyDesc.KeyDataLen[1]);
806 return;
807 }
808 else
809 DBGPRINT(RT_DEBUG_TRACE, ("RSN_IE VALID in Msg 3 of WPA1 4-way handshake!! \n"));
810
811
812 // 2. Check MIC value
813 // Save the MIC and replace with zero
814 NdisMoveMemory(OldMic, pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
815 NdisZeroMemory(pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
816 if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
817 {
818 // AES
819 UCHAR digest[80];
820
821 HMAC_SHA1((PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
822 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
823 }
824 else // TKIP
825 {
826 hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, (PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, Mic);
827 }
828
829 if(!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
830 {
831 DBGPRINT(RT_DEBUG_ERROR, (" MIC Different in msg 3 of 4-way handshake!!!!!!!!!! \n"));
832 return;
833 }
834 else
835 DBGPRINT(RT_DEBUG_TRACE, (" MIC VALID in msg 3 of 4-way handshake!!!!!!!!!! \n"));
836
837 // 3. Check Replay Counter, it has to be larger than last one. No need to be exact one larger
838 if(RTMPCompareMemory(pMsg3->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1)
839 return;
840
841 // Update new replay counter
842 NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
843
844 // 4. Double check ANonce
845 if(!NdisEqualMemory(pAd->StaCfg.ANonce, pMsg3->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE))
846 return;
847
848 // init 802.3 header and Fill Packet
849 MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
850
851 // Zero Message 4 body
852 NdisZeroMemory(&Packet, sizeof(Packet));
853 Packet.ProVer = EAPOL_VER;
854 Packet.ProType = EAPOLKey;
855 Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE; // No data field
856
857 //
858 // Message 4 as EAPOL-Key(0,1,0,0,0,P,0,0,MIC,0)
859 //
860 Packet.KeyDesc.Type = WPA1_KEY_DESC;
861
862 // Key descriptor version and appropriate RSN IE
863 Packet.KeyDesc.KeyInfo.KeyDescVer = peerKeyInfo.KeyDescVer;
864
865 // Update Key Length
866 Packet.KeyDesc.KeyLength[0] = pMsg3->KeyDesc.KeyLength[0];
867 Packet.KeyDesc.KeyLength[1] = pMsg3->KeyDesc.KeyLength[1];
868
869 // Key Type PeerKey
870 Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
871
872 // KeyMic field presented
873 Packet.KeyDesc.KeyInfo.KeyMic = 1;
874
875 // In Msg3, KeyInfo.secure =0 if Group Key HS to come. 1 if no group key HS
876 // Station sends Msg4 KeyInfo.secure should be the same as that in Msg.3
877 Packet.KeyDesc.KeyInfo.Secure= peerKeyInfo.Secure;
878
879 // Convert to little-endian format.
880 *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
881
882 // Key Replay count
883 NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
884
885 // Out buffer for transmitting message 4
886 MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory
887 if(pOutBuffer == NULL)
888 return;
889
890 // Prepare EAPOL frame for MIC calculation
891 // Be careful, only EAPOL frame is counted for MIC calculation
892 MakeOutgoingFrame(pOutBuffer, &FrameLen,
893 Packet.Body_Len[1] + 4, &Packet,
894 END_OF_ARGS);
895
896 // Prepare and Fill MIC value
897 NdisZeroMemory(Mic, sizeof(Mic));
898 if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
899 {
900 // AES
901 UCHAR digest[80];
902
903 HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
904 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
905 }
906 else
907 {
908 hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
909 }
910 NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
911
912 // Update PTK
913 // Prepare pair-wise key information into shared key table
914 NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
915 pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
916 NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
917 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
918 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
919
920 // Decide its ChiperAlg
921 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
922 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
923 else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
924 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
925 else
926 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
927
928 // Update these related information to MAC_TABLE_ENTRY
929 pEntry = &pAd->MacTab.Content[BSSID_WCID];
930 NdisMoveMemory(pEntry->PairwiseKey.Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
931 NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
932 NdisMoveMemory(pEntry->PairwiseKey.TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
933 pEntry->PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
934
935 // Update pairwise key information to ASIC Shared Key Table
936 AsicAddSharedKeyEntry(pAd,
937 BSS0,
938 0,
939 pAd->SharedKey[BSS0][0].CipherAlg,
940 pAd->SharedKey[BSS0][0].Key,
941 pAd->SharedKey[BSS0][0].TxMic,
942 pAd->SharedKey[BSS0][0].RxMic);
943
944 // Update ASIC WCID attribute table and IVEIV table
945 RTMPAddWcidAttributeEntry(pAd,
946 BSS0,
947 0,
948 pAd->SharedKey[BSS0][0].CipherAlg,
949 pEntry);
950
951 // Make transmitting frame
952 MakeOutgoingFrame(pOutBuffer, &FrameLen,
953 LENGTH_802_3, &Header802_3,
954 Packet.Body_Len[1] + 4, &Packet,
955 END_OF_ARGS);
956
957
958 // Copy frame to Tx ring and Send Message 4 to authenticator
959 RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE);
960
961 MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
962
963 DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg3Action <-----\n"));
964}
965
966VOID Wpa2PairMsg3Action(
967 IN PRTMP_ADAPTER pAd,
968 IN MLME_QUEUE_ELEM *Elem)
969
970{
971 PHEADER_802_11 pHeader;
972 PUCHAR pOutBuffer = NULL;
973 UCHAR Header802_3[14];
974 ULONG FrameLen = 0;
975 EAPOL_PACKET Packet;
976 PEAPOL_PACKET pMsg3;
977 UCHAR Mic[16], OldMic[16];
978 UCHAR *mpool, *KEYDATA, *digest;
979 UCHAR Key[32];
980 MAC_TABLE_ENTRY *pEntry = NULL;
981 KEY_INFO peerKeyInfo;
982
983 // allocate memory
984 os_alloc_mem(pAd, (PUCHAR *)&mpool, 1024);
985
986 if(mpool == NULL)
987 return;
988
989 // KEYDATA Len = 512.
990 KEYDATA = (UCHAR *) ROUND_UP(mpool, 4);
991 // digest Len = 80.
992 digest = (UCHAR *) ROUND_UP(KEYDATA + 512, 4);
993
994 DBGPRINT(RT_DEBUG_TRACE, ("Wpa2PairMsg3Action ----->\n"));
995
996 pHeader = (PHEADER_802_11) Elem->Msg;
997
998 // Process message 3 frame.
999 pMsg3 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
1000
1001 NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
1002 NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pMsg3->KeyDesc.KeyInfo, sizeof(KEY_INFO));
1003
1004 *((USHORT*)&peerKeyInfo) = cpu2le16(*((USHORT*)&peerKeyInfo));
1005
1006 // 1. Verify cipher type match
1007 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled && (peerKeyInfo.KeyDescVer!= 2))
1008 {
1009 os_free_mem(pAd, (PUCHAR)mpool);
1010 return;
1011 }
1012 else if(pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled && (peerKeyInfo.KeyDescVer != 1))
1013 {
1014 os_free_mem(pAd, (PUCHAR)mpool);
1015 return;
1016 }
1017
1018 // 2. Check MIC value
1019 // Save the MIC and replace with zero
1020 NdisMoveMemory(OldMic, pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
1021 NdisZeroMemory(pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
1022 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1023 {
1024 // AES
1025 HMAC_SHA1((PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
1026 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
1027 }
1028 else
1029 {
1030 hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, (PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, Mic);
1031 }
1032
1033 if(!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
1034 {
1035 DBGPRINT(RT_DEBUG_ERROR, (" MIC Different in msg 3 of 4-way handshake!!!!!!!!!! \n"));
1036 os_free_mem(pAd, (PUCHAR)mpool);
1037 return;
1038 }
1039 else
1040 DBGPRINT(RT_DEBUG_TRACE, (" MIC VALID in msg 3 of 4-way handshake!!!!!!!!!! \n"));
1041
1042 // 3. Check Replay Counter, it has to be larger than last one. No need to be exact one larger
1043 if(RTMPCompareMemory(pMsg3->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1)
1044 {
1045 os_free_mem(pAd, (PUCHAR)mpool);
1046 return;
1047 }
1048
1049 // Update new replay counter
1050 NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1051
1052 // 4. Double check ANonce
1053 if(!NdisEqualMemory(pAd->StaCfg.ANonce, pMsg3->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE))
1054 {
1055 os_free_mem(pAd, (PUCHAR)mpool);
1056 return;
1057 }
1058
1059 // Obtain GTK
1060 // 5. Decrypt GTK from Key Data
1061 DBGPRINT_RAW(RT_DEBUG_TRACE, ("EKD = %d\n", peerKeyInfo.EKD_DL));
1062 if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1063 {
1064 // Decrypt AES GTK
1065 AES_GTK_KEY_UNWRAP(&pAd->StaCfg.PTK[16], KEYDATA, pMsg3->KeyDesc.KeyDataLen[1],pMsg3->KeyDesc.KeyData);
1066 }
1067 else // TKIP
1068 {
1069 INT i;
1070 // Decrypt TKIP GTK
1071 // Construct 32 bytes RC4 Key
1072 NdisMoveMemory(Key, pMsg3->KeyDesc.KeyIv, 16);
1073 NdisMoveMemory(&Key[16], &pAd->StaCfg.PTK[16], 16);
1074 ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key, 32);
1075 //discard first 256 bytes
1076 for(i = 0; i < 256; i++)
1077 ARCFOUR_BYTE(&pAd->PrivateInfo.WEPCONTEXT);
1078 // Decrypt GTK. Becareful, there is no ICV to check the result is correct or not
1079 ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, KEYDATA, pMsg3->KeyDesc.KeyData, pMsg3->KeyDesc.KeyDataLen[1]);
1080 }
1081
1082 if (!ParseKeyData(pAd, KEYDATA, pMsg3->KeyDesc.KeyDataLen[1], 1))
1083 {
1084 os_free_mem(pAd, (PUCHAR)mpool);
1085 return;
1086 }
1087
1088 // Update GTK to ASIC
1089 // Update group key information to ASIC Shared Key Table
1090 AsicAddSharedKeyEntry(pAd,
1091 BSS0,
1092 pAd->StaCfg.DefaultKeyId,
1093 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
1094 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
1095 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic,
1096 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic);
1097
1098 // Update ASIC WCID attribute table and IVEIV table
1099 RTMPAddWcidAttributeEntry(pAd,
1100 BSS0,
1101 pAd->StaCfg.DefaultKeyId,
1102 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
1103 NULL);
1104
1105 // init 802.3 header and Fill Packet
1106 MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
1107
1108 // Zero message 4 body
1109 NdisZeroMemory(&Packet, sizeof(Packet));
1110 Packet.ProVer = EAPOL_VER;
1111 Packet.ProType = EAPOLKey;
1112 Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE; // No data field
1113
1114 //
1115 // Message 4 as EAPOL-Key(0,1,0,0,0,P,0,0,MIC,0)
1116 //
1117 Packet.KeyDesc.Type = WPA2_KEY_DESC;
1118
1119 // Key descriptor version and appropriate RSN IE
1120 Packet.KeyDesc.KeyInfo.KeyDescVer = peerKeyInfo.KeyDescVer;
1121
1122 // Update Key Length
1123 Packet.KeyDesc.KeyLength[0] = pMsg3->KeyDesc.KeyLength[0];
1124 Packet.KeyDesc.KeyLength[1] = pMsg3->KeyDesc.KeyLength[1];
1125
1126 // Key Type PeerKey
1127 Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
1128
1129 // KeyMic field presented
1130 Packet.KeyDesc.KeyInfo.KeyMic = 1;
1131 Packet.KeyDesc.KeyInfo.Secure = 1;
1132
1133 // Convert to little-endian format.
1134 *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
1135
1136 // Key Replay count
1137 NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1138
1139 // Out buffer for transmitting message 4
1140 MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory
1141 if(pOutBuffer == NULL)
1142 {
1143 os_free_mem(pAd, (PUCHAR)mpool);
1144 return;
1145 }
1146
1147 // Prepare EAPOL frame for MIC calculation
1148 // Be careful, only EAPOL frame is counted for MIC calculation
1149 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1150 Packet.Body_Len[1] + 4, &Packet,
1151 END_OF_ARGS);
1152
1153 // Prepare and Fill MIC value
1154 NdisZeroMemory(Mic, sizeof(Mic));
1155 if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1156 {
1157 // AES
1158 HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
1159 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
1160 }
1161 else
1162 {
1163 hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
1164 }
1165 NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
1166
1167 // Update PTK
1168 // Prepare pair-wise key information into shared key table
1169 NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
1170 pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
1171 NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
1172 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
1173 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
1174
1175 // Decide its ChiperAlg
1176 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1177 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
1178 else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
1179 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1180 else
1181 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
1182
1183 // Update these related information to MAC_TABLE_ENTRY
1184 pEntry = &pAd->MacTab.Content[BSSID_WCID];
1185 NdisMoveMemory(&pEntry->PairwiseKey.Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
1186 NdisMoveMemory(&pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
1187 NdisMoveMemory(&pEntry->PairwiseKey.TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
1188 pEntry->PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
1189
1190 // Update pairwise key information to ASIC Shared Key Table
1191 AsicAddSharedKeyEntry(pAd,
1192 BSS0,
1193 0,
1194 pAd->SharedKey[BSS0][0].CipherAlg,
1195 pAd->SharedKey[BSS0][0].Key,
1196 pAd->SharedKey[BSS0][0].TxMic,
1197 pAd->SharedKey[BSS0][0].RxMic);
1198
1199 // Update ASIC WCID attribute table and IVEIV table
1200 RTMPAddWcidAttributeEntry(pAd,
1201 BSS0,
1202 0,
1203 pAd->SharedKey[BSS0][0].CipherAlg,
1204 pEntry);
1205
1206 // Make Transmitting frame
1207 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1208 LENGTH_802_3, &Header802_3,
1209 Packet.Body_Len[1] + 4, &Packet,
1210 END_OF_ARGS);
1211
1212
1213 // Copy frame to Tx ring and Send Message 4 to authenticator
1214 RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE);
1215
1216 // set 802.1x port control
1217 //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1218 STA_PORT_SECURED(pAd);
1219
1220 // Indicate Connected for GUI
1221 pAd->IndicateMediaState = NdisMediaStateConnected;
1222
1223 MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
1224 os_free_mem(pAd, (PUCHAR)mpool);
1225
1226
1227 // send wireless event - for set key done WPA2
1228 if (pAd->CommonCfg.bWirelessEvent)
1229 RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA2_EVENT_FLAG, pEntry->Addr, BSS0, 0);
1230
1231 DBGPRINT(RT_DEBUG_ERROR, ("Wpa2PairMsg3Action <-----\n"));
1232
1233}
1234
1235/*
1236 ========================================================================
1237
1238 Routine Description:
1239 Process Group key 2-way handshaking
1240
1241 Arguments:
1242 pAd Pointer to our adapter
1243 Elem Message body
1244
1245 Return Value:
1246 None
1247
1248 Note:
1249
1250 ========================================================================
1251*/
1252VOID WpaGroupMsg1Action(
1253 IN PRTMP_ADAPTER pAd,
1254 IN MLME_QUEUE_ELEM *Elem)
1255
1256{
1257 PUCHAR pOutBuffer = NULL;
1258 UCHAR Header802_3[14];
1259 ULONG FrameLen = 0;
1260 EAPOL_PACKET Packet;
1261 PEAPOL_PACKET pGroup;
1262 UCHAR *mpool, *digest, *KEYDATA;
1263 UCHAR Mic[16], OldMic[16];
1264 UCHAR GTK[32], Key[32];
1265 KEY_INFO peerKeyInfo;
1266
1267 // allocate memory
1268 os_alloc_mem(pAd, (PUCHAR *)&mpool, 1024);
1269
1270 if(mpool == NULL)
1271 return;
1272
1273 // digest Len = 80.
1274 digest = (UCHAR *) ROUND_UP(mpool, 4);
1275 // KEYDATA Len = 512.
1276 KEYDATA = (UCHAR *) ROUND_UP(digest + 80, 4);
1277
1278 DBGPRINT(RT_DEBUG_TRACE, ("WpaGroupMsg1Action ----->\n"));
1279
1280 // Process Group Message 1 frame. skip 802.11 header(24) & LLC_SNAP header(8)
1281 pGroup = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
1282
1283 NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
1284 NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pGroup->KeyDesc.KeyInfo, sizeof(KEY_INFO));
1285
1286 *((USHORT*)&peerKeyInfo) = cpu2le16(*((USHORT*)&peerKeyInfo));
1287
1288 // 0. Check cipher type match
1289 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled && (peerKeyInfo.KeyDescVer != 2))
1290 {
1291 os_free_mem(pAd, (PUCHAR)mpool);
1292 return;
1293 }
1294 else if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled && (peerKeyInfo.KeyDescVer != 1))
1295 {
1296 os_free_mem(pAd, (PUCHAR)mpool);
1297 return;
1298 }
1299
1300 // 1. Verify Replay counter
1301 // Check Replay Counter, it has to be larger than last one. No need to be exact one larger
1302 if(RTMPCompareMemory(pGroup->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1)
1303 {
1304 os_free_mem(pAd, (PUCHAR)mpool);
1305 return;
1306 }
1307
1308 // Update new replay counter
1309 NdisMoveMemory(pAd->StaCfg.ReplayCounter, pGroup->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1310
1311 // 2. Verify MIC is valid
1312 // Save the MIC and replace with zero
1313 NdisMoveMemory(OldMic, pGroup->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
1314 NdisZeroMemory(pGroup->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
1315
1316 if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1317 { // AES
1318 HMAC_SHA1((PUCHAR) pGroup, pGroup->Body_Len[1] + 4, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
1319 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
1320 }
1321 else
1322 { // TKIP
1323 hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, (PUCHAR) pGroup, pGroup->Body_Len[1] + 4, Mic);
1324 }
1325
1326 if(!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
1327 {
1328 DBGPRINT(RT_DEBUG_ERROR, (" MIC Different in group msg 1 of 2-way handshake!!!!!!!!!! \n"));
1329 MlmeFreeMemory(pAd, (PUCHAR)mpool);
1330 return;
1331 }
1332 else
1333 DBGPRINT(RT_DEBUG_TRACE, (" MIC VALID in group msg 1 of 2-way handshake!!!!!!!!!! \n"));
1334
1335
1336 // 3. Decrypt GTK from Key Data
1337 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1338 {
1339 // Decrypt AES GTK
1340 AES_GTK_KEY_UNWRAP(&pAd->StaCfg.PTK[16], KEYDATA, pGroup->KeyDesc.KeyDataLen[1], pGroup->KeyDesc.KeyData);
1341 }
1342 else // TKIP
1343 {
1344 INT i;
1345
1346 // Decrypt TKIP GTK
1347 // Construct 32 bytes RC4 Key
1348 NdisMoveMemory(Key, pGroup->KeyDesc.KeyIv, 16);
1349 NdisMoveMemory(&Key[16], &pAd->StaCfg.PTK[16], 16);
1350 ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key, 32);
1351 //discard first 256 bytes
1352 for(i = 0; i < 256; i++)
1353 ARCFOUR_BYTE(&pAd->PrivateInfo.WEPCONTEXT);
1354 // Decrypt GTK. Becareful, there is no ICV to check the result is correct or not
1355 ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, KEYDATA, pGroup->KeyDesc.KeyData, pGroup->KeyDesc.KeyDataLen[1]);
1356 }
1357
1358 // Process decrypted key data material
1359 // Parse keyData to handle KDE format for WPA2PSK
1360 if (peerKeyInfo.EKD_DL)
1361 {
1362 if (!ParseKeyData(pAd, KEYDATA, pGroup->KeyDesc.KeyDataLen[1], 0))
1363 {
1364 os_free_mem(pAd, (PUCHAR)mpool);
1365 return;
1366 }
1367 }
1368 else // WPAPSK
1369 {
1370 // set key material, TxMic and RxMic for WPAPSK
1371 NdisMoveMemory(GTK, KEYDATA, 32);
1372 NdisMoveMemory(pAd->StaCfg.GTK, GTK, 32);
1373 pAd->StaCfg.DefaultKeyId = peerKeyInfo.KeyIndex;
1374
1375 // Prepare pair-wise key information into shared key table
1376 NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY));
1377 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK;
1378 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, GTK, LEN_TKIP_EK);
1379 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, &GTK[16], LEN_TKIP_RXMICK);
1380 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, &GTK[24], LEN_TKIP_TXMICK);
1381
1382 // Update Shared Key CipherAlg
1383 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE;
1384 if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
1385 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
1386 else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
1387 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
1388
1389 //hex_dump("Group Key :", pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, LEN_TKIP_EK);
1390 }
1391
1392 // Update group key information to ASIC Shared Key Table
1393 AsicAddSharedKeyEntry(pAd,
1394 BSS0,
1395 pAd->StaCfg.DefaultKeyId,
1396 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
1397 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
1398 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic,
1399 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic);
1400
1401 // Update ASIC WCID attribute table and IVEIV table
1402 RTMPAddWcidAttributeEntry(pAd,
1403 BSS0,
1404 pAd->StaCfg.DefaultKeyId,
1405 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
1406 NULL);
1407
1408 // set 802.1x port control
1409 //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1410 STA_PORT_SECURED(pAd);
1411
1412 // Indicate Connected for GUI
1413 pAd->IndicateMediaState = NdisMediaStateConnected;
1414
1415 // init header and Fill Packet
1416 MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
1417
1418 // Zero Group message 1 body
1419 NdisZeroMemory(&Packet, sizeof(Packet));
1420 Packet.ProVer = EAPOL_VER;
1421 Packet.ProType = EAPOLKey;
1422 Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE; // No data field
1423
1424 //
1425 // Group Message 2 as EAPOL-Key(1,0,0,0,G,0,0,MIC,0)
1426 //
1427 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
1428 {
1429 Packet.KeyDesc.Type = WPA2_KEY_DESC;
1430 }
1431 else
1432 {
1433 Packet.KeyDesc.Type = WPA1_KEY_DESC;
1434 }
1435
1436 // Key descriptor version and appropriate RSN IE
1437 Packet.KeyDesc.KeyInfo.KeyDescVer = peerKeyInfo.KeyDescVer;
1438
1439 // Update Key Length
1440 Packet.KeyDesc.KeyLength[0] = pGroup->KeyDesc.KeyLength[0];
1441 Packet.KeyDesc.KeyLength[1] = pGroup->KeyDesc.KeyLength[1];
1442
1443 // Key Index as G-Msg 1
1444 if(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
1445 Packet.KeyDesc.KeyInfo.KeyIndex = peerKeyInfo.KeyIndex;
1446
1447 // Key Type Group key
1448 Packet.KeyDesc.KeyInfo.KeyType = GROUPKEY;
1449
1450 // KeyMic field presented
1451 Packet.KeyDesc.KeyInfo.KeyMic = 1;
1452
1453 // Secure bit
1454 Packet.KeyDesc.KeyInfo.Secure = 1;
1455
1456 // Convert to little-endian format.
1457 *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
1458
1459 // Key Replay count
1460 NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pGroup->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1461
1462 // Out buffer for transmitting group message 2
1463 MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory
1464 if(pOutBuffer == NULL)
1465 {
1466 MlmeFreeMemory(pAd, (PUCHAR)mpool);
1467 return;
1468 }
1469
1470 // Prepare EAPOL frame for MIC calculation
1471 // Be careful, only EAPOL frame is counted for MIC calculation
1472 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1473 Packet.Body_Len[1] + 4, &Packet,
1474 END_OF_ARGS);
1475
1476 // Prepare and Fill MIC value
1477 NdisZeroMemory(Mic, sizeof(Mic));
1478 if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1479 {
1480 // AES
1481 HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
1482 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
1483 }
1484 else
1485 {
1486 hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
1487 }
1488 NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
1489
1490
1491 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1492 LENGTH_802_3, &Header802_3,
1493 Packet.Body_Len[1] + 4, &Packet,
1494 END_OF_ARGS);
1495
1496
1497 // 5. Copy frame to Tx ring and prepare for encryption
1498 RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, FALSE);
1499
1500 // 6 Free allocated memory
1501 MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
1502 os_free_mem(pAd, (PUCHAR)mpool);
1503
1504 // send wireless event - for set key done WPA2
1505 if (pAd->CommonCfg.bWirelessEvent)
1506 RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA2_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1507
1508 DBGPRINT(RT_DEBUG_TRACE, ("WpaGroupMsg1Action <-----\n"));
1509}
1510
1511/*
1512 ========================================================================
1513
1514 Routine Description:
1515 Init WPA MAC header
1516
1517 Arguments:
1518 pAd Pointer to our adapter
1519
1520 Return Value:
1521 None
1522
1523 Note:
1524
1525 ========================================================================
1526*/
1527VOID WpaMacHeaderInit(
1528 IN PRTMP_ADAPTER pAd,
1529 IN OUT PHEADER_802_11 pHdr80211,
1530 IN UCHAR wep,
1531 IN PUCHAR pAddr1)
1532{
1533 NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
1534 pHdr80211->FC.Type = BTYPE_DATA;
1535 pHdr80211->FC.ToDs = 1;
1536 if (wep == 1)
1537 pHdr80211->FC.Wep = 1;
1538
1539 // Addr1: BSSID, Addr2: SA, Addr3: DA
1540 COPY_MAC_ADDR(pHdr80211->Addr1, pAddr1);
1541 COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
1542 COPY_MAC_ADDR(pHdr80211->Addr3, pAd->CommonCfg.Bssid);
1543 pHdr80211->Sequence = pAd->Sequence;
1544}
1545
1546/*
1547 ========================================================================
1548
1549 Routine Description:
1550 Copy frame from waiting queue into relative ring buffer and set
1551 appropriate ASIC register to kick hardware encryption before really
1552 sent out to air.
1553
1554 Arguments:
1555 pAd Pointer to our adapter
1556 PNDIS_PACKET Pointer to outgoing Ndis frame
1557 NumberOfFrag Number of fragment required
1558
1559 Return Value:
1560 None
1561
1562 Note:
1563
1564 ========================================================================
1565*/
1566VOID RTMPToWirelessSta(
1567 IN PRTMP_ADAPTER pAd,
1568 IN PUCHAR pHeader802_3,
1569 IN UINT HdrLen,
1570 IN PUCHAR pData,
1571 IN UINT DataLen,
1572 IN BOOLEAN is4wayFrame)
1573
1574{
1575 NDIS_STATUS Status;
1576 PNDIS_PACKET pPacket;
1577 UCHAR Index;
1578
1579 do
1580 {
1581 // 1. build a NDIS packet and call RTMPSendPacket();
1582 // be careful about how/when to release this internal allocated NDIS PACKET buffer
1583 Status = RTMPAllocateNdisPacket(pAd, &pPacket, pHeader802_3, HdrLen, pData, DataLen);
1584 if (Status != NDIS_STATUS_SUCCESS)
1585 break;
1586
1587 if (is4wayFrame)
1588 RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 1);
1589 else
1590 RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 0);
1591
1592 // 2. send out the packet
1593 Status = STASendPacket(pAd, pPacket);
1594 if(Status == NDIS_STATUS_SUCCESS)
1595 {
1596 // Dequeue one frame from TxSwQueue0..3 queue and process it
1597 // There are three place calling dequeue for TX ring.
1598 // 1. Here, right after queueing the frame.
1599 // 2. At the end of TxRingTxDone service routine.
1600 // 3. Upon NDIS call RTMPSendPackets
1601 if((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) &&
1602 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)))
1603 {
1604 for(Index = 0; Index < 5; Index ++)
1605 if(pAd->TxSwQueue[Index].Number > 0)
1606 RTMPDeQueuePacket(pAd, FALSE, Index, MAX_TX_PROCESS);
1607 }
1608 }
1609 } while(FALSE);
1610
1611}
1612
1613/*
1614 ========================================================================
1615
1616 Routine Description:
1617 Check Sanity RSN IE form AP
1618
1619 Arguments:
1620
1621 Return Value:
1622
1623
1624 ========================================================================
1625*/
1626BOOLEAN CheckRSNIE(
1627 IN PRTMP_ADAPTER pAd,
1628 IN PUCHAR pData,
1629 IN UCHAR DataLen,
1630 OUT UCHAR *Offset)
1631{
1632 PUCHAR pVIE;
1633 UCHAR len;
1634 PEID_STRUCT pEid;
1635 BOOLEAN result = FALSE;
1636
1637 pVIE = pData;
1638 len = DataLen;
1639 *Offset = 0;
1640
1641 while (len > sizeof(RSNIE2))
1642 {
1643 pEid = (PEID_STRUCT) pVIE;
1644 // WPA RSN IE
1645 if ((pEid->Eid == IE_WPA) && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)))
1646 {
1647 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) &&
1648 (NdisEqualMemory(pVIE, pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len)) &&
1649 (pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == (pEid->Len + 2)))
1650 {
1651 DBGPRINT(RT_DEBUG_TRACE, ("CheckRSNIE ==> WPA/WPAPSK RSN IE matched in Msg 3, Length(%d) \n", (pEid->Len + 2)));
1652 result = TRUE;
1653 }
1654
1655 *Offset += (pEid->Len + 2);
1656 }
1657 // WPA2 RSN IE
1658 else if ((pEid->Eid == IE_RSN) && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3)))
1659 {
1660 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2 || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) &&
1661 (NdisEqualMemory(pVIE, pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len)) &&
1662 (pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == (pEid->Len + 2)))
1663 {
1664 DBGPRINT(RT_DEBUG_TRACE, ("CheckRSNIE ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", (pEid->Len + 2)));
1665 result = TRUE;
1666 }
1667
1668 *Offset += (pEid->Len + 2);
1669 }
1670 else
1671 {
1672 break;
1673 }
1674
1675 pVIE += (pEid->Len + 2);
1676 len -= (pEid->Len + 2);
1677 }
1678
1679 DBGPRINT(RT_DEBUG_TRACE, ("CheckRSNIE ==> skip_offset(%d) \n", *Offset));
1680
1681 return result;
1682
1683}
1684
1685
1686/*
1687 ========================================================================
1688
1689 Routine Description:
1690 Parse KEYDATA field. KEYDATA[] May contain 2 RSN IE and optionally GTK.
1691 GTK is encaptulated in KDE format at p.83 802.11i D10
1692
1693 Arguments:
1694
1695 Return Value:
1696
1697 Note:
1698 802.11i D10
1699
1700 ========================================================================
1701*/
1702BOOLEAN ParseKeyData(
1703 IN PRTMP_ADAPTER pAd,
1704 IN PUCHAR pKeyData,
1705 IN UCHAR KeyDataLen,
1706 IN UCHAR bPairewise)
1707{
1708 PKDE_ENCAP pKDE = NULL;
1709 PUCHAR pMyKeyData = pKeyData;
1710 UCHAR KeyDataLength = KeyDataLen;
1711 UCHAR GTKLEN;
1712 UCHAR skip_offset;
1713
1714 // Verify The RSN IE contained in Pairewise-Msg 3 and skip it
1715 if (bPairewise)
1716 {
1717 // Check RSN IE whether it is WPA2/WPA2PSK
1718 if (!CheckRSNIE(pAd, pKeyData, KeyDataLen, &skip_offset))
1719 {
1720 DBGPRINT(RT_DEBUG_ERROR, ("ParseKeyData ==> WPA2/WPA2PSK RSN IE mismatched \n"));
1721 hex_dump("Get KEYDATA :", pKeyData, KeyDataLen);
1722 return FALSE;
1723 }
1724 else
1725 {
1726 // skip RSN IE
1727 pMyKeyData += skip_offset;
1728 KeyDataLength -= skip_offset;
1729
1730 //DBGPRINT(RT_DEBUG_TRACE, ("ParseKeyData ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", skip_offset));
1731 }
1732 }
1733
1734 DBGPRINT(RT_DEBUG_TRACE,("ParseKeyData ==> KeyDataLength %d without RSN_IE \n", KeyDataLength));
1735
1736 // Parse EKD format
1737 if (KeyDataLength >= 8)
1738 {
1739 pKDE = (PKDE_ENCAP) pMyKeyData;
1740 }
1741 else
1742 {
1743 DBGPRINT(RT_DEBUG_ERROR, ("ERROR: KeyDataLength is too short \n"));
1744 return FALSE;
1745 }
1746
1747
1748 // Sanity check - shared key index should not be 0
1749 if (pKDE->GTKEncap.Kid == 0)
1750 {
1751 DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key index zero \n"));
1752 return FALSE;
1753 }
1754
1755 // Sanity check - KED length
1756 if (KeyDataLength < (pKDE->Len + 2))
1757 {
1758 DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The len from KDE is too short \n"));
1759 return FALSE;
1760 }
1761
1762 // Get GTK length - refer to IEEE 802.11i-2004 p.82
1763 GTKLEN = pKDE->Len -6;
1764
1765 if (GTKLEN < LEN_AES_KEY)
1766 {
1767 DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key length is too short (%d) \n", GTKLEN));
1768 return FALSE;
1769 }
1770 else
1771 DBGPRINT(RT_DEBUG_TRACE, ("GTK Key with KDE formet got index=%d, len=%d \n", pKDE->GTKEncap.Kid, GTKLEN));
1772
1773 // Update GTK
1774 // set key material, TxMic and RxMic for WPAPSK
1775 NdisMoveMemory(pAd->StaCfg.GTK, pKDE->GTKEncap.GTK, 32);
1776 pAd->StaCfg.DefaultKeyId = pKDE->GTKEncap.Kid;
1777
1778 // Update shared key table
1779 NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY));
1780 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK;
1781 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, pKDE->GTKEncap.GTK, LEN_TKIP_EK);
1782 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, &pKDE->GTKEncap.GTK[16], LEN_TKIP_RXMICK);
1783 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, &pKDE->GTKEncap.GTK[24], LEN_TKIP_TXMICK);
1784
1785 // Update Shared Key CipherAlg
1786 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE;
1787 if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
1788 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
1789 else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
1790 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
1791
1792 return TRUE;
1793
1794}
1795
1796/*
1797 ========================================================================
1798
1799 Routine Description:
1800 Cisco CCKM PRF function
1801
1802 Arguments:
1803 key Cisco Base Transient Key (BTK)
1804 key_len The key length of the BTK
1805 data Ruquest Number(RN) + BSSID
1806 data_len The length of the data
1807 output Store for PTK(Pairwise transient keys)
1808 len The length of the output
1809 Return Value:
1810 None
1811
1812 Note:
1813 802.1i Annex F.9
1814
1815 ========================================================================
1816*/
1817VOID CCKMPRF(
1818 IN UCHAR *key,
1819 IN INT key_len,
1820 IN UCHAR *data,
1821 IN INT data_len,
1822 OUT UCHAR *output,
1823 IN INT len)
1824{
1825 INT i;
1826 UCHAR input[1024];
1827 INT currentindex = 0;
1828 INT total_len;
1829
1830 NdisMoveMemory(input, data, data_len);
1831 total_len = data_len;
1832 input[total_len] = 0;
1833 total_len++;
1834 for (i = 0; i < (len + 19) / 20; i++)
1835 {
1836 HMAC_SHA1(input, total_len, key, key_len, &output[currentindex]);
1837 currentindex += 20;
1838 input[total_len - 1]++;
1839 }
1840}
1841
1842/*
1843 ========================================================================
1844
1845 Routine Description:
1846 Process MIC error indication and record MIC error timer.
1847
1848 Arguments:
1849 pAd Pointer to our adapter
1850 pWpaKey Pointer to the WPA key structure
1851
1852 Return Value:
1853 None
1854
1855 IRQL = DISPATCH_LEVEL
1856
1857 Note:
1858
1859 ========================================================================
1860*/
1861VOID RTMPReportMicError(
1862 IN PRTMP_ADAPTER pAd,
1863 IN PCIPHER_KEY pWpaKey)
1864{
1865 ULONG Now;
1866 UCHAR unicastKey = (pWpaKey->Type == PAIRWISE_KEY ? 1:0);
1867
1868 // Record Last MIC error time and count
1869 Now = jiffies;
1870 if (pAd->StaCfg.MicErrCnt == 0)
1871 {
1872 pAd->StaCfg.MicErrCnt++;
1873 pAd->StaCfg.LastMicErrorTime = Now;
1874 NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
1875 }
1876 else if (pAd->StaCfg.MicErrCnt == 1)
1877 {
1878 if ((pAd->StaCfg.LastMicErrorTime + (60 * OS_HZ)) < Now)
1879 {
1880 // Update Last MIC error time, this did not violate two MIC errors within 60 seconds
1881 pAd->StaCfg.LastMicErrorTime = Now;
1882 }
1883 else
1884 {
1885
1886 if (pAd->CommonCfg.bWirelessEvent)
1887 RTMPSendWirelessEvent(pAd, IW_COUNTER_MEASURES_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1888
1889 pAd->StaCfg.LastMicErrorTime = Now;
1890 // Violate MIC error counts, MIC countermeasures kicks in
1891 pAd->StaCfg.MicErrCnt++;
1892 // We shall block all reception
1893 // We shall clean all Tx ring and disassoicate from AP after next EAPOL frame
1894 //
1895 // No necessary to clean all Tx ring, on RTMPHardTransmit will stop sending non-802.1X EAPOL packets
1896 // if pAd->StaCfg.MicErrCnt greater than 2.
1897 //
1898 // RTMPRingCleanUp(pAd, QID_AC_BK);
1899 // RTMPRingCleanUp(pAd, QID_AC_BE);
1900 // RTMPRingCleanUp(pAd, QID_AC_VI);
1901 // RTMPRingCleanUp(pAd, QID_AC_VO);
1902 // RTMPRingCleanUp(pAd, QID_HCCA);
1903 }
1904 }
1905 else
1906 {
1907 // MIC error count >= 2
1908 // This should not happen
1909 ;
1910 }
1911 MlmeEnqueue(pAd,
1912 MLME_CNTL_STATE_MACHINE,
1913 OID_802_11_MIC_FAILURE_REPORT_FRAME,
1914 1,
1915 &unicastKey);
1916
1917 if (pAd->StaCfg.MicErrCnt == 2)
1918 {
1919 RTMPSetTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, 100);
1920 }
1921}
1922
1923
1924#ifdef WPA_SUPPLICANT_SUPPORT
1925#define LENGTH_EAP_H 4
1926// If the received frame is EAP-Packet ,find out its EAP-Code (Request(0x01), Response(0x02), Success(0x03), Failure(0x04)).
1927INT WpaCheckEapCode(
1928 IN PRTMP_ADAPTER pAd,
1929 IN PUCHAR pFrame,
1930 IN USHORT FrameLen,
1931 IN USHORT OffSet)
1932{
1933
1934 PUCHAR pData;
1935 INT result = 0;
1936
1937 if( FrameLen < OffSet + LENGTH_EAPOL_H + LENGTH_EAP_H )
1938 return result;
1939
1940 pData = pFrame + OffSet; // skip offset bytes
1941
1942 if(*(pData+1) == EAPPacket) // 802.1x header - Packet Type
1943 {
1944 result = *(pData+4); // EAP header - Code
1945 }
1946
1947 return result;
1948}
1949
1950VOID WpaSendMicFailureToWpaSupplicant(
1951 IN PRTMP_ADAPTER pAd,
1952 IN BOOLEAN bUnicast)
1953{
1954 union iwreq_data wrqu;
1955 char custom[IW_CUSTOM_MAX] = {0};
1956
1957 sprintf(custom, "MLME-MICHAELMICFAILURE.indication");
1958 if (bUnicast)
1959 sprintf(custom, "%s unicast", custom);
1960 wrqu.data.length = strlen(custom);
1961 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, custom);
1962
1963 return;
1964}
1965#endif // WPA_SUPPLICANT_SUPPORT //
1966
1967VOID WpaMicFailureReportFrame(
1968 IN PRTMP_ADAPTER pAd,
1969 IN MLME_QUEUE_ELEM *Elem)
1970{
1971 PUCHAR pOutBuffer = NULL;
1972 UCHAR Header802_3[14];
1973 ULONG FrameLen = 0;
1974 EAPOL_PACKET Packet;
1975 UCHAR Mic[16];
1976 BOOLEAN bUnicast;
1977
1978 DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame ----->\n"));
1979
1980 bUnicast = (Elem->Msg[0] == 1 ? TRUE:FALSE);
1981 pAd->Sequence = ((pAd->Sequence) + 1) & (MAX_SEQ_NUMBER);
1982
1983 // init 802.3 header and Fill Packet
1984 MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
1985
1986 NdisZeroMemory(&Packet, sizeof(Packet));
1987 Packet.ProVer = EAPOL_VER;
1988 Packet.ProType = EAPOLKey;
1989
1990 Packet.KeyDesc.Type = WPA1_KEY_DESC;
1991
1992 // Request field presented
1993 Packet.KeyDesc.KeyInfo.Request = 1;
1994
1995 if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1996 {
1997 Packet.KeyDesc.KeyInfo.KeyDescVer = 2;
1998 }
1999 else // TKIP
2000 {
2001 Packet.KeyDesc.KeyInfo.KeyDescVer = 1;
2002 }
2003
2004 Packet.KeyDesc.KeyInfo.KeyType = (bUnicast ? PAIRWISEKEY : GROUPKEY);
2005
2006 // KeyMic field presented
2007 Packet.KeyDesc.KeyInfo.KeyMic = 1;
2008
2009 // Error field presented
2010 Packet.KeyDesc.KeyInfo.Error = 1;
2011
2012 // Update packet length after decide Key data payload
2013 Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE;
2014
2015 // Key Replay Count
2016 NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY);
2017 inc_byte_array(pAd->StaCfg.ReplayCounter, 8);
2018
2019 // Convert to little-endian format.
2020 *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
2021
2022
2023 MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory
2024 if(pOutBuffer == NULL)
2025 {
2026 return;
2027 }
2028
2029 // Prepare EAPOL frame for MIC calculation
2030 // Be careful, only EAPOL frame is counted for MIC calculation
2031 MakeOutgoingFrame(pOutBuffer, &FrameLen,
2032 Packet.Body_Len[1] + 4, &Packet,
2033 END_OF_ARGS);
2034
2035 // Prepare and Fill MIC value
2036 NdisZeroMemory(Mic, sizeof(Mic));
2037 if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
2038 { // AES
2039 UCHAR digest[20] = {0};
2040 HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
2041 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
2042 }
2043 else
2044 { // TKIP
2045 hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
2046 }
2047 NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
2048
2049 MakeOutgoingFrame(pOutBuffer, &FrameLen,
2050 LENGTH_802_3, &Header802_3,
2051 Packet.Body_Len[1] + 4, &Packet,
2052 END_OF_ARGS);
2053
2054 // opy frame to Tx ring and send MIC failure report frame to authenticator
2055 RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, FALSE);
2056
2057 MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
2058
2059 DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame <-----\n"));
2060}
2061
2062/** from wpa_supplicant
2063 * inc_byte_array - Increment arbitrary length byte array by one
2064 * @counter: Pointer to byte array
2065 * @len: Length of the counter in bytes
2066 *
2067 * This function increments the last byte of the counter by one and continues
2068 * rolling over to more significant bytes if the byte was incremented from
2069 * 0xff to 0x00.
2070 */
2071void inc_byte_array(UCHAR *counter, int len)
2072{
2073 int pos = len - 1;
2074 while (pos >= 0) {
2075 counter[pos]++;
2076 if (counter[pos] != 0)
2077 break;
2078 pos--;
2079 }
2080}
2081
2082VOID WpaDisassocApAndBlockAssoc(
2083 IN PVOID SystemSpecific1,
2084 IN PVOID FunctionContext,
2085 IN PVOID SystemSpecific2,
2086 IN PVOID SystemSpecific3)
2087{
2088 RTMP_ADAPTER *pAd = (PRTMP_ADAPTER)FunctionContext;
2089 MLME_DISASSOC_REQ_STRUCT DisassocReq;
2090
2091 // disassoc from current AP first
2092 DBGPRINT(RT_DEBUG_TRACE, ("RTMPReportMicError - disassociate with current AP after sending second continuous EAPOL frame\n"));
2093 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_MIC_FAILURE);
2094 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
2095
2096 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
2097 pAd->StaCfg.bBlockAssoc = TRUE;
2098}
2099
diff --git a/drivers/staging/rt3070/sta_ioctl.c b/drivers/staging/rt3070/sta_ioctl.c
new file mode 100644
index 000000000000..079454835a43
--- /dev/null
+++ b/drivers/staging/rt3070/sta_ioctl.c
@@ -0,0 +1,7203 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 sta_ioctl.c
29
30 Abstract:
31 IOCTL related subroutines
32
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36 Rory Chen 01-03-2003 created
37 Rory Chen 02-14-2005 modify to support RT61
38*/
39
40#include "rt_config.h"
41
42#ifdef DBG
43extern ULONG RTDebugLevel;
44#endif
45
46#define NR_WEP_KEYS 4
47#define WEP_SMALL_KEY_LEN (40/8)
48#define WEP_LARGE_KEY_LEN (104/8)
49
50#define GROUP_KEY_NO 4
51
52extern UCHAR CipherWpa2Template[];
53extern UCHAR CipherWpaPskTkip[];
54extern UCHAR CipherWpaPskTkipLen;
55
56typedef struct PACKED _RT_VERSION_INFO{
57 UCHAR DriverVersionW;
58 UCHAR DriverVersionX;
59 UCHAR DriverVersionY;
60 UCHAR DriverVersionZ;
61 UINT DriverBuildYear;
62 UINT DriverBuildMonth;
63 UINT DriverBuildDay;
64} RT_VERSION_INFO, *PRT_VERSION_INFO;
65
66struct iw_priv_args privtab[] = {
67{ RTPRIV_IOCTL_SET,
68 IW_PRIV_TYPE_CHAR | 1024, 0,
69 "set"},
70
71{ RTPRIV_IOCTL_SHOW, 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
72 ""},
73{ RTPRIV_IOCTL_SHOW, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
74 ""},
75/* --- sub-ioctls definitions --- */
76 { SHOW_CONN_STATUS,
77 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "connStatus" },
78 { SHOW_DRVIER_VERION,
79 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "driverVer" },
80 { SHOW_BA_INFO,
81 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "bainfo" },
82 { SHOW_DESC_INFO,
83 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "descinfo" },
84 { RAIO_OFF,
85 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_off" },
86 { RAIO_ON,
87 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_on" },
88#ifdef QOS_DLS_SUPPORT
89 { SHOW_DLS_ENTRY_INFO,
90 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "dlsentryinfo" },
91#endif // QOS_DLS_SUPPORT //
92 { SHOW_CFG_VALUE,
93 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "show" },
94/* --- sub-ioctls relations --- */
95
96#ifdef DBG
97{ RTPRIV_IOCTL_BBP,
98 IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
99 "bbp"},
100{ RTPRIV_IOCTL_MAC,
101 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024,
102 "mac"},
103#ifdef RT30xx
104{ RTPRIV_IOCTL_RF,
105 IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
106 "rf"},
107#endif // RT30xx //
108{ RTPRIV_IOCTL_E2P,
109 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024,
110 "e2p"},
111#endif /* DBG */
112
113{ RTPRIV_IOCTL_STATISTICS,
114 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
115 "stat"},
116{ RTPRIV_IOCTL_GSITESURVEY,
117 0, IW_PRIV_TYPE_CHAR | 1024,
118 "get_site_survey"},
119
120
121};
122
123INT Set_SSID_Proc(
124 IN PRTMP_ADAPTER pAdapter,
125 IN PUCHAR arg);
126
127#ifdef WMM_SUPPORT
128INT Set_WmmCapable_Proc(
129 IN PRTMP_ADAPTER pAd,
130 IN PUCHAR arg);
131#endif
132
133INT Set_NetworkType_Proc(
134 IN PRTMP_ADAPTER pAdapter,
135 IN PUCHAR arg);
136
137INT Set_AuthMode_Proc(
138 IN PRTMP_ADAPTER pAdapter,
139 IN PUCHAR arg);
140
141INT Set_EncrypType_Proc(
142 IN PRTMP_ADAPTER pAdapter,
143 IN PUCHAR arg);
144
145INT Set_DefaultKeyID_Proc(
146 IN PRTMP_ADAPTER pAdapter,
147 IN PUCHAR arg);
148
149INT Set_Key1_Proc(
150 IN PRTMP_ADAPTER pAdapter,
151 IN PUCHAR arg);
152
153INT Set_Key2_Proc(
154 IN PRTMP_ADAPTER pAdapter,
155 IN PUCHAR arg);
156
157INT Set_Key3_Proc(
158 IN PRTMP_ADAPTER pAdapter,
159 IN PUCHAR arg);
160
161INT Set_Key4_Proc(
162 IN PRTMP_ADAPTER pAdapter,
163 IN PUCHAR arg);
164
165INT Set_WPAPSK_Proc(
166 IN PRTMP_ADAPTER pAdapter,
167 IN PUCHAR arg);
168
169
170INT Set_PSMode_Proc(
171 IN PRTMP_ADAPTER pAdapter,
172 IN PUCHAR arg);
173
174#ifdef WPA_SUPPLICANT_SUPPORT
175INT Set_Wpa_Support(
176 IN PRTMP_ADAPTER pAd,
177 IN PUCHAR arg);
178#endif // WPA_SUPPLICANT_SUPPORT //
179
180#ifdef DBG
181
182VOID RTMPIoctlMAC(
183 IN PRTMP_ADAPTER pAdapter,
184 IN struct iwreq *wrq);
185
186VOID RTMPIoctlE2PROM(
187 IN PRTMP_ADAPTER pAdapter,
188 IN struct iwreq *wrq);
189
190#ifdef RT30xx
191VOID RTMPIoctlRF(
192 IN PRTMP_ADAPTER pAdapter,
193 IN struct iwreq *wrq);
194#endif // RT30xx //
195#endif // DBG //
196
197
198NDIS_STATUS RTMPWPANoneAddKeyProc(
199 IN PRTMP_ADAPTER pAd,
200 IN PVOID pBuf);
201
202INT Set_FragTest_Proc(
203 IN PRTMP_ADAPTER pAdapter,
204 IN PUCHAR arg);
205
206#ifdef DOT11_N_SUPPORT
207INT Set_TGnWifiTest_Proc(
208 IN PRTMP_ADAPTER pAd,
209 IN PUCHAR arg);
210#endif // DOT11_N_SUPPORT //
211
212INT Set_LongRetryLimit_Proc(
213 IN PRTMP_ADAPTER pAdapter,
214 IN PUCHAR arg);
215
216INT Set_ShortRetryLimit_Proc(
217 IN PRTMP_ADAPTER pAdapter,
218 IN PUCHAR arg);
219
220#ifdef EXT_BUILD_CHANNEL_LIST
221INT Set_Ieee80211dClientMode_Proc(
222 IN PRTMP_ADAPTER pAdapter,
223 IN PUCHAR arg);
224#endif // EXT_BUILD_CHANNEL_LIST //
225
226#ifdef CARRIER_DETECTION_SUPPORT
227INT Set_CarrierDetect_Proc(
228 IN PRTMP_ADAPTER pAd,
229 IN PUCHAR arg);
230#endif // CARRIER_DETECTION_SUPPORT //
231
232static struct {
233 CHAR *name;
234 INT (*set_proc)(PRTMP_ADAPTER pAdapter, PUCHAR arg);
235} *PRTMP_PRIVATE_SET_PROC, RTMP_PRIVATE_SUPPORT_PROC[] = {
236 {"DriverVersion", Set_DriverVersion_Proc},
237 {"CountryRegion", Set_CountryRegion_Proc},
238 {"CountryRegionABand", Set_CountryRegionABand_Proc},
239 {"SSID", Set_SSID_Proc},
240 {"WirelessMode", Set_WirelessMode_Proc},
241 {"TxBurst", Set_TxBurst_Proc},
242 {"TxPreamble", Set_TxPreamble_Proc},
243 {"TxPower", Set_TxPower_Proc},
244 {"Channel", Set_Channel_Proc},
245 {"BGProtection", Set_BGProtection_Proc},
246 {"RTSThreshold", Set_RTSThreshold_Proc},
247 {"FragThreshold", Set_FragThreshold_Proc},
248#ifdef DOT11_N_SUPPORT
249 {"HtBw", Set_HtBw_Proc},
250 {"HtMcs", Set_HtMcs_Proc},
251 {"HtGi", Set_HtGi_Proc},
252 {"HtOpMode", Set_HtOpMode_Proc},
253 {"HtExtcha", Set_HtExtcha_Proc},
254 {"HtMpduDensity", Set_HtMpduDensity_Proc},
255 {"HtBaWinSize", Set_HtBaWinSize_Proc},
256 {"HtRdg", Set_HtRdg_Proc},
257 {"HtAmsdu", Set_HtAmsdu_Proc},
258 {"HtAutoBa", Set_HtAutoBa_Proc},
259 {"HtBaDecline", Set_BADecline_Proc},
260 {"HtProtect", Set_HtProtect_Proc},
261 {"HtMimoPs", Set_HtMimoPs_Proc},
262#endif // DOT11_N_SUPPORT //
263
264#ifdef AGGREGATION_SUPPORT
265 {"PktAggregate", Set_PktAggregate_Proc},
266#endif
267
268#ifdef WMM_SUPPORT
269 {"WmmCapable", Set_WmmCapable_Proc},
270#endif
271 {"IEEE80211H", Set_IEEE80211H_Proc},
272 {"NetworkType", Set_NetworkType_Proc},
273 {"AuthMode", Set_AuthMode_Proc},
274 {"EncrypType", Set_EncrypType_Proc},
275 {"DefaultKeyID", Set_DefaultKeyID_Proc},
276 {"Key1", Set_Key1_Proc},
277 {"Key2", Set_Key2_Proc},
278 {"Key3", Set_Key3_Proc},
279 {"Key4", Set_Key4_Proc},
280 {"WPAPSK", Set_WPAPSK_Proc},
281 {"ResetCounter", Set_ResetStatCounter_Proc},
282 {"PSMode", Set_PSMode_Proc},
283#ifdef DBG
284 {"Debug", Set_Debug_Proc},
285#endif
286
287#ifdef RALINK_ATE
288 {"ATE", Set_ATE_Proc},
289 {"ATEDA", Set_ATE_DA_Proc},
290 {"ATESA", Set_ATE_SA_Proc},
291 {"ATEBSSID", Set_ATE_BSSID_Proc},
292 {"ATECHANNEL", Set_ATE_CHANNEL_Proc},
293 {"ATETXPOW0", Set_ATE_TX_POWER0_Proc},
294 {"ATETXPOW1", Set_ATE_TX_POWER1_Proc},
295 {"ATETXANT", Set_ATE_TX_Antenna_Proc},
296 {"ATERXANT", Set_ATE_RX_Antenna_Proc},
297 {"ATETXFREQOFFSET", Set_ATE_TX_FREQOFFSET_Proc},
298 {"ATETXBW", Set_ATE_TX_BW_Proc},
299 {"ATETXLEN", Set_ATE_TX_LENGTH_Proc},
300 {"ATETXCNT", Set_ATE_TX_COUNT_Proc},
301 {"ATETXMCS", Set_ATE_TX_MCS_Proc},
302 {"ATETXMODE", Set_ATE_TX_MODE_Proc},
303 {"ATETXGI", Set_ATE_TX_GI_Proc},
304 {"ATERXFER", Set_ATE_RX_FER_Proc},
305 {"ATERRF", Set_ATE_Read_RF_Proc},
306 {"ATEWRF1", Set_ATE_Write_RF1_Proc},
307 {"ATEWRF2", Set_ATE_Write_RF2_Proc},
308 {"ATEWRF3", Set_ATE_Write_RF3_Proc},
309 {"ATEWRF4", Set_ATE_Write_RF4_Proc},
310 {"ATELDE2P", Set_ATE_Load_E2P_Proc},
311 {"ATERE2P", Set_ATE_Read_E2P_Proc},
312 {"ATESHOW", Set_ATE_Show_Proc},
313 {"ATEHELP", Set_ATE_Help_Proc},
314
315#ifdef RALINK_28xx_QA
316 {"TxStop", Set_TxStop_Proc},
317 {"RxStop", Set_RxStop_Proc},
318#endif // RALINK_28xx_QA //
319#endif // RALINK_ATE //
320
321#ifdef WPA_SUPPLICANT_SUPPORT
322 {"WpaSupport", Set_Wpa_Support},
323#endif // WPA_SUPPLICANT_SUPPORT //
324
325
326
327 {"FixedTxMode", Set_FixedTxMode_Proc},
328#ifdef CONFIG_APSTA_MIXED_SUPPORT
329 {"OpMode", Set_OpMode_Proc},
330#endif // CONFIG_APSTA_MIXED_SUPPORT //
331#ifdef DOT11_N_SUPPORT
332 {"TGnWifiTest", Set_TGnWifiTest_Proc},
333 {"ForceGF", Set_ForceGF_Proc},
334#endif // DOT11_N_SUPPORT //
335#ifdef QOS_DLS_SUPPORT
336 {"DlsAddEntry", Set_DlsAddEntry_Proc},
337 {"DlsTearDownEntry", Set_DlsTearDownEntry_Proc},
338#endif // QOS_DLS_SUPPORT //
339 {"LongRetry", Set_LongRetryLimit_Proc},
340 {"ShortRetry", Set_ShortRetryLimit_Proc},
341#ifdef EXT_BUILD_CHANNEL_LIST
342 {"11dClientMode", Set_Ieee80211dClientMode_Proc},
343#endif // EXT_BUILD_CHANNEL_LIST //
344#ifdef CARRIER_DETECTION_SUPPORT
345 {"CarrierDetect", Set_CarrierDetect_Proc},
346#endif // CARRIER_DETECTION_SUPPORT //
347//2008/09/11:KH add to support efuse<--
348#ifdef RT30xx
349 {"efuseFreeNumber", set_eFuseGetFreeBlockCount_Proc},
350 {"efuseDump", set_eFusedump_Proc},
351 {"efuseLoadFromBin", set_eFuseLoadFromBin_Proc},
352#endif // RT30xx //
353//2008/09/11:KH add to support efuse-->
354 {NULL,}
355};
356
357
358VOID RTMPAddKey(
359 IN PRTMP_ADAPTER pAd,
360 IN PNDIS_802_11_KEY pKey)
361{
362 ULONG KeyIdx;
363 MAC_TABLE_ENTRY *pEntry;
364
365 DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey ------>\n"));
366
367 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
368 {
369 if (pKey->KeyIndex & 0x80000000)
370 {
371 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
372 {
373 NdisZeroMemory(pAd->StaCfg.PMK, 32);
374 NdisMoveMemory(pAd->StaCfg.PMK, pKey->KeyMaterial, pKey->KeyLength);
375 goto end;
376 }
377 // Update PTK
378 NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
379 pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
380 NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pKey->KeyMaterial, LEN_TKIP_EK);
381#ifdef WPA_SUPPLICANT_SUPPORT
382 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
383 {
384 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
385 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
386 }
387 else
388#endif // WPA_SUPPLICANT_SUPPORT //
389 {
390 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
391 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
392 }
393
394 // Decide its ChiperAlg
395 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
396 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
397 else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
398 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
399 else
400 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
401
402 // Update these related information to MAC_TABLE_ENTRY
403 pEntry = &pAd->MacTab.Content[BSSID_WCID];
404 NdisMoveMemory(pEntry->PairwiseKey.Key, pAd->SharedKey[BSS0][0].Key, LEN_TKIP_EK);
405 NdisMoveMemory(pEntry->PairwiseKey.RxMic, pAd->SharedKey[BSS0][0].RxMic, LEN_TKIP_RXMICK);
406 NdisMoveMemory(pEntry->PairwiseKey.TxMic, pAd->SharedKey[BSS0][0].TxMic, LEN_TKIP_TXMICK);
407 pEntry->PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
408
409 // Update pairwise key information to ASIC Shared Key Table
410 AsicAddSharedKeyEntry(pAd,
411 BSS0,
412 0,
413 pAd->SharedKey[BSS0][0].CipherAlg,
414 pAd->SharedKey[BSS0][0].Key,
415 pAd->SharedKey[BSS0][0].TxMic,
416 pAd->SharedKey[BSS0][0].RxMic);
417
418 // Update ASIC WCID attribute table and IVEIV table
419 RTMPAddWcidAttributeEntry(pAd,
420 BSS0,
421 0,
422 pAd->SharedKey[BSS0][0].CipherAlg,
423 pEntry);
424
425 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
426 {
427 // set 802.1x port control
428 //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
429 STA_PORT_SECURED(pAd);
430
431 // Indicate Connected for GUI
432 pAd->IndicateMediaState = NdisMediaStateConnected;
433 }
434 }
435 else
436 {
437 // Update GTK
438 pAd->StaCfg.DefaultKeyId = (pKey->KeyIndex & 0xFF);
439 NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY));
440 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK;
441 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, pKey->KeyMaterial, LEN_TKIP_EK);
442#ifdef WPA_SUPPLICANT_SUPPORT
443 if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
444 {
445 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
446 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
447 }
448 else
449#endif // WPA_SUPPLICANT_SUPPORT //
450 {
451 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
452 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
453 }
454
455 // Update Shared Key CipherAlg
456 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE;
457 if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
458 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
459 else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
460 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
461
462 // Update group key information to ASIC Shared Key Table
463 AsicAddSharedKeyEntry(pAd,
464 BSS0,
465 pAd->StaCfg.DefaultKeyId,
466 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
467 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
468 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic,
469 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic);
470
471 // Update ASIC WCID attribute table and IVEIV table
472 RTMPAddWcidAttributeEntry(pAd,
473 BSS0,
474 pAd->StaCfg.DefaultKeyId,
475 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
476 NULL);
477
478 // set 802.1x port control
479 //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
480 STA_PORT_SECURED(pAd);
481
482 // Indicate Connected for GUI
483 pAd->IndicateMediaState = NdisMediaStateConnected;
484 }
485 }
486 else // dynamic WEP from wpa_supplicant
487 {
488 UCHAR CipherAlg;
489 PUCHAR Key;
490
491 if(pKey->KeyLength == 32)
492 goto end;
493
494 KeyIdx = pKey->KeyIndex & 0x0fffffff;
495
496 if (KeyIdx < 4)
497 {
498 // it is a default shared key, for Pairwise key setting
499 if (pKey->KeyIndex & 0x80000000)
500 {
501 pEntry = MacTableLookup(pAd, pKey->BSSID);
502
503 if (pEntry)
504 {
505 DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey: Set Pair-wise Key\n"));
506
507 // set key material and key length
508 pEntry->PairwiseKey.KeyLen = (UCHAR)pKey->KeyLength;
509 NdisMoveMemory(pEntry->PairwiseKey.Key, &pKey->KeyMaterial, pKey->KeyLength);
510
511 // set Cipher type
512 if (pKey->KeyLength == 5)
513 pEntry->PairwiseKey.CipherAlg = CIPHER_WEP64;
514 else
515 pEntry->PairwiseKey.CipherAlg = CIPHER_WEP128;
516
517 // Add Pair-wise key to Asic
518 AsicAddPairwiseKeyEntry(
519 pAd,
520 pEntry->Addr,
521 (UCHAR)pEntry->Aid,
522 &pEntry->PairwiseKey);
523
524 // update WCID attribute table and IVEIV table for this entry
525 RTMPAddWcidAttributeEntry(
526 pAd,
527 BSS0,
528 KeyIdx, // The value may be not zero
529 pEntry->PairwiseKey.CipherAlg,
530 pEntry);
531
532 }
533 }
534 else
535 {
536 // Default key for tx (shared key)
537 pAd->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
538
539 // set key material and key length
540 pAd->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pKey->KeyLength;
541 NdisMoveMemory(pAd->SharedKey[BSS0][KeyIdx].Key, &pKey->KeyMaterial, pKey->KeyLength);
542
543 // Set Ciper type
544 if (pKey->KeyLength == 5)
545 pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_WEP64;
546 else
547 pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_WEP128;
548
549 CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
550 Key = pAd->SharedKey[BSS0][KeyIdx].Key;
551
552 // Set Group key material to Asic
553 AsicAddSharedKeyEntry(pAd, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
554
555 // Update WCID attribute table and IVEIV table for this group key table
556 RTMPAddWcidAttributeEntry(pAd, BSS0, KeyIdx, CipherAlg, NULL);
557
558 }
559 }
560 }
561end:
562 return;
563}
564
565char * rtstrchr(const char * s, int c)
566{
567 for(; *s != (char) c; ++s)
568 if (*s == '\0')
569 return NULL;
570 return (char *) s;
571}
572
573/*
574This is required for LinEX2004/kernel2.6.7 to provide iwlist scanning function
575*/
576
577int
578rt_ioctl_giwname(struct net_device *dev,
579 struct iw_request_info *info,
580 char *name, char *extra)
581{
582// PRTMP_ADAPTER pAdapter = dev->ml_priv;
583
584#ifdef RT2870
585 strncpy(name, "RT2870 Wireless", IFNAMSIZ);
586#endif // RT2870 //
587 return 0;
588}
589
590int rt_ioctl_siwfreq(struct net_device *dev,
591 struct iw_request_info *info,
592 struct iw_freq *freq, char *extra)
593{
594 PRTMP_ADAPTER pAdapter = dev->ml_priv;
595 int chan = -1;
596
597 //check if the interface is down
598 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
599 {
600 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
601 return -ENETDOWN;
602 }
603
604
605 if (freq->e > 1)
606 return -EINVAL;
607
608 if((freq->e == 0) && (freq->m <= 1000))
609 chan = freq->m; // Setting by channel number
610 else
611 MAP_KHZ_TO_CHANNEL_ID( (freq->m /100) , chan); // Setting by frequency - search the table , like 2.412G, 2.422G,
612
613 if (ChannelSanity(pAdapter, chan) == TRUE)
614 {
615 pAdapter->CommonCfg.Channel = chan;
616 DBGPRINT(RT_DEBUG_ERROR, ("==>rt_ioctl_siwfreq::SIOCSIWFREQ[cmd=0x%x] (Channel=%d)\n", SIOCSIWFREQ, pAdapter->CommonCfg.Channel));
617 }
618 else
619 return -EINVAL;
620
621 return 0;
622}
623int rt_ioctl_giwfreq(struct net_device *dev,
624 struct iw_request_info *info,
625 struct iw_freq *freq, char *extra)
626{
627 VIRTUAL_ADAPTER *pVirtualAd = NULL;
628 PRTMP_ADAPTER pAdapter;
629 UCHAR ch;
630 ULONG m;
631
632 if (dev->priv_flags == INT_MAIN)
633 {
634 pAdapter = dev->ml_priv;
635 }
636 else
637 {
638 pVirtualAd = dev->ml_priv;
639 pAdapter = pVirtualAd->RtmpDev->ml_priv;
640 }
641
642 if (pAdapter == NULL)
643 {
644 /* if 1st open fail, pAd will be free;
645 So the net_dev->ml_priv will be NULL in 2rd open */
646 return -ENETDOWN;
647 }
648
649 ch = pAdapter->CommonCfg.Channel;
650
651 DBGPRINT(RT_DEBUG_TRACE,("==>rt_ioctl_giwfreq %d\n", ch));
652
653 MAP_CHANNEL_ID_TO_KHZ(ch, m);
654 freq->m = m * 100;
655 freq->e = 1;
656 return 0;
657}
658
659int rt_ioctl_siwmode(struct net_device *dev,
660 struct iw_request_info *info,
661 __u32 *mode, char *extra)
662{
663 PRTMP_ADAPTER pAdapter = dev->ml_priv;
664
665 //check if the interface is down
666 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
667 {
668 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
669 return -ENETDOWN;
670 }
671
672 switch (*mode)
673 {
674 case IW_MODE_ADHOC:
675 Set_NetworkType_Proc(pAdapter, "Adhoc");
676 break;
677 case IW_MODE_INFRA:
678 Set_NetworkType_Proc(pAdapter, "Infra");
679 break;
680#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20))
681 case IW_MODE_MONITOR:
682 Set_NetworkType_Proc(pAdapter, "Monitor");
683 break;
684#endif
685 default:
686 DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_siwmode::SIOCSIWMODE (unknown %d)\n", *mode));
687 return -EINVAL;
688 }
689
690 // Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
691 pAdapter->StaCfg.WpaState = SS_NOTUSE;
692
693 return 0;
694}
695
696int rt_ioctl_giwmode(struct net_device *dev,
697 struct iw_request_info *info,
698 __u32 *mode, char *extra)
699{
700 PRTMP_ADAPTER pAdapter = dev->ml_priv;
701
702 if (ADHOC_ON(pAdapter))
703 *mode = IW_MODE_ADHOC;
704 else if (INFRA_ON(pAdapter))
705 *mode = IW_MODE_INFRA;
706#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20))
707 else if (MONITOR_ON(pAdapter))
708 {
709 *mode = IW_MODE_MONITOR;
710 }
711#endif
712 else
713 *mode = IW_MODE_AUTO;
714
715 DBGPRINT(RT_DEBUG_TRACE, ("==>rt_ioctl_giwmode(mode=%d)\n", *mode));
716 return 0;
717}
718
719int rt_ioctl_siwsens(struct net_device *dev,
720 struct iw_request_info *info,
721 char *name, char *extra)
722{
723 PRTMP_ADAPTER pAdapter = dev->ml_priv;
724
725 //check if the interface is down
726 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
727 {
728 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
729 return -ENETDOWN;
730 }
731
732 return 0;
733}
734
735int rt_ioctl_giwsens(struct net_device *dev,
736 struct iw_request_info *info,
737 char *name, char *extra)
738{
739 return 0;
740}
741
742int rt_ioctl_giwrange(struct net_device *dev,
743 struct iw_request_info *info,
744 struct iw_point *data, char *extra)
745{
746 PRTMP_ADAPTER pAdapter = dev->ml_priv;
747
748 struct iw_range *range = (struct iw_range *) extra;
749 u16 val;
750 int i;
751
752 DBGPRINT(RT_DEBUG_TRACE ,("===>rt_ioctl_giwrange\n"));
753 data->length = sizeof(struct iw_range);
754 memset(range, 0, sizeof(struct iw_range));
755
756 range->txpower_capa = IW_TXPOW_DBM;
757
758 if (INFRA_ON(pAdapter)||ADHOC_ON(pAdapter))
759 {
760 range->min_pmp = 1 * 1024;
761 range->max_pmp = 65535 * 1024;
762 range->min_pmt = 1 * 1024;
763 range->max_pmt = 1000 * 1024;
764 range->pmp_flags = IW_POWER_PERIOD;
765 range->pmt_flags = IW_POWER_TIMEOUT;
766 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT |
767 IW_POWER_UNICAST_R | IW_POWER_ALL_R;
768 }
769
770 range->we_version_compiled = WIRELESS_EXT;
771 range->we_version_source = 14;
772
773 range->retry_capa = IW_RETRY_LIMIT;
774 range->retry_flags = IW_RETRY_LIMIT;
775 range->min_retry = 0;
776 range->max_retry = 255;
777
778 range->num_channels = pAdapter->ChannelListNum;
779
780 val = 0;
781 for (i = 1; i <= range->num_channels; i++)
782 {
783 u32 m;
784 range->freq[val].i = pAdapter->ChannelList[i-1].Channel;
785 MAP_CHANNEL_ID_TO_KHZ(pAdapter->ChannelList[i-1].Channel, m);
786 range->freq[val].m = m * 100; /* HZ */
787
788 range->freq[val].e = 1;
789 val++;
790 if (val == IW_MAX_FREQUENCIES)
791 break;
792 }
793 range->num_frequency = val;
794
795 range->max_qual.qual = 100; /* what is correct max? This was not
796 * documented exactly. At least
797 * 69 has been observed. */
798 range->max_qual.level = 0; /* dB */
799 range->max_qual.noise = 0; /* dB */
800
801 /* What would be suitable values for "average/typical" qual? */
802 range->avg_qual.qual = 20;
803 range->avg_qual.level = -60;
804 range->avg_qual.noise = -95;
805 range->sensitivity = 3;
806
807 range->max_encoding_tokens = NR_WEP_KEYS;
808 range->num_encoding_sizes = 2;
809 range->encoding_size[0] = 5;
810 range->encoding_size[1] = 13;
811
812 range->min_rts = 0;
813 range->max_rts = 2347;
814 range->min_frag = 256;
815 range->max_frag = 2346;
816
817#if WIRELESS_EXT > 17
818 /* IW_ENC_CAPA_* bit field */
819 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
820 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
821#endif
822
823 return 0;
824}
825
826int rt_ioctl_siwap(struct net_device *dev,
827 struct iw_request_info *info,
828 struct sockaddr *ap_addr, char *extra)
829{
830 PRTMP_ADAPTER pAdapter = dev->ml_priv;
831 NDIS_802_11_MAC_ADDRESS Bssid;
832
833 //check if the interface is down
834 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
835 {
836 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
837 return -ENETDOWN;
838 }
839
840 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
841 {
842 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
843 DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
844 }
845
846 // tell CNTL state machine to call NdisMSetInformationComplete() after completing
847 // this request, because this request is initiated by NDIS.
848 pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
849 // Prevent to connect AP again in STAMlmePeriodicExec
850 pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
851
852 memset(Bssid, 0, MAC_ADDR_LEN);
853 memcpy(Bssid, ap_addr->sa_data, MAC_ADDR_LEN);
854 MlmeEnqueue(pAdapter,
855 MLME_CNTL_STATE_MACHINE,
856 OID_802_11_BSSID,
857 sizeof(NDIS_802_11_MAC_ADDRESS),
858 (VOID *)&Bssid);
859
860 DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCSIWAP %02x:%02x:%02x:%02x:%02x:%02x\n",
861 Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
862
863 return 0;
864}
865
866int rt_ioctl_giwap(struct net_device *dev,
867 struct iw_request_info *info,
868 struct sockaddr *ap_addr, char *extra)
869{
870 PRTMP_ADAPTER pAdapter = dev->ml_priv;
871
872 if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
873 {
874 ap_addr->sa_family = ARPHRD_ETHER;
875 memcpy(ap_addr->sa_data, &pAdapter->CommonCfg.Bssid, ETH_ALEN);
876 }
877#ifdef WPA_SUPPLICANT_SUPPORT
878 // Add for RT2870
879 else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
880 {
881 ap_addr->sa_family = ARPHRD_ETHER;
882 memcpy(ap_addr->sa_data, &pAdapter->MlmeAux.Bssid, ETH_ALEN);
883 }
884#endif // WPA_SUPPLICANT_SUPPORT //
885 else
886 {
887 DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIWAP(=EMPTY)\n"));
888 return -ENOTCONN;
889 }
890
891 return 0;
892}
893
894/*
895 * Units are in db above the noise floor. That means the
896 * rssi values reported in the tx/rx descriptors in the
897 * driver are the SNR expressed in db.
898 *
899 * If you assume that the noise floor is -95, which is an
900 * excellent assumption 99.5 % of the time, then you can
901 * derive the absolute signal level (i.e. -95 + rssi).
902 * There are some other slight factors to take into account
903 * depending on whether the rssi measurement is from 11b,
904 * 11g, or 11a. These differences are at most 2db and
905 * can be documented.
906 *
907 * NB: various calculations are based on the orinoco/wavelan
908 * drivers for compatibility
909 */
910static void set_quality(PRTMP_ADAPTER pAdapter,
911 struct iw_quality *iq,
912 signed char rssi)
913{
914 __u8 ChannelQuality;
915
916 // Normalize Rssi
917 if (rssi >= -50)
918 ChannelQuality = 100;
919 else if (rssi >= -80) // between -50 ~ -80dbm
920 ChannelQuality = (__u8)(24 + ((rssi + 80) * 26)/10);
921 else if (rssi >= -90) // between -80 ~ -90dbm
922 ChannelQuality = (__u8)((rssi + 90) * 26)/10;
923 else
924 ChannelQuality = 0;
925
926 iq->qual = (__u8)ChannelQuality;
927
928 iq->level = (__u8)(rssi);
929 iq->noise = (pAdapter->BbpWriteLatch[66] > pAdapter->BbpTuning.FalseCcaUpperThreshold) ? ((__u8)pAdapter->BbpTuning.FalseCcaUpperThreshold) : ((__u8) pAdapter->BbpWriteLatch[66]); // noise level (dBm)
930 iq->noise += 256 - 143;
931 iq->updated = pAdapter->iw_stats.qual.updated;
932}
933
934int rt_ioctl_iwaplist(struct net_device *dev,
935 struct iw_request_info *info,
936 struct iw_point *data, char *extra)
937{
938 PRTMP_ADAPTER pAdapter = dev->ml_priv;
939
940 struct sockaddr addr[IW_MAX_AP];
941 struct iw_quality qual[IW_MAX_AP];
942 int i;
943
944 //check if the interface is down
945 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
946 {
947 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
948 data->length = 0;
949 return 0;
950 //return -ENETDOWN;
951 }
952
953 for (i = 0; i <IW_MAX_AP ; i++)
954 {
955 if (i >= pAdapter->ScanTab.BssNr)
956 break;
957 addr[i].sa_family = ARPHRD_ETHER;
958 memcpy(addr[i].sa_data, &pAdapter->ScanTab.BssEntry[i].Bssid, MAC_ADDR_LEN);
959 set_quality(pAdapter, &qual[i], pAdapter->ScanTab.BssEntry[i].Rssi);
960 }
961 data->length = i;
962 memcpy(extra, &addr, i*sizeof(addr[0]));
963 data->flags = 1; /* signal quality present (sort of) */
964 memcpy(extra + i*sizeof(addr[0]), &qual, i*sizeof(qual[i]));
965
966 return 0;
967}
968
969#ifdef SIOCGIWSCAN
970int rt_ioctl_siwscan(struct net_device *dev,
971 struct iw_request_info *info,
972 struct iw_point *data, char *extra)
973{
974 PRTMP_ADAPTER pAdapter = dev->ml_priv;
975
976 ULONG Now;
977 int Status = NDIS_STATUS_SUCCESS;
978
979 //check if the interface is down
980 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
981 {
982 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
983 return -ENETDOWN;
984 }
985
986 if (MONITOR_ON(pAdapter))
987 {
988 DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is in Monitor Mode now !!!\n"));
989 return -EINVAL;
990 }
991
992
993#ifdef WPA_SUPPLICANT_SUPPORT
994 if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
995 {
996 pAdapter->StaCfg.WpaSupplicantScanCount++;
997 }
998#endif // WPA_SUPPLICANT_SUPPORT //
999
1000 pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
1001 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1002 return 0;
1003 do{
1004 Now = jiffies;
1005
1006#ifdef WPA_SUPPLICANT_SUPPORT
1007 if ((pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE) &&
1008 (pAdapter->StaCfg.WpaSupplicantScanCount > 3))
1009 {
1010 DBGPRINT(RT_DEBUG_TRACE, ("!!! WpaSupplicantScanCount > 3\n"));
1011 Status = NDIS_STATUS_SUCCESS;
1012 break;
1013 }
1014#endif // WPA_SUPPLICANT_SUPPORT //
1015
1016 if ((OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED)) &&
1017 ((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
1018 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) &&
1019 (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
1020 {
1021 DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, Port Not Secured! ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
1022 Status = NDIS_STATUS_SUCCESS;
1023 break;
1024 }
1025
1026 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
1027 {
1028 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
1029 DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
1030 }
1031
1032 // tell CNTL state machine to call NdisMSetInformationComplete() after completing
1033 // this request, because this request is initiated by NDIS.
1034 pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
1035 // Reset allowed scan retries
1036 pAdapter->StaCfg.ScanCnt = 0;
1037 pAdapter->StaCfg.LastScanTime = Now;
1038
1039 MlmeEnqueue(pAdapter,
1040 MLME_CNTL_STATE_MACHINE,
1041 OID_802_11_BSSID_LIST_SCAN,
1042 0,
1043 NULL);
1044
1045 Status = NDIS_STATUS_SUCCESS;
1046 RT28XX_MLME_HANDLER(pAdapter);
1047 }while(0);
1048 return 0;
1049}
1050
1051int rt_ioctl_giwscan(struct net_device *dev,
1052 struct iw_request_info *info,
1053 struct iw_point *data, char *extra)
1054{
1055
1056 PRTMP_ADAPTER pAdapter = dev->ml_priv;
1057 int i=0;
1058 char *current_ev = extra, *previous_ev = extra;
1059 char *end_buf;
1060 char *current_val, custom[MAX_CUSTOM_LEN] = {0};
1061#ifndef IWEVGENIE
1062 char idx;
1063#endif // IWEVGENIE //
1064 struct iw_event iwe;
1065
1066 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1067 {
1068 /*
1069 * Still scanning, indicate the caller should try again.
1070 */
1071 return -EAGAIN;
1072 }
1073
1074
1075#ifdef WPA_SUPPLICANT_SUPPORT
1076 if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
1077 {
1078 pAdapter->StaCfg.WpaSupplicantScanCount = 0;
1079 }
1080#endif // WPA_SUPPLICANT_SUPPORT //
1081
1082 if (pAdapter->ScanTab.BssNr == 0)
1083 {
1084 data->length = 0;
1085 return 0;
1086 }
1087
1088#if WIRELESS_EXT >= 17
1089 if (data->length > 0)
1090 end_buf = extra + data->length;
1091 else
1092 end_buf = extra + IW_SCAN_MAX_DATA;
1093#else
1094 end_buf = extra + IW_SCAN_MAX_DATA;
1095#endif
1096
1097 for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
1098 {
1099 if (current_ev >= end_buf)
1100 {
1101#if WIRELESS_EXT >= 17
1102 return -E2BIG;
1103#else
1104 break;
1105#endif
1106 }
1107
1108 //MAC address
1109 //================================
1110 memset(&iwe, 0, sizeof(iwe));
1111 iwe.cmd = SIOCGIWAP;
1112 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
1113 memcpy(iwe.u.ap_addr.sa_data, &pAdapter->ScanTab.BssEntry[i].Bssid, ETH_ALEN);
1114
1115 previous_ev = current_ev;
1116 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
1117 if (current_ev == previous_ev)
1118#if WIRELESS_EXT >= 17
1119 return -E2BIG;
1120#else
1121 break;
1122#endif
1123
1124 /*
1125 Protocol:
1126 it will show scanned AP's WirelessMode .
1127 it might be
1128 802.11a
1129 802.11a/n
1130 802.11g/n
1131 802.11b/g/n
1132 802.11g
1133 802.11b/g
1134 */
1135 memset(&iwe, 0, sizeof(iwe));
1136 iwe.cmd = SIOCGIWNAME;
1137
1138
1139 {
1140 PBSS_ENTRY pBssEntry=&pAdapter->ScanTab.BssEntry[i];
1141 BOOLEAN isGonly=FALSE;
1142 int rateCnt=0;
1143
1144 if (pBssEntry->Channel>14)
1145 {
1146 if (pBssEntry->HtCapabilityLen!=0)
1147 strcpy(iwe.u.name,"802.11a/n");
1148 else
1149 strcpy(iwe.u.name,"802.11a");
1150 }
1151 else
1152 {
1153 /*
1154 if one of non B mode rate is set supported rate . it mean G only.
1155 */
1156 for (rateCnt=0;rateCnt<pBssEntry->SupRateLen;rateCnt++)
1157 {
1158 /*
1159 6Mbps(140) 9Mbps(146) and >=12Mbps(152) are supported rate , it mean G only.
1160 */
1161 if (pBssEntry->SupRate[rateCnt]==140 || pBssEntry->SupRate[rateCnt]==146 || pBssEntry->SupRate[rateCnt]>=152)
1162 isGonly=TRUE;
1163 }
1164
1165 for (rateCnt=0;rateCnt<pBssEntry->ExtRateLen;rateCnt++)
1166 {
1167 if (pBssEntry->ExtRate[rateCnt]==140 || pBssEntry->ExtRate[rateCnt]==146 || pBssEntry->ExtRate[rateCnt]>=152)
1168 isGonly=TRUE;
1169 }
1170
1171
1172 if (pBssEntry->HtCapabilityLen!=0)
1173 {
1174 if (isGonly==TRUE)
1175 strcpy(iwe.u.name,"802.11g/n");
1176 else
1177 strcpy(iwe.u.name,"802.11b/g/n");
1178 }
1179 else
1180 {
1181 if (isGonly==TRUE)
1182 strcpy(iwe.u.name,"802.11g");
1183 else
1184 {
1185 if (pBssEntry->SupRateLen==4 && pBssEntry->ExtRateLen==0)
1186 strcpy(iwe.u.name,"802.11b");
1187 else
1188 strcpy(iwe.u.name,"802.11b/g");
1189 }
1190 }
1191 }
1192 }
1193
1194 previous_ev = current_ev;
1195 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
1196 if (current_ev == previous_ev)
1197#if WIRELESS_EXT >= 17
1198 return -E2BIG;
1199#else
1200 break;
1201#endif
1202
1203 //ESSID
1204 //================================
1205 memset(&iwe, 0, sizeof(iwe));
1206 iwe.cmd = SIOCGIWESSID;
1207 iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].SsidLen;
1208 iwe.u.data.flags = 1;
1209
1210 previous_ev = current_ev;
1211 current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pAdapter->ScanTab.BssEntry[i].Ssid);
1212 if (current_ev == previous_ev)
1213#if WIRELESS_EXT >= 17
1214 return -E2BIG;
1215#else
1216 break;
1217#endif
1218
1219 //Network Type
1220 //================================
1221 memset(&iwe, 0, sizeof(iwe));
1222 iwe.cmd = SIOCGIWMODE;
1223 if (pAdapter->ScanTab.BssEntry[i].BssType == Ndis802_11IBSS)
1224 {
1225 iwe.u.mode = IW_MODE_ADHOC;
1226 }
1227 else if (pAdapter->ScanTab.BssEntry[i].BssType == Ndis802_11Infrastructure)
1228 {
1229 iwe.u.mode = IW_MODE_INFRA;
1230 }
1231 else
1232 {
1233 iwe.u.mode = IW_MODE_AUTO;
1234 }
1235 iwe.len = IW_EV_UINT_LEN;
1236
1237 previous_ev = current_ev;
1238 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
1239 if (current_ev == previous_ev)
1240#if WIRELESS_EXT >= 17
1241 return -E2BIG;
1242#else
1243 break;
1244#endif
1245
1246 //Channel and Frequency
1247 //================================
1248 memset(&iwe, 0, sizeof(iwe));
1249 iwe.cmd = SIOCGIWFREQ;
1250 if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
1251 iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
1252 else
1253 iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
1254 iwe.u.freq.e = 0;
1255 iwe.u.freq.i = 0;
1256
1257 previous_ev = current_ev;
1258 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
1259 if (current_ev == previous_ev)
1260#if WIRELESS_EXT >= 17
1261 return -E2BIG;
1262#else
1263 break;
1264#endif
1265
1266 //Add quality statistics
1267 //================================
1268 memset(&iwe, 0, sizeof(iwe));
1269 iwe.cmd = IWEVQUAL;
1270 iwe.u.qual.level = 0;
1271 iwe.u.qual.noise = 0;
1272 set_quality(pAdapter, &iwe.u.qual, pAdapter->ScanTab.BssEntry[i].Rssi);
1273 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
1274 if (current_ev == previous_ev)
1275#if WIRELESS_EXT >= 17
1276 return -E2BIG;
1277#else
1278 break;
1279#endif
1280
1281 //Encyption key
1282 //================================
1283 memset(&iwe, 0, sizeof(iwe));
1284 iwe.cmd = SIOCGIWENCODE;
1285 if (CAP_IS_PRIVACY_ON (pAdapter->ScanTab.BssEntry[i].CapabilityInfo ))
1286 iwe.u.data.flags =IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
1287 else
1288 iwe.u.data.flags = IW_ENCODE_DISABLED;
1289
1290 previous_ev = current_ev;
1291 current_ev = iwe_stream_add_point(info, current_ev, end_buf,&iwe, (char *)pAdapter->SharedKey[BSS0][(iwe.u.data.flags & IW_ENCODE_INDEX)-1].Key);
1292 if (current_ev == previous_ev)
1293#if WIRELESS_EXT >= 17
1294 return -E2BIG;
1295#else
1296 break;
1297#endif
1298
1299 //Bit Rate
1300 //================================
1301 if (pAdapter->ScanTab.BssEntry[i].SupRateLen)
1302 {
1303 UCHAR tmpRate = pAdapter->ScanTab.BssEntry[i].SupRate[pAdapter->ScanTab.BssEntry[i].SupRateLen-1];
1304 memset(&iwe, 0, sizeof(iwe));
1305 iwe.cmd = SIOCGIWRATE;
1306 current_val = current_ev + IW_EV_LCP_LEN;
1307 if (tmpRate == 0x82)
1308 iwe.u.bitrate.value = 1 * 1000000;
1309 else if (tmpRate == 0x84)
1310 iwe.u.bitrate.value = 2 * 1000000;
1311 else if (tmpRate == 0x8B)
1312 iwe.u.bitrate.value = 5.5 * 1000000;
1313 else if (tmpRate == 0x96)
1314 iwe.u.bitrate.value = 11 * 1000000;
1315 else
1316 iwe.u.bitrate.value = (tmpRate/2) * 1000000;
1317
1318 iwe.u.bitrate.disabled = 0;
1319 current_val = iwe_stream_add_value(info, current_ev,
1320 current_val, end_buf, &iwe,
1321 IW_EV_PARAM_LEN);
1322
1323 if((current_val-current_ev)>IW_EV_LCP_LEN)
1324 current_ev = current_val;
1325 else
1326#if WIRELESS_EXT >= 17
1327 return -E2BIG;
1328#else
1329 break;
1330#endif
1331 }
1332
1333#ifdef IWEVGENIE
1334 //WPA IE
1335 if (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen > 0)
1336 {
1337 memset(&iwe, 0, sizeof(iwe));
1338 memset(&custom[0], 0, MAX_CUSTOM_LEN);
1339 memcpy(custom, &(pAdapter->ScanTab.BssEntry[i].WpaIE.IE[0]),
1340 pAdapter->ScanTab.BssEntry[i].WpaIE.IELen);
1341 iwe.cmd = IWEVGENIE;
1342 iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].WpaIE.IELen;
1343 current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, custom);
1344 if (current_ev == previous_ev)
1345#if WIRELESS_EXT >= 17
1346 return -E2BIG;
1347#else
1348 break;
1349#endif
1350 }
1351
1352 //WPA2 IE
1353 if (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen > 0)
1354 {
1355 memset(&iwe, 0, sizeof(iwe));
1356 memset(&custom[0], 0, MAX_CUSTOM_LEN);
1357 memcpy(custom, &(pAdapter->ScanTab.BssEntry[i].RsnIE.IE[0]),
1358 pAdapter->ScanTab.BssEntry[i].RsnIE.IELen);
1359 iwe.cmd = IWEVGENIE;
1360 iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].RsnIE.IELen;
1361 current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, custom);
1362 if (current_ev == previous_ev)
1363#if WIRELESS_EXT >= 17
1364 return -E2BIG;
1365#else
1366 break;
1367#endif
1368 }
1369#else
1370 //WPA IE
1371 //================================
1372 if (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen > 0)
1373 {
1374 NdisZeroMemory(&iwe, sizeof(iwe));
1375 memset(&custom[0], 0, MAX_CUSTOM_LEN);
1376 iwe.cmd = IWEVCUSTOM;
1377 iwe.u.data.length = (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen * 2) + 7;
1378 NdisMoveMemory(custom, "wpa_ie=", 7);
1379 for (idx = 0; idx < pAdapter->ScanTab.BssEntry[i].WpaIE.IELen; idx++)
1380 sprintf(custom, "%s%02x", custom, pAdapter->ScanTab.BssEntry[i].WpaIE.IE[idx]);
1381 previous_ev = current_ev;
1382 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, custom);
1383 if (current_ev == previous_ev)
1384#if WIRELESS_EXT >= 17
1385 return -E2BIG;
1386#else
1387 break;
1388#endif
1389 }
1390
1391 //WPA2 IE
1392 if (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen > 0)
1393 {
1394 NdisZeroMemory(&iwe, sizeof(iwe));
1395 memset(&custom[0], 0, MAX_CUSTOM_LEN);
1396 iwe.cmd = IWEVCUSTOM;
1397 iwe.u.data.length = (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen * 2) + 7;
1398 NdisMoveMemory(custom, "rsn_ie=", 7);
1399 for (idx = 0; idx < pAdapter->ScanTab.BssEntry[i].RsnIE.IELen; idx++)
1400 sprintf(custom, "%s%02x", custom, pAdapter->ScanTab.BssEntry[i].RsnIE.IE[idx]);
1401 previous_ev = current_ev;
1402 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, custom);
1403 if (current_ev == previous_ev)
1404#if WIRELESS_EXT >= 17
1405 return -E2BIG;
1406#else
1407 break;
1408#endif
1409 }
1410#endif // IWEVGENIE //
1411 }
1412
1413 data->length = current_ev - extra;
1414 pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
1415 DBGPRINT(RT_DEBUG_ERROR ,("===>rt_ioctl_giwscan. %d(%d) BSS returned, data->length = %d\n",i , pAdapter->ScanTab.BssNr, data->length));
1416 return 0;
1417}
1418#endif
1419
1420int rt_ioctl_siwessid(struct net_device *dev,
1421 struct iw_request_info *info,
1422 struct iw_point *data, char *essid)
1423{
1424 PRTMP_ADAPTER pAdapter = dev->ml_priv;
1425
1426 //check if the interface is down
1427 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1428 {
1429 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1430 return -ENETDOWN;
1431 }
1432
1433 if (data->flags)
1434 {
1435 PCHAR pSsidString = NULL;
1436
1437 // Includes null character.
1438 if (data->length > (IW_ESSID_MAX_SIZE + 1))
1439 return -E2BIG;
1440
1441 pSsidString = (CHAR *) kmalloc(MAX_LEN_OF_SSID+1, MEM_ALLOC_FLAG);
1442 if (pSsidString)
1443 {
1444 NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID+1);
1445 NdisMoveMemory(pSsidString, essid, data->length);
1446 if (Set_SSID_Proc(pAdapter, pSsidString) == FALSE)
1447 return -EINVAL;
1448 }
1449 else
1450 return -ENOMEM;
1451 }
1452 else
1453 {
1454 // ANY ssid
1455 if (Set_SSID_Proc(pAdapter, "") == FALSE)
1456 return -EINVAL;
1457 }
1458 return 0;
1459}
1460
1461int rt_ioctl_giwessid(struct net_device *dev,
1462 struct iw_request_info *info,
1463 struct iw_point *data, char *essid)
1464{
1465 PRTMP_ADAPTER pAdapter = dev->ml_priv;
1466
1467 data->flags = 1;
1468 if (MONITOR_ON(pAdapter))
1469 {
1470 data->length = 0;
1471 return 0;
1472 }
1473
1474 if (OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED))
1475 {
1476 DBGPRINT(RT_DEBUG_TRACE ,("MediaState is connected\n"));
1477 data->length = pAdapter->CommonCfg.SsidLen;
1478 memcpy(essid, pAdapter->CommonCfg.Ssid, pAdapter->CommonCfg.SsidLen);
1479 }
1480#ifdef RT2870
1481#ifdef WPA_SUPPLICANT_SUPPORT
1482 // Add for RT2870
1483 else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
1484 {
1485 data->length = pAdapter->CommonCfg.SsidLen;
1486 memcpy(essid, pAdapter->CommonCfg.Ssid, pAdapter->CommonCfg.SsidLen);
1487 }
1488#endif // WPA_SUPPLICANT_SUPPORT //
1489#endif // RT2870 //
1490 else
1491 {//the ANY ssid was specified
1492 data->length = 0;
1493 DBGPRINT(RT_DEBUG_TRACE ,("MediaState is not connected, ess\n"));
1494 }
1495
1496 return 0;
1497
1498}
1499
1500int rt_ioctl_siwnickn(struct net_device *dev,
1501 struct iw_request_info *info,
1502 struct iw_point *data, char *nickname)
1503{
1504 PRTMP_ADAPTER pAdapter = dev->ml_priv;
1505
1506 //check if the interface is down
1507 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1508 {
1509 DBGPRINT(RT_DEBUG_TRACE ,("INFO::Network is down!\n"));
1510 return -ENETDOWN;
1511 }
1512
1513 if (data->length > IW_ESSID_MAX_SIZE)
1514 return -EINVAL;
1515
1516 memset(pAdapter->nickname, 0, IW_ESSID_MAX_SIZE + 1);
1517 memcpy(pAdapter->nickname, nickname, data->length);
1518
1519
1520 return 0;
1521}
1522
1523int rt_ioctl_giwnickn(struct net_device *dev,
1524 struct iw_request_info *info,
1525 struct iw_point *data, char *nickname)
1526{
1527 PRTMP_ADAPTER pAdapter = dev->ml_priv;
1528
1529 if (data->length > strlen(pAdapter->nickname) + 1)
1530 data->length = strlen(pAdapter->nickname) + 1;
1531 if (data->length > 0) {
1532 memcpy(nickname, pAdapter->nickname, data->length-1);
1533 nickname[data->length-1] = '\0';
1534 }
1535 return 0;
1536}
1537
1538int rt_ioctl_siwrts(struct net_device *dev,
1539 struct iw_request_info *info,
1540 struct iw_param *rts, char *extra)
1541{
1542 PRTMP_ADAPTER pAdapter = dev->ml_priv;
1543 u16 val;
1544
1545 //check if the interface is down
1546 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1547 {
1548 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1549 return -ENETDOWN;
1550 }
1551
1552 if (rts->disabled)
1553 val = MAX_RTS_THRESHOLD;
1554 else if (rts->value < 0 || rts->value > MAX_RTS_THRESHOLD)
1555 return -EINVAL;
1556 else if (rts->value == 0)
1557 val = MAX_RTS_THRESHOLD;
1558 else
1559 val = rts->value;
1560
1561 if (val != pAdapter->CommonCfg.RtsThreshold)
1562 pAdapter->CommonCfg.RtsThreshold = val;
1563
1564 return 0;
1565}
1566
1567int rt_ioctl_giwrts(struct net_device *dev,
1568 struct iw_request_info *info,
1569 struct iw_param *rts, char *extra)
1570{
1571 PRTMP_ADAPTER pAdapter = dev->ml_priv;
1572
1573 //check if the interface is down
1574 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1575 {
1576 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1577 return -ENETDOWN;
1578 }
1579
1580 rts->value = pAdapter->CommonCfg.RtsThreshold;
1581 rts->disabled = (rts->value == MAX_RTS_THRESHOLD);
1582 rts->fixed = 1;
1583
1584 return 0;
1585}
1586
1587int rt_ioctl_siwfrag(struct net_device *dev,
1588 struct iw_request_info *info,
1589 struct iw_param *frag, char *extra)
1590{
1591 PRTMP_ADAPTER pAdapter = dev->ml_priv;
1592 u16 val;
1593
1594 //check if the interface is down
1595 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1596 {
1597 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1598 return -ENETDOWN;
1599 }
1600
1601 if (frag->disabled)
1602 val = MAX_FRAG_THRESHOLD;
1603 else if (frag->value >= MIN_FRAG_THRESHOLD || frag->value <= MAX_FRAG_THRESHOLD)
1604 val = __cpu_to_le16(frag->value & ~0x1); /* even numbers only */
1605 else if (frag->value == 0)
1606 val = MAX_FRAG_THRESHOLD;
1607 else
1608 return -EINVAL;
1609
1610 pAdapter->CommonCfg.FragmentThreshold = val;
1611 return 0;
1612}
1613
1614int rt_ioctl_giwfrag(struct net_device *dev,
1615 struct iw_request_info *info,
1616 struct iw_param *frag, char *extra)
1617{
1618 PRTMP_ADAPTER pAdapter = dev->ml_priv;
1619
1620 //check if the interface is down
1621 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1622 {
1623 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1624 return -ENETDOWN;
1625 }
1626
1627 frag->value = pAdapter->CommonCfg.FragmentThreshold;
1628 frag->disabled = (frag->value == MAX_FRAG_THRESHOLD);
1629 frag->fixed = 1;
1630
1631 return 0;
1632}
1633
1634#define MAX_WEP_KEY_SIZE 13
1635#define MIN_WEP_KEY_SIZE 5
1636int rt_ioctl_siwencode(struct net_device *dev,
1637 struct iw_request_info *info,
1638 struct iw_point *erq, char *extra)
1639{
1640 PRTMP_ADAPTER pAdapter = dev->ml_priv;
1641
1642 //check if the interface is down
1643 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1644 {
1645 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1646 return -ENETDOWN;
1647 }
1648
1649 if ((erq->length == 0) &&
1650 (erq->flags & IW_ENCODE_DISABLED))
1651 {
1652 pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
1653 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
1654 pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
1655 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
1656 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
1657 goto done;
1658 }
1659 else if (erq->flags & IW_ENCODE_RESTRICTED || erq->flags & IW_ENCODE_OPEN)
1660 {
1661 //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1662 STA_PORT_SECURED(pAdapter);
1663 pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
1664 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
1665 pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
1666 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
1667 if (erq->flags & IW_ENCODE_RESTRICTED)
1668 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
1669 else
1670 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
1671 }
1672
1673 if (erq->length > 0)
1674 {
1675 int keyIdx = (erq->flags & IW_ENCODE_INDEX) - 1;
1676 /* Check the size of the key */
1677 if (erq->length > MAX_WEP_KEY_SIZE)
1678 {
1679 return -EINVAL;
1680 }
1681 /* Check key index */
1682 if ((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS))
1683 {
1684 DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::Wrong keyIdx=%d! Using default key instead (%d)\n",
1685 keyIdx, pAdapter->StaCfg.DefaultKeyId));
1686
1687 //Using default key
1688 keyIdx = pAdapter->StaCfg.DefaultKeyId;
1689 }
1690 else
1691 {
1692 pAdapter->StaCfg.DefaultKeyId=keyIdx;
1693 }
1694
1695 NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, 16);
1696
1697 if (erq->length == MAX_WEP_KEY_SIZE)
1698 {
1699 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MAX_WEP_KEY_SIZE;
1700 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP128;
1701 }
1702 else if (erq->length == MIN_WEP_KEY_SIZE)
1703 {
1704 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MIN_WEP_KEY_SIZE;
1705 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP64;
1706 }
1707 else
1708 /* Disable the key */
1709 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
1710
1711 /* Check if the key is not marked as invalid */
1712 if(!(erq->flags & IW_ENCODE_NOKEY))
1713 {
1714 /* Copy the key in the driver */
1715 NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, extra, erq->length);
1716 }
1717 }
1718 else
1719 {
1720 /* Do we want to just set the transmit key index ? */
1721 int index = (erq->flags & IW_ENCODE_INDEX) - 1;
1722 if ((index >= 0) && (index < 4))
1723 {
1724 pAdapter->StaCfg.DefaultKeyId = index;
1725 }
1726 else
1727 /* Don't complain if only change the mode */
1728 if(!erq->flags & IW_ENCODE_MODE)
1729 {
1730 return -EINVAL;
1731 }
1732 }
1733
1734done:
1735 DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::erq->flags=%x\n",erq->flags));
1736 DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::AuthMode=%x\n",pAdapter->StaCfg.AuthMode));
1737 DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::DefaultKeyId=%x, KeyLen = %d\n",pAdapter->StaCfg.DefaultKeyId , pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen));
1738 DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::WepStatus=%x\n",pAdapter->StaCfg.WepStatus));
1739 return 0;
1740}
1741
1742int
1743rt_ioctl_giwencode(struct net_device *dev,
1744 struct iw_request_info *info,
1745 struct iw_point *erq, char *key)
1746{
1747 PRTMP_ADAPTER pAdapter = dev->ml_priv;
1748 int kid;
1749
1750 //check if the interface is down
1751 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1752 {
1753 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1754 return -ENETDOWN;
1755 }
1756
1757 kid = erq->flags & IW_ENCODE_INDEX;
1758 DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_giwencode %d\n", erq->flags & IW_ENCODE_INDEX));
1759
1760 if (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled)
1761 {
1762 erq->length = 0;
1763 erq->flags = IW_ENCODE_DISABLED;
1764 }
1765 else if ((kid > 0) && (kid <=4))
1766 {
1767 // copy wep key
1768 erq->flags = kid ; /* NB: base 1 */
1769 if (erq->length > pAdapter->SharedKey[BSS0][kid-1].KeyLen)
1770 erq->length = pAdapter->SharedKey[BSS0][kid-1].KeyLen;
1771 memcpy(key, pAdapter->SharedKey[BSS0][kid-1].Key, erq->length);
1772 //if ((kid == pAdapter->PortCfg.DefaultKeyId))
1773 //erq->flags |= IW_ENCODE_ENABLED; /* XXX */
1774 if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
1775 erq->flags |= IW_ENCODE_RESTRICTED; /* XXX */
1776 else
1777 erq->flags |= IW_ENCODE_OPEN; /* XXX */
1778
1779 }
1780 else if (kid == 0)
1781 {
1782 if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
1783 erq->flags |= IW_ENCODE_RESTRICTED; /* XXX */
1784 else
1785 erq->flags |= IW_ENCODE_OPEN; /* XXX */
1786 erq->length = pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen;
1787 memcpy(key, pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key, erq->length);
1788 // copy default key ID
1789 if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
1790 erq->flags |= IW_ENCODE_RESTRICTED; /* XXX */
1791 else
1792 erq->flags |= IW_ENCODE_OPEN; /* XXX */
1793 erq->flags = pAdapter->StaCfg.DefaultKeyId + 1; /* NB: base 1 */
1794 erq->flags |= IW_ENCODE_ENABLED; /* XXX */
1795 }
1796
1797 return 0;
1798
1799}
1800
1801static int
1802rt_ioctl_setparam(struct net_device *dev, struct iw_request_info *info,
1803 void *w, char *extra)
1804{
1805 VIRTUAL_ADAPTER *pVirtualAd = NULL;
1806 PRTMP_ADAPTER pAdapter;
1807 POS_COOKIE pObj;
1808 char *this_char = extra;
1809 char *value;
1810 int Status=0;
1811
1812 if (dev->priv_flags == INT_MAIN)
1813 {
1814 pAdapter = dev->ml_priv;
1815 }
1816 else
1817 {
1818 pVirtualAd = dev->ml_priv;
1819 pAdapter = pVirtualAd->RtmpDev->ml_priv;
1820 }
1821 pObj = (POS_COOKIE) pAdapter->OS_Cookie;
1822
1823 if (pAdapter == NULL)
1824 {
1825 /* if 1st open fail, pAd will be free;
1826 So the net_dev->ml_priv will be NULL in 2rd open */
1827 return -ENETDOWN;
1828 }
1829
1830 {
1831 pObj->ioctl_if_type = INT_MAIN;
1832 pObj->ioctl_if = MAIN_MBSSID;
1833 }
1834
1835 //check if the interface is down
1836 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1837 {
1838 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1839 return -ENETDOWN;
1840 }
1841
1842 if (!*this_char)
1843 return -EINVAL;
1844
1845 if ((value = rtstrchr(this_char, '=')) != NULL)
1846 *value++ = 0;
1847
1848 if (!value)
1849 return -EINVAL;
1850
1851 // reject setting nothing besides ANY ssid(ssidLen=0)
1852 if (!*value && (strcmp(this_char, "SSID") != 0))
1853 return -EINVAL;
1854
1855 for (PRTMP_PRIVATE_SET_PROC = RTMP_PRIVATE_SUPPORT_PROC; PRTMP_PRIVATE_SET_PROC->name; PRTMP_PRIVATE_SET_PROC++)
1856 {
1857 if (strcmp(this_char, PRTMP_PRIVATE_SET_PROC->name) == 0)
1858 {
1859 if(!PRTMP_PRIVATE_SET_PROC->set_proc(pAdapter, value))
1860 { //FALSE:Set private failed then return Invalid argument
1861 Status = -EINVAL;
1862 }
1863 break; //Exit for loop.
1864 }
1865 }
1866
1867 if(PRTMP_PRIVATE_SET_PROC->name == NULL)
1868 { //Not found argument
1869 Status = -EINVAL;
1870 DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_setparam:: (iwpriv) Not Support Set Command [%s=%s]\n", this_char, value));
1871 }
1872
1873 return Status;
1874}
1875
1876
1877static int
1878rt_private_get_statistics(struct net_device *dev, struct iw_request_info *info,
1879 struct iw_point *wrq, char *extra)
1880{
1881 INT Status = 0;
1882 PRTMP_ADAPTER pAd = dev->ml_priv;
1883
1884 if (extra == NULL)
1885 {
1886 wrq->length = 0;
1887 return -EIO;
1888 }
1889
1890 memset(extra, 0x00, IW_PRIV_SIZE_MASK);
1891 sprintf(extra, "\n\n");
1892
1893#ifdef RALINK_ATE
1894 if (ATE_ON(pAd))
1895 {
1896 sprintf(extra+strlen(extra), "Tx success = %ld\n", (ULONG)pAd->ate.TxDoneCount);
1897 //sprintf(extra+strlen(extra), "Tx success without retry = %ld\n", (ULONG)pAd->ate.TxDoneCount);
1898 }
1899 else
1900#endif // RALINK_ATE //
1901 {
1902 sprintf(extra+strlen(extra), "Tx success = %ld\n", (ULONG)pAd->WlanCounters.TransmittedFragmentCount.QuadPart);
1903 sprintf(extra+strlen(extra), "Tx success without retry = %ld\n", (ULONG)pAd->WlanCounters.TransmittedFragmentCount.QuadPart - (ULONG)pAd->WlanCounters.RetryCount.QuadPart);
1904 }
1905 sprintf(extra+strlen(extra), "Tx success after retry = %ld\n", (ULONG)pAd->WlanCounters.RetryCount.QuadPart);
1906 sprintf(extra+strlen(extra), "Tx fail to Rcv ACK after retry = %ld\n", (ULONG)pAd->WlanCounters.FailedCount.QuadPart);
1907 sprintf(extra+strlen(extra), "RTS Success Rcv CTS = %ld\n", (ULONG)pAd->WlanCounters.RTSSuccessCount.QuadPart);
1908 sprintf(extra+strlen(extra), "RTS Fail Rcv CTS = %ld\n", (ULONG)pAd->WlanCounters.RTSFailureCount.QuadPart);
1909
1910 sprintf(extra+strlen(extra), "Rx success = %ld\n", (ULONG)pAd->WlanCounters.ReceivedFragmentCount.QuadPart);
1911 sprintf(extra+strlen(extra), "Rx with CRC = %ld\n", (ULONG)pAd->WlanCounters.FCSErrorCount.QuadPart);
1912 sprintf(extra+strlen(extra), "Rx drop due to out of resource = %ld\n", (ULONG)pAd->Counters8023.RxNoBuffer);
1913 sprintf(extra+strlen(extra), "Rx duplicate frame = %ld\n", (ULONG)pAd->WlanCounters.FrameDuplicateCount.QuadPart);
1914
1915 sprintf(extra+strlen(extra), "False CCA (one second) = %ld\n", (ULONG)pAd->RalinkCounters.OneSecFalseCCACnt);
1916#ifdef RALINK_ATE
1917 if (ATE_ON(pAd))
1918 {
1919 if (pAd->ate.RxAntennaSel == 0)
1920 {
1921 sprintf(extra+strlen(extra), "RSSI-A = %ld\n", (LONG)(pAd->ate.LastRssi0 - pAd->BbpRssiToDbmDelta));
1922 sprintf(extra+strlen(extra), "RSSI-B (if available) = %ld\n", (LONG)(pAd->ate.LastRssi1 - pAd->BbpRssiToDbmDelta));
1923 sprintf(extra+strlen(extra), "RSSI-C (if available) = %ld\n\n", (LONG)(pAd->ate.LastRssi2 - pAd->BbpRssiToDbmDelta));
1924 }
1925 else
1926 {
1927 sprintf(extra+strlen(extra), "RSSI = %ld\n", (LONG)(pAd->ate.LastRssi0 - pAd->BbpRssiToDbmDelta));
1928 }
1929 }
1930 else
1931#endif // RALINK_ATE //
1932 {
1933 sprintf(extra+strlen(extra), "RSSI-A = %ld\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi0 - pAd->BbpRssiToDbmDelta));
1934 sprintf(extra+strlen(extra), "RSSI-B (if available) = %ld\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi1 - pAd->BbpRssiToDbmDelta));
1935 sprintf(extra+strlen(extra), "RSSI-C (if available) = %ld\n\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi2 - pAd->BbpRssiToDbmDelta));
1936 }
1937#ifdef WPA_SUPPLICANT_SUPPORT
1938 sprintf(extra+strlen(extra), "WpaSupplicantUP = %d\n\n", pAd->StaCfg.WpaSupplicantUP);
1939#endif // WPA_SUPPLICANT_SUPPORT //
1940
1941
1942 wrq->length = strlen(extra) + 1; // 1: size of '\0'
1943 DBGPRINT(RT_DEBUG_TRACE, ("<== rt_private_get_statistics, wrq->length = %d\n", wrq->length));
1944
1945 return Status;
1946}
1947
1948#ifdef DOT11_N_SUPPORT
1949void getBaInfo(
1950 IN PRTMP_ADAPTER pAd,
1951 IN PUCHAR pOutBuf)
1952{
1953 INT i, j;
1954 BA_ORI_ENTRY *pOriBAEntry;
1955 BA_REC_ENTRY *pRecBAEntry;
1956
1957 for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
1958 {
1959 PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
1960 if (((pEntry->ValidAsCLI || pEntry->ValidAsApCli) && (pEntry->Sst == SST_ASSOC))
1961 || (pEntry->ValidAsWDS) || (pEntry->ValidAsMesh))
1962 {
1963 sprintf(pOutBuf, "%s\n%02X:%02X:%02X:%02X:%02X:%02X (Aid = %d) (AP) -\n",
1964 pOutBuf,
1965 pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
1966 pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5], pEntry->Aid);
1967
1968 sprintf(pOutBuf, "%s[Recipient]\n", pOutBuf);
1969 for (j=0; j < NUM_OF_TID; j++)
1970 {
1971 if (pEntry->BARecWcidArray[j] != 0)
1972 {
1973 pRecBAEntry =&pAd->BATable.BARecEntry[pEntry->BARecWcidArray[j]];
1974 sprintf(pOutBuf, "%sTID=%d, BAWinSize=%d, LastIndSeq=%d, ReorderingPkts=%d\n", pOutBuf, j, pRecBAEntry->BAWinSize, pRecBAEntry->LastIndSeq, pRecBAEntry->list.qlen);
1975 }
1976 }
1977 sprintf(pOutBuf, "%s\n", pOutBuf);
1978
1979 sprintf(pOutBuf, "%s[Originator]\n", pOutBuf);
1980 for (j=0; j < NUM_OF_TID; j++)
1981 {
1982 if (pEntry->BAOriWcidArray[j] != 0)
1983 {
1984 pOriBAEntry =&pAd->BATable.BAOriEntry[pEntry->BAOriWcidArray[j]];
1985 sprintf(pOutBuf, "%sTID=%d, BAWinSize=%d, StartSeq=%d, CurTxSeq=%d\n", pOutBuf, j, pOriBAEntry->BAWinSize, pOriBAEntry->Sequence, pEntry->TxSeq[j]);
1986 }
1987 }
1988 sprintf(pOutBuf, "%s\n\n", pOutBuf);
1989 }
1990 if (strlen(pOutBuf) > (IW_PRIV_SIZE_MASK - 30))
1991 break;
1992 }
1993
1994 return;
1995}
1996#endif // DOT11_N_SUPPORT //
1997
1998static int
1999rt_private_show(struct net_device *dev, struct iw_request_info *info,
2000 struct iw_point *wrq, char *extra)
2001{
2002 INT Status = 0;
2003 VIRTUAL_ADAPTER *pVirtualAd = NULL;
2004 PRTMP_ADAPTER pAd;
2005 POS_COOKIE pObj;
2006 u32 subcmd = wrq->flags;
2007
2008 if (dev->priv_flags == INT_MAIN)
2009 pAd = dev->ml_priv;
2010 else
2011 {
2012 pVirtualAd = dev->ml_priv;
2013 pAd = pVirtualAd->RtmpDev->ml_priv;
2014 }
2015 pObj = (POS_COOKIE) pAd->OS_Cookie;
2016
2017 if (pAd == NULL)
2018 {
2019 /* if 1st open fail, pAd will be free;
2020 So the net_dev->ml_priv will be NULL in 2rd open */
2021 return -ENETDOWN;
2022 }
2023
2024 if (extra == NULL)
2025 {
2026 wrq->length = 0;
2027 return -EIO;
2028 }
2029 memset(extra, 0x00, IW_PRIV_SIZE_MASK);
2030
2031 {
2032 pObj->ioctl_if_type = INT_MAIN;
2033 pObj->ioctl_if = MAIN_MBSSID;
2034 }
2035
2036 switch(subcmd)
2037 {
2038
2039 case SHOW_CONN_STATUS:
2040 if (MONITOR_ON(pAd))
2041 {
2042#ifdef DOT11_N_SUPPORT
2043 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
2044 pAd->CommonCfg.RegTransmitSetting.field.BW)
2045 sprintf(extra, "Monitor Mode(CentralChannel %d)\n", pAd->CommonCfg.CentralChannel);
2046 else
2047#endif // DOT11_N_SUPPORT //
2048 sprintf(extra, "Monitor Mode(Channel %d)\n", pAd->CommonCfg.Channel);
2049 }
2050 else
2051 {
2052 if (pAd->IndicateMediaState == NdisMediaStateConnected)
2053 {
2054 if (INFRA_ON(pAd))
2055 {
2056 sprintf(extra, "Connected(AP: %s[%02X:%02X:%02X:%02X:%02X:%02X])\n",
2057 pAd->CommonCfg.Ssid,
2058 pAd->CommonCfg.Bssid[0],
2059 pAd->CommonCfg.Bssid[1],
2060 pAd->CommonCfg.Bssid[2],
2061 pAd->CommonCfg.Bssid[3],
2062 pAd->CommonCfg.Bssid[4],
2063 pAd->CommonCfg.Bssid[5]);
2064 DBGPRINT(RT_DEBUG_TRACE ,("Ssid=%s ,Ssidlen = %d\n",pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen));
2065 }
2066 else if (ADHOC_ON(pAd))
2067 sprintf(extra, "Connected\n");
2068 }
2069 else
2070 {
2071 sprintf(extra, "Disconnected\n");
2072 DBGPRINT(RT_DEBUG_TRACE ,("ConnStatus is not connected\n"));
2073 }
2074 }
2075 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2076 break;
2077 case SHOW_DRVIER_VERION:
2078 sprintf(extra, "Driver version-%s, %s %s\n", STA_DRIVER_VERSION, __DATE__, __TIME__ );
2079 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2080 break;
2081#ifdef DOT11_N_SUPPORT
2082 case SHOW_BA_INFO:
2083 getBaInfo(pAd, extra);
2084 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2085 break;
2086#endif // DOT11_N_SUPPORT //
2087 case SHOW_DESC_INFO:
2088 {
2089 Show_DescInfo_Proc(pAd, NULL);
2090 wrq->length = 0; // 1: size of '\0'
2091 }
2092 break;
2093 case RAIO_OFF:
2094 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
2095 {
2096 sprintf(extra, "Scanning\n");
2097 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2098 break;
2099 }
2100 pAd->StaCfg.bSwRadio = FALSE;
2101 if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
2102 {
2103 pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
2104 if (pAd->StaCfg.bRadio == FALSE)
2105 {
2106 MlmeRadioOff(pAd);
2107 // Update extra information
2108 pAd->ExtraInfo = SW_RADIO_OFF;
2109 }
2110 }
2111 sprintf(extra, "Radio Off\n");
2112 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2113 break;
2114 case RAIO_ON:
2115 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
2116 {
2117 sprintf(extra, "Scanning\n");
2118 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2119 break;
2120 }
2121 pAd->StaCfg.bSwRadio = TRUE;
2122 //if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
2123 {
2124 pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
2125 if (pAd->StaCfg.bRadio == TRUE)
2126 {
2127 MlmeRadioOn(pAd);
2128 // Update extra information
2129 pAd->ExtraInfo = EXTRA_INFO_CLEAR;
2130 }
2131 }
2132 sprintf(extra, "Radio On\n");
2133 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2134 break;
2135
2136
2137#ifdef QOS_DLS_SUPPORT
2138 case SHOW_DLS_ENTRY_INFO:
2139 {
2140 Set_DlsEntryInfo_Display_Proc(pAd, NULL);
2141 wrq->length = 0; // 1: size of '\0'
2142 }
2143 break;
2144#endif // QOS_DLS_SUPPORT //
2145
2146 case SHOW_CFG_VALUE:
2147 {
2148 Status = RTMPShowCfgValue(pAd, wrq->pointer, extra);
2149 if (Status == 0)
2150 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2151 }
2152 break;
2153 default:
2154 DBGPRINT(RT_DEBUG_TRACE, ("%s - unknow subcmd = %d\n", __FUNCTION__, subcmd));
2155 break;
2156 }
2157
2158 return Status;
2159}
2160
2161#ifdef SIOCSIWMLME
2162int rt_ioctl_siwmlme(struct net_device *dev,
2163 struct iw_request_info *info,
2164 union iwreq_data *wrqu,
2165 char *extra)
2166{
2167 PRTMP_ADAPTER pAd = dev->ml_priv;
2168 struct iw_mlme *pMlme = (struct iw_mlme *)wrqu->data.pointer;
2169 MLME_QUEUE_ELEM MsgElem;
2170 MLME_DISASSOC_REQ_STRUCT DisAssocReq;
2171 MLME_DEAUTH_REQ_STRUCT DeAuthReq;
2172
2173 DBGPRINT(RT_DEBUG_TRACE, ("====> %s\n", __FUNCTION__));
2174
2175 if (pMlme == NULL)
2176 return -EINVAL;
2177
2178 switch(pMlme->cmd)
2179 {
2180#ifdef IW_MLME_DEAUTH
2181 case IW_MLME_DEAUTH:
2182 DBGPRINT(RT_DEBUG_TRACE, ("====> %s - IW_MLME_DEAUTH\n", __FUNCTION__));
2183 COPY_MAC_ADDR(DeAuthReq.Addr, pAd->CommonCfg.Bssid);
2184 DeAuthReq.Reason = pMlme->reason_code;
2185 MsgElem.MsgLen = sizeof(MLME_DEAUTH_REQ_STRUCT);
2186 NdisMoveMemory(MsgElem.Msg, &DeAuthReq, sizeof(MLME_DEAUTH_REQ_STRUCT));
2187 MlmeDeauthReqAction(pAd, &MsgElem);
2188 if (INFRA_ON(pAd))
2189 {
2190 LinkDown(pAd, FALSE);
2191 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
2192 }
2193 break;
2194#endif // IW_MLME_DEAUTH //
2195#ifdef IW_MLME_DISASSOC
2196 case IW_MLME_DISASSOC:
2197 DBGPRINT(RT_DEBUG_TRACE, ("====> %s - IW_MLME_DISASSOC\n", __FUNCTION__));
2198 COPY_MAC_ADDR(DisAssocReq.Addr, pAd->CommonCfg.Bssid);
2199 DisAssocReq.Reason = pMlme->reason_code;
2200
2201 MsgElem.Machine = ASSOC_STATE_MACHINE;
2202 MsgElem.MsgType = MT2_MLME_DISASSOC_REQ;
2203 MsgElem.MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
2204 NdisMoveMemory(MsgElem.Msg, &DisAssocReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
2205
2206 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
2207 MlmeDisassocReqAction(pAd, &MsgElem);
2208 break;
2209#endif // IW_MLME_DISASSOC //
2210 default:
2211 DBGPRINT(RT_DEBUG_TRACE, ("====> %s - Unknow Command\n", __FUNCTION__));
2212 break;
2213 }
2214
2215 return 0;
2216}
2217#endif // SIOCSIWMLME //
2218
2219#if WIRELESS_EXT > 17
2220int rt_ioctl_siwauth(struct net_device *dev,
2221 struct iw_request_info *info,
2222 union iwreq_data *wrqu, char *extra)
2223{
2224 PRTMP_ADAPTER pAdapter = dev->ml_priv;
2225 struct iw_param *param = &wrqu->param;
2226
2227 //check if the interface is down
2228 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2229 {
2230 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2231 return -ENETDOWN;
2232 }
2233 switch (param->flags & IW_AUTH_INDEX) {
2234 case IW_AUTH_WPA_VERSION:
2235 if (param->value == IW_AUTH_WPA_VERSION_WPA)
2236 {
2237 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
2238 if (pAdapter->StaCfg.BssType == BSS_ADHOC)
2239 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
2240 }
2241 else if (param->value == IW_AUTH_WPA_VERSION_WPA2)
2242 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
2243
2244 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __FUNCTION__, param->value));
2245 break;
2246 case IW_AUTH_CIPHER_PAIRWISE:
2247 if (param->value == IW_AUTH_CIPHER_NONE)
2248 {
2249 pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
2250 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
2251 pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
2252 }
2253 else if (param->value == IW_AUTH_CIPHER_WEP40 ||
2254 param->value == IW_AUTH_CIPHER_WEP104)
2255 {
2256 pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
2257 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
2258 pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
2259#ifdef WPA_SUPPLICANT_SUPPORT
2260 pAdapter->StaCfg.IEEE8021X = FALSE;
2261#endif // WPA_SUPPLICANT_SUPPORT //
2262 }
2263 else if (param->value == IW_AUTH_CIPHER_TKIP)
2264 {
2265 pAdapter->StaCfg.WepStatus = Ndis802_11Encryption2Enabled;
2266 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
2267 pAdapter->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2268 }
2269 else if (param->value == IW_AUTH_CIPHER_CCMP)
2270 {
2271 pAdapter->StaCfg.WepStatus = Ndis802_11Encryption3Enabled;
2272 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
2273 pAdapter->StaCfg.PairCipher = Ndis802_11Encryption3Enabled;
2274 }
2275 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_PAIRWISE - param->value = %d!\n", __FUNCTION__, param->value));
2276 break;
2277 case IW_AUTH_CIPHER_GROUP:
2278 if (param->value == IW_AUTH_CIPHER_NONE)
2279 {
2280 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
2281 }
2282 else if (param->value == IW_AUTH_CIPHER_WEP40 ||
2283 param->value == IW_AUTH_CIPHER_WEP104)
2284 {
2285 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
2286 }
2287 else if (param->value == IW_AUTH_CIPHER_TKIP)
2288 {
2289 pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption2Enabled;
2290 }
2291 else if (param->value == IW_AUTH_CIPHER_CCMP)
2292 {
2293 pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption3Enabled;
2294 }
2295 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_GROUP - param->value = %d!\n", __FUNCTION__, param->value));
2296 break;
2297 case IW_AUTH_KEY_MGMT:
2298 if (param->value == IW_AUTH_KEY_MGMT_802_1X)
2299 {
2300 if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
2301 {
2302 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
2303#ifdef WPA_SUPPLICANT_SUPPORT
2304 pAdapter->StaCfg.IEEE8021X = FALSE;
2305#endif // WPA_SUPPLICANT_SUPPORT //
2306 }
2307 else if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
2308 {
2309 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
2310#ifdef WPA_SUPPLICANT_SUPPORT
2311 pAdapter->StaCfg.IEEE8021X = FALSE;
2312#endif // WPA_SUPPLICANT_SUPPORT //
2313 }
2314#ifdef WPA_SUPPLICANT_SUPPORT
2315 else
2316 // WEP 1x
2317 pAdapter->StaCfg.IEEE8021X = TRUE;
2318#endif // WPA_SUPPLICANT_SUPPORT //
2319 }
2320 else if (param->value == 0)
2321 {
2322 //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2323 STA_PORT_SECURED(pAdapter);
2324 }
2325 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_KEY_MGMT - param->value = %d!\n", __FUNCTION__, param->value));
2326 break;
2327 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
2328 break;
2329 case IW_AUTH_PRIVACY_INVOKED:
2330 /*if (param->value == 0)
2331 {
2332 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
2333 pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
2334 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
2335 pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
2336 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
2337 }*/
2338 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_PRIVACY_INVOKED - param->value = %d!\n", __FUNCTION__, param->value));
2339 break;
2340 case IW_AUTH_DROP_UNENCRYPTED:
2341 if (param->value != 0)
2342 pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
2343 else
2344 {
2345 //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2346 STA_PORT_SECURED(pAdapter);
2347 }
2348 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __FUNCTION__, param->value));
2349 break;
2350 case IW_AUTH_80211_AUTH_ALG:
2351 if (param->value & IW_AUTH_ALG_SHARED_KEY)
2352 {
2353 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
2354 }
2355 else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM)
2356 {
2357 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
2358 }
2359 else
2360 return -EINVAL;
2361 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_80211_AUTH_ALG - param->value = %d!\n", __FUNCTION__, param->value));
2362 break;
2363 case IW_AUTH_WPA_ENABLED:
2364 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_ENABLED - Driver supports WPA!(param->value = %d)\n", __FUNCTION__, param->value));
2365 break;
2366 default:
2367 return -EOPNOTSUPP;
2368}
2369
2370 return 0;
2371}
2372
2373int rt_ioctl_giwauth(struct net_device *dev,
2374 struct iw_request_info *info,
2375 union iwreq_data *wrqu, char *extra)
2376{
2377 PRTMP_ADAPTER pAdapter = dev->ml_priv;
2378 struct iw_param *param = &wrqu->param;
2379
2380 //check if the interface is down
2381 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2382 {
2383 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2384 return -ENETDOWN;
2385 }
2386
2387 switch (param->flags & IW_AUTH_INDEX) {
2388 case IW_AUTH_DROP_UNENCRYPTED:
2389 param->value = (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled) ? 0 : 1;
2390 break;
2391
2392 case IW_AUTH_80211_AUTH_ALG:
2393 param->value = (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared) ? IW_AUTH_ALG_SHARED_KEY : IW_AUTH_ALG_OPEN_SYSTEM;
2394 break;
2395
2396 case IW_AUTH_WPA_ENABLED:
2397 param->value = (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) ? 1 : 0;
2398 break;
2399
2400 default:
2401 return -EOPNOTSUPP;
2402 }
2403 DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_giwauth::param->value = %d!\n", param->value));
2404 return 0;
2405}
2406
2407void fnSetCipherKey(
2408 IN PRTMP_ADAPTER pAdapter,
2409 IN INT keyIdx,
2410 IN UCHAR CipherAlg,
2411 IN BOOLEAN bGTK,
2412 IN struct iw_encode_ext *ext)
2413{
2414 NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
2415 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = LEN_TKIP_EK;
2416 NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, LEN_TKIP_EK);
2417 NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].TxMic, ext->key + LEN_TKIP_EK, LEN_TKIP_TXMICK);
2418 NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].RxMic, ext->key + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
2419 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CipherAlg;
2420
2421 // Update group key information to ASIC Shared Key Table
2422 AsicAddSharedKeyEntry(pAdapter,
2423 BSS0,
2424 keyIdx,
2425 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
2426 pAdapter->SharedKey[BSS0][keyIdx].Key,
2427 pAdapter->SharedKey[BSS0][keyIdx].TxMic,
2428 pAdapter->SharedKey[BSS0][keyIdx].RxMic);
2429
2430 if (bGTK)
2431 // Update ASIC WCID attribute table and IVEIV table
2432 RTMPAddWcidAttributeEntry(pAdapter,
2433 BSS0,
2434 keyIdx,
2435 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
2436 NULL);
2437 else
2438 // Update ASIC WCID attribute table and IVEIV table
2439 RTMPAddWcidAttributeEntry(pAdapter,
2440 BSS0,
2441 keyIdx,
2442 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
2443 &pAdapter->MacTab.Content[BSSID_WCID]);
2444}
2445
2446int rt_ioctl_siwencodeext(struct net_device *dev,
2447 struct iw_request_info *info,
2448 union iwreq_data *wrqu,
2449 char *extra)
2450 {
2451 PRTMP_ADAPTER pAdapter = dev->ml_priv;
2452 struct iw_point *encoding = &wrqu->encoding;
2453 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
2454 int keyIdx, alg = ext->alg;
2455
2456 //check if the interface is down
2457 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2458 {
2459 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2460 return -ENETDOWN;
2461 }
2462
2463 if (encoding->flags & IW_ENCODE_DISABLED)
2464 {
2465 keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
2466 // set BSSID wcid entry of the Pair-wise Key table as no-security mode
2467 AsicRemovePairwiseKeyEntry(pAdapter, BSS0, BSSID_WCID);
2468 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
2469 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_NONE;
2470 AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)keyIdx);
2471 NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
2472 DBGPRINT(RT_DEBUG_TRACE, ("%s::Remove all keys!(encoding->flags = %x)\n", __FUNCTION__, encoding->flags));
2473 }
2474 else
2475 {
2476 // Get Key Index and convet to our own defined key index
2477 keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
2478 if((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS))
2479 return -EINVAL;
2480
2481 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2482 {
2483 pAdapter->StaCfg.DefaultKeyId = keyIdx;
2484 DBGPRINT(RT_DEBUG_TRACE, ("%s::DefaultKeyId = %d\n", __FUNCTION__, pAdapter->StaCfg.DefaultKeyId));
2485 }
2486
2487 switch (alg) {
2488 case IW_ENCODE_ALG_NONE:
2489 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_NONE\n", __FUNCTION__));
2490 break;
2491 case IW_ENCODE_ALG_WEP:
2492 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_WEP - ext->key_len = %d, keyIdx = %d\n", __FUNCTION__, ext->key_len, keyIdx));
2493 if (ext->key_len == MAX_WEP_KEY_SIZE)
2494 {
2495 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MAX_WEP_KEY_SIZE;
2496 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP128;
2497 }
2498 else if (ext->key_len == MIN_WEP_KEY_SIZE)
2499 {
2500 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MIN_WEP_KEY_SIZE;
2501 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP64;
2502 }
2503 else
2504 return -EINVAL;
2505
2506 NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, 16);
2507 NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, ext->key_len);
2508 break;
2509 case IW_ENCODE_ALG_TKIP:
2510 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_TKIP - keyIdx = %d, ext->key_len = %d\n", __FUNCTION__, keyIdx, ext->key_len));
2511 if (ext->key_len == 32)
2512 {
2513 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2514 {
2515 fnSetCipherKey(pAdapter, keyIdx, CIPHER_TKIP, FALSE, ext);
2516 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
2517 {
2518 //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2519 STA_PORT_SECURED(pAdapter);
2520 }
2521 }
2522 else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
2523 {
2524 fnSetCipherKey(pAdapter, keyIdx, CIPHER_TKIP, TRUE, ext);
2525
2526 // set 802.1x port control
2527 //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2528 STA_PORT_SECURED(pAdapter);
2529 }
2530 }
2531 else
2532 return -EINVAL;
2533 break;
2534 case IW_ENCODE_ALG_CCMP:
2535 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2536 {
2537 fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, FALSE, ext);
2538 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
2539 //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2540 STA_PORT_SECURED(pAdapter);
2541 }
2542 else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
2543 {
2544 fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, TRUE, ext);
2545
2546 // set 802.1x port control
2547 //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2548 STA_PORT_SECURED(pAdapter);
2549 }
2550 break;
2551 default:
2552 return -EINVAL;
2553 }
2554 }
2555
2556 return 0;
2557}
2558
2559int
2560rt_ioctl_giwencodeext(struct net_device *dev,
2561 struct iw_request_info *info,
2562 union iwreq_data *wrqu, char *extra)
2563{
2564 PRTMP_ADAPTER pAd = dev->ml_priv;
2565 PCHAR pKey = NULL;
2566 struct iw_point *encoding = &wrqu->encoding;
2567 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
2568 int idx, max_key_len;
2569
2570 DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_giwencodeext\n"));
2571
2572 max_key_len = encoding->length - sizeof(*ext);
2573 if (max_key_len < 0)
2574 return -EINVAL;
2575
2576 idx = encoding->flags & IW_ENCODE_INDEX;
2577 if (idx)
2578 {
2579 if (idx < 1 || idx > 4)
2580 return -EINVAL;
2581 idx--;
2582
2583 if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
2584 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled))
2585 {
2586 if (idx != pAd->StaCfg.DefaultKeyId)
2587 {
2588 ext->key_len = 0;
2589 return 0;
2590 }
2591 }
2592 }
2593 else
2594 idx = pAd->StaCfg.DefaultKeyId;
2595
2596 encoding->flags = idx + 1;
2597 memset(ext, 0, sizeof(*ext));
2598
2599 ext->key_len = 0;
2600 switch(pAd->StaCfg.WepStatus) {
2601 case Ndis802_11WEPDisabled:
2602 ext->alg = IW_ENCODE_ALG_NONE;
2603 encoding->flags |= IW_ENCODE_DISABLED;
2604 break;
2605 case Ndis802_11WEPEnabled:
2606 ext->alg = IW_ENCODE_ALG_WEP;
2607 if (pAd->SharedKey[BSS0][idx].KeyLen > max_key_len)
2608 return -E2BIG;
2609 else
2610 {
2611 ext->key_len = pAd->SharedKey[BSS0][idx].KeyLen;
2612 pKey = &(pAd->SharedKey[BSS0][idx].Key[0]);
2613 }
2614 break;
2615 case Ndis802_11Encryption2Enabled:
2616 case Ndis802_11Encryption3Enabled:
2617 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
2618 ext->alg = IW_ENCODE_ALG_TKIP;
2619 else
2620 ext->alg = IW_ENCODE_ALG_CCMP;
2621
2622 if (max_key_len < 32)
2623 return -E2BIG;
2624 else
2625 {
2626 ext->key_len = 32;
2627 pKey = &pAd->StaCfg.PMK[0];
2628 }
2629 break;
2630 default:
2631 return -EINVAL;
2632 }
2633
2634 if (ext->key_len && pKey)
2635 {
2636 encoding->flags |= IW_ENCODE_ENABLED;
2637 memcpy(ext->key, pKey, ext->key_len);
2638 }
2639
2640 return 0;
2641}
2642
2643#ifdef SIOCSIWGENIE
2644int rt_ioctl_siwgenie(struct net_device *dev,
2645 struct iw_request_info *info,
2646 union iwreq_data *wrqu, char *extra)
2647{
2648 PRTMP_ADAPTER pAd = dev->ml_priv;
2649
2650 if (wrqu->data.length > MAX_LEN_OF_RSNIE ||
2651 (wrqu->data.length && extra == NULL))
2652 return -EINVAL;
2653
2654 if (wrqu->data.length)
2655 {
2656 pAd->StaCfg.RSNIE_Len = wrqu->data.length;
2657 NdisMoveMemory(&pAd->StaCfg.RSN_IE[0], extra, pAd->StaCfg.RSNIE_Len);
2658 }
2659 else
2660 {
2661 pAd->StaCfg.RSNIE_Len = 0;
2662 NdisZeroMemory(&pAd->StaCfg.RSN_IE[0], MAX_LEN_OF_RSNIE);
2663 }
2664
2665 return 0;
2666}
2667#endif // SIOCSIWGENIE //
2668
2669int rt_ioctl_giwgenie(struct net_device *dev,
2670 struct iw_request_info *info,
2671 union iwreq_data *wrqu, char *extra)
2672{
2673 PRTMP_ADAPTER pAd = dev->ml_priv;
2674
2675 if ((pAd->StaCfg.RSNIE_Len == 0) ||
2676 (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA))
2677 {
2678 wrqu->data.length = 0;
2679 return 0;
2680 }
2681
2682#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
2683#ifdef SIOCSIWGENIE
2684 if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
2685 {
2686 if (wrqu->data.length < pAd->StaCfg.RSNIE_Len)
2687 return -E2BIG;
2688
2689 wrqu->data.length = pAd->StaCfg.RSNIE_Len;
2690 memcpy(extra, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
2691 }
2692 else
2693#endif // SIOCSIWGENIE //
2694#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2695 {
2696 UCHAR RSNIe = IE_WPA;
2697
2698 if (wrqu->data.length < (pAd->StaCfg.RSNIE_Len + 2)) // ID, Len
2699 return -E2BIG;
2700 wrqu->data.length = pAd->StaCfg.RSNIE_Len + 2;
2701
2702 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
2703 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2))
2704 RSNIe = IE_RSN;
2705
2706 extra[0] = (char)RSNIe;
2707 extra[1] = pAd->StaCfg.RSNIE_Len;
2708 memcpy(extra+2, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
2709 }
2710
2711 return 0;
2712}
2713
2714int rt_ioctl_siwpmksa(struct net_device *dev,
2715 struct iw_request_info *info,
2716 union iwreq_data *wrqu,
2717 char *extra)
2718{
2719 PRTMP_ADAPTER pAd = dev->ml_priv;
2720 struct iw_pmksa *pPmksa = (struct iw_pmksa *)wrqu->data.pointer;
2721 INT CachedIdx = 0, idx = 0;
2722
2723 if (pPmksa == NULL)
2724 return -EINVAL;
2725
2726 DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_siwpmksa\n"));
2727 switch(pPmksa->cmd)
2728 {
2729 case IW_PMKSA_FLUSH:
2730 NdisZeroMemory(pAd->StaCfg.SavedPMK, sizeof(BSSID_INFO)*PMKID_NO);
2731 DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_FLUSH\n"));
2732 break;
2733 case IW_PMKSA_REMOVE:
2734 for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++)
2735 {
2736 // compare the BSSID
2737 if (NdisEqualMemory(pPmksa->bssid.sa_data, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN))
2738 {
2739 NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN);
2740 NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].PMKID, 16);
2741 for (idx = CachedIdx; idx < (pAd->StaCfg.SavedPMKNum - 1); idx++)
2742 {
2743 NdisMoveMemory(&pAd->StaCfg.SavedPMK[idx].BSSID[0], &pAd->StaCfg.SavedPMK[idx+1].BSSID[0], MAC_ADDR_LEN);
2744 NdisMoveMemory(&pAd->StaCfg.SavedPMK[idx].PMKID[0], &pAd->StaCfg.SavedPMK[idx+1].PMKID[0], 16);
2745 }
2746 pAd->StaCfg.SavedPMKNum--;
2747 break;
2748 }
2749 }
2750
2751 DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_REMOVE\n"));
2752 break;
2753 case IW_PMKSA_ADD:
2754 for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++)
2755 {
2756 // compare the BSSID
2757 if (NdisEqualMemory(pPmksa->bssid.sa_data, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN))
2758 break;
2759 }
2760
2761 // Found, replace it
2762 if (CachedIdx < PMKID_NO)
2763 {
2764 DBGPRINT(RT_DEBUG_OFF, ("Update PMKID, idx = %d\n", CachedIdx));
2765 NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].BSSID[0], pPmksa->bssid.sa_data, MAC_ADDR_LEN);
2766 NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].PMKID[0], pPmksa->pmkid, 16);
2767 pAd->StaCfg.SavedPMKNum++;
2768 }
2769 // Not found, replace the last one
2770 else
2771 {
2772 // Randomly replace one
2773 CachedIdx = (pPmksa->bssid.sa_data[5] % PMKID_NO);
2774 DBGPRINT(RT_DEBUG_OFF, ("Update PMKID, idx = %d\n", CachedIdx));
2775 NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].BSSID[0], pPmksa->bssid.sa_data, MAC_ADDR_LEN);
2776 NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].PMKID[0], pPmksa->pmkid, 16);
2777 }
2778
2779 DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_ADD\n"));
2780 break;
2781 default:
2782 DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - Unknow Command!!\n"));
2783 break;
2784 }
2785
2786 return 0;
2787}
2788#endif // #if WIRELESS_EXT > 17
2789
2790#ifdef DBG
2791static int
2792rt_private_ioctl_bbp(struct net_device *dev, struct iw_request_info *info,
2793 struct iw_point *wrq, char *extra)
2794 {
2795 CHAR *this_char;
2796 CHAR *value = NULL;
2797 UCHAR regBBP = 0;
2798// CHAR arg[255]={0};
2799 UINT32 bbpId;
2800 UINT32 bbpValue;
2801 BOOLEAN bIsPrintAllBBP = FALSE;
2802 INT Status = 0;
2803 PRTMP_ADAPTER pAdapter = dev->ml_priv;
2804
2805
2806 memset(extra, 0x00, IW_PRIV_SIZE_MASK);
2807
2808 if (wrq->length > 1) //No parameters.
2809 {
2810 sprintf(extra, "\n");
2811
2812 //Parsing Read or Write
2813 this_char = wrq->pointer;
2814 DBGPRINT(RT_DEBUG_TRACE, ("this_char=%s\n", this_char));
2815 if (!*this_char)
2816 goto next;
2817
2818 if ((value = rtstrchr(this_char, '=')) != NULL)
2819 *value++ = 0;
2820
2821 if (!value || !*value)
2822 { //Read
2823 DBGPRINT(RT_DEBUG_TRACE, ("this_char=%s, value=%s\n", this_char, value));
2824 if (sscanf(this_char, "%d", &(bbpId)) == 1)
2825 {
2826#ifndef RT30xx
2827 if (bbpId <= 136)
2828#endif // RT30xx //
2829#ifdef RT30xx
2830 if (bbpId <= 138) // edit by johnli, RF power sequence setup, add BBP R138 for ADC dynamic on/off control
2831#endif // RT30xx //
2832 {
2833#ifdef RALINK_ATE
2834 if (ATE_ON(pAdapter))
2835 {
2836 ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2837 }
2838 else
2839#endif // RALINK_ATE //
2840 {
2841 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2842 }
2843 sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X\n", bbpId, bbpId*2, regBBP);
2844 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2845 DBGPRINT(RT_DEBUG_TRACE, ("msg=%s\n", extra));
2846 }
2847 else
2848 {//Invalid parametes, so default printk all bbp
2849 bIsPrintAllBBP = TRUE;
2850 goto next;
2851 }
2852 }
2853 else
2854 { //Invalid parametes, so default printk all bbp
2855 bIsPrintAllBBP = TRUE;
2856 goto next;
2857 }
2858 }
2859 else
2860 { //Write
2861 if ((sscanf(this_char, "%d", &(bbpId)) == 1) && (sscanf(value, "%x", &(bbpValue)) == 1))
2862 {
2863#ifndef RT30xx
2864 if (bbpId <= 136)
2865#endif // RT30xx //
2866#ifdef RT30xx
2867 if (bbpId <= 138) // edit by johnli, RF power sequence setup, add BBP R138 for ADC dynamic on/off control
2868#endif // RT30xx //
2869 {
2870#ifdef RALINK_ATE
2871 if (ATE_ON(pAdapter))
2872 {
2873 ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, bbpId, bbpValue);
2874 //Read it back for showing
2875 ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2876 }
2877 else
2878#endif // RALINK_ATE //
2879 {
2880 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, bbpId, bbpValue);
2881 //Read it back for showing
2882 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2883 }
2884 sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X\n", bbpId, bbpId*2, regBBP);
2885 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2886 DBGPRINT(RT_DEBUG_TRACE, ("msg=%s\n", extra));
2887 }
2888 else
2889 {//Invalid parametes, so default printk all bbp
2890 bIsPrintAllBBP = TRUE;
2891 goto next;
2892 }
2893 }
2894 else
2895 { //Invalid parametes, so default printk all bbp
2896 bIsPrintAllBBP = TRUE;
2897 goto next;
2898 }
2899 }
2900 }
2901 else
2902 bIsPrintAllBBP = TRUE;
2903
2904next:
2905 if (bIsPrintAllBBP)
2906 {
2907 memset(extra, 0x00, IW_PRIV_SIZE_MASK);
2908 sprintf(extra, "\n");
2909#ifndef RT30xx
2910 for (bbpId = 0; bbpId <= 136; bbpId++)
2911#endif // RT30xx //
2912#ifdef RT30xx
2913 for (bbpId = 0; bbpId <= 138; bbpId++) // edit by johnli, RF power sequence setup, add BBP R138 for ADC dynamic on/off control
2914#endif // RT30xx //
2915 {
2916 if (strlen(extra) >= (IW_PRIV_SIZE_MASK - 10))
2917 break;
2918#ifdef RALINK_ATE
2919 if (ATE_ON(pAdapter))
2920 {
2921 ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2922 }
2923 else
2924#endif // RALINK_ATE //
2925 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2926/*
2927 sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X ", bbpId, bbpId*2, regBBP);
2928 if (bbpId%5 == 4)
2929 sprintf(extra+strlen(extra), "\n");
2930*/
2931 sprintf(extra+strlen(extra), "%03d = %02X\n", bbpId, regBBP); // edit by johnli, change display format
2932 }
2933
2934 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2935 DBGPRINT(RT_DEBUG_TRACE, ("wrq->length = %d\n", wrq->length));
2936 }
2937
2938 DBGPRINT(RT_DEBUG_TRACE, ("<==rt_private_ioctl_bbp\n\n"));
2939
2940 return Status;
2941}
2942#endif // DBG //
2943
2944int rt_ioctl_siwrate(struct net_device *dev,
2945 struct iw_request_info *info,
2946 union iwreq_data *wrqu, char *extra)
2947{
2948 PRTMP_ADAPTER pAd = dev->ml_priv;
2949 UINT32 rate = wrqu->bitrate.value, fixed = wrqu->bitrate.fixed;
2950
2951 //check if the interface is down
2952 if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2953 {
2954 DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::Network is down!\n"));
2955 return -ENETDOWN;
2956 }
2957
2958 DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::(rate = %d, fixed = %d)\n", rate, fixed));
2959 /* rate = -1 => auto rate
2960 rate = X, fixed = 1 => (fixed rate X)
2961 */
2962 if (rate == -1)
2963 {
2964 //Auto Rate
2965 pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
2966 pAd->StaCfg.bAutoTxRateSwitch = TRUE;
2967 if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
2968 (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM))
2969 RTMPSetDesiredRates(pAd, -1);
2970
2971#ifdef DOT11_N_SUPPORT
2972 SetCommonHT(pAd);
2973#endif // DOT11_N_SUPPORT //
2974 }
2975 else
2976 {
2977 if (fixed)
2978 {
2979 pAd->StaCfg.bAutoTxRateSwitch = FALSE;
2980 if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
2981 (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM))
2982 RTMPSetDesiredRates(pAd, rate);
2983 else
2984 {
2985 pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
2986#ifdef DOT11_N_SUPPORT
2987 SetCommonHT(pAd);
2988#endif // DOT11_N_SUPPORT //
2989 }
2990 DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::(HtMcs=%d)\n",pAd->StaCfg.DesiredTransmitSetting.field.MCS));
2991 }
2992 else
2993 {
2994 // TODO: rate = X, fixed = 0 => (rates <= X)
2995 return -EOPNOTSUPP;
2996 }
2997 }
2998
2999 return 0;
3000}
3001
3002int rt_ioctl_giwrate(struct net_device *dev,
3003 struct iw_request_info *info,
3004 union iwreq_data *wrqu, char *extra)
3005{
3006 PRTMP_ADAPTER pAd = dev->ml_priv;
3007 int rate_index = 0, rate_count = 0;
3008 HTTRANSMIT_SETTING ht_setting;
3009 __s32 ralinkrate[] =
3010 {2, 4, 11, 22, // CCK
3011 12, 18, 24, 36, 48, 72, 96, 108, // OFDM
3012 13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234, 260, // 20MHz, 800ns GI, MCS: 0 ~ 15
3013 39, 78, 117, 156, 234, 312, 351, 390, // 20MHz, 800ns GI, MCS: 16 ~ 23
3014 27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540, // 40MHz, 800ns GI, MCS: 0 ~ 15
3015 81, 162, 243, 324, 486, 648, 729, 810, // 40MHz, 800ns GI, MCS: 16 ~ 23
3016 14, 29, 43, 57, 87, 115, 130, 144, 29, 59, 87, 115, 173, 230, 260, 288, // 20MHz, 400ns GI, MCS: 0 ~ 15
3017 43, 87, 130, 173, 260, 317, 390, 433, // 20MHz, 400ns GI, MCS: 16 ~ 23
3018 30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600, // 40MHz, 400ns GI, MCS: 0 ~ 15
3019 90, 180, 270, 360, 540, 720, 810, 900}; // 40MHz, 400ns GI, MCS: 16 ~ 23
3020
3021 rate_count = sizeof(ralinkrate)/sizeof(__s32);
3022 //check if the interface is down
3023 if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
3024 {
3025 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
3026 return -ENETDOWN;
3027 }
3028
3029 if ((pAd->StaCfg.bAutoTxRateSwitch == FALSE) &&
3030 (INFRA_ON(pAd)) &&
3031 ((pAd->CommonCfg.PhyMode <= PHY_11G) || (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM)))
3032 ht_setting.word = pAd->StaCfg.HTPhyMode.word;
3033 else
3034 ht_setting.word = pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word;
3035
3036#ifdef DOT11_N_SUPPORT
3037 if (ht_setting.field.MODE >= MODE_HTMIX)
3038 {
3039// rate_index = 12 + ((UCHAR)ht_setting.field.BW *16) + ((UCHAR)ht_setting.field.ShortGI *32) + ((UCHAR)ht_setting.field.MCS);
3040 rate_index = 12 + ((UCHAR)ht_setting.field.BW *24) + ((UCHAR)ht_setting.field.ShortGI *48) + ((UCHAR)ht_setting.field.MCS);
3041 }
3042 else
3043#endif // DOT11_N_SUPPORT //
3044 if (ht_setting.field.MODE == MODE_OFDM)
3045 rate_index = (UCHAR)(ht_setting.field.MCS) + 4;
3046 else if (ht_setting.field.MODE == MODE_CCK)
3047 rate_index = (UCHAR)(ht_setting.field.MCS);
3048
3049 if (rate_index < 0)
3050 rate_index = 0;
3051
3052 if (rate_index > rate_count)
3053 rate_index = rate_count;
3054
3055 wrqu->bitrate.value = ralinkrate[rate_index] * 500000;
3056 wrqu->bitrate.disabled = 0;
3057
3058 return 0;
3059}
3060
3061static const iw_handler rt_handler[] =
3062{
3063 (iw_handler) NULL, /* SIOCSIWCOMMIT */
3064 (iw_handler) rt_ioctl_giwname, /* SIOCGIWNAME */
3065 (iw_handler) NULL, /* SIOCSIWNWID */
3066 (iw_handler) NULL, /* SIOCGIWNWID */
3067 (iw_handler) rt_ioctl_siwfreq, /* SIOCSIWFREQ */
3068 (iw_handler) rt_ioctl_giwfreq, /* SIOCGIWFREQ */
3069 (iw_handler) rt_ioctl_siwmode, /* SIOCSIWMODE */
3070 (iw_handler) rt_ioctl_giwmode, /* SIOCGIWMODE */
3071 (iw_handler) NULL, /* SIOCSIWSENS */
3072 (iw_handler) NULL, /* SIOCGIWSENS */
3073 (iw_handler) NULL /* not used */, /* SIOCSIWRANGE */
3074 (iw_handler) rt_ioctl_giwrange, /* SIOCGIWRANGE */
3075 (iw_handler) NULL /* not used */, /* SIOCSIWPRIV */
3076 (iw_handler) NULL /* kernel code */, /* SIOCGIWPRIV */
3077 (iw_handler) NULL /* not used */, /* SIOCSIWSTATS */
3078 (iw_handler) rt28xx_get_wireless_stats /* kernel code */, /* SIOCGIWSTATS */
3079 (iw_handler) NULL, /* SIOCSIWSPY */
3080 (iw_handler) NULL, /* SIOCGIWSPY */
3081 (iw_handler) NULL, /* SIOCSIWTHRSPY */
3082 (iw_handler) NULL, /* SIOCGIWTHRSPY */
3083 (iw_handler) rt_ioctl_siwap, /* SIOCSIWAP */
3084 (iw_handler) rt_ioctl_giwap, /* SIOCGIWAP */
3085#ifdef SIOCSIWMLME
3086 (iw_handler) rt_ioctl_siwmlme, /* SIOCSIWMLME */
3087#else
3088 (iw_handler) NULL, /* SIOCSIWMLME */
3089#endif // SIOCSIWMLME //
3090 (iw_handler) rt_ioctl_iwaplist, /* SIOCGIWAPLIST */
3091#ifdef SIOCGIWSCAN
3092 (iw_handler) rt_ioctl_siwscan, /* SIOCSIWSCAN */
3093 (iw_handler) rt_ioctl_giwscan, /* SIOCGIWSCAN */
3094#else
3095 (iw_handler) NULL, /* SIOCSIWSCAN */
3096 (iw_handler) NULL, /* SIOCGIWSCAN */
3097#endif /* SIOCGIWSCAN */
3098 (iw_handler) rt_ioctl_siwessid, /* SIOCSIWESSID */
3099 (iw_handler) rt_ioctl_giwessid, /* SIOCGIWESSID */
3100 (iw_handler) rt_ioctl_siwnickn, /* SIOCSIWNICKN */
3101 (iw_handler) rt_ioctl_giwnickn, /* SIOCGIWNICKN */
3102 (iw_handler) NULL, /* -- hole -- */
3103 (iw_handler) NULL, /* -- hole -- */
3104 (iw_handler) rt_ioctl_siwrate, /* SIOCSIWRATE */
3105 (iw_handler) rt_ioctl_giwrate, /* SIOCGIWRATE */
3106 (iw_handler) rt_ioctl_siwrts, /* SIOCSIWRTS */
3107 (iw_handler) rt_ioctl_giwrts, /* SIOCGIWRTS */
3108 (iw_handler) rt_ioctl_siwfrag, /* SIOCSIWFRAG */
3109 (iw_handler) rt_ioctl_giwfrag, /* SIOCGIWFRAG */
3110 (iw_handler) NULL, /* SIOCSIWTXPOW */
3111 (iw_handler) NULL, /* SIOCGIWTXPOW */
3112 (iw_handler) NULL, /* SIOCSIWRETRY */
3113 (iw_handler) NULL, /* SIOCGIWRETRY */
3114 (iw_handler) rt_ioctl_siwencode, /* SIOCSIWENCODE */
3115 (iw_handler) rt_ioctl_giwencode, /* SIOCGIWENCODE */
3116 (iw_handler) NULL, /* SIOCSIWPOWER */
3117 (iw_handler) NULL, /* SIOCGIWPOWER */
3118 (iw_handler) NULL, /* -- hole -- */
3119 (iw_handler) NULL, /* -- hole -- */
3120#if WIRELESS_EXT > 17
3121 (iw_handler) rt_ioctl_siwgenie, /* SIOCSIWGENIE */
3122 (iw_handler) rt_ioctl_giwgenie, /* SIOCGIWGENIE */
3123 (iw_handler) rt_ioctl_siwauth, /* SIOCSIWAUTH */
3124 (iw_handler) rt_ioctl_giwauth, /* SIOCGIWAUTH */
3125 (iw_handler) rt_ioctl_siwencodeext, /* SIOCSIWENCODEEXT */
3126 (iw_handler) rt_ioctl_giwencodeext, /* SIOCGIWENCODEEXT */
3127 (iw_handler) rt_ioctl_siwpmksa, /* SIOCSIWPMKSA */
3128#endif
3129};
3130
3131static const iw_handler rt_priv_handlers[] = {
3132 (iw_handler) NULL, /* + 0x00 */
3133 (iw_handler) NULL, /* + 0x01 */
3134#ifndef CONFIG_AP_SUPPORT
3135 (iw_handler) rt_ioctl_setparam, /* + 0x02 */
3136#else
3137 (iw_handler) NULL, /* + 0x02 */
3138#endif // CONFIG_AP_SUPPORT //
3139#ifdef DBG
3140 (iw_handler) rt_private_ioctl_bbp, /* + 0x03 */
3141#else
3142 (iw_handler) NULL, /* + 0x03 */
3143#endif
3144 (iw_handler) NULL, /* + 0x04 */
3145 (iw_handler) NULL, /* + 0x05 */
3146 (iw_handler) NULL, /* + 0x06 */
3147 (iw_handler) NULL, /* + 0x07 */
3148 (iw_handler) NULL, /* + 0x08 */
3149 (iw_handler) rt_private_get_statistics, /* + 0x09 */
3150 (iw_handler) NULL, /* + 0x0A */
3151 (iw_handler) NULL, /* + 0x0B */
3152 (iw_handler) NULL, /* + 0x0C */
3153 (iw_handler) NULL, /* + 0x0D */
3154 (iw_handler) NULL, /* + 0x0E */
3155 (iw_handler) NULL, /* + 0x0F */
3156 (iw_handler) NULL, /* + 0x10 */
3157 (iw_handler) rt_private_show, /* + 0x11 */
3158 (iw_handler) NULL, /* + 0x12 */
3159 (iw_handler) NULL, /* + 0x13 */
3160 (iw_handler) NULL, /* + 0x15 */
3161 (iw_handler) NULL, /* + 0x17 */
3162 (iw_handler) NULL, /* + 0x18 */
3163};
3164
3165const struct iw_handler_def rt28xx_iw_handler_def =
3166{
3167#define N(a) (sizeof (a) / sizeof (a[0]))
3168 .standard = (iw_handler *) rt_handler,
3169 .num_standard = sizeof(rt_handler) / sizeof(iw_handler),
3170 .private = (iw_handler *) rt_priv_handlers,
3171 .num_private = N(rt_priv_handlers),
3172 .private_args = (struct iw_priv_args *) privtab,
3173 .num_private_args = N(privtab),
3174#if IW_HANDLER_VERSION >= 7
3175 .get_wireless_stats = rt28xx_get_wireless_stats,
3176#endif
3177};
3178
3179INT RTMPSetInformation(
3180 IN PRTMP_ADAPTER pAdapter,
3181 IN OUT struct ifreq *rq,
3182 IN INT cmd)
3183{
3184 struct iwreq *wrq = (struct iwreq *) rq;
3185 NDIS_802_11_SSID Ssid;
3186 NDIS_802_11_MAC_ADDRESS Bssid;
3187 RT_802_11_PHY_MODE PhyMode;
3188 RT_802_11_STA_CONFIG StaConfig;
3189 NDIS_802_11_RATES aryRates;
3190 RT_802_11_PREAMBLE Preamble;
3191 NDIS_802_11_WEP_STATUS WepStatus;
3192 NDIS_802_11_AUTHENTICATION_MODE AuthMode = Ndis802_11AuthModeMax;
3193 NDIS_802_11_NETWORK_INFRASTRUCTURE BssType;
3194 NDIS_802_11_RTS_THRESHOLD RtsThresh;
3195 NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh;
3196 NDIS_802_11_POWER_MODE PowerMode;
3197 PNDIS_802_11_KEY pKey = NULL;
3198 PNDIS_802_11_WEP pWepKey =NULL;
3199 PNDIS_802_11_REMOVE_KEY pRemoveKey = NULL;
3200 NDIS_802_11_CONFIGURATION Config, *pConfig = NULL;
3201 NDIS_802_11_NETWORK_TYPE NetType;
3202 ULONG Now;
3203 UINT KeyIdx = 0;
3204 INT Status = NDIS_STATUS_SUCCESS, MaxPhyMode = PHY_11G;
3205 ULONG PowerTemp;
3206 BOOLEAN RadioState;
3207 BOOLEAN StateMachineTouched = FALSE;
3208#ifdef DOT11_N_SUPPORT
3209 OID_SET_HT_PHYMODE HT_PhyMode; //11n ,kathy
3210#endif // DOT11_N_SUPPORT //
3211#ifdef WPA_SUPPLICANT_SUPPORT
3212 PNDIS_802_11_PMKID pPmkId = NULL;
3213 BOOLEAN IEEE8021xState = FALSE;
3214 BOOLEAN IEEE8021x_required_keys = FALSE;
3215 UCHAR wpa_supplicant_enable = 0;
3216#endif // WPA_SUPPLICANT_SUPPORT //
3217
3218#ifdef SNMP_SUPPORT
3219 TX_RTY_CFG_STRUC tx_rty_cfg;
3220 ULONG ShortRetryLimit, LongRetryLimit;
3221 UCHAR ctmp;
3222#endif // SNMP_SUPPORT //
3223
3224
3225#ifdef DOT11_N_SUPPORT
3226 MaxPhyMode = PHY_11N_5G;
3227#endif // DOT11_N_SUPPORT //
3228
3229
3230 DBGPRINT(RT_DEBUG_TRACE, ("-->RTMPSetInformation(), 0x%08x\n", cmd&0x7FFF));
3231 switch(cmd & 0x7FFF) {
3232 case RT_OID_802_11_COUNTRY_REGION:
3233 if (wrq->u.data.length < sizeof(UCHAR))
3234 Status = -EINVAL;
3235 // Only avaliable when EEPROM not programming
3236 else if (!(pAdapter->CommonCfg.CountryRegion & 0x80) && !(pAdapter->CommonCfg.CountryRegionForABand & 0x80))
3237 {
3238 ULONG Country;
3239 UCHAR TmpPhy;
3240
3241 Status = copy_from_user(&Country, wrq->u.data.pointer, wrq->u.data.length);
3242 pAdapter->CommonCfg.CountryRegion = (UCHAR)(Country & 0x000000FF);
3243 pAdapter->CommonCfg.CountryRegionForABand = (UCHAR)((Country >> 8) & 0x000000FF);
3244 TmpPhy = pAdapter->CommonCfg.PhyMode;
3245 pAdapter->CommonCfg.PhyMode = 0xff;
3246 // Build all corresponding channel information
3247 RTMPSetPhyMode(pAdapter, TmpPhy);
3248#ifdef DOT11_N_SUPPORT
3249 SetCommonHT(pAdapter);
3250#endif // DOT11_N_SUPPORT //
3251 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_COUNTRY_REGION (A:%d B/G:%d)\n", pAdapter->CommonCfg.CountryRegionForABand,
3252 pAdapter->CommonCfg.CountryRegion));
3253 }
3254 break;
3255 case OID_802_11_BSSID_LIST_SCAN:
3256 #ifdef RALINK_ATE
3257 if (ATE_ON(pAdapter))
3258 {
3259 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
3260 break;
3261 }
3262#endif // RALINK_ATE //
3263 Now = jiffies;
3264 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_BSSID_LIST_SCAN, TxCnt = %d \n", pAdapter->RalinkCounters.LastOneSecTotalTxCount));
3265
3266 if (MONITOR_ON(pAdapter))
3267 {
3268 DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is in Monitor Mode now !!!\n"));
3269 break;
3270 }
3271
3272 //Benson add 20080527, when radio off, sta don't need to scan
3273 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RADIO_OFF))
3274 break;
3275
3276 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
3277 {
3278 DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is scanning now !!!\n"));
3279 pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
3280 Status = NDIS_STATUS_SUCCESS;
3281 break;
3282 }
3283
3284 if (pAdapter->RalinkCounters.LastOneSecTotalTxCount > 100)
3285 {
3286 DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
3287 Status = NDIS_STATUS_SUCCESS;
3288 pAdapter->StaCfg.ScanCnt = 99; // Prevent auto scan triggered by this OID
3289 break;
3290 }
3291
3292 if ((OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED)) &&
3293 ((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
3294 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
3295 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
3296 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) &&
3297 (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
3298 {
3299 DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, Port Not Secured! ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
3300 Status = NDIS_STATUS_SUCCESS;
3301 pAdapter->StaCfg.ScanCnt = 99; // Prevent auto scan triggered by this OID
3302 break;
3303 }
3304
3305
3306 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
3307 {
3308 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
3309 DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
3310 }
3311
3312 // tell CNTL state machine to call NdisMSetInformationComplete() after completing
3313 // this request, because this request is initiated by NDIS.
3314 pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
3315 // Reset allowed scan retries
3316 pAdapter->StaCfg.ScanCnt = 0;
3317 pAdapter->StaCfg.LastScanTime = Now;
3318
3319 pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
3320 RTMP_SET_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
3321 MlmeEnqueue(pAdapter,
3322 MLME_CNTL_STATE_MACHINE,
3323 OID_802_11_BSSID_LIST_SCAN,
3324 0,
3325 NULL);
3326
3327 Status = NDIS_STATUS_SUCCESS;
3328 StateMachineTouched = TRUE;
3329 break;
3330 case OID_802_11_SSID:
3331 if (wrq->u.data.length != sizeof(NDIS_802_11_SSID))
3332 Status = -EINVAL;
3333 else
3334 {
3335 PCHAR pSsidString = NULL;
3336 Status = copy_from_user(&Ssid, wrq->u.data.pointer, wrq->u.data.length);
3337
3338 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SSID (Len=%d,Ssid=%s)\n", Ssid.SsidLength, Ssid.Ssid));
3339 if (Ssid.SsidLength > MAX_LEN_OF_SSID)
3340 Status = -EINVAL;
3341 else
3342 {
3343 if (Ssid.SsidLength == 0)
3344 {
3345 Set_SSID_Proc(pAdapter, "");
3346 }
3347 else
3348 {
3349 pSsidString = (CHAR *) kmalloc(MAX_LEN_OF_SSID+1, MEM_ALLOC_FLAG);
3350 if (pSsidString)
3351 {
3352 NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID+1);
3353 NdisMoveMemory(pSsidString, Ssid.Ssid, Ssid.SsidLength);
3354 Set_SSID_Proc(pAdapter, pSsidString);
3355 kfree(pSsidString);
3356 }
3357 else
3358 Status = -ENOMEM;
3359 }
3360 }
3361 }
3362 break;
3363 case OID_802_11_BSSID:
3364#ifdef RALINK_ATE
3365 if (ATE_ON(pAdapter))
3366 {
3367 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
3368 break;
3369 }
3370#endif // RALINK_ATE //
3371 if (wrq->u.data.length != sizeof(NDIS_802_11_MAC_ADDRESS))
3372 Status = -EINVAL;
3373 else
3374 {
3375 Status = copy_from_user(&Bssid, wrq->u.data.pointer, wrq->u.data.length);
3376
3377 // tell CNTL state machine to call NdisMSetInformationComplete() after completing
3378 // this request, because this request is initiated by NDIS.
3379 pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
3380
3381 // Prevent to connect AP again in STAMlmePeriodicExec
3382 pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
3383
3384 // Reset allowed scan retries
3385 pAdapter->StaCfg.ScanCnt = 0;
3386
3387 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
3388 {
3389 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
3390 DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
3391 }
3392 MlmeEnqueue(pAdapter,
3393 MLME_CNTL_STATE_MACHINE,
3394 OID_802_11_BSSID,
3395 sizeof(NDIS_802_11_MAC_ADDRESS),
3396 (VOID *)&Bssid);
3397 Status = NDIS_STATUS_SUCCESS;
3398 StateMachineTouched = TRUE;
3399
3400 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_BSSID %02x:%02x:%02x:%02x:%02x:%02x\n",
3401 Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
3402 }
3403 break;
3404 case RT_OID_802_11_RADIO:
3405 if (wrq->u.data.length != sizeof(BOOLEAN))
3406 Status = -EINVAL;
3407 else
3408 {
3409 Status = copy_from_user(&RadioState, wrq->u.data.pointer, wrq->u.data.length);
3410 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_RADIO (=%d)\n", RadioState));
3411 if (pAdapter->StaCfg.bSwRadio != RadioState)
3412 {
3413 pAdapter->StaCfg.bSwRadio = RadioState;
3414 if (pAdapter->StaCfg.bRadio != (pAdapter->StaCfg.bHwRadio && pAdapter->StaCfg.bSwRadio))
3415 {
3416 pAdapter->StaCfg.bRadio = (pAdapter->StaCfg.bHwRadio && pAdapter->StaCfg.bSwRadio);
3417 if (pAdapter->StaCfg.bRadio == TRUE)
3418 {
3419 MlmeRadioOn(pAdapter);
3420 // Update extra information
3421 pAdapter->ExtraInfo = EXTRA_INFO_CLEAR;
3422 }
3423 else
3424 {
3425 MlmeRadioOff(pAdapter);
3426 // Update extra information
3427 pAdapter->ExtraInfo = SW_RADIO_OFF;
3428 }
3429 }
3430 }
3431 }
3432 break;
3433 case RT_OID_802_11_PHY_MODE:
3434 if (wrq->u.data.length != sizeof(RT_802_11_PHY_MODE))
3435 Status = -EINVAL;
3436 else
3437 {
3438 Status = copy_from_user(&PhyMode, wrq->u.data.pointer, wrq->u.data.length);
3439 if (PhyMode <= MaxPhyMode)
3440 {
3441 RTMPSetPhyMode(pAdapter, PhyMode);
3442#ifdef DOT11_N_SUPPORT
3443 SetCommonHT(pAdapter);
3444#endif // DOT11_N_SUPPORT //
3445 }
3446 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_PHY_MODE (=%d)\n", PhyMode));
3447 }
3448 break;
3449 case RT_OID_802_11_STA_CONFIG:
3450 if (wrq->u.data.length != sizeof(RT_802_11_STA_CONFIG))
3451 Status = -EINVAL;
3452 else
3453 {
3454 Status = copy_from_user(&StaConfig, wrq->u.data.pointer, wrq->u.data.length);
3455 pAdapter->CommonCfg.bEnableTxBurst = StaConfig.EnableTxBurst;
3456 pAdapter->CommonCfg.UseBGProtection = StaConfig.UseBGProtection;
3457 pAdapter->CommonCfg.bUseShortSlotTime = 1; // 2003-10-30 always SHORT SLOT capable
3458 if ((pAdapter->CommonCfg.PhyMode != StaConfig.AdhocMode) &&
3459 (StaConfig.AdhocMode <= MaxPhyMode))
3460 {
3461 // allow dynamic change of "USE OFDM rate or not" in ADHOC mode
3462 // if setting changed, need to reset current TX rate as well as BEACON frame format
3463 pAdapter->CommonCfg.PhyMode = StaConfig.AdhocMode;
3464 if (pAdapter->StaCfg.BssType == BSS_ADHOC)
3465 {
3466 RTMPSetPhyMode(pAdapter, PhyMode);
3467 MlmeUpdateTxRates(pAdapter, FALSE, 0);
3468 MakeIbssBeacon(pAdapter); // re-build BEACON frame
3469 AsicEnableIbssSync(pAdapter); // copy to on-chip memory
3470 }
3471 }
3472 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_STA_CONFIG (Burst=%d, Protection=%ld,ShortSlot=%d\n",
3473 pAdapter->CommonCfg.bEnableTxBurst,
3474 pAdapter->CommonCfg.UseBGProtection,
3475 pAdapter->CommonCfg.bUseShortSlotTime));
3476 }
3477 break;
3478 case OID_802_11_DESIRED_RATES:
3479 if (wrq->u.data.length != sizeof(NDIS_802_11_RATES))
3480 Status = -EINVAL;
3481 else
3482 {
3483 Status = copy_from_user(&aryRates, wrq->u.data.pointer, wrq->u.data.length);
3484 NdisZeroMemory(pAdapter->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
3485 NdisMoveMemory(pAdapter->CommonCfg.DesireRate, &aryRates, sizeof(NDIS_802_11_RATES));
3486 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DESIRED_RATES (%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x)\n",
3487 pAdapter->CommonCfg.DesireRate[0],pAdapter->CommonCfg.DesireRate[1],
3488 pAdapter->CommonCfg.DesireRate[2],pAdapter->CommonCfg.DesireRate[3],
3489 pAdapter->CommonCfg.DesireRate[4],pAdapter->CommonCfg.DesireRate[5],
3490 pAdapter->CommonCfg.DesireRate[6],pAdapter->CommonCfg.DesireRate[7] ));
3491 // Changing DesiredRate may affect the MAX TX rate we used to TX frames out
3492 MlmeUpdateTxRates(pAdapter, FALSE, 0);
3493 }
3494 break;
3495 case RT_OID_802_11_PREAMBLE:
3496 if (wrq->u.data.length != sizeof(RT_802_11_PREAMBLE))
3497 Status = -EINVAL;
3498 else
3499 {
3500 Status = copy_from_user(&Preamble, wrq->u.data.pointer, wrq->u.data.length);
3501 if (Preamble == Rt802_11PreambleShort)
3502 {
3503 pAdapter->CommonCfg.TxPreamble = Preamble;
3504 MlmeSetTxPreamble(pAdapter, Rt802_11PreambleShort);
3505 }
3506 else if ((Preamble == Rt802_11PreambleLong) || (Preamble == Rt802_11PreambleAuto))
3507 {
3508 // if user wants AUTO, initialize to LONG here, then change according to AP's
3509 // capability upon association.
3510 pAdapter->CommonCfg.TxPreamble = Preamble;
3511 MlmeSetTxPreamble(pAdapter, Rt802_11PreambleLong);
3512 }
3513 else
3514 {
3515 Status = -EINVAL;
3516 break;
3517 }
3518 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_PREAMBLE (=%d)\n", Preamble));
3519 }
3520 break;
3521 case OID_802_11_WEP_STATUS:
3522 if (wrq->u.data.length != sizeof(NDIS_802_11_WEP_STATUS))
3523 Status = -EINVAL;
3524 else
3525 {
3526 Status = copy_from_user(&WepStatus, wrq->u.data.pointer, wrq->u.data.length);
3527 // Since TKIP, AES, WEP are all supported. It should not have any invalid setting
3528 if (WepStatus <= Ndis802_11Encryption3KeyAbsent)
3529 {
3530 if (pAdapter->StaCfg.WepStatus != WepStatus)
3531 {
3532 // Config has changed
3533 pAdapter->bConfigChanged = TRUE;
3534 }
3535 pAdapter->StaCfg.WepStatus = WepStatus;
3536 pAdapter->StaCfg.OrigWepStatus = WepStatus;
3537 pAdapter->StaCfg.PairCipher = WepStatus;
3538 pAdapter->StaCfg.GroupCipher = WepStatus;
3539 }
3540 else
3541 {
3542 Status = -EINVAL;
3543 break;
3544 }
3545 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEP_STATUS (=%d)\n",WepStatus));
3546 }
3547 break;
3548 case OID_802_11_AUTHENTICATION_MODE:
3549 if (wrq->u.data.length != sizeof(NDIS_802_11_AUTHENTICATION_MODE))
3550 Status = -EINVAL;
3551 else
3552 {
3553 Status = copy_from_user(&AuthMode, wrq->u.data.pointer, wrq->u.data.length);
3554 if (AuthMode > Ndis802_11AuthModeMax)
3555 {
3556 Status = -EINVAL;
3557 break;
3558 }
3559 else
3560 {
3561 if (pAdapter->StaCfg.AuthMode != AuthMode)
3562 {
3563 // Config has changed
3564 pAdapter->bConfigChanged = TRUE;
3565 }
3566 pAdapter->StaCfg.AuthMode = AuthMode;
3567 }
3568 pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
3569 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_AUTHENTICATION_MODE (=%d) \n",pAdapter->StaCfg.AuthMode));
3570 }
3571 break;
3572 case OID_802_11_INFRASTRUCTURE_MODE:
3573 if (wrq->u.data.length != sizeof(NDIS_802_11_NETWORK_INFRASTRUCTURE))
3574 Status = -EINVAL;
3575 else
3576 {
3577 Status = copy_from_user(&BssType, wrq->u.data.pointer, wrq->u.data.length);
3578
3579 if (BssType == Ndis802_11IBSS)
3580 Set_NetworkType_Proc(pAdapter, "Adhoc");
3581 else if (BssType == Ndis802_11Infrastructure)
3582 Set_NetworkType_Proc(pAdapter, "Infra");
3583 else if (BssType == Ndis802_11Monitor)
3584 Set_NetworkType_Proc(pAdapter, "Monitor");
3585 else
3586 {
3587 Status = -EINVAL;
3588 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_INFRASTRUCTURE_MODE (unknown)\n"));
3589 }
3590 }
3591 break;
3592 case OID_802_11_REMOVE_WEP:
3593 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_WEP\n"));
3594 if (wrq->u.data.length != sizeof(NDIS_802_11_KEY_INDEX))
3595 {
3596 Status = -EINVAL;
3597 }
3598 else
3599 {
3600 KeyIdx = *(NDIS_802_11_KEY_INDEX *) wrq->u.data.pointer;
3601
3602 if (KeyIdx & 0x80000000)
3603 {
3604 // Should never set default bit when remove key
3605 Status = -EINVAL;
3606 }
3607 else
3608 {
3609 KeyIdx = KeyIdx & 0x0fffffff;
3610 if (KeyIdx >= 4){
3611 Status = -EINVAL;
3612 }
3613 else
3614 {
3615 pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = 0;
3616 pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
3617 AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)KeyIdx);
3618 }
3619 }
3620 }
3621 break;
3622 case RT_OID_802_11_RESET_COUNTERS:
3623 NdisZeroMemory(&pAdapter->WlanCounters, sizeof(COUNTER_802_11));
3624 NdisZeroMemory(&pAdapter->Counters8023, sizeof(COUNTER_802_3));
3625 NdisZeroMemory(&pAdapter->RalinkCounters, sizeof(COUNTER_RALINK));
3626 pAdapter->Counters8023.RxNoBuffer = 0;
3627 pAdapter->Counters8023.GoodReceives = 0;
3628 pAdapter->Counters8023.RxNoBuffer = 0;
3629#ifdef RT2870
3630 pAdapter->BulkOutComplete = 0;
3631 pAdapter->BulkOutCompleteOther= 0;
3632 pAdapter->BulkOutCompleteCancel = 0;
3633 pAdapter->BulkOutReq = 0;
3634 pAdapter->BulkInReq= 0;
3635 pAdapter->BulkInComplete = 0;
3636 pAdapter->BulkInCompleteFail = 0;
3637#endif // RT2870 //
3638 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_RESET_COUNTERS \n"));
3639 break;
3640 case OID_802_11_RTS_THRESHOLD:
3641 if (wrq->u.data.length != sizeof(NDIS_802_11_RTS_THRESHOLD))
3642 Status = -EINVAL;
3643 else
3644 {
3645 Status = copy_from_user(&RtsThresh, wrq->u.data.pointer, wrq->u.data.length);
3646 if (RtsThresh > MAX_RTS_THRESHOLD)
3647 Status = -EINVAL;
3648 else
3649 pAdapter->CommonCfg.RtsThreshold = (USHORT)RtsThresh;
3650 }
3651 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_RTS_THRESHOLD (=%ld)\n",RtsThresh));
3652 break;
3653 case OID_802_11_FRAGMENTATION_THRESHOLD:
3654 if (wrq->u.data.length != sizeof(NDIS_802_11_FRAGMENTATION_THRESHOLD))
3655 Status = -EINVAL;
3656 else
3657 {
3658 Status = copy_from_user(&FragThresh, wrq->u.data.pointer, wrq->u.data.length);
3659 pAdapter->CommonCfg.bUseZeroToDisableFragment = FALSE;
3660 if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD)
3661 {
3662 if (FragThresh == 0)
3663 {
3664 pAdapter->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD;
3665 pAdapter->CommonCfg.bUseZeroToDisableFragment = TRUE;
3666 }
3667 else
3668 Status = -EINVAL;
3669 }
3670 else
3671 pAdapter->CommonCfg.FragmentThreshold = (USHORT)FragThresh;
3672 }
3673 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_FRAGMENTATION_THRESHOLD (=%ld) \n",FragThresh));
3674 break;
3675 case OID_802_11_POWER_MODE:
3676 if (wrq->u.data.length != sizeof(NDIS_802_11_POWER_MODE))
3677 Status = -EINVAL;
3678 else
3679 {
3680 Status = copy_from_user(&PowerMode, wrq->u.data.pointer, wrq->u.data.length);
3681 if (PowerMode == Ndis802_11PowerModeCAM)
3682 Set_PSMode_Proc(pAdapter, "CAM");
3683 else if (PowerMode == Ndis802_11PowerModeMAX_PSP)
3684 Set_PSMode_Proc(pAdapter, "Max_PSP");
3685 else if (PowerMode == Ndis802_11PowerModeFast_PSP)
3686 Set_PSMode_Proc(pAdapter, "Fast_PSP");
3687 else if (PowerMode == Ndis802_11PowerModeLegacy_PSP)
3688 Set_PSMode_Proc(pAdapter, "Legacy_PSP");
3689 else
3690 Status = -EINVAL;
3691 }
3692 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_POWER_MODE (=%d)\n",PowerMode));
3693 break;
3694 case RT_OID_802_11_TX_POWER_LEVEL_1:
3695 if (wrq->u.data.length < sizeof(ULONG))
3696 Status = -EINVAL;
3697 else
3698 {
3699 Status = copy_from_user(&PowerTemp, wrq->u.data.pointer, wrq->u.data.length);
3700 if (PowerTemp > 100)
3701 PowerTemp = 0xffffffff; // AUTO
3702 pAdapter->CommonCfg.TxPowerDefault = PowerTemp; //keep current setting.
3703 pAdapter->CommonCfg.TxPowerPercentage = pAdapter->CommonCfg.TxPowerDefault;
3704 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_TX_POWER_LEVEL_1 (=%ld)\n", pAdapter->CommonCfg.TxPowerPercentage));
3705 }
3706 break;
3707 case OID_802_11_NETWORK_TYPE_IN_USE:
3708 if (wrq->u.data.length != sizeof(NDIS_802_11_NETWORK_TYPE))
3709 Status = -EINVAL;
3710 else
3711 {
3712 Status = copy_from_user(&NetType, wrq->u.data.pointer, wrq->u.data.length);
3713
3714 if (NetType == Ndis802_11DS)
3715 RTMPSetPhyMode(pAdapter, PHY_11B);
3716 else if (NetType == Ndis802_11OFDM24)
3717 RTMPSetPhyMode(pAdapter, PHY_11BG_MIXED);
3718 else if (NetType == Ndis802_11OFDM5)
3719 RTMPSetPhyMode(pAdapter, PHY_11A);
3720 else
3721 Status = -EINVAL;
3722#ifdef DOT11_N_SUPPORT
3723 if (Status == NDIS_STATUS_SUCCESS)
3724 SetCommonHT(pAdapter);
3725#endif // DOT11_N_SUPPORT //
3726 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_NETWORK_TYPE_IN_USE (=%d)\n",NetType));
3727 }
3728 break;
3729 // For WPA PSK PMK key
3730 case RT_OID_802_11_ADD_WPA:
3731 pKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
3732 if(pKey == NULL)
3733 {
3734 Status = -ENOMEM;
3735 break;
3736 }
3737
3738 Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
3739 if (pKey->Length != wrq->u.data.length)
3740 {
3741 Status = -EINVAL;
3742 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA, Failed!!\n"));
3743 }
3744 else
3745 {
3746 if ((pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
3747 (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
3748 (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone) )
3749 {
3750 Status = -EOPNOTSUPP;
3751 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA, Failed!! [AuthMode != WPAPSK/WPA2PSK/WPANONE]\n"));
3752 }
3753 else if ((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
3754 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
3755 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) ) // Only for WPA PSK mode
3756 {
3757 NdisMoveMemory(pAdapter->StaCfg.PMK, &pKey->KeyMaterial, pKey->KeyLength);
3758 // Use RaConfig as PSK agent.
3759 // Start STA supplicant state machine
3760 if (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
3761 pAdapter->StaCfg.WpaState = SS_START;
3762
3763 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
3764 }
3765 else
3766 {
3767 pAdapter->StaCfg.WpaState = SS_NOTUSE;
3768 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
3769 }
3770 }
3771 kfree(pKey);
3772 break;
3773 case OID_802_11_REMOVE_KEY:
3774 pRemoveKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
3775 if(pRemoveKey == NULL)
3776 {
3777 Status = -ENOMEM;
3778 break;
3779 }
3780
3781 Status = copy_from_user(pRemoveKey, wrq->u.data.pointer, wrq->u.data.length);
3782 if (pRemoveKey->Length != wrq->u.data.length)
3783 {
3784 Status = -EINVAL;
3785 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!\n"));
3786 }
3787 else
3788 {
3789 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3790 {
3791 RTMPWPARemoveKeyProc(pAdapter, pRemoveKey);
3792 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Remove WPA Key!!\n"));
3793 }
3794 else
3795 {
3796 KeyIdx = pRemoveKey->KeyIndex;
3797
3798 if (KeyIdx & 0x80000000)
3799 {
3800 // Should never set default bit when remove key
3801 Status = -EINVAL;
3802 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!(Should never set default bit when remove key)\n"));
3803 }
3804 else
3805 {
3806 KeyIdx = KeyIdx & 0x0fffffff;
3807 if (KeyIdx > 3)
3808 {
3809 Status = -EINVAL;
3810 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!(KeyId[%d] out of range)\n", KeyIdx));
3811 }
3812 else
3813 {
3814 pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = 0;
3815 pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
3816 AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)KeyIdx);
3817 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY (id=0x%x, Len=%d-byte)\n", pRemoveKey->KeyIndex, pRemoveKey->Length));
3818 }
3819 }
3820 }
3821 }
3822 kfree(pRemoveKey);
3823 break;
3824 // New for WPA
3825 case OID_802_11_ADD_KEY:
3826 pKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
3827 if(pKey == NULL)
3828 {
3829 Status = -ENOMEM;
3830 break;
3831 }
3832 Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
3833 if (pKey->Length != wrq->u.data.length)
3834 {
3835 Status = -EINVAL;
3836 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_KEY, Failed!!\n"));
3837 }
3838 else
3839 {
3840 RTMPAddKey(pAdapter, pKey);
3841 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_KEY (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
3842 }
3843 kfree(pKey);
3844 break;
3845 case OID_802_11_CONFIGURATION:
3846 if (wrq->u.data.length != sizeof(NDIS_802_11_CONFIGURATION))
3847 Status = -EINVAL;
3848 else
3849 {
3850 Status = copy_from_user(&Config, wrq->u.data.pointer, wrq->u.data.length);
3851 pConfig = &Config;
3852
3853 if ((pConfig->BeaconPeriod >= 20) && (pConfig->BeaconPeriod <=400))
3854 pAdapter->CommonCfg.BeaconPeriod = (USHORT) pConfig->BeaconPeriod;
3855
3856 pAdapter->StaActive.AtimWin = (USHORT) pConfig->ATIMWindow;
3857 MAP_KHZ_TO_CHANNEL_ID(pConfig->DSConfig, pAdapter->CommonCfg.Channel);
3858 //
3859 // Save the channel on MlmeAux for CntlOidRTBssidProc used.
3860 //
3861 pAdapter->MlmeAux.Channel = pAdapter->CommonCfg.Channel;
3862
3863 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_CONFIGURATION (BeacnPeriod=%ld,AtimW=%ld,Ch=%d)\n",
3864 pConfig->BeaconPeriod, pConfig->ATIMWindow, pAdapter->CommonCfg.Channel));
3865 // Config has changed
3866 pAdapter->bConfigChanged = TRUE;
3867 }
3868 break;
3869#ifdef DOT11_N_SUPPORT
3870 case RT_OID_802_11_SET_HT_PHYMODE:
3871 if (wrq->u.data.length != sizeof(OID_SET_HT_PHYMODE))
3872 Status = -EINVAL;
3873 else
3874 {
3875 POID_SET_HT_PHYMODE pHTPhyMode = &HT_PhyMode;
3876
3877 Status = copy_from_user(&HT_PhyMode, wrq->u.data.pointer, wrq->u.data.length);
3878 DBGPRINT(RT_DEBUG_TRACE, ("Set::pHTPhyMode (PhyMode = %d,TransmitNo = %d, HtMode = %d, ExtOffset = %d , MCS = %d, BW = %d, STBC = %d, SHORTGI = %d) \n",
3879 pHTPhyMode->PhyMode, pHTPhyMode->TransmitNo,pHTPhyMode->HtMode,pHTPhyMode->ExtOffset,
3880 pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->SHORTGI));
3881 if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
3882 RTMPSetHT(pAdapter, pHTPhyMode);
3883 }
3884 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_HT_PHYMODE(MCS=%d,BW=%d,SGI=%d,STBC=%d)\n",
3885 pAdapter->StaCfg.HTPhyMode.field.MCS, pAdapter->StaCfg.HTPhyMode.field.BW, pAdapter->StaCfg.HTPhyMode.field.ShortGI,
3886 pAdapter->StaCfg.HTPhyMode.field.STBC));
3887 break;
3888#endif // DOT11_N_SUPPORT //
3889 case RT_OID_802_11_SET_APSD_SETTING:
3890 if (wrq->u.data.length != sizeof(ULONG))
3891 Status = -EINVAL;
3892 else
3893 {
3894 ULONG apsd ;
3895 Status = copy_from_user(&apsd, wrq->u.data.pointer, wrq->u.data.length);
3896
3897 /*-------------------------------------------------------------------
3898 |B31~B7 | B6~B5 | B4 | B3 | B2 | B1 | B0 |
3899 ---------------------------------------------------------------------
3900 | Rsvd | Max SP Len | AC_VO | AC_VI | AC_BK | AC_BE | APSD Capable |
3901 ---------------------------------------------------------------------*/
3902 pAdapter->CommonCfg.bAPSDCapable = (apsd & 0x00000001) ? TRUE : FALSE;
3903 pAdapter->CommonCfg.bAPSDAC_BE = ((apsd & 0x00000002) >> 1) ? TRUE : FALSE;
3904 pAdapter->CommonCfg.bAPSDAC_BK = ((apsd & 0x00000004) >> 2) ? TRUE : FALSE;
3905 pAdapter->CommonCfg.bAPSDAC_VI = ((apsd & 0x00000008) >> 3) ? TRUE : FALSE;
3906 pAdapter->CommonCfg.bAPSDAC_VO = ((apsd & 0x00000010) >> 4) ? TRUE : FALSE;
3907 pAdapter->CommonCfg.MaxSPLength = (UCHAR)((apsd & 0x00000060) >> 5);
3908
3909 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_APSD_SETTING (apsd=0x%lx, APSDCap=%d, [BE,BK,VI,VO]=[%d/%d/%d/%d], MaxSPLen=%d)\n", apsd, pAdapter->CommonCfg.bAPSDCapable,
3910 pAdapter->CommonCfg.bAPSDAC_BE, pAdapter->CommonCfg.bAPSDAC_BK, pAdapter->CommonCfg.bAPSDAC_VI, pAdapter->CommonCfg.bAPSDAC_VO, pAdapter->CommonCfg.MaxSPLength));
3911 }
3912 break;
3913
3914 case RT_OID_802_11_SET_APSD_PSM:
3915 if (wrq->u.data.length != sizeof(ULONG))
3916 Status = -EINVAL;
3917 else
3918 {
3919 // Driver needs to notify AP when PSM changes
3920 Status = copy_from_user(&pAdapter->CommonCfg.bAPSDForcePowerSave, wrq->u.data.pointer, wrq->u.data.length);
3921 if (pAdapter->CommonCfg.bAPSDForcePowerSave != pAdapter->StaCfg.Psm)
3922 {
3923 MlmeSetPsmBit(pAdapter, pAdapter->CommonCfg.bAPSDForcePowerSave);
3924 RTMPSendNullFrame(pAdapter, pAdapter->CommonCfg.TxRate, TRUE);
3925 }
3926 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_APSD_PSM (bAPSDForcePowerSave:%d)\n", pAdapter->CommonCfg.bAPSDForcePowerSave));
3927 }
3928 break;
3929#ifdef QOS_DLS_SUPPORT
3930 case RT_OID_802_11_SET_DLS:
3931 if (wrq->u.data.length != sizeof(ULONG))
3932 Status = -EINVAL;
3933 else
3934 {
3935 BOOLEAN oldvalue = pAdapter->CommonCfg.bDLSCapable;
3936 Status = copy_from_user(&pAdapter->CommonCfg.bDLSCapable, wrq->u.data.pointer, wrq->u.data.length);
3937 if (oldvalue && !pAdapter->CommonCfg.bDLSCapable)
3938 {
3939 int i;
3940 // tear down local dls table entry
3941 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
3942 {
3943 if (pAdapter->StaCfg.DLSEntry[i].Valid && (pAdapter->StaCfg.DLSEntry[i].Status == DLS_FINISH))
3944 {
3945 pAdapter->StaCfg.DLSEntry[i].Status = DLS_NONE;
3946 pAdapter->StaCfg.DLSEntry[i].Valid = FALSE;
3947 RTMPSendDLSTearDownFrame(pAdapter, pAdapter->StaCfg.DLSEntry[i].MacAddr);
3948 }
3949 }
3950
3951 // tear down peer dls table entry
3952 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
3953 {
3954 if (pAdapter->StaCfg.DLSEntry[i].Valid && (pAdapter->StaCfg.DLSEntry[i].Status == DLS_FINISH))
3955 {
3956 pAdapter->StaCfg.DLSEntry[i].Status = DLS_NONE;
3957 pAdapter->StaCfg.DLSEntry[i].Valid = FALSE;
3958 RTMPSendDLSTearDownFrame(pAdapter, pAdapter->StaCfg.DLSEntry[i].MacAddr);
3959 }
3960 }
3961 }
3962
3963 DBGPRINT(RT_DEBUG_TRACE,("Set::RT_OID_802_11_SET_DLS (=%d)\n", pAdapter->CommonCfg.bDLSCapable));
3964 }
3965 break;
3966
3967 case RT_OID_802_11_SET_DLS_PARAM:
3968 if (wrq->u.data.length != sizeof(RT_802_11_DLS_UI))
3969 Status = -EINVAL;
3970 else
3971 {
3972 RT_802_11_DLS Dls;
3973
3974 NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
3975 RTMPMoveMemory(&Dls, wrq->u.data.pointer, sizeof(RT_802_11_DLS_UI));
3976 MlmeEnqueue(pAdapter,
3977 MLME_CNTL_STATE_MACHINE,
3978 RT_OID_802_11_SET_DLS_PARAM,
3979 sizeof(RT_802_11_DLS),
3980 &Dls);
3981 DBGPRINT(RT_DEBUG_TRACE,("Set::RT_OID_802_11_SET_DLS_PARAM \n"));
3982 }
3983 break;
3984#endif // QOS_DLS_SUPPORT //
3985 case RT_OID_802_11_SET_WMM:
3986 if (wrq->u.data.length != sizeof(BOOLEAN))
3987 Status = -EINVAL;
3988 else
3989 {
3990 Status = copy_from_user(&pAdapter->CommonCfg.bWmmCapable, wrq->u.data.pointer, wrq->u.data.length);
3991 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_WMM (=%d) \n", pAdapter->CommonCfg.bWmmCapable));
3992 }
3993 break;
3994
3995 case OID_802_11_DISASSOCIATE:
3996#ifdef RALINK_ATE
3997 if (ATE_ON(pAdapter))
3998 {
3999 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
4000 break;
4001 }
4002#endif // RALINK_ATE //
4003 //
4004 // Set NdisRadioStateOff to TRUE, instead of called MlmeRadioOff.
4005 // Later on, NDIS_802_11_BSSID_LIST_EX->NumberOfItems should be 0
4006 // when query OID_802_11_BSSID_LIST.
4007 //
4008 // TRUE: NumberOfItems will set to 0.
4009 // FALSE: NumberOfItems no change.
4010 //
4011 pAdapter->CommonCfg.NdisRadioStateOff = TRUE;
4012 // Set to immediately send the media disconnect event
4013 pAdapter->MlmeAux.CurrReqIsFromNdis = TRUE;
4014 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DISASSOCIATE \n"));
4015
4016 if (INFRA_ON(pAdapter))
4017 {
4018 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
4019 {
4020 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
4021 DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
4022 }
4023
4024 MlmeEnqueue(pAdapter,
4025 MLME_CNTL_STATE_MACHINE,
4026 OID_802_11_DISASSOCIATE,
4027 0,
4028 NULL);
4029
4030 StateMachineTouched = TRUE;
4031 }
4032 break;
4033
4034#ifdef DOT11_N_SUPPORT
4035 case RT_OID_802_11_SET_IMME_BA_CAP:
4036 if (wrq->u.data.length != sizeof(OID_BACAP_STRUC))
4037 Status = -EINVAL;
4038 else
4039 {
4040 OID_BACAP_STRUC Orde ;
4041 Status = copy_from_user(&Orde, wrq->u.data.pointer, wrq->u.data.length);
4042 if (Orde.Policy > BA_NOTUSE)
4043 {
4044 Status = NDIS_STATUS_INVALID_DATA;
4045 }
4046 else if (Orde.Policy == BA_NOTUSE)
4047 {
4048 pAdapter->CommonCfg.BACapability.field.Policy = BA_NOTUSE;
4049 pAdapter->CommonCfg.BACapability.field.MpduDensity = Orde.MpduDensity;
4050 pAdapter->CommonCfg.DesiredHtPhy.MpduDensity = Orde.MpduDensity;
4051 pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable = Orde.AmsduEnable;
4052 pAdapter->CommonCfg.DesiredHtPhy.AmsduSize= Orde.AmsduSize;
4053 pAdapter->CommonCfg.DesiredHtPhy.MimoPs= Orde.MMPSmode;
4054 pAdapter->CommonCfg.BACapability.field.MMPSmode = Orde.MMPSmode;
4055 // UPdata to HT IE
4056 pAdapter->CommonCfg.HtCapability.HtCapInfo.MimoPs = Orde.MMPSmode;
4057 pAdapter->CommonCfg.HtCapability.HtCapInfo.AMsduSize = Orde.AmsduSize;
4058 pAdapter->CommonCfg.HtCapability.HtCapParm.MpduDensity = Orde.MpduDensity;
4059 }
4060 else
4061 {
4062 pAdapter->CommonCfg.BACapability.field.AutoBA = Orde.AutoBA;
4063 pAdapter->CommonCfg.BACapability.field.Policy = IMMED_BA; // we only support immediate BA.
4064 pAdapter->CommonCfg.BACapability.field.MpduDensity = Orde.MpduDensity;
4065 pAdapter->CommonCfg.DesiredHtPhy.MpduDensity = Orde.MpduDensity;
4066 pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable = Orde.AmsduEnable;
4067 pAdapter->CommonCfg.DesiredHtPhy.AmsduSize= Orde.AmsduSize;
4068 pAdapter->CommonCfg.DesiredHtPhy.MimoPs = Orde.MMPSmode;
4069 pAdapter->CommonCfg.BACapability.field.MMPSmode = Orde.MMPSmode;
4070
4071 // UPdata to HT IE
4072 pAdapter->CommonCfg.HtCapability.HtCapInfo.MimoPs = Orde.MMPSmode;
4073 pAdapter->CommonCfg.HtCapability.HtCapInfo.AMsduSize = Orde.AmsduSize;
4074 pAdapter->CommonCfg.HtCapability.HtCapParm.MpduDensity = Orde.MpduDensity;
4075
4076 if (pAdapter->CommonCfg.BACapability.field.RxBAWinLimit > MAX_RX_REORDERBUF)
4077 pAdapter->CommonCfg.BACapability.field.RxBAWinLimit = MAX_RX_REORDERBUF;
4078
4079 }
4080
4081 pAdapter->CommonCfg.REGBACapability.word = pAdapter->CommonCfg.BACapability.word;
4082 DBGPRINT(RT_DEBUG_TRACE, ("Set::(Orde.AutoBA = %d) (Policy=%d)(ReBAWinLimit=%d)(TxBAWinLimit=%d)(AutoMode=%d)\n",Orde.AutoBA, pAdapter->CommonCfg.BACapability.field.Policy,
4083 pAdapter->CommonCfg.BACapability.field.RxBAWinLimit,pAdapter->CommonCfg.BACapability.field.TxBAWinLimit, pAdapter->CommonCfg.BACapability.field.AutoBA));
4084 DBGPRINT(RT_DEBUG_TRACE, ("Set::(MimoPs = %d)(AmsduEnable = %d) (AmsduSize=%d)(MpduDensity=%d)\n",pAdapter->CommonCfg.DesiredHtPhy.MimoPs, pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable,
4085 pAdapter->CommonCfg.DesiredHtPhy.AmsduSize, pAdapter->CommonCfg.DesiredHtPhy.MpduDensity));
4086 }
4087
4088 break;
4089 case RT_OID_802_11_ADD_IMME_BA:
4090 DBGPRINT(RT_DEBUG_TRACE, (" Set :: RT_OID_802_11_ADD_IMME_BA \n"));
4091 if (wrq->u.data.length != sizeof(OID_ADD_BA_ENTRY))
4092 Status = -EINVAL;
4093 else
4094 {
4095 UCHAR index;
4096 OID_ADD_BA_ENTRY BA;
4097 MAC_TABLE_ENTRY *pEntry;
4098
4099 Status = copy_from_user(&BA, wrq->u.data.pointer, wrq->u.data.length);
4100 if (BA.TID > 15)
4101 {
4102 Status = NDIS_STATUS_INVALID_DATA;
4103 break;
4104 }
4105 else
4106 {
4107 //BATableInsertEntry
4108 //As ad-hoc mode, BA pair is not limited to only BSSID. so add via OID.
4109 index = BA.TID;
4110 // in ad hoc mode, when adding BA pair, we should insert this entry into MACEntry too
4111 pEntry = MacTableLookup(pAdapter, BA.MACAddr);
4112 if (!pEntry)
4113 {
4114 DBGPRINT(RT_DEBUG_TRACE, ("RT_OID_802_11_ADD_IMME_BA. break on no connection.----:%x:%x\n", BA.MACAddr[4], BA.MACAddr[5]));
4115 break;
4116 }
4117 if (BA.IsRecipient == FALSE)
4118 {
4119 if (pEntry->bIAmBadAtheros == TRUE)
4120 pAdapter->CommonCfg.BACapability.field.RxBAWinLimit = 0x10;
4121
4122 BAOriSessionSetUp(pAdapter, pEntry, index, 0, 100, TRUE);
4123 }
4124 else
4125 {
4126 //BATableInsertEntry(pAdapter, pEntry->Aid, BA.MACAddr, 0, 0xffff, BA.TID, BA.nMSDU, BA.IsRecipient);
4127 }
4128
4129 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_IMME_BA. Rec = %d. Mac = %x:%x:%x:%x:%x:%x . \n",
4130 BA.IsRecipient, BA.MACAddr[0], BA.MACAddr[1], BA.MACAddr[2], BA.MACAddr[2]
4131 , BA.MACAddr[4], BA.MACAddr[5]));
4132 }
4133 }
4134 break;
4135
4136 case RT_OID_802_11_TEAR_IMME_BA:
4137 DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA \n"));
4138 if (wrq->u.data.length != sizeof(OID_ADD_BA_ENTRY))
4139 Status = -EINVAL;
4140 else
4141 {
4142 POID_ADD_BA_ENTRY pBA;
4143 MAC_TABLE_ENTRY *pEntry;
4144
4145 pBA = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
4146
4147 if (pBA == NULL)
4148 {
4149 DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA kmalloc() can't allocate enough memory\n"));
4150 Status = NDIS_STATUS_FAILURE;
4151 }
4152 else
4153 {
4154 Status = copy_from_user(pBA, wrq->u.data.pointer, wrq->u.data.length);
4155 DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA(TID=%d, bAllTid=%d)\n", pBA->TID, pBA->bAllTid));
4156
4157 if (!pBA->bAllTid && (pBA->TID > NUM_OF_TID))
4158 {
4159 Status = NDIS_STATUS_INVALID_DATA;
4160 break;
4161 }
4162
4163 if (pBA->IsRecipient == FALSE)
4164 {
4165 pEntry = MacTableLookup(pAdapter, pBA->MACAddr);
4166 DBGPRINT(RT_DEBUG_TRACE, (" pBA->IsRecipient == FALSE\n"));
4167 if (pEntry)
4168 {
4169 DBGPRINT(RT_DEBUG_TRACE, (" pBA->pEntry\n"));
4170 BAOriSessionTearDown(pAdapter, pEntry->Aid, pBA->TID, FALSE, TRUE);
4171 }
4172 else
4173 DBGPRINT(RT_DEBUG_TRACE, ("Set :: Not found pEntry \n"));
4174 }
4175 else
4176 {
4177 pEntry = MacTableLookup(pAdapter, pBA->MACAddr);
4178 if (pEntry)
4179 {
4180 BARecSessionTearDown( pAdapter, (UCHAR)pEntry->Aid, pBA->TID, TRUE);
4181 }
4182 else
4183 DBGPRINT(RT_DEBUG_TRACE, ("Set :: Not found pEntry \n"));
4184 }
4185 kfree(pBA);
4186 }
4187 }
4188 break;
4189#endif // DOT11_N_SUPPORT //
4190
4191 // For WPA_SUPPLICANT to set static wep key
4192 case OID_802_11_ADD_WEP:
4193 pWepKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
4194
4195 if(pWepKey == NULL)
4196 {
4197 Status = -ENOMEM;
4198 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed!!\n"));
4199 break;
4200 }
4201 Status = copy_from_user(pWepKey, wrq->u.data.pointer, wrq->u.data.length);
4202 if (Status)
4203 {
4204 Status = -EINVAL;
4205 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed (length mismatch)!!\n"));
4206 }
4207 else
4208 {
4209 KeyIdx = pWepKey->KeyIndex & 0x0fffffff;
4210 // KeyIdx must be 0 ~ 3
4211 if (KeyIdx > 4)
4212 {
4213 Status = -EINVAL;
4214 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed (KeyIdx must be smaller than 4)!!\n"));
4215 }
4216 else
4217 {
4218 UCHAR CipherAlg = 0;
4219 PUCHAR Key;
4220
4221 // set key material and key length
4222 NdisZeroMemory(pAdapter->SharedKey[BSS0][KeyIdx].Key, 16);
4223 pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
4224 NdisMoveMemory(pAdapter->SharedKey[BSS0][KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
4225
4226 switch(pWepKey->KeyLength)
4227 {
4228 case 5:
4229 CipherAlg = CIPHER_WEP64;
4230 break;
4231 case 13:
4232 CipherAlg = CIPHER_WEP128;
4233 break;
4234 default:
4235 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, only support CIPHER_WEP64(len:5) & CIPHER_WEP128(len:13)!!\n"));
4236 Status = -EINVAL;
4237 break;
4238 }
4239 pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CipherAlg;
4240
4241 // Default key for tx (shared key)
4242 if (pWepKey->KeyIndex & 0x80000000)
4243 {
4244#ifdef WPA_SUPPLICANT_SUPPORT
4245 // set key material and key length
4246 NdisZeroMemory(pAdapter->StaCfg.DesireSharedKey[KeyIdx].Key, 16);
4247 pAdapter->StaCfg.DesireSharedKey[KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
4248 NdisMoveMemory(pAdapter->StaCfg.DesireSharedKey[KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
4249 pAdapter->StaCfg.DesireSharedKeyId = KeyIdx;
4250 pAdapter->StaCfg.DesireSharedKey[KeyIdx].CipherAlg = CipherAlg;
4251#endif // WPA_SUPPLICANT_SUPPORT //
4252 pAdapter->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
4253 }
4254
4255#ifdef WPA_SUPPLICANT_SUPPORT
4256 if (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)
4257#endif // WPA_SUPPLICANT_SUPPORT
4258 {
4259 Key = pAdapter->SharedKey[BSS0][KeyIdx].Key;
4260
4261 // Set key material and cipherAlg to Asic
4262 AsicAddSharedKeyEntry(pAdapter, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
4263
4264 if (pWepKey->KeyIndex & 0x80000000)
4265 {
4266 PMAC_TABLE_ENTRY pEntry = &pAdapter->MacTab.Content[BSSID_WCID];
4267 // Assign group key info
4268 RTMPAddWcidAttributeEntry(pAdapter, BSS0, KeyIdx, CipherAlg, NULL);
4269 // Assign pairwise key info
4270 RTMPAddWcidAttributeEntry(pAdapter, BSS0, KeyIdx, CipherAlg, pEntry);
4271 }
4272 }
4273 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP (id=0x%x, Len=%d-byte), %s\n", pWepKey->KeyIndex, pWepKey->KeyLength, (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED) ? "Port Secured":"Port NOT Secured"));
4274 }
4275 }
4276 kfree(pWepKey);
4277 break;
4278#ifdef WPA_SUPPLICANT_SUPPORT
4279 case OID_SET_COUNTERMEASURES:
4280 if (wrq->u.data.length != sizeof(int))
4281 Status = -EINVAL;
4282 else
4283 {
4284 int enabled = 0;
4285 Status = copy_from_user(&enabled, wrq->u.data.pointer, wrq->u.data.length);
4286 if (enabled == 1)
4287 pAdapter->StaCfg.bBlockAssoc = TRUE;
4288 else
4289 // WPA MIC error should block association attempt for 60 seconds
4290 pAdapter->StaCfg.bBlockAssoc = FALSE;
4291 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_SET_COUNTERMEASURES bBlockAssoc=%s\n", pAdapter->StaCfg.bBlockAssoc ? "TRUE":"FALSE"));
4292 }
4293 break;
4294 case RT_OID_WPA_SUPPLICANT_SUPPORT:
4295 if (wrq->u.data.length != sizeof(UCHAR))
4296 Status = -EINVAL;
4297 else
4298 {
4299 Status = copy_from_user(&wpa_supplicant_enable, wrq->u.data.pointer, wrq->u.data.length);
4300 pAdapter->StaCfg.WpaSupplicantUP = wpa_supplicant_enable;
4301 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_WPA_SUPPLICANT_SUPPORT (=%d)\n", pAdapter->StaCfg.WpaSupplicantUP));
4302 }
4303 break;
4304 case OID_802_11_DEAUTHENTICATION:
4305 if (wrq->u.data.length != sizeof(MLME_DEAUTH_REQ_STRUCT))
4306 Status = -EINVAL;
4307 else
4308 {
4309 MLME_DEAUTH_REQ_STRUCT *pInfo;
4310 MLME_QUEUE_ELEM *MsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
4311
4312 pInfo = (MLME_DEAUTH_REQ_STRUCT *) MsgElem->Msg;
4313 Status = copy_from_user(pInfo, wrq->u.data.pointer, wrq->u.data.length);
4314 MlmeDeauthReqAction(pAdapter, MsgElem);
4315 kfree(MsgElem);
4316
4317 if (INFRA_ON(pAdapter))
4318 {
4319 LinkDown(pAdapter, FALSE);
4320 pAdapter->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
4321 }
4322 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DEAUTHENTICATION (Reason=%d)\n", pInfo->Reason));
4323 }
4324 break;
4325 case OID_802_11_DROP_UNENCRYPTED:
4326 if (wrq->u.data.length != sizeof(int))
4327 Status = -EINVAL;
4328 else
4329 {
4330 int enabled = 0;
4331 Status = copy_from_user(&enabled, wrq->u.data.pointer, wrq->u.data.length);
4332 if (enabled == 1)
4333 pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
4334 else
4335 pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
4336 NdisAcquireSpinLock(&pAdapter->MacTabLock);
4337 pAdapter->MacTab.Content[BSSID_WCID].PortSecured = pAdapter->StaCfg.PortSecured;
4338 NdisReleaseSpinLock(&pAdapter->MacTabLock);
4339 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DROP_UNENCRYPTED (=%d)\n", enabled));
4340 }
4341 break;
4342 case OID_802_11_SET_IEEE8021X:
4343 if (wrq->u.data.length != sizeof(BOOLEAN))
4344 Status = -EINVAL;
4345 else
4346 {
4347 Status = copy_from_user(&IEEE8021xState, wrq->u.data.pointer, wrq->u.data.length);
4348 pAdapter->StaCfg.IEEE8021X = IEEE8021xState;
4349 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_IEEE8021X (=%d)\n", IEEE8021xState));
4350 }
4351 break;
4352 case OID_802_11_SET_IEEE8021X_REQUIRE_KEY:
4353 if (wrq->u.data.length != sizeof(BOOLEAN))
4354 Status = -EINVAL;
4355 else
4356 {
4357 Status = copy_from_user(&IEEE8021x_required_keys, wrq->u.data.pointer, wrq->u.data.length);
4358 pAdapter->StaCfg.IEEE8021x_required_keys = IEEE8021x_required_keys;
4359 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_IEEE8021X_REQUIRE_KEY (%d)\n", IEEE8021x_required_keys));
4360 }
4361 break;
4362 case OID_802_11_PMKID:
4363 pPmkId = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
4364
4365 if(pPmkId == NULL) {
4366 Status = -ENOMEM;
4367 break;
4368 }
4369 Status = copy_from_user(pPmkId, wrq->u.data.pointer, wrq->u.data.length);
4370
4371 // check the PMKID information
4372 if (pPmkId->BSSIDInfoCount == 0)
4373 NdisZeroMemory(pAdapter->StaCfg.SavedPMK, sizeof(BSSID_INFO)*PMKID_NO);
4374 else
4375 {
4376 PBSSID_INFO pBssIdInfo;
4377 UINT BssIdx;
4378 UINT CachedIdx;
4379
4380 for (BssIdx = 0; BssIdx < pPmkId->BSSIDInfoCount; BssIdx++)
4381 {
4382 // point to the indexed BSSID_INFO structure
4383 pBssIdInfo = (PBSSID_INFO) ((PUCHAR) pPmkId + 2 * sizeof(UINT) + BssIdx * sizeof(BSSID_INFO));
4384 // Find the entry in the saved data base.
4385 for (CachedIdx = 0; CachedIdx < pAdapter->StaCfg.SavedPMKNum; CachedIdx++)
4386 {
4387 // compare the BSSID
4388 if (NdisEqualMemory(pBssIdInfo->BSSID, pAdapter->StaCfg.SavedPMK[CachedIdx].BSSID, sizeof(NDIS_802_11_MAC_ADDRESS)))
4389 break;
4390 }
4391
4392 // Found, replace it
4393 if (CachedIdx < PMKID_NO)
4394 {
4395 DBGPRINT(RT_DEBUG_OFF, ("Update OID_802_11_PMKID, idx = %d\n", CachedIdx));
4396 NdisMoveMemory(&pAdapter->StaCfg.SavedPMK[CachedIdx], pBssIdInfo, sizeof(BSSID_INFO));
4397 pAdapter->StaCfg.SavedPMKNum++;
4398 }
4399 // Not found, replace the last one
4400 else
4401 {
4402 // Randomly replace one
4403 CachedIdx = (pBssIdInfo->BSSID[5] % PMKID_NO);
4404 DBGPRINT(RT_DEBUG_OFF, ("Update OID_802_11_PMKID, idx = %d\n", CachedIdx));
4405 NdisMoveMemory(&pAdapter->StaCfg.SavedPMK[CachedIdx], pBssIdInfo, sizeof(BSSID_INFO));
4406 }
4407 }
4408 }
4409 if(pPmkId)
4410 kfree(pPmkId);
4411 break;
4412#endif // WPA_SUPPLICANT_SUPPORT //
4413
4414
4415
4416#ifdef SNMP_SUPPORT
4417 case OID_802_11_SHORTRETRYLIMIT:
4418 if (wrq->u.data.length != sizeof(ULONG))
4419 Status = -EINVAL;
4420 else
4421 {
4422 Status = copy_from_user(&ShortRetryLimit, wrq->u.data.pointer, wrq->u.data.length);
4423 RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
4424 tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit;
4425 RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
4426 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SHORTRETRYLIMIT (tx_rty_cfg.field.ShortRetryLimit=%d, ShortRetryLimit=%ld)\n", tx_rty_cfg.field.ShortRtyLimit, ShortRetryLimit));
4427 }
4428 break;
4429
4430 case OID_802_11_LONGRETRYLIMIT:
4431 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_LONGRETRYLIMIT \n"));
4432 if (wrq->u.data.length != sizeof(ULONG))
4433 Status = -EINVAL;
4434 else
4435 {
4436 Status = copy_from_user(&LongRetryLimit, wrq->u.data.pointer, wrq->u.data.length);
4437 RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
4438 tx_rty_cfg.field.LongRtyLimit = LongRetryLimit;
4439 RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
4440 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_LONGRETRYLIMIT (tx_rty_cfg.field.LongRetryLimit= %d,LongRetryLimit=%ld)\n", tx_rty_cfg.field.LongRtyLimit, LongRetryLimit));
4441 }
4442 break;
4443
4444 case OID_802_11_WEPDEFAULTKEYVALUE:
4445 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYVALUE\n"));
4446 pKey = kmalloc(wrq->u.data.length, GFP_KERNEL);
4447 Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
4448 //pKey = &WepKey;
4449
4450 if ( pKey->Length != wrq->u.data.length)
4451 {
4452 Status = -EINVAL;
4453 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYVALUE, Failed!!\n"));
4454 }
4455 KeyIdx = pKey->KeyIndex & 0x0fffffff;
4456 DBGPRINT(RT_DEBUG_TRACE,("pKey->KeyIndex =%d, pKey->KeyLength=%d\n", pKey->KeyIndex, pKey->KeyLength));
4457
4458 // it is a shared key
4459 if (KeyIdx > 4)
4460 Status = -EINVAL;
4461 else
4462 {
4463 pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen = (UCHAR) pKey->KeyLength;
4464 NdisMoveMemory(&pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key, &pKey->KeyMaterial, pKey->KeyLength);
4465 if (pKey->KeyIndex & 0x80000000)
4466 {
4467 // Default key for tx (shared key)
4468 pAdapter->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
4469 }
4470 //RestartAPIsRequired = TRUE;
4471 }
4472 break;
4473
4474
4475 case OID_802_11_WEPDEFAULTKEYID:
4476 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYID \n"));
4477
4478 if (wrq->u.data.length != sizeof(UCHAR))
4479 Status = -EINVAL;
4480 else
4481 Status = copy_from_user(&pAdapter->StaCfg.DefaultKeyId, wrq->u.data.pointer, wrq->u.data.length);
4482
4483 break;
4484
4485
4486 case OID_802_11_CURRENTCHANNEL:
4487 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_CURRENTCHANNEL \n"));
4488 if (wrq->u.data.length != sizeof(UCHAR))
4489 Status = -EINVAL;
4490 else
4491 {
4492 Status = copy_from_user(&ctmp, wrq->u.data.pointer, wrq->u.data.length);
4493 sprintf(&ctmp,"%d", ctmp);
4494 Set_Channel_Proc(pAdapter, &ctmp);
4495 }
4496 break;
4497#endif
4498
4499
4500
4501 default:
4502 DBGPRINT(RT_DEBUG_TRACE, ("Set::unknown IOCTL's subcmd = 0x%08x\n", cmd));
4503 Status = -EOPNOTSUPP;
4504 break;
4505 }
4506
4507
4508 return Status;
4509}
4510
4511INT RTMPQueryInformation(
4512 IN PRTMP_ADAPTER pAdapter,
4513 IN OUT struct ifreq *rq,
4514 IN INT cmd)
4515{
4516 struct iwreq *wrq = (struct iwreq *) rq;
4517 NDIS_802_11_BSSID_LIST_EX *pBssidList = NULL;
4518 PNDIS_WLAN_BSSID_EX pBss;
4519 NDIS_802_11_SSID Ssid;
4520 NDIS_802_11_CONFIGURATION *pConfiguration = NULL;
4521 RT_802_11_LINK_STATUS *pLinkStatus = NULL;
4522 RT_802_11_STA_CONFIG *pStaConfig = NULL;
4523 NDIS_802_11_STATISTICS *pStatistics = NULL;
4524 NDIS_802_11_RTS_THRESHOLD RtsThresh;
4525 NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh;
4526 NDIS_802_11_POWER_MODE PowerMode;
4527 NDIS_802_11_NETWORK_INFRASTRUCTURE BssType;
4528 RT_802_11_PREAMBLE PreamType;
4529 NDIS_802_11_AUTHENTICATION_MODE AuthMode;
4530 NDIS_802_11_WEP_STATUS WepStatus;
4531 NDIS_MEDIA_STATE MediaState;
4532 ULONG BssBufSize, ulInfo=0, NetworkTypeList[4], apsd = 0;
4533 USHORT BssLen = 0;
4534 PUCHAR pBuf = NULL, pPtr;
4535 INT Status = NDIS_STATUS_SUCCESS;
4536 UINT we_version_compiled;
4537 UCHAR i, Padding = 0;
4538 BOOLEAN RadioState;
4539 UCHAR driverVersion[8];
4540 OID_SET_HT_PHYMODE *pHTPhyMode = NULL;
4541
4542
4543#ifdef SNMP_SUPPORT
4544 //for snmp, kathy
4545 DefaultKeyIdxValue *pKeyIdxValue;
4546 INT valueLen;
4547 TX_RTY_CFG_STRUC tx_rty_cfg;
4548 ULONG ShortRetryLimit, LongRetryLimit;
4549 UCHAR tmp[64];
4550#endif //SNMP
4551
4552 switch(cmd)
4553 {
4554 case RT_OID_DEVICE_NAME:
4555 wrq->u.data.length = sizeof(STA_NIC_DEVICE_NAME);
4556 Status = copy_to_user(wrq->u.data.pointer, STA_NIC_DEVICE_NAME, wrq->u.data.length);
4557 break;
4558 case RT_OID_VERSION_INFO:
4559 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_VERSION_INFO \n"));
4560 wrq->u.data.length = 8*sizeof(UCHAR);
4561 sprintf(&driverVersion[0], "%s", STA_DRIVER_VERSION);
4562 driverVersion[7] = '\0';
4563 if (copy_to_user(wrq->u.data.pointer, &driverVersion, wrq->u.data.length))
4564 {
4565 Status = -EFAULT;
4566 }
4567 break;
4568#ifdef RALINK_ATE
4569 case RT_QUERY_ATE_TXDONE_COUNT:
4570 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_QUERY_ATE_TXDONE_COUNT \n"));
4571 wrq->u.data.length = sizeof(UINT32);
4572 if (copy_to_user(wrq->u.data.pointer, &pAdapter->ate.TxDoneCount, wrq->u.data.length))
4573 {
4574 Status = -EFAULT;
4575 }
4576 break;
4577#endif // RALINK_ATE //
4578 case OID_802_11_BSSID_LIST:
4579 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
4580 {
4581 /*
4582 * Still scanning, indicate the caller should try again.
4583 */
4584 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID_LIST (Still scanning)\n"));
4585 return -EAGAIN;
4586 }
4587 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID_LIST (%d BSS returned)\n",pAdapter->ScanTab.BssNr));
4588 pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
4589 // Claculate total buffer size required
4590 BssBufSize = sizeof(ULONG);
4591
4592 for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
4593 {
4594 // Align pointer to 4 bytes boundary.
4595 //Padding = 4 - (pAdapter->ScanTab.BssEntry[i].VarIELen & 0x0003);
4596 //if (Padding == 4)
4597 // Padding = 0;
4598 BssBufSize += (sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen + Padding);
4599 }
4600
4601 // For safety issue, we add 256 bytes just in case
4602 BssBufSize += 256;
4603 // Allocate the same size as passed from higher layer
4604 pBuf = kmalloc(BssBufSize, MEM_ALLOC_FLAG);
4605 if(pBuf == NULL)
4606 {
4607 Status = -ENOMEM;
4608 break;
4609 }
4610 // Init 802_11_BSSID_LIST_EX structure
4611 NdisZeroMemory(pBuf, BssBufSize);
4612 pBssidList = (PNDIS_802_11_BSSID_LIST_EX) pBuf;
4613 pBssidList->NumberOfItems = pAdapter->ScanTab.BssNr;
4614
4615 // Calculate total buffer length
4616 BssLen = 4; // Consist of NumberOfItems
4617 // Point to start of NDIS_WLAN_BSSID_EX
4618 // pPtr = pBuf + sizeof(ULONG);
4619 pPtr = (PUCHAR) &pBssidList->Bssid[0];
4620 for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
4621 {
4622 pBss = (PNDIS_WLAN_BSSID_EX) pPtr;
4623 NdisMoveMemory(&pBss->MacAddress, &pAdapter->ScanTab.BssEntry[i].Bssid, MAC_ADDR_LEN);
4624 if ((pAdapter->ScanTab.BssEntry[i].Hidden == 1) && (pAdapter->StaCfg.bShowHiddenSSID == FALSE))
4625 {
4626 //
4627 // We must return this SSID during 4way handshaking, otherwise Aegis will failed to parse WPA infomation
4628 // and then failed to send EAPOl farame.
4629 //
4630 if ((pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) && (pAdapter->StaCfg.PortSecured != WPA_802_1X_PORT_SECURED))
4631 {
4632 pBss->Ssid.SsidLength = pAdapter->ScanTab.BssEntry[i].SsidLen;
4633 NdisMoveMemory(pBss->Ssid.Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen);
4634 }
4635 else
4636 pBss->Ssid.SsidLength = 0;
4637 }
4638 else
4639 {
4640 pBss->Ssid.SsidLength = pAdapter->ScanTab.BssEntry[i].SsidLen;
4641 NdisMoveMemory(pBss->Ssid.Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen);
4642 }
4643 pBss->Privacy = pAdapter->ScanTab.BssEntry[i].Privacy;
4644 pBss->Rssi = pAdapter->ScanTab.BssEntry[i].Rssi - pAdapter->BbpRssiToDbmDelta;
4645 pBss->NetworkTypeInUse = NetworkTypeInUseSanity(&pAdapter->ScanTab.BssEntry[i]);
4646 pBss->Configuration.Length = sizeof(NDIS_802_11_CONFIGURATION);
4647 pBss->Configuration.BeaconPeriod = pAdapter->ScanTab.BssEntry[i].BeaconPeriod;
4648 pBss->Configuration.ATIMWindow = pAdapter->ScanTab.BssEntry[i].AtimWin;
4649
4650 MAP_CHANNEL_ID_TO_KHZ(pAdapter->ScanTab.BssEntry[i].Channel, pBss->Configuration.DSConfig);
4651
4652 if (pAdapter->ScanTab.BssEntry[i].BssType == BSS_INFRA)
4653 pBss->InfrastructureMode = Ndis802_11Infrastructure;
4654 else
4655 pBss->InfrastructureMode = Ndis802_11IBSS;
4656
4657 NdisMoveMemory(pBss->SupportedRates, pAdapter->ScanTab.BssEntry[i].SupRate, pAdapter->ScanTab.BssEntry[i].SupRateLen);
4658 NdisMoveMemory(pBss->SupportedRates + pAdapter->ScanTab.BssEntry[i].SupRateLen,
4659 pAdapter->ScanTab.BssEntry[i].ExtRate,
4660 pAdapter->ScanTab.BssEntry[i].ExtRateLen);
4661
4662 if (pAdapter->ScanTab.BssEntry[i].VarIELen == 0)
4663 {
4664 pBss->IELength = sizeof(NDIS_802_11_FIXED_IEs);
4665 NdisMoveMemory(pBss->IEs, &pAdapter->ScanTab.BssEntry[i].FixIEs, sizeof(NDIS_802_11_FIXED_IEs));
4666 pPtr = pPtr + sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs);
4667 }
4668 else
4669 {
4670 pBss->IELength = (ULONG)(sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen);
4671 pPtr = pPtr + sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs);
4672 NdisMoveMemory(pBss->IEs, &pAdapter->ScanTab.BssEntry[i].FixIEs, sizeof(NDIS_802_11_FIXED_IEs));
4673 NdisMoveMemory(pBss->IEs + sizeof(NDIS_802_11_FIXED_IEs), pAdapter->ScanTab.BssEntry[i].VarIEs, pAdapter->ScanTab.BssEntry[i].VarIELen);
4674 pPtr += pAdapter->ScanTab.BssEntry[i].VarIELen;
4675 }
4676 pBss->Length = (ULONG)(sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen + Padding);
4677
4678#if WIRELESS_EXT < 17
4679 if ((BssLen + pBss->Length) < wrq->u.data.length)
4680 BssLen += pBss->Length;
4681 else
4682 {
4683 pBssidList->NumberOfItems = i;
4684 break;
4685 }
4686#else
4687 BssLen += pBss->Length;
4688#endif
4689 }
4690
4691#if WIRELESS_EXT < 17
4692 wrq->u.data.length = BssLen;
4693#else
4694 if (BssLen > wrq->u.data.length)
4695 {
4696 kfree(pBssidList);
4697 return -E2BIG;
4698 }
4699 else
4700 wrq->u.data.length = BssLen;
4701#endif
4702 Status = copy_to_user(wrq->u.data.pointer, pBssidList, BssLen);
4703 kfree(pBssidList);
4704 break;
4705 case OID_802_3_CURRENT_ADDRESS:
4706 wrq->u.data.length = MAC_ADDR_LEN;
4707 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CurrentAddress, wrq->u.data.length);
4708 break;
4709 case OID_GEN_MEDIA_CONNECT_STATUS:
4710 if (pAdapter->IndicateMediaState == NdisMediaStateConnected)
4711 MediaState = NdisMediaStateConnected;
4712 else
4713 MediaState = NdisMediaStateDisconnected;
4714
4715 wrq->u.data.length = sizeof(NDIS_MEDIA_STATE);
4716 Status = copy_to_user(wrq->u.data.pointer, &MediaState, wrq->u.data.length);
4717 break;
4718 case OID_802_11_BSSID:
4719#ifdef RALINK_ATE
4720 if (ATE_ON(pAdapter))
4721 {
4722 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
4723 Status = NDIS_STATUS_RESOURCES;
4724 break;
4725 }
4726#endif // RALINK_ATE //
4727 if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
4728 {
4729 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Bssid, sizeof(NDIS_802_11_MAC_ADDRESS));
4730
4731 }
4732 else
4733 {
4734 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID(=EMPTY)\n"));
4735 Status = -ENOTCONN;
4736 }
4737 break;
4738 case OID_802_11_SSID:
4739 NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
4740 NdisZeroMemory(Ssid.Ssid, MAX_LEN_OF_SSID);
4741 Ssid.SsidLength = pAdapter->CommonCfg.SsidLen;
4742 memcpy(Ssid.Ssid, pAdapter->CommonCfg.Ssid, Ssid.SsidLength);
4743 wrq->u.data.length = sizeof(NDIS_802_11_SSID);
4744 Status = copy_to_user(wrq->u.data.pointer, &Ssid, wrq->u.data.length);
4745 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_SSID (Len=%d, ssid=%s)\n", Ssid.SsidLength,Ssid.Ssid));
4746 break;
4747 case RT_OID_802_11_QUERY_LINK_STATUS:
4748 pLinkStatus = (RT_802_11_LINK_STATUS *) kmalloc(sizeof(RT_802_11_LINK_STATUS), MEM_ALLOC_FLAG);
4749 if (pLinkStatus)
4750 {
4751 pLinkStatus->CurrTxRate = RateIdTo500Kbps[pAdapter->CommonCfg.TxRate]; // unit : 500 kbps
4752 pLinkStatus->ChannelQuality = pAdapter->Mlme.ChannelQuality;
4753 pLinkStatus->RxByteCount = pAdapter->RalinkCounters.ReceivedByteCount;
4754 pLinkStatus->TxByteCount = pAdapter->RalinkCounters.TransmittedByteCount;
4755 pLinkStatus->CentralChannel = pAdapter->CommonCfg.CentralChannel;
4756 wrq->u.data.length = sizeof(RT_802_11_LINK_STATUS);
4757 Status = copy_to_user(wrq->u.data.pointer, pLinkStatus, wrq->u.data.length);
4758 kfree(pLinkStatus);
4759 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LINK_STATUS\n"));
4760 }
4761 else
4762 {
4763 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LINK_STATUS(kmalloc failed)\n"));
4764 Status = -EFAULT;
4765 }
4766 break;
4767 case OID_802_11_CONFIGURATION:
4768 pConfiguration = (NDIS_802_11_CONFIGURATION *) kmalloc(sizeof(NDIS_802_11_CONFIGURATION), MEM_ALLOC_FLAG);
4769 if (pConfiguration)
4770 {
4771 pConfiguration->Length = sizeof(NDIS_802_11_CONFIGURATION);
4772 pConfiguration->BeaconPeriod = pAdapter->CommonCfg.BeaconPeriod;
4773 pConfiguration->ATIMWindow = pAdapter->StaActive.AtimWin;
4774 MAP_CHANNEL_ID_TO_KHZ(pAdapter->CommonCfg.Channel, pConfiguration->DSConfig);
4775 wrq->u.data.length = sizeof(NDIS_802_11_CONFIGURATION);
4776 Status = copy_to_user(wrq->u.data.pointer, pConfiguration, wrq->u.data.length);
4777 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CONFIGURATION(BeaconPeriod=%ld,AtimW=%ld,Channel=%d) \n",
4778 pConfiguration->BeaconPeriod, pConfiguration->ATIMWindow, pAdapter->CommonCfg.Channel));
4779 kfree(pConfiguration);
4780 }
4781 else
4782 {
4783 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CONFIGURATION(kmalloc failed)\n"));
4784 Status = -EFAULT;
4785 }
4786 break;
4787 case RT_OID_802_11_SNR_0:
4788 if ((pAdapter->StaCfg.LastSNR0 > 0))
4789 {
4790 ulInfo = ((0xeb - pAdapter->StaCfg.LastSNR0) * 3) / 16 ;
4791 wrq->u.data.length = sizeof(ulInfo);
4792 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4793 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_SNR_0(0x=%lx)\n", ulInfo));
4794 }
4795 else
4796 Status = -EFAULT;
4797 break;
4798 case RT_OID_802_11_SNR_1:
4799 if ((pAdapter->Antenna.field.RxPath > 1) &&
4800 (pAdapter->StaCfg.LastSNR1 > 0))
4801 {
4802 ulInfo = ((0xeb - pAdapter->StaCfg.LastSNR1) * 3) / 16 ;
4803 wrq->u.data.length = sizeof(ulInfo);
4804 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4805 DBGPRINT(RT_DEBUG_TRACE,("Query::RT_OID_802_11_SNR_1(0x=%lx)\n",ulInfo));
4806 }
4807 else
4808 Status = -EFAULT;
4809 DBGPRINT(RT_DEBUG_TRACE,("Query::RT_OID_802_11_SNR_1(pAdapter->StaCfg.LastSNR1=%d)\n",pAdapter->StaCfg.LastSNR1));
4810 break;
4811 case OID_802_11_RSSI_TRIGGER:
4812 ulInfo = pAdapter->StaCfg.RssiSample.LastRssi0 - pAdapter->BbpRssiToDbmDelta;
4813 wrq->u.data.length = sizeof(ulInfo);
4814 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4815 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_RSSI_TRIGGER(=%ld)\n", ulInfo));
4816 break;
4817 case OID_802_11_RSSI:
4818 case RT_OID_802_11_RSSI:
4819 ulInfo = pAdapter->StaCfg.RssiSample.LastRssi0;
4820 wrq->u.data.length = sizeof(ulInfo);
4821 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4822 break;
4823 case RT_OID_802_11_RSSI_1:
4824 ulInfo = pAdapter->StaCfg.RssiSample.LastRssi1;
4825 wrq->u.data.length = sizeof(ulInfo);
4826 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4827 break;
4828 case RT_OID_802_11_RSSI_2:
4829 ulInfo = pAdapter->StaCfg.RssiSample.LastRssi2;
4830 wrq->u.data.length = sizeof(ulInfo);
4831 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4832 break;
4833 case OID_802_11_STATISTICS:
4834 pStatistics = (NDIS_802_11_STATISTICS *) kmalloc(sizeof(NDIS_802_11_STATISTICS), MEM_ALLOC_FLAG);
4835 if (pStatistics)
4836 {
4837 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_STATISTICS \n"));
4838 // add the most up-to-date h/w raw counters into software counters
4839 NICUpdateRawCounters(pAdapter);
4840
4841 // Sanity check for calculation of sucessful count
4842 if (pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart < pAdapter->WlanCounters.RetryCount.QuadPart)
4843 pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart = pAdapter->WlanCounters.RetryCount.QuadPart;
4844
4845 pStatistics->TransmittedFragmentCount.QuadPart = pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart;
4846 pStatistics->MulticastTransmittedFrameCount.QuadPart = pAdapter->WlanCounters.MulticastTransmittedFrameCount.QuadPart;
4847 pStatistics->FailedCount.QuadPart = pAdapter->WlanCounters.FailedCount.QuadPart;
4848 pStatistics->RetryCount.QuadPart = pAdapter->WlanCounters.RetryCount.QuadPart;
4849 pStatistics->MultipleRetryCount.QuadPart = pAdapter->WlanCounters.MultipleRetryCount.QuadPart;
4850 pStatistics->RTSSuccessCount.QuadPart = pAdapter->WlanCounters.RTSSuccessCount.QuadPart;
4851 pStatistics->RTSFailureCount.QuadPart = pAdapter->WlanCounters.RTSFailureCount.QuadPart;
4852 pStatistics->ACKFailureCount.QuadPart = pAdapter->WlanCounters.ACKFailureCount.QuadPart;
4853 pStatistics->FrameDuplicateCount.QuadPart = pAdapter->WlanCounters.FrameDuplicateCount.QuadPart;
4854 pStatistics->ReceivedFragmentCount.QuadPart = pAdapter->WlanCounters.ReceivedFragmentCount.QuadPart;
4855 pStatistics->MulticastReceivedFrameCount.QuadPart = pAdapter->WlanCounters.MulticastReceivedFrameCount.QuadPart;
4856#ifdef DBG
4857 pStatistics->FCSErrorCount = pAdapter->RalinkCounters.RealFcsErrCount;
4858#else
4859 pStatistics->FCSErrorCount.QuadPart = pAdapter->WlanCounters.FCSErrorCount.QuadPart;
4860 pStatistics->FrameDuplicateCount.u.LowPart = pAdapter->WlanCounters.FrameDuplicateCount.u.LowPart / 100;
4861#endif
4862 wrq->u.data.length = sizeof(NDIS_802_11_STATISTICS);
4863 Status = copy_to_user(wrq->u.data.pointer, pStatistics, wrq->u.data.length);
4864 kfree(pStatistics);
4865 }
4866 else
4867 {
4868 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_STATISTICS(kmalloc failed)\n"));
4869 Status = -EFAULT;
4870 }
4871 break;
4872 case OID_GEN_RCV_OK:
4873 ulInfo = pAdapter->Counters8023.GoodReceives;
4874 wrq->u.data.length = sizeof(ulInfo);
4875 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4876 break;
4877 case OID_GEN_RCV_NO_BUFFER:
4878 ulInfo = pAdapter->Counters8023.RxNoBuffer;
4879 wrq->u.data.length = sizeof(ulInfo);
4880 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4881 break;
4882 case RT_OID_802_11_PHY_MODE:
4883 ulInfo = (ULONG)pAdapter->CommonCfg.PhyMode;
4884 wrq->u.data.length = sizeof(ulInfo);
4885 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4886 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PHY_MODE (=%ld)\n", ulInfo));
4887 break;
4888 case RT_OID_802_11_STA_CONFIG:
4889 pStaConfig = (RT_802_11_STA_CONFIG *) kmalloc(sizeof(RT_802_11_STA_CONFIG), MEM_ALLOC_FLAG);
4890 if (pStaConfig)
4891 {
4892 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG\n"));
4893 pStaConfig->EnableTxBurst = pAdapter->CommonCfg.bEnableTxBurst;
4894 pStaConfig->EnableTurboRate = 0;
4895 pStaConfig->UseBGProtection = pAdapter->CommonCfg.UseBGProtection;
4896 pStaConfig->UseShortSlotTime = pAdapter->CommonCfg.bUseShortSlotTime;
4897 //pStaConfig->AdhocMode = pAdapter->StaCfg.AdhocMode;
4898 pStaConfig->HwRadioStatus = (pAdapter->StaCfg.bHwRadio == TRUE) ? 1 : 0;
4899 pStaConfig->Rsv1 = 0;
4900 pStaConfig->SystemErrorBitmap = pAdapter->SystemErrorBitmap;
4901 wrq->u.data.length = sizeof(RT_802_11_STA_CONFIG);
4902 Status = copy_to_user(wrq->u.data.pointer, pStaConfig, wrq->u.data.length);
4903 kfree(pStaConfig);
4904 }
4905 else
4906 {
4907 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
4908 Status = -EFAULT;
4909 }
4910 break;
4911 case OID_802_11_RTS_THRESHOLD:
4912 RtsThresh = pAdapter->CommonCfg.RtsThreshold;
4913 wrq->u.data.length = sizeof(RtsThresh);
4914 Status = copy_to_user(wrq->u.data.pointer, &RtsThresh, wrq->u.data.length);
4915 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_RTS_THRESHOLD(=%ld)\n", RtsThresh));
4916 break;
4917 case OID_802_11_FRAGMENTATION_THRESHOLD:
4918 FragThresh = pAdapter->CommonCfg.FragmentThreshold;
4919 if (pAdapter->CommonCfg.bUseZeroToDisableFragment == TRUE)
4920 FragThresh = 0;
4921 wrq->u.data.length = sizeof(FragThresh);
4922 Status = copy_to_user(wrq->u.data.pointer, &FragThresh, wrq->u.data.length);
4923 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_FRAGMENTATION_THRESHOLD(=%ld)\n", FragThresh));
4924 break;
4925 case OID_802_11_POWER_MODE:
4926 PowerMode = pAdapter->StaCfg.WindowsPowerMode;
4927 wrq->u.data.length = sizeof(PowerMode);
4928 Status = copy_to_user(wrq->u.data.pointer, &PowerMode, wrq->u.data.length);
4929 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_POWER_MODE(=%d)\n", PowerMode));
4930 break;
4931 case RT_OID_802_11_RADIO:
4932 RadioState = (BOOLEAN) pAdapter->StaCfg.bSwRadio;
4933 wrq->u.data.length = sizeof(RadioState);
4934 Status = copy_to_user(wrq->u.data.pointer, &RadioState, wrq->u.data.length);
4935 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_RADIO (=%d)\n", RadioState));
4936 break;
4937 case OID_802_11_INFRASTRUCTURE_MODE:
4938 if (pAdapter->StaCfg.BssType == BSS_ADHOC)
4939 BssType = Ndis802_11IBSS;
4940 else if (pAdapter->StaCfg.BssType == BSS_INFRA)
4941 BssType = Ndis802_11Infrastructure;
4942 else if (pAdapter->StaCfg.BssType == BSS_MONITOR)
4943 BssType = Ndis802_11Monitor;
4944 else
4945 BssType = Ndis802_11AutoUnknown;
4946
4947 wrq->u.data.length = sizeof(BssType);
4948 Status = copy_to_user(wrq->u.data.pointer, &BssType, wrq->u.data.length);
4949 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_INFRASTRUCTURE_MODE(=%d)\n", BssType));
4950 break;
4951 case RT_OID_802_11_PREAMBLE:
4952 PreamType = pAdapter->CommonCfg.TxPreamble;
4953 wrq->u.data.length = sizeof(PreamType);
4954 Status = copy_to_user(wrq->u.data.pointer, &PreamType, wrq->u.data.length);
4955 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PREAMBLE(=%d)\n", PreamType));
4956 break;
4957 case OID_802_11_AUTHENTICATION_MODE:
4958 AuthMode = pAdapter->StaCfg.AuthMode;
4959 wrq->u.data.length = sizeof(AuthMode);
4960 Status = copy_to_user(wrq->u.data.pointer, &AuthMode, wrq->u.data.length);
4961 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_AUTHENTICATION_MODE(=%d)\n", AuthMode));
4962 break;
4963 case OID_802_11_WEP_STATUS:
4964 WepStatus = pAdapter->StaCfg.WepStatus;
4965 wrq->u.data.length = sizeof(WepStatus);
4966 Status = copy_to_user(wrq->u.data.pointer, &WepStatus, wrq->u.data.length);
4967 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_WEP_STATUS(=%d)\n", WepStatus));
4968 break;
4969 case OID_802_11_TX_POWER_LEVEL:
4970 wrq->u.data.length = sizeof(ULONG);
4971 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.TxPower, wrq->u.data.length);
4972 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_TX_POWER_LEVEL %x\n",pAdapter->CommonCfg.TxPower));
4973 break;
4974 case RT_OID_802_11_TX_POWER_LEVEL_1:
4975 wrq->u.data.length = sizeof(ULONG);
4976 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.TxPowerPercentage, wrq->u.data.length);
4977 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_TX_POWER_LEVEL_1 (=%ld)\n", pAdapter->CommonCfg.TxPowerPercentage));
4978 break;
4979 case OID_802_11_NETWORK_TYPES_SUPPORTED:
4980 if ((pAdapter->RfIcType == RFIC_2850) || (pAdapter->RfIcType == RFIC_2750))
4981 {
4982 NetworkTypeList[0] = 3; // NumberOfItems = 3
4983 NetworkTypeList[1] = Ndis802_11DS; // NetworkType[1] = 11b
4984 NetworkTypeList[2] = Ndis802_11OFDM24; // NetworkType[2] = 11g
4985 NetworkTypeList[3] = Ndis802_11OFDM5; // NetworkType[3] = 11a
4986 wrq->u.data.length = 16;
4987 Status = copy_to_user(wrq->u.data.pointer, &NetworkTypeList[0], wrq->u.data.length);
4988 }
4989 else
4990 {
4991 NetworkTypeList[0] = 2; // NumberOfItems = 2
4992 NetworkTypeList[1] = Ndis802_11DS; // NetworkType[1] = 11b
4993 NetworkTypeList[2] = Ndis802_11OFDM24; // NetworkType[2] = 11g
4994 wrq->u.data.length = 12;
4995 Status = copy_to_user(wrq->u.data.pointer, &NetworkTypeList[0], wrq->u.data.length);
4996 }
4997 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_NETWORK_TYPES_SUPPORTED\n"));
4998 break;
4999 case OID_802_11_NETWORK_TYPE_IN_USE:
5000 wrq->u.data.length = sizeof(ULONG);
5001 if (pAdapter->CommonCfg.PhyMode == PHY_11A)
5002 ulInfo = Ndis802_11OFDM5;
5003 else if ((pAdapter->CommonCfg.PhyMode == PHY_11BG_MIXED) || (pAdapter->CommonCfg.PhyMode == PHY_11G))
5004 ulInfo = Ndis802_11OFDM24;
5005 else
5006 ulInfo = Ndis802_11DS;
5007 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
5008 break;
5009 case RT_OID_802_11_QUERY_LAST_RX_RATE:
5010 ulInfo = (ULONG)pAdapter->LastRxRate;
5011 wrq->u.data.length = sizeof(ulInfo);
5012 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
5013 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LAST_RX_RATE (=%ld)\n", ulInfo));
5014 break;
5015 case RT_OID_802_11_QUERY_LAST_TX_RATE:
5016 //ulInfo = (ULONG)pAdapter->LastTxRate;
5017 ulInfo = (ULONG)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word;
5018 wrq->u.data.length = sizeof(ulInfo);
5019 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
5020 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LAST_TX_RATE (=%lx)\n", ulInfo));
5021 break;
5022 case RT_OID_802_11_QUERY_EEPROM_VERSION:
5023 wrq->u.data.length = sizeof(ULONG);
5024 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->EepromVersion, wrq->u.data.length);
5025 break;
5026 case RT_OID_802_11_QUERY_FIRMWARE_VERSION:
5027 wrq->u.data.length = sizeof(ULONG);
5028 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->FirmwareVersion, wrq->u.data.length);
5029 break;
5030 case RT_OID_802_11_QUERY_NOISE_LEVEL:
5031 wrq->u.data.length = sizeof(UCHAR);
5032 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->BbpWriteLatch[66], wrq->u.data.length);
5033 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_NOISE_LEVEL (=%d)\n", pAdapter->BbpWriteLatch[66]));
5034 break;
5035 case RT_OID_802_11_EXTRA_INFO:
5036 wrq->u.data.length = sizeof(ULONG);
5037 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->ExtraInfo, wrq->u.data.length);
5038 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_EXTRA_INFO (=%ld)\n", pAdapter->ExtraInfo));
5039 break;
5040 case RT_OID_WE_VERSION_COMPILED:
5041 wrq->u.data.length = sizeof(UINT);
5042 we_version_compiled = WIRELESS_EXT;
5043 Status = copy_to_user(wrq->u.data.pointer, &we_version_compiled, wrq->u.data.length);
5044 break;
5045 case RT_OID_802_11_QUERY_APSD_SETTING:
5046 apsd = (pAdapter->CommonCfg.bAPSDCapable | (pAdapter->CommonCfg.bAPSDAC_BE << 1) | (pAdapter->CommonCfg.bAPSDAC_BK << 2)
5047 | (pAdapter->CommonCfg.bAPSDAC_VI << 3) | (pAdapter->CommonCfg.bAPSDAC_VO << 4) | (pAdapter->CommonCfg.MaxSPLength << 5));
5048
5049 wrq->u.data.length = sizeof(ULONG);
5050 Status = copy_to_user(wrq->u.data.pointer, &apsd, wrq->u.data.length);
5051 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_APSD_SETTING (=0x%lx,APSDCap=%d,AC_BE=%d,AC_BK=%d,AC_VI=%d,AC_VO=%d,MAXSPLen=%d)\n",
5052 apsd,pAdapter->CommonCfg.bAPSDCapable,pAdapter->CommonCfg.bAPSDAC_BE,pAdapter->CommonCfg.bAPSDAC_BK,pAdapter->CommonCfg.bAPSDAC_VI,pAdapter->CommonCfg.bAPSDAC_VO,pAdapter->CommonCfg.MaxSPLength));
5053 break;
5054 case RT_OID_802_11_QUERY_APSD_PSM:
5055 wrq->u.data.length = sizeof(ULONG);
5056 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bAPSDForcePowerSave, wrq->u.data.length);
5057 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_APSD_PSM (=%d)\n", pAdapter->CommonCfg.bAPSDForcePowerSave));
5058 break;
5059 case RT_OID_802_11_QUERY_WMM:
5060 wrq->u.data.length = sizeof(BOOLEAN);
5061 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bWmmCapable, wrq->u.data.length);
5062 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_WMM (=%d)\n", pAdapter->CommonCfg.bWmmCapable));
5063 break;
5064#ifdef WPA_SUPPLICANT_SUPPORT
5065 case RT_OID_NEW_DRIVER:
5066 {
5067 UCHAR enabled = 1;
5068 wrq->u.data.length = sizeof(UCHAR);
5069 Status = copy_to_user(wrq->u.data.pointer, &enabled, wrq->u.data.length);
5070 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_NEW_DRIVER (=%d)\n", enabled));
5071 }
5072 break;
5073 case RT_OID_WPA_SUPPLICANT_SUPPORT:
5074 wrq->u.data.length = sizeof(UCHAR);
5075 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->StaCfg.WpaSupplicantUP, wrq->u.data.length);
5076 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_WPA_SUPPLICANT_SUPPORT (=%d)\n", pAdapter->StaCfg.WpaSupplicantUP));
5077 break;
5078#endif // WPA_SUPPLICANT_SUPPORT //
5079
5080 case RT_OID_DRIVER_DEVICE_NAME:
5081 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_DRIVER_DEVICE_NAME \n"));
5082 wrq->u.data.length = 16;
5083 if (copy_to_user(wrq->u.data.pointer, pAdapter->StaCfg.dev_name, wrq->u.data.length))
5084 {
5085 Status = -EFAULT;
5086 }
5087 break;
5088 case RT_OID_802_11_QUERY_HT_PHYMODE:
5089 pHTPhyMode = (OID_SET_HT_PHYMODE *) kmalloc(sizeof(OID_SET_HT_PHYMODE), MEM_ALLOC_FLAG);
5090 if (pHTPhyMode)
5091 {
5092 pHTPhyMode->PhyMode = pAdapter->CommonCfg.PhyMode;
5093 pHTPhyMode->HtMode = (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE;
5094 pHTPhyMode->BW = (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.BW;
5095 pHTPhyMode->MCS= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS;
5096 pHTPhyMode->SHORTGI= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI;
5097 pHTPhyMode->STBC= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC;
5098
5099 pHTPhyMode->ExtOffset = ((pAdapter->CommonCfg.CentralChannel < pAdapter->CommonCfg.Channel) ? (EXTCHA_BELOW) : (EXTCHA_ABOVE));
5100 wrq->u.data.length = sizeof(OID_SET_HT_PHYMODE);
5101 if (copy_to_user(wrq->u.data.pointer, pHTPhyMode, wrq->u.data.length))
5102 {
5103 Status = -EFAULT;
5104 }
5105 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_HT_PHYMODE (PhyMode = %d, MCS =%d, BW = %d, STBC = %d, ExtOffset=%d)\n",
5106 pHTPhyMode->HtMode, pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->ExtOffset));
5107 DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (.word = %x )\n", pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word));
5108 }
5109 else
5110 {
5111 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
5112 Status = -EFAULT;
5113 }
5114 break;
5115 case RT_OID_802_11_COUNTRY_REGION:
5116 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_COUNTRY_REGION \n"));
5117 wrq->u.data.length = sizeof(ulInfo);
5118 ulInfo = pAdapter->CommonCfg.CountryRegionForABand;
5119 ulInfo = (ulInfo << 8)|(pAdapter->CommonCfg.CountryRegion);
5120 if (copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length))
5121 {
5122 Status = -EFAULT;
5123 }
5124 break;
5125 case RT_OID_802_11_QUERY_DAT_HT_PHYMODE:
5126 pHTPhyMode = (OID_SET_HT_PHYMODE *) kmalloc(sizeof(OID_SET_HT_PHYMODE), MEM_ALLOC_FLAG);
5127 if (pHTPhyMode)
5128 {
5129 pHTPhyMode->PhyMode = pAdapter->CommonCfg.PhyMode;
5130 pHTPhyMode->HtMode = (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.HTMODE;
5131 pHTPhyMode->BW = (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.BW;
5132 pHTPhyMode->MCS= (UCHAR)pAdapter->StaCfg.DesiredTransmitSetting.field.MCS;
5133 pHTPhyMode->SHORTGI= (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.ShortGI;
5134 pHTPhyMode->STBC= (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.STBC;
5135
5136 wrq->u.data.length = sizeof(OID_SET_HT_PHYMODE);
5137 if (copy_to_user(wrq->u.data.pointer, pHTPhyMode, wrq->u.data.length))
5138 {
5139 Status = -EFAULT;
5140 }
5141 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_HT_PHYMODE (PhyMode = %d, MCS =%d, BW = %d, STBC = %d, ExtOffset=%d)\n",
5142 pHTPhyMode->HtMode, pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->ExtOffset));
5143 DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (.word = %x )\n", pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word));
5144 }
5145 else
5146 {
5147 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
5148 Status = -EFAULT;
5149 }
5150 break;
5151 case RT_OID_QUERY_MULTIPLE_CARD_SUPPORT:
5152 wrq->u.data.length = sizeof(UCHAR);
5153 i = 0;
5154#ifdef MULTIPLE_CARD_SUPPORT
5155 i = 1;
5156#endif // MULTIPLE_CARD_SUPPORT //
5157 if (copy_to_user(wrq->u.data.pointer, &i, wrq->u.data.length))
5158 {
5159 Status = -EFAULT;
5160 }
5161 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_QUERY_MULTIPLE_CARD_SUPPORT(=%d) \n", i));
5162 break;
5163#ifdef SNMP_SUPPORT
5164 case RT_OID_802_11_MAC_ADDRESS:
5165 wrq->u.data.length = MAC_ADDR_LEN;
5166 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CurrentAddress, wrq->u.data.length);
5167 break;
5168
5169 case RT_OID_802_11_MANUFACTUREROUI:
5170 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTUREROUI \n"));
5171 wrq->u.data.length = ManufacturerOUI_LEN;
5172 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CurrentAddress, wrq->u.data.length);
5173 break;
5174
5175 case RT_OID_802_11_MANUFACTURERNAME:
5176 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTURERNAME \n"));
5177 wrq->u.data.length = strlen(ManufacturerNAME);
5178 Status = copy_to_user(wrq->u.data.pointer, ManufacturerNAME, wrq->u.data.length);
5179 break;
5180
5181 case RT_OID_802_11_RESOURCETYPEIDNAME:
5182 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_RESOURCETYPEIDNAME \n"));
5183 wrq->u.data.length = strlen(ResourceTypeIdName);
5184 Status = copy_to_user(wrq->u.data.pointer, ResourceTypeIdName, wrq->u.data.length);
5185 break;
5186
5187 case RT_OID_802_11_PRIVACYOPTIONIMPLEMENTED:
5188 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PRIVACYOPTIONIMPLEMENTED \n"));
5189 ulInfo = 1; // 1 is support wep else 2 is not support.
5190 wrq->u.data.length = sizeof(ulInfo);
5191 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
5192 break;
5193
5194 case RT_OID_802_11_POWERMANAGEMENTMODE:
5195 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_POWERMANAGEMENTMODE \n"));
5196 if (pAdapter->StaCfg.Psm == PSMP_ACTION)
5197 ulInfo = 1; // 1 is power active else 2 is power save.
5198 else
5199 ulInfo = 2;
5200
5201 wrq->u.data.length = sizeof(ulInfo);
5202 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
5203 break;
5204
5205 case OID_802_11_WEPDEFAULTKEYVALUE:
5206 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_WEPDEFAULTKEYVALUE \n"));
5207 //KeyIdxValue.KeyIdx = pAd->PortCfg.MBSSID[pAd->IoctlIF].DefaultKeyId;
5208 pKeyIdxValue = wrq->u.data.pointer;
5209 DBGPRINT(RT_DEBUG_TRACE,("KeyIdxValue.KeyIdx = %d, \n",pKeyIdxValue->KeyIdx));
5210 valueLen = pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen;
5211 NdisMoveMemory(pKeyIdxValue->Value,
5212 &pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key,
5213 valueLen);
5214 pKeyIdxValue->Value[valueLen]='\0';
5215
5216 wrq->u.data.length = sizeof(DefaultKeyIdxValue);
5217
5218 Status = copy_to_user(wrq->u.data.pointer, pKeyIdxValue, wrq->u.data.length);
5219 DBGPRINT(RT_DEBUG_TRACE,("DefaultKeyId = %d, total len = %d, str len=%d, KeyValue= %02x %02x %02x %02x \n", pAdapter->StaCfg.DefaultKeyId, wrq->u.data.length, pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen,
5220 pAdapter->SharedKey[BSS0][0].Key[0],
5221 pAdapter->SharedKey[BSS0][1].Key[0],
5222 pAdapter->SharedKey[BSS0][2].Key[0],
5223 pAdapter->SharedKey[BSS0][3].Key[0]));
5224 break;
5225
5226 case OID_802_11_WEPDEFAULTKEYID:
5227 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_WEPDEFAULTKEYID \n"));
5228 wrq->u.data.length = sizeof(UCHAR);
5229 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->StaCfg.DefaultKeyId, wrq->u.data.length);
5230 DBGPRINT(RT_DEBUG_TRACE, ("DefaultKeyId =%d \n", pAdapter->StaCfg.DefaultKeyId));
5231 break;
5232
5233 case RT_OID_802_11_WEPKEYMAPPINGLENGTH:
5234 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_WEPKEYMAPPINGLENGTH \n"));
5235 wrq->u.data.length = sizeof(UCHAR);
5236 Status = copy_to_user(wrq->u.data.pointer,
5237 &pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen,
5238 wrq->u.data.length);
5239 break;
5240
5241 case OID_802_11_SHORTRETRYLIMIT:
5242 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_SHORTRETRYLIMIT \n"));
5243 wrq->u.data.length = sizeof(ULONG);
5244 RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
5245 ShortRetryLimit = tx_rty_cfg.field.ShortRtyLimit;
5246 DBGPRINT(RT_DEBUG_TRACE, ("ShortRetryLimit =%ld, tx_rty_cfg.field.ShortRetryLimit=%d\n", ShortRetryLimit, tx_rty_cfg.field.ShortRtyLimit));
5247 Status = copy_to_user(wrq->u.data.pointer, &ShortRetryLimit, wrq->u.data.length);
5248 break;
5249
5250 case OID_802_11_LONGRETRYLIMIT:
5251 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_LONGRETRYLIMIT \n"));
5252 wrq->u.data.length = sizeof(ULONG);
5253 RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
5254 LongRetryLimit = tx_rty_cfg.field.LongRtyLimit;
5255 DBGPRINT(RT_DEBUG_TRACE, ("LongRetryLimit =%ld, tx_rty_cfg.field.LongRtyLimit=%d\n", LongRetryLimit, tx_rty_cfg.field.LongRtyLimit));
5256 Status = copy_to_user(wrq->u.data.pointer, &LongRetryLimit, wrq->u.data.length);
5257 break;
5258
5259 case RT_OID_802_11_PRODUCTID:
5260 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PRODUCTID \n"));
5261
5262#ifdef RT2870
5263 sprintf(tmp, "%04x %04x\n", ((POS_COOKIE)pAdapter->OS_Cookie)->pUsb_Dev->descriptor.idVendor ,((POS_COOKIE)pAdapter->OS_Cookie)->pUsb_Dev->descriptor.idProduct);
5264
5265#endif // RT2870 //
5266 wrq->u.data.length = strlen(tmp);
5267 Status = copy_to_user(wrq->u.data.pointer, tmp, wrq->u.data.length);
5268 break;
5269
5270 case RT_OID_802_11_MANUFACTUREID:
5271 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTUREID \n"));
5272 wrq->u.data.length = strlen(ManufacturerNAME);
5273 Status = copy_to_user(wrq->u.data.pointer, ManufacturerNAME, wrq->u.data.length);
5274 break;
5275
5276 case OID_802_11_CURRENTCHANNEL:
5277 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CURRENTCHANNEL \n"));
5278 wrq->u.data.length = sizeof(UCHAR);
5279 DBGPRINT(RT_DEBUG_TRACE, ("sizeof UCHAR=%d, channel=%d \n", sizeof(UCHAR), pAdapter->CommonCfg.Channel));
5280 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Channel, wrq->u.data.length);
5281 DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5282 break;
5283#endif //SNMP_SUPPORT
5284
5285 case OID_802_11_BUILD_CHANNEL_EX:
5286 {
5287 UCHAR value;
5288 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BUILD_CHANNEL_EX \n"));
5289 wrq->u.data.length = sizeof(UCHAR);
5290#ifdef EXT_BUILD_CHANNEL_LIST
5291 DBGPRINT(RT_DEBUG_TRACE, ("Support EXT_BUILD_CHANNEL_LIST.\n"));
5292 value = 1;
5293#else
5294 DBGPRINT(RT_DEBUG_TRACE, ("Doesn't support EXT_BUILD_CHANNEL_LIST.\n"));
5295 value = 0;
5296#endif // EXT_BUILD_CHANNEL_LIST //
5297 Status = copy_to_user(wrq->u.data.pointer, &value, 1);
5298 DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5299 }
5300 break;
5301
5302 case OID_802_11_GET_CH_LIST:
5303 {
5304 PRT_CHANNEL_LIST_INFO pChListBuf;
5305
5306 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_CH_LIST \n"));
5307 if (pAdapter->ChannelListNum == 0)
5308 {
5309 wrq->u.data.length = 0;
5310 break;
5311 }
5312
5313 pChListBuf = (RT_CHANNEL_LIST_INFO *) kmalloc(sizeof(RT_CHANNEL_LIST_INFO), MEM_ALLOC_FLAG);
5314 if (pChListBuf == NULL)
5315 {
5316 wrq->u.data.length = 0;
5317 break;
5318 }
5319
5320 pChListBuf->ChannelListNum = pAdapter->ChannelListNum;
5321 for (i = 0; i < pChListBuf->ChannelListNum; i++)
5322 pChListBuf->ChannelList[i] = pAdapter->ChannelList[i].Channel;
5323
5324 wrq->u.data.length = sizeof(RT_CHANNEL_LIST_INFO);
5325 Status = copy_to_user(wrq->u.data.pointer, pChListBuf, sizeof(RT_CHANNEL_LIST_INFO));
5326 DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5327
5328 if (pChListBuf)
5329 kfree(pChListBuf);
5330 }
5331 break;
5332
5333 case OID_802_11_GET_COUNTRY_CODE:
5334 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_COUNTRY_CODE \n"));
5335 wrq->u.data.length = 2;
5336 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.CountryCode, 2);
5337 DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5338 break;
5339
5340 case OID_802_11_GET_CHANNEL_GEOGRAPHY:
5341 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_CHANNEL_GEOGRAPHY \n"));
5342 wrq->u.data.length = 1;
5343 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Geography, 1);
5344 DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5345 break;
5346
5347
5348#ifdef QOS_DLS_SUPPORT
5349 case RT_OID_802_11_QUERY_DLS:
5350 wrq->u.data.length = sizeof(BOOLEAN);
5351 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bDLSCapable, wrq->u.data.length);
5352 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_DLS(=%d)\n", pAdapter->CommonCfg.bDLSCapable));
5353 break;
5354
5355 case RT_OID_802_11_QUERY_DLS_PARAM:
5356 {
5357 PRT_802_11_DLS_INFO pDlsInfo = kmalloc(sizeof(RT_802_11_DLS_INFO), GFP_ATOMIC);
5358 if (pDlsInfo == NULL)
5359 break;
5360
5361 for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
5362 {
5363 RTMPMoveMemory(&pDlsInfo->Entry[i], &pAdapter->StaCfg.DLSEntry[i], sizeof(RT_802_11_DLS_UI));
5364 }
5365
5366 pDlsInfo->num = MAX_NUM_OF_DLS_ENTRY;
5367 wrq->u.data.length = sizeof(RT_802_11_DLS_INFO);
5368 Status = copy_to_user(wrq->u.data.pointer, pDlsInfo, wrq->u.data.length);
5369 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_DLS_PARAM\n"));
5370
5371 if (pDlsInfo)
5372 kfree(pDlsInfo);
5373 }
5374 break;
5375#endif // QOS_DLS_SUPPORT //
5376 default:
5377 DBGPRINT(RT_DEBUG_TRACE, ("Query::unknown IOCTL's subcmd = 0x%08x\n", cmd));
5378 Status = -EOPNOTSUPP;
5379 break;
5380 }
5381 return Status;
5382}
5383
5384INT rt28xx_sta_ioctl(
5385 IN struct net_device *net_dev,
5386 IN OUT struct ifreq *rq,
5387 IN INT cmd)
5388{
5389 POS_COOKIE pObj;
5390 VIRTUAL_ADAPTER *pVirtualAd = NULL;
5391 RTMP_ADAPTER *pAd = NULL;
5392 struct iwreq *wrq = (struct iwreq *) rq;
5393 BOOLEAN StateMachineTouched = FALSE;
5394 INT Status = NDIS_STATUS_SUCCESS;
5395 USHORT subcmd;
5396
5397 if (net_dev->priv_flags == INT_MAIN)
5398 {
5399 pAd = net_dev->ml_priv;
5400 }
5401 else
5402 {
5403 pVirtualAd = net_dev->ml_priv;
5404 pAd = pVirtualAd->RtmpDev->ml_priv;
5405 }
5406 pObj = (POS_COOKIE) pAd->OS_Cookie;
5407
5408 if (pAd == NULL)
5409 {
5410 /* if 1st open fail, pAd will be free;
5411 So the net_dev->ml_priv will be NULL in 2rd open */
5412 return -ENETDOWN;
5413 }
5414
5415 //check if the interface is down
5416 if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
5417 {
5418#ifdef CONFIG_APSTA_MIXED_SUPPORT
5419 if (wrq->u.data.pointer == NULL)
5420 {
5421 return Status;
5422 }
5423
5424 if (strstr(wrq->u.data.pointer, "OpMode") == NULL)
5425#endif // CONFIG_APSTA_MIXED_SUPPORT //
5426 {
5427 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
5428 return -ENETDOWN;
5429 }
5430 }
5431
5432 { // determine this ioctl command is comming from which interface.
5433 pObj->ioctl_if_type = INT_MAIN;
5434 pObj->ioctl_if = MAIN_MBSSID;
5435 }
5436
5437 switch(cmd)
5438 {
5439#ifdef RALINK_ATE
5440#ifdef RALINK_28xx_QA
5441 case RTPRIV_IOCTL_ATE:
5442 {
5443 RtmpDoAte(pAd, wrq);
5444 }
5445 break;
5446#endif // RALINK_28xx_QA //
5447#endif // RALINK_ATE //
5448 case SIOCGIFHWADDR:
5449 DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIFHWADDR\n"));
5450 memcpy(wrq->u.name, pAd->CurrentAddress, ETH_ALEN);
5451 break;
5452 case SIOCGIWNAME:
5453 {
5454 char *name=&wrq->u.name[0];
5455 rt_ioctl_giwname(net_dev, NULL, name, NULL);
5456 break;
5457 }
5458 case SIOCGIWESSID: //Get ESSID
5459 {
5460 struct iw_point *essid=&wrq->u.essid;
5461 rt_ioctl_giwessid(net_dev, NULL, essid, essid->pointer);
5462 break;
5463 }
5464 case SIOCSIWESSID: //Set ESSID
5465 {
5466 struct iw_point *essid=&wrq->u.essid;
5467 rt_ioctl_siwessid(net_dev, NULL, essid, essid->pointer);
5468 break;
5469 }
5470 case SIOCSIWNWID: // set network id (the cell)
5471 case SIOCGIWNWID: // get network id
5472 Status = -EOPNOTSUPP;
5473 break;
5474 case SIOCSIWFREQ: //set channel/frequency (Hz)
5475 {
5476 struct iw_freq *freq=&wrq->u.freq;
5477 rt_ioctl_siwfreq(net_dev, NULL, freq, NULL);
5478 break;
5479 }
5480 case SIOCGIWFREQ: // get channel/frequency (Hz)
5481 {
5482 struct iw_freq *freq=&wrq->u.freq;
5483 rt_ioctl_giwfreq(net_dev, NULL, freq, NULL);
5484 break;
5485 }
5486 case SIOCSIWNICKN: //set node name/nickname
5487 {
5488 struct iw_point *data=&wrq->u.data;
5489 rt_ioctl_siwnickn(net_dev, NULL, data, NULL);
5490 break;
5491 }
5492 case SIOCGIWNICKN: //get node name/nickname
5493 {
5494 struct iw_point *data=&wrq->u.data;
5495 rt_ioctl_giwnickn(net_dev, NULL, data, NULL);
5496 break;
5497 }
5498 case SIOCGIWRATE: //get default bit rate (bps)
5499 rt_ioctl_giwrate(net_dev, NULL, &wrq->u, NULL);
5500 break;
5501 case SIOCSIWRATE: //set default bit rate (bps)
5502 rt_ioctl_siwrate(net_dev, NULL, &wrq->u, NULL);
5503 break;
5504 case SIOCGIWRTS: // get RTS/CTS threshold (bytes)
5505 {
5506 struct iw_param *rts=&wrq->u.rts;
5507 rt_ioctl_giwrts(net_dev, NULL, rts, NULL);
5508 break;
5509 }
5510 case SIOCSIWRTS: //set RTS/CTS threshold (bytes)
5511 {
5512 struct iw_param *rts=&wrq->u.rts;
5513 rt_ioctl_siwrts(net_dev, NULL, rts, NULL);
5514 break;
5515 }
5516 case SIOCGIWFRAG: //get fragmentation thr (bytes)
5517 {
5518 struct iw_param *frag=&wrq->u.frag;
5519 rt_ioctl_giwfrag(net_dev, NULL, frag, NULL);
5520 break;
5521 }
5522 case SIOCSIWFRAG: //set fragmentation thr (bytes)
5523 {
5524 struct iw_param *frag=&wrq->u.frag;
5525 rt_ioctl_siwfrag(net_dev, NULL, frag, NULL);
5526 break;
5527 }
5528 case SIOCGIWENCODE: //get encoding token & mode
5529 {
5530 struct iw_point *erq=&wrq->u.encoding;
5531 if(erq->pointer)
5532 rt_ioctl_giwencode(net_dev, NULL, erq, erq->pointer);
5533 break;
5534 }
5535 case SIOCSIWENCODE: //set encoding token & mode
5536 {
5537 struct iw_point *erq=&wrq->u.encoding;
5538 if(erq->pointer)
5539 rt_ioctl_siwencode(net_dev, NULL, erq, erq->pointer);
5540 break;
5541 }
5542 case SIOCGIWAP: //get access point MAC addresses
5543 {
5544 struct sockaddr *ap_addr=&wrq->u.ap_addr;
5545 rt_ioctl_giwap(net_dev, NULL, ap_addr, ap_addr->sa_data);
5546 break;
5547 }
5548 case SIOCSIWAP: //set access point MAC addresses
5549 {
5550 struct sockaddr *ap_addr=&wrq->u.ap_addr;
5551 rt_ioctl_siwap(net_dev, NULL, ap_addr, ap_addr->sa_data);
5552 break;
5553 }
5554 case SIOCGIWMODE: //get operation mode
5555 {
5556 __u32 *mode=&wrq->u.mode;
5557 rt_ioctl_giwmode(net_dev, NULL, mode, NULL);
5558 break;
5559 }
5560 case SIOCSIWMODE: //set operation mode
5561 {
5562 __u32 *mode=&wrq->u.mode;
5563 rt_ioctl_siwmode(net_dev, NULL, mode, NULL);
5564 break;
5565 }
5566 case SIOCGIWSENS: //get sensitivity (dBm)
5567 case SIOCSIWSENS: //set sensitivity (dBm)
5568 case SIOCGIWPOWER: //get Power Management settings
5569 case SIOCSIWPOWER: //set Power Management settings
5570 case SIOCGIWTXPOW: //get transmit power (dBm)
5571 case SIOCSIWTXPOW: //set transmit power (dBm)
5572 case SIOCGIWRANGE: //Get range of parameters
5573 case SIOCGIWRETRY: //get retry limits and lifetime
5574 case SIOCSIWRETRY: //set retry limits and lifetime
5575 Status = -EOPNOTSUPP;
5576 break;
5577 case RT_PRIV_IOCTL:
5578 case RT_PRIV_IOCTL_EXT:
5579 subcmd = wrq->u.data.flags;
5580 if( subcmd & OID_GET_SET_TOGGLE)
5581 Status = RTMPSetInformation(pAd, rq, subcmd);
5582 else
5583 Status = RTMPQueryInformation(pAd, rq, subcmd);
5584 break;
5585 case SIOCGIWPRIV:
5586 if (wrq->u.data.pointer)
5587 {
5588 if ( access_ok(VERIFY_WRITE, wrq->u.data.pointer, sizeof(privtab)) != TRUE)
5589 break;
5590 wrq->u.data.length = sizeof(privtab) / sizeof(privtab[0]);
5591 if (copy_to_user(wrq->u.data.pointer, privtab, sizeof(privtab)))
5592 Status = -EFAULT;
5593 }
5594 break;
5595 case RTPRIV_IOCTL_SET:
5596 if(access_ok(VERIFY_READ, wrq->u.data.pointer, wrq->u.data.length) != TRUE)
5597 break;
5598 rt_ioctl_setparam(net_dev, NULL, NULL, wrq->u.data.pointer);
5599 break;
5600 case RTPRIV_IOCTL_GSITESURVEY:
5601 RTMPIoctlGetSiteSurvey(pAd, wrq);
5602 break;
5603#ifdef DBG
5604 case RTPRIV_IOCTL_MAC:
5605 RTMPIoctlMAC(pAd, wrq);
5606 break;
5607 case RTPRIV_IOCTL_E2P:
5608 RTMPIoctlE2PROM(pAd, wrq);
5609 break;
5610#ifdef RT30xx
5611 case RTPRIV_IOCTL_RF:
5612 RTMPIoctlRF(pAd, wrq);
5613 break;
5614#endif // RT30xx //
5615#endif // DBG //
5616 case SIOCETHTOOL:
5617 break;
5618 default:
5619 DBGPRINT(RT_DEBUG_ERROR, ("IOCTL::unknown IOCTL's cmd = 0x%08x\n", cmd));
5620 Status = -EOPNOTSUPP;
5621 break;
5622 }
5623
5624 if(StateMachineTouched) // Upper layer sent a MLME-related operations
5625 RT28XX_MLME_HANDLER(pAd);
5626
5627 return Status;
5628}
5629
5630/*
5631 ==========================================================================
5632 Description:
5633 Set SSID
5634 Return:
5635 TRUE if all parameters are OK, FALSE otherwise
5636 ==========================================================================
5637*/
5638INT Set_SSID_Proc(
5639 IN PRTMP_ADAPTER pAdapter,
5640 IN PUCHAR arg)
5641{
5642 NDIS_802_11_SSID Ssid, *pSsid=NULL;
5643 BOOLEAN StateMachineTouched = FALSE;
5644 int success = TRUE;
5645
5646 if( strlen(arg) <= MAX_LEN_OF_SSID)
5647 {
5648 NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
5649 if (strlen(arg) != 0)
5650 {
5651 NdisMoveMemory(Ssid.Ssid, arg, strlen(arg));
5652 Ssid.SsidLength = strlen(arg);
5653 }
5654 else //ANY ssid
5655 {
5656 Ssid.SsidLength = 0;
5657 memcpy(Ssid.Ssid, "", 0);
5658 pAdapter->StaCfg.BssType = BSS_INFRA;
5659 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
5660 pAdapter->StaCfg.WepStatus = Ndis802_11EncryptionDisabled;
5661 }
5662 pSsid = &Ssid;
5663
5664 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
5665 {
5666 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
5667 DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
5668 }
5669
5670 pAdapter->MlmeAux.CurrReqIsFromNdis = TRUE;
5671 pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
5672 pAdapter->bConfigChanged = TRUE;
5673
5674 MlmeEnqueue(pAdapter,
5675 MLME_CNTL_STATE_MACHINE,
5676 OID_802_11_SSID,
5677 sizeof(NDIS_802_11_SSID),
5678 (VOID *)pSsid);
5679
5680 StateMachineTouched = TRUE;
5681 DBGPRINT(RT_DEBUG_TRACE, ("Set_SSID_Proc::(Len=%d,Ssid=%s)\n", Ssid.SsidLength, Ssid.Ssid));
5682 }
5683 else
5684 success = FALSE;
5685
5686 if (StateMachineTouched) // Upper layer sent a MLME-related operations
5687 RT28XX_MLME_HANDLER(pAdapter);
5688
5689 return success;
5690}
5691
5692#ifdef WMM_SUPPORT
5693/*
5694 ==========================================================================
5695 Description:
5696 Set WmmCapable Enable or Disable
5697 Return:
5698 TRUE if all parameters are OK, FALSE otherwise
5699 ==========================================================================
5700*/
5701INT Set_WmmCapable_Proc(
5702 IN PRTMP_ADAPTER pAd,
5703 IN PUCHAR arg)
5704{
5705 BOOLEAN bWmmCapable;
5706
5707 bWmmCapable = simple_strtol(arg, 0, 10);
5708
5709 if ((bWmmCapable == 1)
5710#ifdef RT2870
5711 && (pAd->NumberOfPipes >= 5)
5712#endif // RT2870 //
5713 )
5714 pAd->CommonCfg.bWmmCapable = TRUE;
5715 else if (bWmmCapable == 0)
5716 pAd->CommonCfg.bWmmCapable = FALSE;
5717 else
5718 return FALSE; //Invalid argument
5719
5720 DBGPRINT(RT_DEBUG_TRACE, ("Set_WmmCapable_Proc::(bWmmCapable=%d)\n",
5721 pAd->CommonCfg.bWmmCapable));
5722
5723 return TRUE;
5724}
5725#endif // WMM_SUPPORT //
5726
5727/*
5728 ==========================================================================
5729 Description:
5730 Set Network Type(Infrastructure/Adhoc mode)
5731 Return:
5732 TRUE if all parameters are OK, FALSE otherwise
5733 ==========================================================================
5734*/
5735INT Set_NetworkType_Proc(
5736 IN PRTMP_ADAPTER pAdapter,
5737 IN PUCHAR arg)
5738{
5739 UINT32 Value = 0;
5740
5741 if (strcmp(arg, "Adhoc") == 0)
5742 {
5743 if (pAdapter->StaCfg.BssType != BSS_ADHOC)
5744 {
5745 // Config has changed
5746 pAdapter->bConfigChanged = TRUE;
5747 if (MONITOR_ON(pAdapter))
5748 {
5749 RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, STANORMAL);
5750 RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
5751 Value &= (~0x80);
5752 RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
5753 OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
5754 pAdapter->StaCfg.bAutoReconnect = TRUE;
5755 LinkDown(pAdapter, FALSE);
5756 }
5757 if (INFRA_ON(pAdapter))
5758 {
5759 //BOOLEAN Cancelled;
5760 // Set the AutoReconnectSsid to prevent it reconnect to old SSID
5761 // Since calling this indicate user don't want to connect to that SSID anymore.
5762 pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
5763 NdisZeroMemory(pAdapter->MlmeAux.AutoReconnectSsid, pAdapter->MlmeAux.AutoReconnectSsidLen);
5764
5765 LinkDown(pAdapter, FALSE);
5766
5767 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event BB!\n"));
5768 }
5769 }
5770 pAdapter->StaCfg.BssType = BSS_ADHOC;
5771 pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
5772 DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(AD-HOC)\n"));
5773 }
5774 else if (strcmp(arg, "Infra") == 0)
5775 {
5776 if (pAdapter->StaCfg.BssType != BSS_INFRA)
5777 {
5778 // Config has changed
5779 pAdapter->bConfigChanged = TRUE;
5780 if (MONITOR_ON(pAdapter))
5781 {
5782 RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, STANORMAL);
5783 RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
5784 Value &= (~0x80);
5785 RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
5786 OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
5787 pAdapter->StaCfg.bAutoReconnect = TRUE;
5788 LinkDown(pAdapter, FALSE);
5789 }
5790 if (ADHOC_ON(pAdapter))
5791 {
5792 // Set the AutoReconnectSsid to prevent it reconnect to old SSID
5793 // Since calling this indicate user don't want to connect to that SSID anymore.
5794 pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
5795 NdisZeroMemory(pAdapter->MlmeAux.AutoReconnectSsid, pAdapter->MlmeAux.AutoReconnectSsidLen);
5796
5797 LinkDown(pAdapter, FALSE);
5798 }
5799 }
5800 pAdapter->StaCfg.BssType = BSS_INFRA;
5801 pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
5802 DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(INFRA)\n"));
5803
5804 pAdapter->StaCfg.BssType = BSS_INFRA;
5805 }
5806 else if (strcmp(arg, "Monitor") == 0)
5807 {
5808 UCHAR bbpValue = 0;
5809 BCN_TIME_CFG_STRUC csr;
5810 OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_INFRA_ON);
5811 OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_ADHOC_ON);
5812 OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
5813 // disable all periodic state machine
5814 pAdapter->StaCfg.bAutoReconnect = FALSE;
5815 // reset all mlme state machine
5816 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
5817 DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_MEDIA_STATE_CONNECTED \n"));
5818 if (pAdapter->CommonCfg.CentralChannel == 0)
5819 {
5820#ifdef DOT11_N_SUPPORT
5821 if (pAdapter->CommonCfg.PhyMode == PHY_11AN_MIXED)
5822 pAdapter->CommonCfg.CentralChannel = 36;
5823 else
5824#endif // DOT11_N_SUPPORT //
5825 pAdapter->CommonCfg.CentralChannel = 6;
5826 }
5827#ifdef DOT11_N_SUPPORT
5828 else
5829 N_ChannelCheck(pAdapter);
5830#endif // DOT11_N_SUPPORT //
5831
5832#ifdef DOT11_N_SUPPORT
5833 if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
5834 pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
5835 pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)
5836 {
5837 // 40MHz ,control channel at lower
5838 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
5839 bbpValue &= (~0x18);
5840 bbpValue |= 0x10;
5841 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
5842 pAdapter->CommonCfg.BBPCurrentBW = BW_40;
5843 // RX : control channel at lower
5844 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, &bbpValue);
5845 bbpValue &= (~0x20);
5846 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, bbpValue);
5847
5848 RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
5849 Value &= 0xfffffffe;
5850 RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
5851 pAdapter->CommonCfg.CentralChannel = pAdapter->CommonCfg.Channel + 2;
5852 AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.CentralChannel, FALSE);
5853 AsicLockChannel(pAdapter, pAdapter->CommonCfg.CentralChannel);
5854 DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
5855 pAdapter->CommonCfg.Channel,
5856 pAdapter->CommonCfg.CentralChannel));
5857 }
5858 else if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
5859 pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
5860 pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_BELOW)
5861 {
5862 // 40MHz ,control channel at upper
5863 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
5864 bbpValue &= (~0x18);
5865 bbpValue |= 0x10;
5866 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
5867 pAdapter->CommonCfg.BBPCurrentBW = BW_40;
5868 RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
5869 Value |= 0x1;
5870 RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
5871
5872 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, &bbpValue);
5873 bbpValue |= (0x20);
5874 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, bbpValue);
5875 pAdapter->CommonCfg.CentralChannel = pAdapter->CommonCfg.Channel - 2;
5876 AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.CentralChannel, FALSE);
5877 AsicLockChannel(pAdapter, pAdapter->CommonCfg.CentralChannel);
5878 DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
5879 pAdapter->CommonCfg.Channel,
5880 pAdapter->CommonCfg.CentralChannel));
5881 }
5882 else
5883#endif // DOT11_N_SUPPORT //
5884 {
5885 // 20MHz
5886 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
5887 bbpValue &= (~0x18);
5888 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
5889 pAdapter->CommonCfg.BBPCurrentBW = BW_20;
5890 AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.Channel, FALSE);
5891 AsicLockChannel(pAdapter, pAdapter->CommonCfg.Channel);
5892 DBGPRINT(RT_DEBUG_TRACE, ("BW_20, Channel(%d)\n", pAdapter->CommonCfg.Channel));
5893 }
5894 // Enable Rx with promiscuous reception
5895 RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, 0x3);
5896 // ASIC supporsts sniffer function with replacing RSSI with timestamp.
5897 //RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
5898 //Value |= (0x80);
5899 //RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
5900 // disable sync
5901 RTMP_IO_READ32(pAdapter, BCN_TIME_CFG, &csr.word);
5902 csr.field.bBeaconGen = 0;
5903 csr.field.bTBTTEnable = 0;
5904 csr.field.TsfSyncMode = 0;
5905 RTMP_IO_WRITE32(pAdapter, BCN_TIME_CFG, csr.word);
5906
5907 pAdapter->StaCfg.BssType = BSS_MONITOR;
5908 pAdapter->net_dev->type = ARPHRD_IEEE80211_PRISM; //ARPHRD_IEEE80211; // IEEE80211
5909 DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(MONITOR)\n"));
5910 }
5911
5912 // Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
5913 pAdapter->StaCfg.WpaState = SS_NOTUSE;
5914
5915 DBGPRINT(RT_DEBUG_TRACE, ("Set_NetworkType_Proc::(NetworkType=%d)\n", pAdapter->StaCfg.BssType));
5916
5917 return TRUE;
5918}
5919
5920/*
5921 ==========================================================================
5922 Description:
5923 Set Authentication mode
5924 Return:
5925 TRUE if all parameters are OK, FALSE otherwise
5926 ==========================================================================
5927*/
5928INT Set_AuthMode_Proc(
5929 IN PRTMP_ADAPTER pAdapter,
5930 IN PUCHAR arg)
5931{
5932 if ((strcmp(arg, "WEPAUTO") == 0) || (strcmp(arg, "wepauto") == 0))
5933 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch;
5934 else if ((strcmp(arg, "OPEN") == 0) || (strcmp(arg, "open") == 0))
5935 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
5936 else if ((strcmp(arg, "SHARED") == 0) || (strcmp(arg, "shared") == 0))
5937 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
5938 else if ((strcmp(arg, "WPAPSK") == 0) || (strcmp(arg, "wpapsk") == 0))
5939 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
5940 else if ((strcmp(arg, "WPANONE") == 0) || (strcmp(arg, "wpanone") == 0))
5941 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
5942 else if ((strcmp(arg, "WPA2PSK") == 0) || (strcmp(arg, "wpa2psk") == 0))
5943 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
5944#ifdef WPA_SUPPLICANT_SUPPORT
5945 else if ((strcmp(arg, "WPA") == 0) || (strcmp(arg, "wpa") == 0))
5946 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
5947 else if ((strcmp(arg, "WPA2") == 0) || (strcmp(arg, "wpa2") == 0))
5948 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
5949#endif // WPA_SUPPLICANT_SUPPORT //
5950 else
5951 return FALSE;
5952
5953 pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
5954
5955 DBGPRINT(RT_DEBUG_TRACE, ("Set_AuthMode_Proc::(AuthMode=%d)\n", pAdapter->StaCfg.AuthMode));
5956
5957 return TRUE;
5958}
5959
5960/*
5961 ==========================================================================
5962 Description:
5963 Set Encryption Type
5964 Return:
5965 TRUE if all parameters are OK, FALSE otherwise
5966 ==========================================================================
5967*/
5968INT Set_EncrypType_Proc(
5969 IN PRTMP_ADAPTER pAdapter,
5970 IN PUCHAR arg)
5971{
5972 if ((strcmp(arg, "NONE") == 0) || (strcmp(arg, "none") == 0))
5973 {
5974 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
5975 return TRUE; // do nothing
5976
5977 pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
5978 pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
5979 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
5980 }
5981 else if ((strcmp(arg, "WEP") == 0) || (strcmp(arg, "wep") == 0))
5982 {
5983 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
5984 return TRUE; // do nothing
5985
5986 pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
5987 pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
5988 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
5989 }
5990 else if ((strcmp(arg, "TKIP") == 0) || (strcmp(arg, "tkip") == 0))
5991 {
5992 if (pAdapter->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
5993 return TRUE; // do nothing
5994
5995 pAdapter->StaCfg.WepStatus = Ndis802_11Encryption2Enabled;
5996 pAdapter->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
5997 pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption2Enabled;
5998 }
5999 else if ((strcmp(arg, "AES") == 0) || (strcmp(arg, "aes") == 0))
6000 {
6001 if (pAdapter->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
6002 return TRUE; // do nothing
6003
6004 pAdapter->StaCfg.WepStatus = Ndis802_11Encryption3Enabled;
6005 pAdapter->StaCfg.PairCipher = Ndis802_11Encryption3Enabled;
6006 pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption3Enabled;
6007 }
6008 else
6009 return FALSE;
6010
6011 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
6012
6013 DBGPRINT(RT_DEBUG_TRACE, ("Set_EncrypType_Proc::(EncrypType=%d)\n", pAdapter->StaCfg.WepStatus));
6014
6015 return TRUE;
6016}
6017
6018/*
6019 ==========================================================================
6020 Description:
6021 Set Default Key ID
6022 Return:
6023 TRUE if all parameters are OK, FALSE otherwise
6024 ==========================================================================
6025*/
6026INT Set_DefaultKeyID_Proc(
6027 IN PRTMP_ADAPTER pAdapter,
6028 IN PUCHAR arg)
6029{
6030 ULONG KeyIdx;
6031
6032 KeyIdx = simple_strtol(arg, 0, 10);
6033 if((KeyIdx >= 1 ) && (KeyIdx <= 4))
6034 pAdapter->StaCfg.DefaultKeyId = (UCHAR) (KeyIdx - 1 );
6035 else
6036 return FALSE; //Invalid argument
6037
6038 DBGPRINT(RT_DEBUG_TRACE, ("Set_DefaultKeyID_Proc::(DefaultKeyID=%d)\n", pAdapter->StaCfg.DefaultKeyId));
6039
6040 return TRUE;
6041}
6042
6043/*
6044 ==========================================================================
6045 Description:
6046 Set WEP KEY1
6047 Return:
6048 TRUE if all parameters are OK, FALSE otherwise
6049 ==========================================================================
6050*/
6051INT Set_Key1_Proc(
6052 IN PRTMP_ADAPTER pAdapter,
6053 IN PUCHAR arg)
6054{
6055 int KeyLen;
6056 int i;
6057 UCHAR CipherAlg=CIPHER_WEP64;
6058
6059 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6060 return TRUE; // do nothing
6061
6062 KeyLen = strlen(arg);
6063
6064 switch (KeyLen)
6065 {
6066 case 5: //wep 40 Ascii type
6067 pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen;
6068 memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen);
6069 CipherAlg = CIPHER_WEP64;
6070 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Ascii"));
6071 break;
6072 case 10: //wep 40 Hex type
6073 for(i=0; i < KeyLen; i++)
6074 {
6075 if( !isxdigit(*(arg+i)) )
6076 return FALSE; //Not Hex value;
6077 }
6078 pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen / 2 ;
6079 AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2);
6080 CipherAlg = CIPHER_WEP64;
6081 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex"));
6082 break;
6083 case 13: //wep 104 Ascii type
6084 pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen;
6085 memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen);
6086 CipherAlg = CIPHER_WEP128;
6087 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Ascii"));
6088 break;
6089 case 26: //wep 104 Hex type
6090 for(i=0; i < KeyLen; i++)
6091 {
6092 if( !isxdigit(*(arg+i)) )
6093 return FALSE; //Not Hex value;
6094 }
6095 pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen / 2 ;
6096 AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2);
6097 CipherAlg = CIPHER_WEP128;
6098 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex"));
6099 break;
6100 default: //Invalid argument
6101 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::Invalid argument (=%s)\n", arg));
6102 return FALSE;
6103 }
6104
6105 pAdapter->SharedKey[BSS0][0].CipherAlg = CipherAlg;
6106
6107 // Set keys (into ASIC)
6108 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6109 ; // not support
6110 else // Old WEP stuff
6111 {
6112 AsicAddSharedKeyEntry(pAdapter,
6113 0,
6114 0,
6115 pAdapter->SharedKey[BSS0][0].CipherAlg,
6116 pAdapter->SharedKey[BSS0][0].Key,
6117 NULL,
6118 NULL);
6119 }
6120
6121 return TRUE;
6122}
6123/*
6124 ==========================================================================
6125
6126 Description:
6127 Set WEP KEY2
6128 Return:
6129 TRUE if all parameters are OK, FALSE otherwise
6130 ==========================================================================
6131*/
6132INT Set_Key2_Proc(
6133 IN PRTMP_ADAPTER pAdapter,
6134 IN PUCHAR arg)
6135{
6136 int KeyLen;
6137 int i;
6138 UCHAR CipherAlg=CIPHER_WEP64;
6139
6140 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6141 return TRUE; // do nothing
6142
6143 KeyLen = strlen(arg);
6144
6145 switch (KeyLen)
6146 {
6147 case 5: //wep 40 Ascii type
6148 pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen;
6149 memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen);
6150 CipherAlg = CIPHER_WEP64;
6151 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii"));
6152 break;
6153 case 10: //wep 40 Hex type
6154 for(i=0; i < KeyLen; i++)
6155 {
6156 if( !isxdigit(*(arg+i)) )
6157 return FALSE; //Not Hex value;
6158 }
6159 pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ;
6160 AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2);
6161 CipherAlg = CIPHER_WEP64;
6162 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex"));
6163 break;
6164 case 13: //wep 104 Ascii type
6165 pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen;
6166 memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen);
6167 CipherAlg = CIPHER_WEP128;
6168 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii"));
6169 break;
6170 case 26: //wep 104 Hex type
6171 for(i=0; i < KeyLen; i++)
6172 {
6173 if( !isxdigit(*(arg+i)) )
6174 return FALSE; //Not Hex value;
6175 }
6176 pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ;
6177 AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2);
6178 CipherAlg = CIPHER_WEP128;
6179 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex"));
6180 break;
6181 default: //Invalid argument
6182 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::Invalid argument (=%s)\n", arg));
6183 return FALSE;
6184 }
6185 pAdapter->SharedKey[BSS0][1].CipherAlg = CipherAlg;
6186
6187 // Set keys (into ASIC)
6188 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6189 ; // not support
6190 else // Old WEP stuff
6191 {
6192 AsicAddSharedKeyEntry(pAdapter,
6193 0,
6194 1,
6195 pAdapter->SharedKey[BSS0][1].CipherAlg,
6196 pAdapter->SharedKey[BSS0][1].Key,
6197 NULL,
6198 NULL);
6199 }
6200
6201 return TRUE;
6202}
6203/*
6204 ==========================================================================
6205 Description:
6206 Set WEP KEY3
6207 Return:
6208 TRUE if all parameters are OK, FALSE otherwise
6209 ==========================================================================
6210*/
6211INT Set_Key3_Proc(
6212 IN PRTMP_ADAPTER pAdapter,
6213 IN PUCHAR arg)
6214{
6215 int KeyLen;
6216 int i;
6217 UCHAR CipherAlg=CIPHER_WEP64;
6218
6219 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6220 return TRUE; // do nothing
6221
6222 KeyLen = strlen(arg);
6223
6224 switch (KeyLen)
6225 {
6226 case 5: //wep 40 Ascii type
6227 pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen;
6228 memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen);
6229 CipherAlg = CIPHER_WEP64;
6230 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg));
6231 break;
6232 case 10: //wep 40 Hex type
6233 for(i=0; i < KeyLen; i++)
6234 {
6235 if( !isxdigit(*(arg+i)) )
6236 return FALSE; //Not Hex value;
6237 }
6238 pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ;
6239 AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2);
6240 CipherAlg = CIPHER_WEP64;
6241 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg));
6242 break;
6243 case 13: //wep 104 Ascii type
6244 pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen;
6245 memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen);
6246 CipherAlg = CIPHER_WEP128;
6247 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg));
6248 break;
6249 case 26: //wep 104 Hex type
6250 for(i=0; i < KeyLen; i++)
6251 {
6252 if( !isxdigit(*(arg+i)) )
6253 return FALSE; //Not Hex value;
6254 }
6255 pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ;
6256 AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2);
6257 CipherAlg = CIPHER_WEP128;
6258 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg));
6259 break;
6260 default: //Invalid argument
6261 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::Invalid argument (=%s)\n", arg));
6262 return FALSE;
6263 }
6264 pAdapter->SharedKey[BSS0][2].CipherAlg = CipherAlg;
6265
6266 // Set keys (into ASIC)
6267 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6268 ; // not support
6269 else // Old WEP stuff
6270 {
6271 AsicAddSharedKeyEntry(pAdapter,
6272 0,
6273 2,
6274 pAdapter->SharedKey[BSS0][2].CipherAlg,
6275 pAdapter->SharedKey[BSS0][2].Key,
6276 NULL,
6277 NULL);
6278 }
6279
6280 return TRUE;
6281}
6282/*
6283 ==========================================================================
6284 Description:
6285 Set WEP KEY4
6286 Return:
6287 TRUE if all parameters are OK, FALSE otherwise
6288 ==========================================================================
6289*/
6290INT Set_Key4_Proc(
6291 IN PRTMP_ADAPTER pAdapter,
6292 IN PUCHAR arg)
6293{
6294 int KeyLen;
6295 int i;
6296 UCHAR CipherAlg=CIPHER_WEP64;
6297
6298 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6299 return TRUE; // do nothing
6300
6301 KeyLen = strlen(arg);
6302
6303 switch (KeyLen)
6304 {
6305 case 5: //wep 40 Ascii type
6306 pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen;
6307 memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen);
6308 CipherAlg = CIPHER_WEP64;
6309 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii"));
6310 break;
6311 case 10: //wep 40 Hex type
6312 for(i=0; i < KeyLen; i++)
6313 {
6314 if( !isxdigit(*(arg+i)) )
6315 return FALSE; //Not Hex value;
6316 }
6317 pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ;
6318 AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2);
6319 CipherAlg = CIPHER_WEP64;
6320 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex"));
6321 break;
6322 case 13: //wep 104 Ascii type
6323 pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen;
6324 memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen);
6325 CipherAlg = CIPHER_WEP128;
6326 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii"));
6327 break;
6328 case 26: //wep 104 Hex type
6329 for(i=0; i < KeyLen; i++)
6330 {
6331 if( !isxdigit(*(arg+i)) )
6332 return FALSE; //Not Hex value;
6333 }
6334 pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ;
6335 AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2);
6336 CipherAlg = CIPHER_WEP128;
6337 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex"));
6338 break;
6339 default: //Invalid argument
6340 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::Invalid argument (=%s)\n", arg));
6341 return FALSE;
6342 }
6343 pAdapter->SharedKey[BSS0][3].CipherAlg = CipherAlg;
6344
6345 // Set keys (into ASIC)
6346 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6347 ; // not support
6348 else // Old WEP stuff
6349 {
6350 AsicAddSharedKeyEntry(pAdapter,
6351 0,
6352 3,
6353 pAdapter->SharedKey[BSS0][3].CipherAlg,
6354 pAdapter->SharedKey[BSS0][3].Key,
6355 NULL,
6356 NULL);
6357 }
6358
6359 return TRUE;
6360}
6361
6362/*
6363 ==========================================================================
6364 Description:
6365 Set WPA PSK key
6366 Return:
6367 TRUE if all parameters are OK, FALSE otherwise
6368 ==========================================================================
6369*/
6370INT Set_WPAPSK_Proc(
6371 IN PRTMP_ADAPTER pAdapter,
6372 IN PUCHAR arg)
6373{
6374 UCHAR keyMaterial[40];
6375
6376 if ((pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
6377 (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
6378 (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
6379 )
6380 return TRUE; // do nothing
6381
6382 DBGPRINT(RT_DEBUG_TRACE, ("Set_WPAPSK_Proc::(WPAPSK=%s)\n", arg));
6383
6384 NdisZeroMemory(keyMaterial, 40);
6385
6386 if ((strlen(arg) < 8) || (strlen(arg) > 64))
6387 {
6388 DBGPRINT(RT_DEBUG_TRACE, ("Set failed!!(WPAPSK=%s), WPAPSK key-string required 8 ~ 64 characters \n", arg));
6389 return FALSE;
6390 }
6391
6392 if (strlen(arg) == 64)
6393 {
6394 AtoH(arg, keyMaterial, 32);
6395 NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32);
6396
6397 }
6398 else
6399 {
6400 PasswordHash((char *)arg, pAdapter->MlmeAux.Ssid, pAdapter->MlmeAux.SsidLen, keyMaterial);
6401 NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32);
6402 }
6403
6404
6405
6406 if(pAdapter->StaCfg.BssType == BSS_ADHOC &&
6407 pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
6408 {
6409 pAdapter->StaCfg.WpaState = SS_NOTUSE;
6410 }
6411 else
6412 {
6413 // Start STA supplicant state machine
6414 pAdapter->StaCfg.WpaState = SS_START;
6415 }
6416
6417 return TRUE;
6418}
6419
6420/*
6421 ==========================================================================
6422 Description:
6423 Set Power Saving mode
6424 Return:
6425 TRUE if all parameters are OK, FALSE otherwise
6426 ==========================================================================
6427*/
6428INT Set_PSMode_Proc(
6429 IN PRTMP_ADAPTER pAdapter,
6430 IN PUCHAR arg)
6431{
6432 if (pAdapter->StaCfg.BssType == BSS_INFRA)
6433 {
6434 if ((strcmp(arg, "Max_PSP") == 0) ||
6435 (strcmp(arg, "max_psp") == 0) ||
6436 (strcmp(arg, "MAX_PSP") == 0))
6437 {
6438 // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
6439 // to exclude certain situations.
6440 if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
6441 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP;
6442 pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP;
6443 OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
6444 pAdapter->StaCfg.DefaultListenCount = 5;
6445
6446 }
6447 else if ((strcmp(arg, "Fast_PSP") == 0) ||
6448 (strcmp(arg, "fast_psp") == 0) ||
6449 (strcmp(arg, "FAST_PSP") == 0))
6450 {
6451 // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
6452 // to exclude certain situations.
6453 OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
6454 if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
6455 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP;
6456 pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP;
6457 pAdapter->StaCfg.DefaultListenCount = 3;
6458 }
6459 else if ((strcmp(arg, "Legacy_PSP") == 0) ||
6460 (strcmp(arg, "legacy_psp") == 0) ||
6461 (strcmp(arg, "LEGACY_PSP") == 0))
6462 {
6463 // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
6464 // to exclude certain situations.
6465 OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
6466 if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
6467 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP;
6468 pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP;
6469 pAdapter->StaCfg.DefaultListenCount = 3;
6470 }
6471 else
6472 {
6473 //Default Ndis802_11PowerModeCAM
6474 // clear PSM bit immediately
6475 MlmeSetPsmBit(pAdapter, PWR_ACTIVE);
6476 OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
6477 if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
6478 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
6479 pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
6480 }
6481
6482 DBGPRINT(RT_DEBUG_TRACE, ("Set_PSMode_Proc::(PSMode=%ld)\n", pAdapter->StaCfg.WindowsPowerMode));
6483 }
6484 else
6485 return FALSE;
6486
6487
6488 return TRUE;
6489}
6490
6491#ifdef WPA_SUPPLICANT_SUPPORT
6492/*
6493 ==========================================================================
6494 Description:
6495 Set WpaSupport flag.
6496 Value:
6497 0: Driver ignore wpa_supplicant.
6498 1: wpa_supplicant initiates scanning and AP selection.
6499 2: driver takes care of scanning, AP selection, and IEEE 802.11 association parameters.
6500 Return:
6501 TRUE if all parameters are OK, FALSE otherwise
6502 ==========================================================================
6503*/
6504INT Set_Wpa_Support(
6505 IN PRTMP_ADAPTER pAd,
6506 IN PUCHAR arg)
6507{
6508
6509 if ( simple_strtol(arg, 0, 10) == 0)
6510 pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
6511 else if ( simple_strtol(arg, 0, 10) == 1)
6512 pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE;
6513 else if ( simple_strtol(arg, 0, 10) == 2)
6514 pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE_WITH_WEB_UI;
6515 else
6516 pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
6517
6518 DBGPRINT(RT_DEBUG_TRACE, ("Set_Wpa_Support::(WpaSupplicantUP=%d)\n", pAd->StaCfg.WpaSupplicantUP));
6519
6520 return TRUE;
6521}
6522#endif // WPA_SUPPLICANT_SUPPORT //
6523
6524#ifdef DBG
6525/*
6526 ==========================================================================
6527 Description:
6528 Read / Write MAC
6529 Arguments:
6530 pAdapter Pointer to our adapter
6531 wrq Pointer to the ioctl argument
6532
6533 Return Value:
6534 None
6535
6536 Note:
6537 Usage:
6538 1.) iwpriv ra0 mac 0 ==> read MAC where Addr=0x0
6539 2.) iwpriv ra0 mac 0=12 ==> write MAC where Addr=0x0, value=12
6540 ==========================================================================
6541*/
6542VOID RTMPIoctlMAC(
6543 IN PRTMP_ADAPTER pAdapter,
6544 IN struct iwreq *wrq)
6545{
6546 CHAR *this_char;
6547 CHAR *value;
6548 INT j = 0, k = 0;
6549 CHAR msg[1024];
6550 CHAR arg[255];
6551 ULONG macAddr = 0;
6552 UCHAR temp[16], temp2[16];
6553 UINT32 macValue = 0;
6554 INT Status;
6555 BOOLEAN bIsPrintAllMAC = FALSE;
6556
6557
6558 memset(msg, 0x00, 1024);
6559 if (wrq->u.data.length > 1) //No parameters.
6560 {
6561 Status = copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length);
6562 sprintf(msg, "\n");
6563
6564 //Parsing Read or Write
6565 this_char = arg;
6566 if (!*this_char)
6567 goto next;
6568
6569 if ((value = rtstrchr(this_char, '=')) != NULL)
6570 *value++ = 0;
6571
6572 if (!value || !*value)
6573 { //Read
6574 // Sanity check
6575 if(strlen(this_char) > 4)
6576 goto next;
6577
6578 j = strlen(this_char);
6579 while(j-- > 0)
6580 {
6581 if(this_char[j] > 'f' || this_char[j] < '0')
6582 return;
6583 }
6584
6585 // Mac Addr
6586 k = j = strlen(this_char);
6587 while(j-- > 0)
6588 {
6589 this_char[4-k+j] = this_char[j];
6590 }
6591
6592 while(k < 4)
6593 this_char[3-k++]='0';
6594 this_char[4]='\0';
6595
6596 if(strlen(this_char) == 4)
6597 {
6598 AtoH(this_char, temp, 2);
6599 macAddr = *temp*256 + temp[1];
6600 if (macAddr < 0xFFFF)
6601 {
6602 RTMP_IO_READ32(pAdapter, macAddr, &macValue);
6603 DBGPRINT(RT_DEBUG_TRACE, ("MacAddr=%lx, MacValue=%x\n", macAddr, macValue));
6604 sprintf(msg+strlen(msg), "[0x%08lX]:%08X ", macAddr , macValue);
6605 }
6606 else
6607 {//Invalid parametes, so default printk all mac
6608 bIsPrintAllMAC = TRUE;
6609 goto next;
6610 }
6611 }
6612 }
6613 else
6614 { //Write
6615 memcpy(&temp2, value, strlen(value));
6616 temp2[strlen(value)] = '\0';
6617
6618 // Sanity check
6619 if((strlen(this_char) > 4) || strlen(temp2) > 8)
6620 goto next;
6621
6622 j = strlen(this_char);
6623 while(j-- > 0)
6624 {
6625 if(this_char[j] > 'f' || this_char[j] < '0')
6626 return;
6627 }
6628
6629 j = strlen(temp2);
6630 while(j-- > 0)
6631 {
6632 if(temp2[j] > 'f' || temp2[j] < '0')
6633 return;
6634 }
6635
6636 //MAC Addr
6637 k = j = strlen(this_char);
6638 while(j-- > 0)
6639 {
6640 this_char[4-k+j] = this_char[j];
6641 }
6642
6643 while(k < 4)
6644 this_char[3-k++]='0';
6645 this_char[4]='\0';
6646
6647 //MAC value
6648 k = j = strlen(temp2);
6649 while(j-- > 0)
6650 {
6651 temp2[8-k+j] = temp2[j];
6652 }
6653
6654 while(k < 8)
6655 temp2[7-k++]='0';
6656 temp2[8]='\0';
6657
6658 {
6659 AtoH(this_char, temp, 2);
6660 macAddr = *temp*256 + temp[1];
6661
6662 AtoH(temp2, temp, 4);
6663 macValue = *temp*256*256*256 + temp[1]*256*256 + temp[2]*256 + temp[3];
6664
6665 // debug mode
6666 if (macAddr == (HW_DEBUG_SETTING_BASE + 4))
6667 {
6668 // 0x2bf4: byte0 non-zero: enable R17 tuning, 0: disable R17 tuning
6669 if (macValue & 0x000000ff)
6670 {
6671 pAdapter->BbpTuning.bEnable = TRUE;
6672 DBGPRINT(RT_DEBUG_TRACE,("turn on R17 tuning\n"));
6673 }
6674 else
6675 {
6676 UCHAR R66;
6677 pAdapter->BbpTuning.bEnable = FALSE;
6678 R66 = 0x26 + GET_LNA_GAIN(pAdapter);
6679#ifdef RALINK_ATE
6680 if (ATE_ON(pAdapter))
6681 {
6682 ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R66, (0x26 + GET_LNA_GAIN(pAdapter)));
6683 }
6684 else
6685#endif // RALINK_ATE //
6686 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R66, (0x26 + GET_LNA_GAIN(pAdapter)));
6687 DBGPRINT(RT_DEBUG_TRACE,("turn off R17 tuning, restore to 0x%02x\n", R66));
6688 }
6689 return;
6690 }
6691
6692 DBGPRINT(RT_DEBUG_TRACE, ("MacAddr=%02lx, MacValue=0x%x\n", macAddr, macValue));
6693
6694 RTMP_IO_WRITE32(pAdapter, macAddr, macValue);
6695 sprintf(msg+strlen(msg), "[0x%08lX]:%08X ", macAddr, macValue);
6696 }
6697 }
6698 }
6699 else
6700 bIsPrintAllMAC = TRUE;
6701next:
6702 if (bIsPrintAllMAC)
6703 {
6704 struct file *file_w;
6705 PCHAR fileName = "MacDump.txt";
6706 mm_segment_t orig_fs;
6707
6708 orig_fs = get_fs();
6709 set_fs(KERNEL_DS);
6710
6711 // open file
6712 file_w = filp_open(fileName, O_WRONLY|O_CREAT, 0);
6713 if (IS_ERR(file_w))
6714 {
6715 DBGPRINT(RT_DEBUG_TRACE, ("-->2) %s: Error %ld opening %s\n", __FUNCTION__, -PTR_ERR(file_w), fileName));
6716 }
6717 else
6718 {
6719 if (file_w->f_op && file_w->f_op->write)
6720 {
6721 file_w->f_pos = 0;
6722 macAddr = 0x1000;
6723
6724 while (macAddr <= 0x1800)
6725 {
6726 RTMP_IO_READ32(pAdapter, macAddr, &macValue);
6727 sprintf(msg, "%08lx = %08X\n", macAddr, macValue);
6728
6729 // write data to file
6730 file_w->f_op->write(file_w, msg, strlen(msg), &file_w->f_pos);
6731
6732 printk("%s", msg);
6733 macAddr += 4;
6734 }
6735 sprintf(msg, "\nDump all MAC values to %s\n", fileName);
6736 }
6737 filp_close(file_w, NULL);
6738 }
6739 set_fs(orig_fs);
6740 }
6741 if(strlen(msg) == 1)
6742 sprintf(msg+strlen(msg), "===>Error command format!");
6743
6744 // Copy the information into the user buffer
6745 wrq->u.data.length = strlen(msg);
6746 Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
6747
6748 DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlMAC\n\n"));
6749}
6750
6751/*
6752 ==========================================================================
6753 Description:
6754 Read / Write E2PROM
6755 Arguments:
6756 pAdapter Pointer to our adapter
6757 wrq Pointer to the ioctl argument
6758
6759 Return Value:
6760 None
6761
6762 Note:
6763 Usage:
6764 1.) iwpriv ra0 e2p 0 ==> read E2PROM where Addr=0x0
6765 2.) iwpriv ra0 e2p 0=1234 ==> write E2PROM where Addr=0x0, value=1234
6766 ==========================================================================
6767*/
6768VOID RTMPIoctlE2PROM(
6769 IN PRTMP_ADAPTER pAdapter,
6770 IN struct iwreq *wrq)
6771{
6772 CHAR *this_char;
6773 CHAR *value;
6774 INT j = 0, k = 0;
6775 CHAR msg[1024];
6776 CHAR arg[255];
6777 USHORT eepAddr = 0;
6778 UCHAR temp[16], temp2[16];
6779 USHORT eepValue;
6780 int Status;
6781 BOOLEAN bIsPrintAllE2P = FALSE;
6782
6783
6784 memset(msg, 0x00, 1024);
6785 if (wrq->u.data.length > 1) //No parameters.
6786 {
6787 Status = copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length);
6788 sprintf(msg, "\n");
6789
6790 //Parsing Read or Write
6791 this_char = arg;
6792
6793
6794 if (!*this_char)
6795 goto next;
6796
6797 if ((value = rtstrchr(this_char, '=')) != NULL)
6798 *value++ = 0;
6799
6800 if (!value || !*value)
6801 { //Read
6802
6803 // Sanity check
6804 if(strlen(this_char) > 4)
6805 goto next;
6806
6807 j = strlen(this_char);
6808 while(j-- > 0)
6809 {
6810 if(this_char[j] > 'f' || this_char[j] < '0')
6811 return;
6812 }
6813
6814 // E2PROM addr
6815 k = j = strlen(this_char);
6816 while(j-- > 0)
6817 {
6818 this_char[4-k+j] = this_char[j];
6819 }
6820
6821 while(k < 4)
6822 this_char[3-k++]='0';
6823 this_char[4]='\0';
6824
6825 if(strlen(this_char) == 4)
6826 {
6827 AtoH(this_char, temp, 2);
6828 eepAddr = *temp*256 + temp[1];
6829 if (eepAddr < 0xFFFF)
6830 {
6831 RT28xx_EEPROM_READ16(pAdapter, eepAddr, eepValue);
6832 sprintf(msg+strlen(msg), "[0x%04X]:0x%04X ", eepAddr , eepValue);
6833 }
6834 else
6835 {//Invalid parametes, so default printk all bbp
6836 bIsPrintAllE2P = TRUE;
6837 goto next;
6838 }
6839 }
6840 }
6841 else
6842 { //Write
6843 memcpy(&temp2, value, strlen(value));
6844 temp2[strlen(value)] = '\0';
6845
6846 // Sanity check
6847 if((strlen(this_char) > 4) || strlen(temp2) > 8)
6848 goto next;
6849
6850 j = strlen(this_char);
6851 while(j-- > 0)
6852 {
6853 if(this_char[j] > 'f' || this_char[j] < '0')
6854 return;
6855 }
6856 j = strlen(temp2);
6857 while(j-- > 0)
6858 {
6859 if(temp2[j] > 'f' || temp2[j] < '0')
6860 return;
6861 }
6862
6863 //MAC Addr
6864 k = j = strlen(this_char);
6865 while(j-- > 0)
6866 {
6867 this_char[4-k+j] = this_char[j];
6868 }
6869
6870 while(k < 4)
6871 this_char[3-k++]='0';
6872 this_char[4]='\0';
6873
6874 //MAC value
6875 k = j = strlen(temp2);
6876 while(j-- > 0)
6877 {
6878 temp2[4-k+j] = temp2[j];
6879 }
6880
6881 while(k < 4)
6882 temp2[3-k++]='0';
6883 temp2[4]='\0';
6884
6885 AtoH(this_char, temp, 2);
6886 eepAddr = *temp*256 + temp[1];
6887
6888 AtoH(temp2, temp, 2);
6889 eepValue = *temp*256 + temp[1];
6890
6891 RT28xx_EEPROM_WRITE16(pAdapter, eepAddr, eepValue);
6892 sprintf(msg+strlen(msg), "[0x%02X]:%02X ", eepAddr, eepValue);
6893 }
6894 }
6895 else
6896 bIsPrintAllE2P = TRUE;
6897next:
6898 if (bIsPrintAllE2P)
6899 {
6900 struct file *file_w;
6901 PCHAR fileName = "EEPROMDump.txt";
6902 mm_segment_t orig_fs;
6903
6904 orig_fs = get_fs();
6905 set_fs(KERNEL_DS);
6906
6907 // open file
6908 file_w = filp_open(fileName, O_WRONLY|O_CREAT, 0);
6909 if (IS_ERR(file_w))
6910 {
6911 DBGPRINT(RT_DEBUG_TRACE, ("-->2) %s: Error %ld opening %s\n", __FUNCTION__, -PTR_ERR(file_w), fileName));
6912 }
6913 else
6914 {
6915 if (file_w->f_op && file_w->f_op->write)
6916 {
6917 file_w->f_pos = 0;
6918 eepAddr = 0x00;
6919
6920 while (eepAddr <= 0xFE)
6921 {
6922 RT28xx_EEPROM_READ16(pAdapter, eepAddr, eepValue);
6923 sprintf(msg, "%08x = %04x\n", eepAddr , eepValue);
6924
6925 // write data to file
6926 file_w->f_op->write(file_w, msg, strlen(msg), &file_w->f_pos);
6927
6928 printk("%s", msg);
6929 eepAddr += 2;
6930 }
6931 sprintf(msg, "\nDump all EEPROM values to %s\n", fileName);
6932 }
6933 filp_close(file_w, NULL);
6934 }
6935 set_fs(orig_fs);
6936 }
6937 if(strlen(msg) == 1)
6938 sprintf(msg+strlen(msg), "===>Error command format!");
6939
6940
6941 // Copy the information into the user buffer
6942 wrq->u.data.length = strlen(msg);
6943 Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
6944
6945 DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlE2PROM\n"));
6946}
6947#ifdef RT30xx
6948/*
6949 ==========================================================================
6950 Description:
6951 Read / Write RF register
6952Arguments:
6953 pAdapter Pointer to our adapter
6954 wrq Pointer to the ioctl argument
6955
6956 Return Value:
6957 None
6958
6959 Note:
6960 Usage:
6961 1.) iwpriv ra0 rf ==> read all RF registers
6962 2.) iwpriv ra0 rf 1 ==> read RF where RegID=1
6963 3.) iwpriv ra0 rf 1=10 ==> write RF R1=0x10
6964 ==========================================================================
6965*/
6966VOID RTMPIoctlRF(
6967 IN PRTMP_ADAPTER pAdapter,
6968 IN struct iwreq *wrq)
6969{
6970 CHAR *this_char;
6971 CHAR *value;
6972 UCHAR regRF = 0;
6973 CHAR msg[2048];
6974 CHAR arg[255];
6975 INT rfId;
6976 LONG rfValue;
6977 int Status;
6978 BOOLEAN bIsPrintAllRF = FALSE;
6979
6980
6981 memset(msg, 0x00, 2048);
6982 if (wrq->u.data.length > 1) //No parameters.
6983 {
6984 Status = copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length);
6985 sprintf(msg, "\n");
6986
6987 //Parsing Read or Write
6988 this_char = arg;
6989 if (!*this_char)
6990 goto next;
6991
6992 if ((value = strchr(this_char, '=')) != NULL)
6993 *value++ = 0;
6994
6995 if (!value || !*value)
6996 { //Read
6997 if (sscanf(this_char, "%d", &(rfId)) == 1)
6998 {
6999 if (rfId <= 31)
7000 {
7001 // In RT2860 ATE mode, we do not load 8051 firmware.
7002 //We must access RF directly.
7003 // For RT2870 ATE mode, ATE_RF_IO_WRITE8(/READ8)_BY_REG_ID are redefined.
7004#ifdef RALINK_ATE
7005 if (ATE_ON(pAdapter))
7006 {
7007 ATE_RF_IO_READ8_BY_REG_ID(pAdapter, rfId, &regRF);
7008 }
7009 else
7010#endif // RALINK_ATE //
7011 // according to Andy, Gary, David require.
7012 // the command rf shall read rf register directly for dubug.
7013 // BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
7014 RT30xxReadRFRegister(pAdapter, rfId, &regRF);
7015
7016 sprintf(msg+strlen(msg), "R%02d[0x%02x]:%02X ", rfId, rfId*2, regRF);
7017 }
7018 else
7019 {//Invalid parametes, so default printk all RF
7020 bIsPrintAllRF = TRUE;
7021 goto next;
7022 }
7023 }
7024 else
7025 { //Invalid parametes, so default printk all RF
7026 bIsPrintAllRF = TRUE;
7027 goto next;
7028 }
7029 }
7030 else
7031 { //Write
7032 if ((sscanf(this_char, "%d", &(rfId)) == 1) && (sscanf(value, "%lx", &(rfValue)) == 1))
7033 {
7034 if (rfId <= 31)
7035 {
7036 // In RT2860 ATE mode, we do not load 8051 firmware.
7037 // We should access RF registers directly.
7038 // For RT2870 ATE mode, ATE_RF_IO_WRITE8/READ8_BY_REG_ID are redefined.
7039#ifdef RALINK_ATE
7040 if (ATE_ON(pAdapter))
7041 {
7042 ATE_RF_IO_READ8_BY_REG_ID(pAdapter, rfId, &regRF);
7043 ATE_RF_IO_WRITE8_BY_REG_ID(pAdapter, (UCHAR)rfId,(UCHAR) rfValue);
7044 //Read it back for showing
7045 ATE_RF_IO_READ8_BY_REG_ID(pAdapter, rfId, &regRF);
7046 sprintf(msg+strlen(msg), "R%02d[0x%02X]:%02X\n", rfId, rfId*2, regRF);
7047 }
7048 else
7049#endif // RALINK_ATE //
7050 {
7051 // according to Andy, Gary, David require.
7052 // the command RF shall read/write RF register directly for dubug.
7053 //BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
7054 //BBP_IO_WRITE8_BY_REG_ID(pAdapter, (UCHAR)bbpId,(UCHAR) bbpValue);
7055 RT30xxReadRFRegister(pAdapter, rfId, &regRF);
7056 RT30xxWriteRFRegister(pAdapter, (UCHAR)rfId,(UCHAR) rfValue);
7057 //Read it back for showing
7058 //BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
7059 RT30xxReadRFRegister(pAdapter, rfId, &regRF);
7060 sprintf(msg+strlen(msg), "R%02d[0x%02X]:%02X\n", rfId, rfId*2, regRF);
7061 }
7062 }
7063 else
7064 {//Invalid parametes, so default printk all RF
7065 bIsPrintAllRF = TRUE;
7066 }
7067 }
7068 else
7069 { //Invalid parametes, so default printk all RF
7070 bIsPrintAllRF = TRUE;
7071 }
7072 }
7073 }
7074 else
7075 bIsPrintAllRF = TRUE;
7076next:
7077 if (bIsPrintAllRF)
7078 {
7079 memset(msg, 0x00, 2048);
7080 sprintf(msg, "\n");
7081 for (rfId = 0; rfId <= 31; rfId++)
7082 {
7083 // In RT2860 ATE mode, we do not load 8051 firmware.
7084 // We should access RF registers directly.
7085 // For RT2870 ATE mode, ATE_RF_IO_WRITE8/READ8_BY_REG_ID are redefined.
7086#ifdef RALINK_ATE
7087 if (ATE_ON(pAdapter))
7088 {
7089 ATE_RF_IO_READ8_BY_REG_ID(pAdapter, rfId, &regRF);
7090 }
7091 else
7092#endif // RALINK_ATE //
7093
7094 // according to Andy, Gary, David require.
7095 // the command RF shall read/write RF register directly for dubug.
7096 RT30xxReadRFRegister(pAdapter, rfId, &regRF);
7097 sprintf(msg+strlen(msg), "%03d = %02X\n", rfId, regRF);
7098 }
7099 // Copy the information into the user buffer
7100 DBGPRINT(RT_DEBUG_TRACE, ("strlen(msg)=%d\n", (UINT32)strlen(msg)));
7101 wrq->u.data.length = strlen(msg);
7102 if (copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length))
7103 {
7104 DBGPRINT(RT_DEBUG_TRACE, ("%s: copy_to_user() fail\n", __FUNCTION__));
7105 }
7106 }
7107 else
7108 {
7109 if(strlen(msg) == 1)
7110 sprintf(msg+strlen(msg), "===>Error command format!");
7111
7112 DBGPRINT(RT_DEBUG_TRACE, ("copy to user [msg=%s]\n", msg));
7113 // Copy the information into the user buffer
7114 DBGPRINT(RT_DEBUG_TRACE, ("strlen(msg) =%d\n", (UINT32)strlen(msg)));
7115
7116 // Copy the information into the user buffer
7117 wrq->u.data.length = strlen(msg);
7118 Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
7119 }
7120
7121 DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlRF\n\n"));
7122}
7123#endif // RT30xx //
7124#endif // DBG //
7125
7126
7127
7128
7129INT Set_TGnWifiTest_Proc(
7130 IN PRTMP_ADAPTER pAd,
7131 IN PUCHAR arg)
7132{
7133 if (simple_strtol(arg, 0, 10) == 0)
7134 pAd->StaCfg.bTGnWifiTest = FALSE;
7135 else
7136 pAd->StaCfg.bTGnWifiTest = TRUE;
7137
7138 DBGPRINT(RT_DEBUG_TRACE, ("IF Set_TGnWifiTest_Proc::(bTGnWifiTest=%d)\n", pAd->StaCfg.bTGnWifiTest));
7139 return TRUE;
7140}
7141
7142INT Set_LongRetryLimit_Proc(
7143 IN PRTMP_ADAPTER pAdapter,
7144 IN PUCHAR arg)
7145{
7146 TX_RTY_CFG_STRUC tx_rty_cfg;
7147 UCHAR LongRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
7148
7149 RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
7150 tx_rty_cfg.field.LongRtyLimit = LongRetryLimit;
7151 RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
7152 DBGPRINT(RT_DEBUG_TRACE, ("IF Set_LongRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
7153 return TRUE;
7154}
7155
7156INT Set_ShortRetryLimit_Proc(
7157 IN PRTMP_ADAPTER pAdapter,
7158 IN PUCHAR arg)
7159{
7160 TX_RTY_CFG_STRUC tx_rty_cfg;
7161 UCHAR ShortRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
7162
7163 RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
7164 tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit;
7165 RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
7166 DBGPRINT(RT_DEBUG_TRACE, ("IF Set_ShortRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
7167 return TRUE;
7168}
7169
7170#ifdef EXT_BUILD_CHANNEL_LIST
7171INT Set_Ieee80211dClientMode_Proc(
7172 IN PRTMP_ADAPTER pAdapter,
7173 IN PUCHAR arg)
7174{
7175 if (simple_strtol(arg, 0, 10) == 0)
7176 pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_None;
7177 else if (simple_strtol(arg, 0, 10) == 1)
7178 pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_Flexible;
7179 else if (simple_strtol(arg, 0, 10) == 2)
7180 pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_Strict;
7181 else
7182 return FALSE;
7183
7184 DBGPRINT(RT_DEBUG_TRACE, ("Set_Ieee802dMode_Proc::(IEEEE0211dMode=%d)\n", pAdapter->StaCfg.IEEE80211dClientMode));
7185 return TRUE;
7186}
7187#endif // EXT_BUILD_CHANNEL_LIST //
7188
7189#ifdef CARRIER_DETECTION_SUPPORT
7190INT Set_CarrierDetect_Proc(
7191 IN PRTMP_ADAPTER pAd,
7192 IN PUCHAR arg)
7193{
7194 if (simple_strtol(arg, 0, 10) == 0)
7195 pAd->CommonCfg.CarrierDetect.Enable = FALSE;
7196 else
7197 pAd->CommonCfg.CarrierDetect.Enable = TRUE;
7198
7199 DBGPRINT(RT_DEBUG_TRACE, ("IF Set_CarrierDetect_Proc::(CarrierDetect.Enable=%d)\n", pAd->CommonCfg.CarrierDetect.Enable));
7200 return TRUE;
7201}
7202#endif // CARRIER_DETECTION_SUPPORT //
7203
diff --git a/drivers/staging/rt3070/wpa.h b/drivers/staging/rt3070/wpa.h
new file mode 100644
index 000000000000..88c7c8bf3fcd
--- /dev/null
+++ b/drivers/staging/rt3070/wpa.h
@@ -0,0 +1,356 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 wpa.h
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Name Date Modification logs
36*/
37
38#ifndef __WPA_H__
39#define __WPA_H__
40
41// EAPOL Key descripter frame format related length
42#define LEN_KEY_DESC_NONCE 32
43#define LEN_KEY_DESC_IV 16
44#define LEN_KEY_DESC_RSC 8
45#define LEN_KEY_DESC_ID 8
46#define LEN_KEY_DESC_REPLAY 8
47#define LEN_KEY_DESC_MIC 16
48
49// The length is the EAPoL-Key frame except key data field.
50// Please refer to 802.11i-2004 ,Figure 43u in p.78
51#define LEN_EAPOL_KEY_MSG (sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE)
52
53// EAP Code Type.
54#define EAP_CODE_REQUEST 1
55#define EAP_CODE_RESPONSE 2
56#define EAP_CODE_SUCCESS 3
57#define EAP_CODE_FAILURE 4
58
59// EAPOL frame Protocol Version
60#define EAPOL_VER 1
61#define EAPOL_VER2 2
62
63// EAPOL-KEY Descriptor Type
64#define WPA1_KEY_DESC 0xfe
65#define WPA2_KEY_DESC 0x02
66
67// Key Descriptor Version of Key Information
68#define DESC_TYPE_TKIP 1
69#define DESC_TYPE_AES 2
70#define DESC_TYPE_MESH 3
71
72#define LEN_MSG1_2WAY 0x7f
73#define MAX_LEN_OF_EAP_HS 256
74
75#define LEN_MASTER_KEY 32
76
77// EAPOL EK, MK
78#define LEN_EAP_EK 16
79#define LEN_EAP_MICK 16
80#define LEN_EAP_KEY ((LEN_EAP_EK)+(LEN_EAP_MICK))
81// TKIP key related
82#define LEN_PMKID 16
83#define LEN_TKIP_EK 16
84#define LEN_TKIP_RXMICK 8
85#define LEN_TKIP_TXMICK 8
86#define LEN_AES_EK 16
87#define LEN_AES_KEY LEN_AES_EK
88#define LEN_TKIP_KEY ((LEN_TKIP_EK)+(LEN_TKIP_RXMICK)+(LEN_TKIP_TXMICK))
89#define TKIP_AP_TXMICK_OFFSET ((LEN_EAP_KEY)+(LEN_TKIP_EK))
90#define TKIP_AP_RXMICK_OFFSET (TKIP_AP_TXMICK_OFFSET+LEN_TKIP_TXMICK)
91#define TKIP_GTK_LENGTH ((LEN_TKIP_EK)+(LEN_TKIP_RXMICK)+(LEN_TKIP_TXMICK))
92#define LEN_PTK ((LEN_EAP_KEY)+(LEN_TKIP_KEY))
93
94// RSN IE Length definition
95#define MAX_LEN_OF_RSNIE 90
96#define MIN_LEN_OF_RSNIE 8
97
98//EAP Packet Type
99#define EAPPacket 0
100#define EAPOLStart 1
101#define EAPOLLogoff 2
102#define EAPOLKey 3
103#define EAPOLASFAlert 4
104#define EAPTtypeMax 5
105
106#define EAPOL_MSG_INVALID 0
107#define EAPOL_PAIR_MSG_1 1
108#define EAPOL_PAIR_MSG_2 2
109#define EAPOL_PAIR_MSG_3 3
110#define EAPOL_PAIR_MSG_4 4
111#define EAPOL_GROUP_MSG_1 5
112#define EAPOL_GROUP_MSG_2 6
113
114#define PAIRWISEKEY 1
115#define GROUPKEY 0
116
117// Retry timer counter initial value
118#define PEER_MSG1_RETRY_TIMER_CTR 0
119#define PEER_MSG3_RETRY_TIMER_CTR 10
120#define GROUP_MSG1_RETRY_TIMER_CTR 20
121
122
123#define EAPOL_START_DISABLE 0
124#define EAPOL_START_PSK 1
125#define EAPOL_START_1X 2
126
127#define MIX_CIPHER_WPA_TKIP_ON(x) (((x) & 0x08) != 0)
128#define MIX_CIPHER_WPA_AES_ON(x) (((x) & 0x04) != 0)
129#define MIX_CIPHER_WPA2_TKIP_ON(x) (((x) & 0x02) != 0)
130#define MIX_CIPHER_WPA2_AES_ON(x) (((x) & 0x01) != 0)
131
132#define ROUND_UP(__x, __y) \
133 (((ULONG)((__x)+((__y)-1))) & ((ULONG)~((__y)-1)))
134
135#define ADD_ONE_To_64BIT_VAR(_V) \
136{ \
137 UCHAR cnt = LEN_KEY_DESC_REPLAY; \
138 do \
139 { \
140 cnt--; \
141 _V[cnt]++; \
142 if (cnt == 0) \
143 break; \
144 }while (_V[cnt] == 0); \
145}
146
147#define IS_WPA_CAPABILITY(a) (((a) >= Ndis802_11AuthModeWPA) && ((a) <= Ndis802_11AuthModeWPA1PSKWPA2PSK))
148
149// EAPOL Key Information definition within Key descriptor format
150typedef struct PACKED _KEY_INFO
151{
152#ifdef RT_BIG_ENDIAN
153 UCHAR KeyAck:1;
154 UCHAR Install:1;
155 UCHAR KeyIndex:2;
156 UCHAR KeyType:1;
157 UCHAR KeyDescVer:3;
158 UCHAR Rsvd:3;
159 UCHAR EKD_DL:1; // EKD for AP; DL for STA
160 UCHAR Request:1;
161 UCHAR Error:1;
162 UCHAR Secure:1;
163 UCHAR KeyMic:1;
164#else
165 UCHAR KeyMic:1;
166 UCHAR Secure:1;
167 UCHAR Error:1;
168 UCHAR Request:1;
169 UCHAR EKD_DL:1; // EKD for AP; DL for STA
170 UCHAR Rsvd:3;
171 UCHAR KeyDescVer:3;
172 UCHAR KeyType:1;
173 UCHAR KeyIndex:2;
174 UCHAR Install:1;
175 UCHAR KeyAck:1;
176#endif
177} KEY_INFO, *PKEY_INFO;
178
179// EAPOL Key descriptor format
180typedef struct PACKED _KEY_DESCRIPTER
181{
182 UCHAR Type;
183 KEY_INFO KeyInfo;
184 UCHAR KeyLength[2];
185 UCHAR ReplayCounter[LEN_KEY_DESC_REPLAY];
186 UCHAR KeyNonce[LEN_KEY_DESC_NONCE];
187 UCHAR KeyIv[LEN_KEY_DESC_IV];
188 UCHAR KeyRsc[LEN_KEY_DESC_RSC];
189 UCHAR KeyId[LEN_KEY_DESC_ID];
190 UCHAR KeyMic[LEN_KEY_DESC_MIC];
191 UCHAR KeyDataLen[2];
192 UCHAR KeyData[MAX_LEN_OF_RSNIE];
193} KEY_DESCRIPTER, *PKEY_DESCRIPTER;
194
195typedef struct PACKED _EAPOL_PACKET
196{
197 UCHAR ProVer;
198 UCHAR ProType;
199 UCHAR Body_Len[2];
200 KEY_DESCRIPTER KeyDesc;
201} EAPOL_PACKET, *PEAPOL_PACKET;
202
203//802.11i D10 page 83
204typedef struct PACKED _GTK_ENCAP
205{
206#ifndef RT_BIG_ENDIAN
207 UCHAR Kid:2;
208 UCHAR tx:1;
209 UCHAR rsv:5;
210 UCHAR rsv1;
211#else
212 UCHAR rsv:5;
213 UCHAR tx:1;
214 UCHAR Kid:2;
215 UCHAR rsv1;
216#endif
217 UCHAR GTK[TKIP_GTK_LENGTH];
218} GTK_ENCAP, *PGTK_ENCAP;
219
220typedef struct PACKED _KDE_ENCAP
221{
222 UCHAR Type;
223 UCHAR Len;
224 UCHAR OUI[3];
225 UCHAR DataType;
226 GTK_ENCAP GTKEncap;
227} KDE_ENCAP, *PKDE_ENCAP;
228
229// For WPA1
230typedef struct PACKED _RSNIE {
231 UCHAR oui[4];
232 USHORT version;
233 UCHAR mcast[4];
234 USHORT ucount;
235 struct PACKED {
236 UCHAR oui[4];
237 }ucast[1];
238} RSNIE, *PRSNIE;
239
240// For WPA2
241typedef struct PACKED _RSNIE2 {
242 USHORT version;
243 UCHAR mcast[4];
244 USHORT ucount;
245 struct PACKED {
246 UCHAR oui[4];
247 }ucast[1];
248} RSNIE2, *PRSNIE2;
249
250// AKM Suite
251typedef struct PACKED _RSNIE_AUTH {
252 USHORT acount;
253 struct PACKED {
254 UCHAR oui[4];
255 }auth[1];
256} RSNIE_AUTH,*PRSNIE_AUTH;
257
258typedef union PACKED _RSN_CAPABILITIES {
259 struct PACKED {
260#ifdef RT_BIG_ENDIAN
261 USHORT Rsvd:10;
262 USHORT GTKSA_R_Counter:2;
263 USHORT PTKSA_R_Counter:2;
264 USHORT No_Pairwise:1;
265 USHORT PreAuth:1;
266#else
267 USHORT PreAuth:1;
268 USHORT No_Pairwise:1;
269 USHORT PTKSA_R_Counter:2;
270 USHORT GTKSA_R_Counter:2;
271 USHORT Rsvd:10;
272#endif
273 } field;
274 USHORT word;
275} RSN_CAPABILITIES, *PRSN_CAPABILITIES;
276
277typedef struct PACKED _EAP_HDR {
278 UCHAR ProVer;
279 UCHAR ProType;
280 UCHAR Body_Len[2];
281 UCHAR code;
282 UCHAR identifier;
283 UCHAR length[2]; // including code and identifier, followed by length-2 octets of data
284} EAP_HDR, *PEAP_HDR;
285
286// For supplicant state machine states. 802.11i Draft 4.1, p. 97
287// We simplified it
288typedef enum _WpaState
289{
290 SS_NOTUSE, // 0
291 SS_START, // 1
292 SS_WAIT_MSG_3, // 2
293 SS_WAIT_GROUP, // 3
294 SS_FINISH, // 4
295 SS_KEYUPDATE, // 5
296} WPA_STATE;
297
298//
299// The definition of the cipher combination
300//
301// bit3 bit2 bit1 bit0
302// +------------+------------+
303// | WPA | WPA2 |
304// +------+-----+------+-----+
305// | TKIP | AES | TKIP | AES |
306// | 0 | 1 | 1 | 0 | -> 0x06
307// | 0 | 1 | 1 | 1 | -> 0x07
308// | 1 | 0 | 0 | 1 | -> 0x09
309// | 1 | 0 | 1 | 1 | -> 0x0B
310// | 1 | 1 | 0 | 1 | -> 0x0D
311// | 1 | 1 | 1 | 0 | -> 0x0E
312// | 1 | 1 | 1 | 1 | -> 0x0F
313// +------+-----+------+-----+
314//
315typedef enum _WpaMixPairCipher
316{
317 MIX_CIPHER_NOTUSE = 0x00,
318 WPA_NONE_WPA2_TKIPAES = 0x03, // WPA2-TKIPAES
319 WPA_AES_WPA2_TKIP = 0x06,
320 WPA_AES_WPA2_TKIPAES = 0x07,
321 WPA_TKIP_WPA2_AES = 0x09,
322 WPA_TKIP_WPA2_TKIPAES = 0x0B,
323 WPA_TKIPAES_WPA2_NONE = 0x0C, // WPA-TKIPAES
324 WPA_TKIPAES_WPA2_AES = 0x0D,
325 WPA_TKIPAES_WPA2_TKIP = 0x0E,
326 WPA_TKIPAES_WPA2_TKIPAES = 0x0F,
327} WPA_MIX_PAIR_CIPHER;
328
329typedef struct PACKED _RSN_IE_HEADER_STRUCT {
330 UCHAR Eid;
331 UCHAR Length;
332 USHORT Version; // Little endian format
333} RSN_IE_HEADER_STRUCT, *PRSN_IE_HEADER_STRUCT;
334
335// Cipher suite selector types
336typedef struct PACKED _CIPHER_SUITE_STRUCT {
337 UCHAR Oui[3];
338 UCHAR Type;
339} CIPHER_SUITE_STRUCT, *PCIPHER_SUITE_STRUCT;
340
341// Authentication and Key Management suite selector
342typedef struct PACKED _AKM_SUITE_STRUCT {
343 UCHAR Oui[3];
344 UCHAR Type;
345} AKM_SUITE_STRUCT, *PAKM_SUITE_STRUCT;
346
347// RSN capability
348typedef struct PACKED _RSN_CAPABILITY {
349 USHORT Rsv:10;
350 USHORT GTKSAReplayCnt:2;
351 USHORT PTKSAReplayCnt:2;
352 USHORT NoPairwise:1;
353 USHORT PreAuth:1;
354} RSN_CAPABILITY, *PRSN_CAPABILITY;
355
356#endif